跨平台声音API

9
我正在开发一个需要实时音频流的应用程序。我希望使用一些跨平台(Windows / Linux / BSD)的开源库,用C或C++编写,即使使用各自操作系统的声音API也是一种选择。
我已经阅读了有关各种声音库的一些资料,包括SFML、SDL和PortAudio。诚然,我还没有足够的研究关于FreeBSD和Linux中的声音(它们之间有多相似?)。
主要要求如下:
1.从所选麦克风获取音频以通过网络发送, 2.将数据发送到一组输出设备, 3.处理声音(过滤、清除噪音、复用流等),但这可以在获得音频数据后完成,库本身不需要能够执行任何此类操作。 4.具有合理的低延迟。
我的主要关注点是这些API似乎主要针对游戏(其中声音通常从磁盘加载,并且几乎没有录制声音,而是与播放同样重要地通过网络流式传输)。
是否有人对这些或其他声音API有指针/警告/建议,或者有关通过各自操作系统的API实现此功能的优缺点?
注意: 虽然这个问题:“要求我们推荐或找到书籍、工具、软件库、教程或其他离线资源,这些问题对于Stack Overflow来说都是不相关的”,但是当考虑到“它们往往会吸引有偏见的答案和垃圾邮件”时,我认为这个问题不应该关闭。寻找此类库的人将很难找到任何东西,而对此问题的回答实际上概括了所有可用选项。因此,这属于被程序员广泛使用的“通常涵盖…软件工具”的接受答案类别。

你看过Pulseaudio了吗? - Herr von Wurst
只有在为已经设置好PulseAudio的LINUX发行版编写时,才有必要专门为其编写。 - msam
5个回答

7
PortAudio是您所描述的应用程序的绝佳选择--它在所有这些平台上运行,使用C语言编写,提供低延迟,并且具有回调和阻塞I/O选项。它绝对符合您的要求,并且并不特别针对游戏。实际上,我会说还有其他API更适合游戏,而PortAudio更适合于像您这样的voip应用程序、音频播放器、专业音频应用程序、音频录制、软件无线电等通用音频I/O。

另一个您可以考虑的选择是RTAudio,但我对它不太熟悉。据我了解,它比较简单(没有阻塞I/O AFAIK),并且支持更多平台,包括移动操作系统,尽管PortAudio的开发人员也在处理这个问题。

关于FreeBSD与Linux之间的问题:Linux使用ALSA,而其他Unix使用OSS。OSS和ALSA都提供兼容性层,因此ALSA具有OSS兼容性,反之亦然,但根据我的经验,两个兼容性层中都存在错误。不过,也许自从我上次使用它以来情况已经变得更好了。

一些Linux桌面系统在ALSA上运行PulseAudio。我不确定FreeBSD是否也是这样。由于某种原因,大多数系统默认情况下将ALSA配置为独占模式。虽然这在理论上很容易解决,但配置文件很奇怪,大多数用户从未这样做过,也永远不会这样做,这意味着一旦PulseAudio接管,您就无法直接访问ALSA设备,因此除非您希望使用户更改其配置(如果您的应用程序需要真正低的延迟),否则您可能还需要一个PulseAudio驱动程序。

我相当确定PortAudio支持PulseAudio,尽管它的网站上可能没有提到。我会在邮件列表上询问并在此处更新。

更新:邮件列表上有人认为您可以使用Alsa驱动程序来访问PulseAudio。这对我来说是(好!)消息,但事实就在那里。


2

libsoundio是一个符合您要求的低级别C库。

需要注意的是:它目前还不支持OSS(FreeBSD)或sndio(OpenBSD)。


2
我认为SDL和OpenAL都是常见且广泛支持的。除非它们不能满足您的需求,否则建议不要降低级别,因为这样会失去平台独立性。
它们似乎专注于游戏的原因仅仅是因为游戏是更难的用例之一。所以如果您能够支持游戏,那么您就有可能支持其他应用程序需要的任何功能(除了工作室软件)。
考虑到您对低延迟的目标。游戏需要极低的延迟来确保声音效果与屏幕上的动作匹配得很好。我猜这也是您想要这个功能的原因(这样您的声音就可以与视频流匹配,语音通道中没有停顿)。
顺便说一下,您对游戏的看法并不正确。很多游戏都有用户语音通道进行团队沟通。此外,它们可能包括过程化声音和音效。
我找到了另一个叫做 SFML 的库,它包含录制支持。我不是很了解它,但我看到它可以替代SDL。

1
这是录制音频的链接!https://dev59.com/qnA75IYBdhLWcg3w4tN7 - NotKyon
不幸的是,我没有意识到SDL不支持录制(或者我错过了什么),所以现在这个选项已经被排除了。不过我会研究一下OpenAL。 - msam
是的,非常抱歉,我以为SDL可以录制声音,但我也找不到相应的API。也许新的版本已经有了,或者需要打补丁。 - edA-qa mort-ora-y
添加SFML的引用,另一个选项。 - edA-qa mort-ora-y
1
SDL2支持按照https://wiki.libsdl.org/SDL_OpenAudioDevice进行捕获。SDL_OpenAudioDevice()函数提到“iscapture:非零值指定应打开一个设备进行录音,而不是播放”。 - Stéphane Gourichon
SFML不是低延迟的。sf::SoundStream需要至少1500个样本@ 44100,我想。我尝试了每1/50秒882个样本,但失败了。OpenAL无法处理如此快的声音。 - Cthutu

1
我强烈建议您在跨平台(Linux/Mac/Windows)Qt框架上开发,并使用其自己的Qt库。在QtMultimedia模块中,您可以使用QAudioInput从麦克风捕获原始音频。您还可以使用QtMultimedia进行处理。
Qt框架非常优化多媒体和游戏应用程序,因此您不会失去性能。

除了简单的蜂鸣声之外,Qt提供的音频API都不太好用。请参考我在这里的回答:https://dev59.com/_FbTa4cB1Zd3GeqP7Ap6#5602687 - edA-qa mort-ora-y
这可能对早期版本是正确的,但是我已经使用了Qt4.7来制作我的两个游戏,并且拥有广泛的音效。 - Ashish Gaurav
除非4.7有全新的声音API,否则我不相信它能解决我发现的问题。 - edA-qa mort-ora-y

-1

Linphone包含了Mediastreamer2,用于这个确切的目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接