来自20+个麦克风的输入
有人问我能不能写一个程序,监控至少20个麦克风的输入,全部在一台电脑上。
现在我在用Python(2.6)做原型,系统是Ubuntu,使用的是Alsa。到目前为止,我的尝试引发了不少问题……
Ubuntu是必须的,Alsa不是必需的,而Python是比较理想的选择。
关于硬件,有人建议使用多个声卡。还有一种方法是用一系列USB集线器和麦克风适配器(像这些),这样所有设备都是一样的,连接在同一个USB总线上。
问题:
我怎么能同时从一张声卡录制多个麦克风的声音?(比如同时使用线路输入和麦克风输入,谁知道怎么用超过两个输入的,bonus哦!)
在USB的设置中,我怎么能知道一张声卡(USB适配器)插在USB集线器(或一串USB集线器)上的哪个位置?
如果解决方案是直接通过USB访问麦克风,那么设备在USB总线上的位置仅仅取决于它插在USB集线器的哪个端口,还是说在开关机之间可能会改变?
最后,如果使用原始访问,我该如何最好地获取数据(我对pyUSB没有经验),从原始数据转换成音频需要什么处理吗?
编辑:
这里的“监控”是指我被要求将输入录制到磁盘上(理想情况下是在设定的阈值以上,speex编解码器看起来很合适),监控音量水平,提供图形反馈,并设置至少一个输出,循环显示所有活动的麦克风。
Python并不是长期的需求,只是我目前找到的获取声卡PCM数据的最简单方法(不过只限于麦克风)。
我打算将声卡的轮询和数据处理放在不同的线程中,但我在这方面经验不多。
我在哪里可以找到更多关于实现USB音频类驱动的信息?
8 个回答
我个人建议你需要一些硬件,比如一个数字混音台,这样才能支持所有这些输入。否则,我真的怀疑你能否轻松让多个麦克风同时工作。在你开始写代码来录制这些输入之前,检查一下电脑是否能处理这种情况,应该是第一步。
另外,我也不太推荐在这里使用Python。首先,这听起来像是一个对性能要求比较高的情况;其次,在*类Unix系统上,我不想用低级语言做任何事情,除非是C/C++(在Windows上,我可能会推荐C++或C#)。
关于硬件,有一个建议是使用多个声卡。另一个建议是使用一系列的USB集线器和麦克风适配器(像这些)
这些也是多个声卡:每个声卡都提供一个USB音频设备接口,它们的时钟是独立的,这可能会导致你在同步时遇到问题。
我从来没有尝试过同时使用20个这样的设备,但我觉得这会非常不可靠。这些设备都是便宜的消费品,并不是为了那种使用场景设计的;虽然我认为它们不会达到USB 2.0的带宽限制,但在那之前它们就可能不再可靠了。顺便提一下,你链接的那个型号评价非常差。
如果可以的话,考虑使用高端的声卡,带有多个输入。例如,Delta-1010LT价格合理,而且似乎支持ALSA。还有很多外部设备(USB、Firewire、RME的产品)提供8个以上的输入选项;ESI有一个16输入的机架,但ALSA的驱动情况看起来不太乐观。
使用一个同步的设备,可以一次性获取多个音频输入,这比使用很多独立的声卡要容易得多。你可能还是不想直接在Python中处理样本,但可以通过像PySndObj这样的工具,将更高级的处理/分析工具连接到Python中。
这里提到的“监控”这个词的意思其实很广泛。监控可以指“记录到硬盘上”、“检测音量超过某个阈值”或者“在频率域进行更高级的分析(也就是传统的信号处理)”。这三种方式对CPU的使用和用Python实现的可行性影响很大,具体要看你想做什么,Python可能并不是最合适的选择。
如果你决定使用Python,我想提醒你几点:
- Python在音频支持方面比较薄弱。
- Python的ALSA绑定(pyalsa)主要用于序列器、混音器和硬件控制,而不是读取PCM样本(不过这些绑定可能对管理设备有帮助)。
- 在某些多线程情况下,Python会遇到问题(比如GIL——全局解释器锁),虽然可以通过使用独立的Python进程来避免,但这并不总是理想的选择(我假设你是在多核/多处理器系统上运行,并希望将20个音频输入的监控负载分配到多个CPU上)。
- 像音频分析这样的CPU和内存密集型操作并不是Python的强项。不过,PCM数据可以通过struct.unpack()解包,信号分析可以使用NumPy和SciPy中的例程来完成。
每个线路输入和麦克风应该是立体声的,这样每个输入实际上提供两个麦克风输入,也就是每个声卡有四个麦克风。假设你有20个输入,那就需要五个USB音频适配器。顺便说一下,要使用线路输入,你需要某种麦克风前置放大器,这可能比你想要的要贵。在这种情况下,你需要10个USB音频适配器来处理20个输入。
我想提醒你,大多数低端的USB集线器可能无法处理5到10个音频适配器的流量。为此,我建议你确保使用USB 2.0高速集线器(即使实际的音频设备是USB 1.1全速或更慢),这样才能确保有足够的上行带宽。如果有选择的话,获取带有4或5个外部USB端口的PCI USB适配器卡并不难。顺便提一下,你提到的USB设备只有立体声输出和麦克风输入(没有线路输入)。
理想情况下,你应该使用USB等时传输模式来实现低延迟和稳定的传输,但我怀疑ALSA驱动是否支持这个功能。
关于USB声卡的逻辑到物理映射,可以通过设置一组udev规则来为设备提供有用且一致的命名方案,这可以基于USB层次结构,或者如果你愿意,也可以使用序列号(如果设备有的话)或其他属性。无论如何,你应该能够使用udev规则根据设备的身份或物理位置来稳定音频设备的映射。
我对pyUSB一无所知,但我看到它支持等时传输模式。乍一看,pyUSB可以实现非常精确的控制,但我怀疑你可能会写比预期更多的代码(基本上你需要在Python中实现USB音频类驱动的更好部分)。
希望这些信息对你有帮助!