⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adin_mic_linux_alsa.c

📁 julius version 4.12.about sound recognition.
💻 C
📖 第 1 页 / 共 2 页
字号:
      return(FALSE);    }    if ((minsize = snd_pcm_hw_params_get_period_size_min(hwparams, &dir)) < 0) {      jlog("Error: adin_alsa: cannot get minimum period size\n");      return(FALSE);    }#else        has_current_period = TRUE;    if ((err = snd_pcm_hw_params_get_period_time(hwparams, &period_time_current, &dir)) < 0) {      has_current_period = FALSE;    }    if (has_current_period) {      jlog("Stat: adin_alsa: current latency time: %d msec\n", period_time_current / 1000);    }#endif    /* set period time (near value will be used) */#if (SND_LIB_MAJOR == 0)    periodsize = actual_rate * latency / 1000 * sizeof(SP16);    if (periodsize < minsize) {      jlog("Stat: adin_alsa: PCM latency of %d ms (%d bytes) too small, use device minimum %d bytes\n", latency, periodsize, minsize);      periodsize = minsize;    } else if (periodsize > maxsize) {      jlog("Stat: adin_alsa: PCM latency of %d ms (%d bytes) too large, use device maximum %d bytes\n", latency, periodsize, maxsize);      periodsize = maxsize;    }    actual_size = snd_pcm_hw_params_set_period_size_near(handle, hwparams, periodsize, &dir);    if (actual_size < 0) {      jlog("Error: adin_alsa: cannot set PCM record period size to %d (%s)\n", periodsize, snd_strerror(actual_size));      return(FALSE);    }    if (actual_size != periodsize) {      jlog("Stat: adin_alsa: PCM period size: %d bytes (%dms) -> %d bytes\n", periodsize, latency, actual_size);    }    jlog("Stat: Audio I/O Latency = %d msec (data fragment = %d frames)\n", actual_size * 1000 / (actual_rate * sizeof(SP16)), actual_size / sizeof(SP16));#else    period_time = latency * 1000;    if (!force && has_current_period && period_time > period_time_current) {	jlog("Stat: adin_alsa: current latency (%dms) is shorter than %dms, leave it\n", period_time_current / 1000, latency);	period_time = period_time_current;    } else {      if ((err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0)) < 0) {	jlog("Error: adin_alsa: cannot set PCM record period time to %d msec (%s)\n", period_time / 1000, snd_strerror(err));	return(FALSE);      }      snd_pcm_hw_params_get_period_size(hwparams, &chunk_size, 0);      jlog("Stat: adin_alsa: latency set to %d msec (chunk = %d bytes)\n", period_time / 1000, chunk_size);    }#endif#if (SND_LIB_MAJOR == 0)    /* set number of periods ( = 2) */    if ((err = snd_pcm_hw_params_set_periods(handle, hwparams, sizeof(SP16), 0)) < 0) {      jlog("Error: adin_alsa: cannot set PCM number of periods to %d (%s)\n", sizeof(SP16), snd_strerror(err));      return(FALSE);    }#endif  }  /* apply the configuration to the PCM device */  if ((err = snd_pcm_hw_params(handle, hwparams)) < 0) {    jlog("Error: adin_alsa: cannot set PCM hardware parameters (%s)\n", snd_strerror(err));    return(FALSE);  }  /* prepare for recording */  if ((err = snd_pcm_prepare(handle)) < 0) {    jlog("Error: adin_alsa: failed to prepare audio interface (%s)\n", snd_strerror(err));  }#if (SND_LIB_MAJOR == 0)  /* prepare for polling */  count = snd_pcm_poll_descriptors_count(handle);  if (count <= 0) {    jlog("Error: adin_alsa: invalid PCM poll descriptors count\n");    return(FALSE);  }  ufds = mymalloc(sizeof(struct pollfd) * count);  if ((err = snd_pcm_poll_descriptors(handle, ufds, count)) < 0) {    jlog("Error: adin_alsa: unable to obtain poll descriptors for PCM recording (%s)\n", snd_strerror(err));    return(FALSE);  }#endif  /* output status */  output_card_info(pcm_name, handle);  return(TRUE);#endif /* HAS_ALSA */}#ifdef HAS_ALSA/**  * Error recovery when PCM buffer underrun or suspend. *  * @param handle [in] audio handler * @param err [in] error code *  * @return 0 on success, otherwise the given errno. */static intxrun_recovery(snd_pcm_t *handle, int err){  if (err == -EPIPE) {    /* under-run */    err = snd_pcm_prepare(handle);    if (err < 0)      jlog("Error: adin_alsa: can't recovery from PCM buffer underrun, prepare failed: %s\n", snd_strerror(err));    return 0;  } else if (err == -ESTRPIPE) {    while ((err = snd_pcm_resume(handle)) == -EAGAIN)      sleep(1);       /* wait until the suspend flag is released */    if (err < 0) {      err = snd_pcm_prepare(handle);      if (err < 0)	jlog("Error: adin_alsa: can't recovery from PCM buffer suspend, prepare failed: %s\n", snd_strerror(err));    }    return 0;  }  return err;}#endif /* HAS_ALSA *//**  * Start recording. *  * @return TRUE on success, FALSE on failure. */booleanadin_alsa_begin(){#ifndef HAS_ALSA  return FALSE;#else  int err;  snd_pcm_state_t status;  /* check hardware status */  while(1) {			/* wait till prepared */    status = snd_pcm_state(handle);    switch(status) {    case SND_PCM_STATE_PREPARED: /* prepared for operation */      if ((err = snd_pcm_start(handle)) < 0) {	jlog("Error: adin_alsa: cannot start PCM (%s)\n", snd_strerror(err));	return (FALSE);      }      return(TRUE);      break;    case SND_PCM_STATE_RUNNING:	/* capturing the samples of other application */      if ((err = snd_pcm_drop(handle)) < 0) { /* discard the existing samples */	jlog("Error: adin_alsa: cannot drop PCM (%s)\n", snd_strerror(err));	return (FALSE);      }      break;    case SND_PCM_STATE_XRUN:	/* buffer overrun */      if ((err = xrun_recovery(handle, -EPIPE)) < 0) {	jlog("Error: adin_alsa: PCM XRUN recovery failed (%s)\n", snd_strerror(err));	return(FALSE);      }      break;    case SND_PCM_STATE_SUSPENDED:	/* suspended by power management system */      if ((err = xrun_recovery(handle, -ESTRPIPE)) < 0) {	jlog("Error: adin_alsa: PCM XRUN recovery failed (%s)\n", snd_strerror(err));	return(FALSE);      }      break;    default:      /* do nothing */      break;    }  }  return(TRUE);#endif /* HAS_ALSA */}  /**  * Stop recording. *  * @return TRUE on success, FALSE on failure. */booleanadin_alsa_end(){  return(TRUE);}/** * @brief  Read samples from device *  * Try to read @a sampnum samples and returns actual number of recorded * samples currently available.  This function will block until * at least one sample can be obtained. *  * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read *  * @return actural number of read samples, -2 if an error occured. */intadin_alsa_read(SP16 *buf, int sampnum){#ifndef HAS_ALSA  return -2;#else  int cnt;#if (SND_LIB_MAJOR == 0)  snd_pcm_sframes_t avail;  while ((avail = snd_pcm_avail_update(handle)) <= 0) {    usleep(latency * 1000);  }  if (avail < sampnum) {    cnt = snd_pcm_readi(handle, buf, avail);  } else {    cnt = snd_pcm_readi(handle, buf, sampnum);  }#else  int ret;  snd_pcm_status_t *status;  int res;  struct timeval now, diff, tstamp;  ret = snd_pcm_wait(handle, MAXPOLLINTERVAL);  switch (ret) {  case 0:			/* timeout */    jlog("Warning: adin_alsa: no data fragment after %d msec?\n", MAXPOLLINTERVAL);    cnt = 0;    break;  case 1:			/* has data */    cnt = snd_pcm_readi(handle, buf, sampnum); /* read available (non-block) */    break;  case -EPIPE:			/* pipe error */    /* try to recover the broken pipe */    snd_pcm_status_alloca(&status);    if ((res = snd_pcm_status(handle, status))<0) {      jlog("Error: adin_alsa: broken pipe: status error (%s)\n", snd_strerror(res));      return -2;    }    if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {      gettimeofday(&now, 0);      snd_pcm_status_get_trigger_tstamp(status, &tstamp);      timersub(&now, &tstamp, &diff);      jlog("Warning: adin_alsa: overrun!!! (at least %.3f ms long)\n",	   diff.tv_sec * 1000 + diff.tv_usec / 1000.0);      if ((res = snd_pcm_prepare(handle))<0) {	jlog("Error: adin_alsa: overrun: prepare error (%s)", snd_strerror(res));	return -2;      }      break;         /* ok, data should be accepted again */    } else if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) {      jlog("Warning: adin_alsa: draining: capture stream format change? attempting recover...\n");      if ((res = snd_pcm_prepare(handle))<0) {	jlog("Error: adin_alsa: draining: prepare error (%s)", snd_strerror(res));	return -2;      }      break;    }    jlog("Error: adin_alsa: error in snd_pcm_wait() (%s)\n", snd_pcm_state_name(snd_pcm_status_get_state(status)));    return -2;  default:			/* other poll error */    jlog("Error: adin_alsa: error in snd_pcm_wait() (%s)\n", snd_strerror(ret));    return(-2);			/* error */  }#endif  if (cnt < 0) {    jlog("Error: adin_alsa: failed to read PCM (%s)\n", snd_strerror(cnt));    return(-2);  }  if (need_swap) {    swap_sample_bytes(buf, cnt);  }  return(cnt);#endif /* HAS_ALSA */}/* end of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -