ALSA出现了看似正确的时机,出现了意外的欠载情况

时间:2018-11-03 12:26:36

标签: c linux alsa openembedded imx6

我为snd_pcm_writei()调用中的虚假欠载错误而发疯。

我使用阻止设置:

snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);

这是snd_pcm_dump_sw_setup()输出:

  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 1764
  period_event : 0
  start_threshold  : 1
  stop_threshold   : 3528
  silence_threshold: 0
  silence_size : 0
  boundary     : 1849688064

设置硬件参数时,我记录snd_pcm_hw_params_set_rate_near(),snd_pcm_hw_params_set_periods_near(),snd_pcm_hw_params_set_period_size_near()调用的结果:

3719.1287 D [AlsaSound] SOUND: setupWithFreq sampling rate: 44100, dir: 0
3719.1288 D [AlsaSound] SOUND: number of periods: 2, dir: 0
3719.1289 D [AlsaSound] SOUND: period size: 1764 frames, dir: 0

以下是填充循环中的相关部分,反复称为:

log.debug("play %d samples", n);
while ((ret = snd_pcm_writei(handle, playBuf, n)) != (long)n) {
    if (ret < 0) {
        log.warn("ALSA error: %s\n", snd_strerror(ret));
        if ((ret = snd_pcm_recover(handle, ret, 0)) < 0) {
            log.error("ALSA error after recover: %s\n", snd_strerror(ret));
            checkFatalAlsaError(snd_pcm_prepare(handle), "ALSA irrecoverable error: %s");
        }
    } else {
        log.warn("ALSA short write...?\n");
        break;
    }
}

这是一切正常的日志:

3751.3029 D [AlsaSound] Starting square sound, nsamples: 3528, nPeriods: 2, nFrames: 1764
3751.3030 D [AlsaSound] play 1739 samples
3751.3037 D [AlsaSound] play 1739 samples
3751.3046 D [AlsaSound] play 50 samples
3751.3048 D [AlsaSound] Stop sound

有时我会得到:

3752.8764 D [AlsaSound] Setup square sound, time: 800, nsamples: 3528
3752.8769 D [AlsaSound] Starting square sound, nsamples: 3528, nPeriods: 2, nFrames: 1764
3752.8770 D [AlsaSound] play 1739 samples
3752.8779 D [AlsaSound] play 1739 samples
3752.8782 W [AlsaSound] ALSA error: Broken pipe
ALSA lib ../../../alsa-lib-1.1.4.1/src/pcm/pcm.c:8323:(snd_pcm_recover) underrun occurred
3752.8792 D [AlsaSound] play 50 samples
3752.8793 D [AlsaSound] Stop sound

从日志时间戳可以看出,欠载发生在第一次写入的2毫秒内-写入约40毫秒的样本。所示的两个示例在任何其他方面都是相同的,该设备未播放声音并且正在prepare()中。

可能是什么问题以及解决方案?

请注意,我故意写的样本少于期间大小。

Linux内核4.9.87版,libasound2版本1.1.4.1-r0,ARM(Colibri iMX6)平台

0 个答案:

没有答案