我目前正在试验实时信号处理,所以我去尝试了 PortAudio(来自 C)。
我的电脑上有两个音频接口,板载声音(Intel HD Audio)和一个 USB 音频接口。两者通常在 Linux 上的 ALSA 下都能正常工作。我还尝试了 Linux 上 JACK 下的 USB 音频接口,这也很完美。
我所做的:
我的代码只是初始化 PortAudio,打开并启动一个流(一个通道,paInt32
样本格式,defaultLowInputLatency
/ defaultLowOutputLatency
,尽管我尝试更改为paFloat32
or defaultHighInputLatency
/ defaultHighOutputLatency
,但没有任何改进)。
sizeof(int32_t) * frameCount
每次调用回调时,它都会将字节memcpy
从输入复制到输出缓冲区,然后返回paContinue
。它在回调中什么也不做。没有内存分配,没有系统调用,没有任何东西可以阻塞。它只是输出它读取的内容。代码很简单,但我仍然无法运行它。
memcpy
用循环将frameCount
类型的元素从输入复制到输出缓冲区替换int32_t
并没有改变任何东西。
我试过的:
使用 PortAudio 尝试了以下场景。
- 通过 USB 音频接口输入和输出,PortAudio 上的回调机制,ALSA 后端。
- 通过 USB 音频接口输入和输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,ALSA 后端。
- 通过 USB 音频接口输入,通过板载声音输出,PortAudio 上的回调机制,ALSA 后端。
- 通过 USB 音频接口输入,通过板载声音输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,ALSA 后端。
- 通过 USB 音频接口输入和输出,PortAudio 上的回调机制,JACK 后端。
- 通过 USB 音频接口输入和输出,在具有 1024 个样本缓冲区大小的 PortAudio 上阻塞 I/O,JACK 后端。
我遇到的问题:
结果如下。(数字代表上述场景。)
- 设备无输出。
- 设备输出不稳定(中断)。一直有很多缓冲区不足。
- 设备无输出。
- 设备的输出不可靠。有时有效,有时无效。(无需更改任何内容,只需多次运行可执行文件。)当它工作时,延迟开始时很低,但随着时间的推移会增加并且变得非常明显。
- 设备无输出。
- 设备无输出。
在每次尝试之间,如果 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 有一个内核级组件。)
我的问题:
任何人都知道这里有什么问题以及我该如何解决?或者至少,我怎么能把它缩小一点?