【发布时间】:2016-05-20 01:53:54
【问题描述】:
我目前正在试验实时信号处理,所以我尝试了 PortAudio(来自 C)。
我的电脑上有两个音频接口,板载声音(英特尔高清音频)和一个 USB 音频接口。两者通常在 Linux 上的 ALSA 下都能正常工作。我也试过Linux下JACK下的USB音频接口,效果也很好。
我的工作:
我的代码只是初始化 PortAudio,打开并启动一个流(一个通道,paInt32 样本格式,defaultLowInputLatency/defaultLowOutputLatency,尽管我尝试更改为 paFloat32 或 defaultHighInputLatency/defaultHighOutputLatency,其中没有任何改善)。
在每次调用回调时,它通过memcpy 将sizeof(int32_t) * frameCount 字节从输入缓冲区复制到输出缓冲区,然后返回paContinue。它在回调中什么也不做。没有内存分配,没有系统调用,没有任何东西可以阻塞。它只是输出它读取的内容。代码很简单,还是不能运行。
将memcpy 替换为循环将int32_t 类型的frameCount 元素从输入缓冲区复制到输出缓冲区并没有改变任何内容。
我的尝试:
使用 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 有一个内核级组件。)
我的问题:
任何人都知道这里有什么问题以及我该如何解决它?或者至少,我怎样才能把范围缩小一点?
【问题讨论】:
-
请出示您的代码。
-
给你!非常感谢您的时间和努力! /// PortAudio(基于回调):pastebin.com/MrHpkXEA /// PortAudio(阻塞 I/O):pastebin.com/MDdUZ8W3 /// RtAudio(基于回调):pastebin.com/YCQ0JpSR
-
FWIW,我在 Ubuntu 16.04.1 上使用简单的 PortAudio 应用程序遇到了同样的问题。我间歇性地收到此错误。确实非常令人沮丧!
-
我在 rasberian 上的 pyaudio 也有类似的问题。使用添加空帧的建议答案进行测试。
标签: linux audio alsa portaudio jack