4

我目前正在试验实时信号处理,所以我去尝试了 PortAudio(来自 C)。

我的电脑上有两个音频接口,板载声音(Intel HD Audio)和一个 USB 音频接口。两者通常在 Linux 上的 ALSA 下都能正常工作。我还尝试了 Linux 上 JACK 下的 USB 音频接口,这也很完美。

我所做的:

我的代码只是初始化 PortAudio,打开并启动一个流(一个通道,paInt32样本格式,defaultLowInputLatency/ defaultLowOutputLatency,尽管我尝试更改为paFloat32or defaultHighInputLatency/ defaultHighOutputLatency,但没有任何改进)。

sizeof(int32_t) * frameCount每次调用回调时,它都会将字节memcpy从输入复制到输出缓冲区,然后返回paContinue。它在回调中什么也不做。没有内存分配,没有系统调用,没有任何东西可以阻塞。它只是输出它读取的内容。代码很简单,但我仍然无法运行它。

memcpy用循环将frameCount类型的元素从输入复制到输出缓冲区替换int32_t并没有改变任何东西。

我试过的:

使用 PortAudio 尝试了以下场景。

  1. 通过 USB 音频接口输入和输出,PortAudio 上的回调机制,ALSA 后端。
  2. 通过 USB 音频接口输入和输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,ALSA 后端。
  3. 通过 USB 音频接口输入,通过板载声音输出,PortAudio 上的回调机制,ALSA 后端。
  4. 通过 USB 音频接口输入,通过板载声音输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,ALSA 后端。
  5. 通过 USB 音频接口输入和输出,PortAudio 上的回调机制,JACK 后端。
  6. 通过 USB 音频接口输入和输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,JACK 后端。

我遇到的问题:

结果如下。(数字代表上述场景。)

  1. 设备无输出。
  2. 设备输出不稳定(中断)。一直有很多缓冲区不足。
  3. 设备无输出。
  4. 设备的输出不可靠。有时有效,有时无效。(无需更改任何内容,只需多次运行可执行文件。)当它工作时,延迟开始时很低,但随着时间的推移会增加并且变得非常明显。
  5. 设备无输出。
  6. 设备无输出。

在每次尝试之间,如果 ALSA 仍然响应,它会被测试(有时它会完全“锁定”,因此没有应用程序可以再输出声音)并重新启动系统以防 ALSA 被“锁定”,然后继续测试。

更多详细信息,在跟踪问题时可能很有用:

在根本没有输出的情况下,我在使用 ALSA 作为后端时收到以下错误消息。

Expression 'err' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3350
Expression 'ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3876
Expression 'PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4248

使用 JACK 作为后端时,我收到以下错误消息。

Cannot lock down 42435354 byte memory area (Cannot allocate memory)

此外,无论我使用什么方法,我总是会收到这些警告。

ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map

在使用 ALSA 时,我还会收到一两个关于欠载的投诉。

ALSA lib pcm.c:7905:(snd_pcm_recover) underrun occurred

我调用的 PortAudio 函数(按此顺序Pa_Initialize, Pa_OpenStream, Pa_StartStream, Pa_StopStream, Pa_CloseStream, Pa_Terminate, )都返回paNoError.

PortAudio 附带的paex_read_write_wire.c(阻塞 I/O)示例通常可以访问设备,但也会遇到很多欠载(例如我的测试用例 2)。

在任何一种情况下,都没有什么有趣的东西出现在dmesg. (刚刚检查过,因为 ALSA 有一个内核级组件。)

我的问题:

任何人都知道这里有什么问题以及我该如何解决?或者至少,我怎么能把它缩小一点?

4

2 回答 2

1

当您只写入一个样本块时,播放设备将在您即将写入下一个块时用完样本。

在开始读/写循环之前,您应该用零样本填充播放设备的缓冲区。

于 2016-02-10T09:25:29.517 回答
0

我不清楚细节,但对我来说,从默认的低输入/输出延迟切换到默认的高输入/输出延迟可以解决这个问题,而且我无法感知延迟的变化。

于 2020-03-25T21:44:57.893 回答