c++ - Portaudio 和 ALSA : "Cannot obtain info for CTL elem"

标签 c++ audio alsa portaudio

我正在尝试使用 Portaudio。首先,我想运行发行版中包含的测试程序。将头文件 portaudio.h 和 libportaudio.a 复制到测试目录后,我成功编译了 patest_sine8.c:

$ g++ -o test1 patest_sine8.c -lrt -lm -lpthread -lasound libportaudio.a

当我运行程序时,输出如下:

PortAudio Test: output signed 8 bit sine wave.
ALSA lib setup.c:548:(add_elem) Cannot obtain info for CTL elem (MIXER,'AC97 2ch->4ch Copy Switch',0,0,0): No such file or directory
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib setup.c:548:(add_elem) Cannot obtain info for CTL elem (MIXER,'AC97 2ch->4ch Copy Switch',0,0,0): No such file or directory
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib setup.c:548:(add_elem) Cannot obtain info for CTL elem (PCM,'IEC958 Playback PCM Stream',0,0,0): No such file or directory
ALSA lib setup.c:548:(add_elem) Cannot obtain info for CTL elem (PCM,'IEC958 Playback PCM Stream',0,0,0): No such file or directory
ALSA lib setup.c:548:(add_elem) Cannot obtain info for CTL elem (PCM,'IEC958 Playback PCM Stream',0,0,0): No such file or directory
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:7843:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:7843:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:7843:(snd_pcm_recover) underrun occurred

声音确实从扬声器中发出,但显然有问题。 最近在带有 VMware 的虚拟机中安装 Fedora 21 (XFCE) 时会发生这种情况。安装后我必须运行 alsaunmute 才能获得声音,它的输出是:

/sbin/alsactl: sysfs_init:48: sysfs path '/sys' is invalid

Found hardware: "ENS1371" "Cirrus Logic CS4297A rev 3" "AC97a:43525913" "0x1274" "0x1371"
Hardware is initialized using a generic method

有人能指出正确的方向让 Portaudio 工作吗?

最佳答案

声音缓冲器和数据传输

声卡有一个硬件缓冲区,用于存储录制的样本。当缓冲区足够满时,它会产生一个中断。内核声音驱动程序然后使用直接内存访问 (DMA) 将样本传输到内存中的应用程序缓冲区。同样,为了播放,另一个应用程序缓冲区使用 DMA 从内存传输到声卡的硬件缓冲区。

这些硬件缓冲区是环形缓冲区,这意味着当到达缓冲区的末尾时数据回绕到开始处。维护一个指针以跟踪硬件缓冲区和应用程序缓冲区中的当前位置。在内核之外,只对应用程序缓冲区感兴趣,因此从这里开始我们只讨论应用程序缓冲区。

缓冲区的大小可以通过 ALSA 库调用进行编程。缓冲区可能非常大,在一次操作中传输它可能会导致 Not Acceptable 延迟,称为延迟。为了解决这个问题,ALSA 将缓冲区拆分成一系列周期(在 OSS/Free 中称为片段)并以周期为单位传输数据。

在播放期间,如果应用程序没有足够快地将数据传递到缓冲区,它就会变得数据不足,从而导致称为欠载的错误。 ALSA 文档有时使用术语 XRUN 来指代这两种情况。正确设计的应用程序可以最大限度地减少 XRUN 并在发生时恢复。

关于c++ - Portaudio 和 ALSA : "Cannot obtain info for CTL elem",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27552562/

相关文章:

c++ - 轻量级 QObject - 兼容基类

qt - 使用 QMediaPlayer 进行音频可视化

c# - Naudio - 将 32 位 wav 转换为 16 位 wav

android - MediaRecorder 在录制开始时保持沉默(延迟?)

c++ - 递归删除指定数据的链表

c++ - 如何优化 Cuda 内核性能?

audio - 为 Alsa/Pulse 环回创建实时音频过滤器

audio - QAudioInput 录制声音失败

c++ - 传递枚举数组是什么意思?

c - ALSA snd_pcm_sw_params_set_stop_threshold() 设置为较低的值会导致欠载