I've been asked (if it's possible) to write a program monitoring the input of at least 20 microphones, on a single computer.

Currently I'm prototyping in python (2.6), on a Ubuntu system using Alsa. My attempts so far have created quite a few questions...

Ubuntu is a requirement, Alsa isn't, and python is an ideal.

For hardware, one suggestion is multiple sound cards. The other is a series of usb hubs and microphone adaptors (like these) (In which case the devices would all be identical and on the same USB bus)


How can I simultaneously record multiple microphones from a single sound card? (e.g. using line-in as well as mic, bonus for anyone who know how I can use more than just two inputs!)

In the USB setup, how can I identify which position a sound card (usb adapter) in plugged in to a USB hub (or chain of USB hubs).

If a solution is raw access to the microphones via USB, is a devices position on a usb bus depend only on which port on a USB hub they are plugged into, or do could it change between powering the computer on and off?

Last, if using raw access, how do I best get the data (no current experience with pyUSB) and what conversion (if any) is required from raw -> audio?


By monitor, I've been asked to record input to disk (ideally above a set threshold, which the speex codec looks ideal for), monitor volume levels, provide graphic feedback and set up at least one output that cycles through all active microphones.

Python isn't a long term requirement, just the easiest way I've found so far to get the PCM data from a sound card (microphone only however)

I am intending to have the polling of the soundcards and data processing take place in separate threads, an area that I haven't got much experience with.

Where would I find more information on implementing a USB audio class driver?

+6  A: 

The definition of "monitor" is a very big variable here. Monitor could mean "record to disk", "detect volume levels above a particular threshold" or "perform higher level analysis in the frequency domain (i.e. conventional signal processing)." These three have very different implications for CPU usage and the feasibility of Python. Python may not be the best fit depending on what you want to do.

If you go with Python, I'll note the following:

  • Python's audio support is very weak
  • The python ALSA bindings (pyalsa) are for sequencer, mixer and hardware control, not reading PCM samples (though the bindings might be helpful for managing the devices)
  • Python has issues in certain multi-threaded conditions (cf. the GIL — the Global Interpreter Lock) which can be avoided entirely by having separate Python processes but this is not desirable in all cases either (I'm presuming that you are running on a multi-core/processor system and want to divide the load of monitoring the 20 audio inputs across the CPUs).
  • CPU and memory intense operations such as one would expect in audio analysis is not Python's strong suit. Having said that, PCM data could be unpacked via struct.unpack() and signal analysis could be done with routines found in NumPy and SciPy.

Each line input and mic should be stereoscopic, effectively providing two mic inputs each, that's four mic's per sound card. Assuming just 20 inputs that means five USB audio adapters. BTW, to use line-in you'll need some sort of mic pre-amp which might be more pricey than you'd want. In that case, you would need 10 USB audio adapters for 20 inputs.

I would caution that most low-end hubs will probably not be able to handle the traffic for 5-10 audio adapters. For that matter, I'd be sure that you had a USB 2.0 Highspeed hub (even if the actual audio devices are USB 1.1 full-speed or slower) to be sure you have enough upstream bandwidth. If you have the option, it is not hard to get PCI USB adapter cards with 4 or 5 external USB ports. BTW, the USB device you show only has stereo-out and mic-in (no line-in).

BTW, ideally you'd use USB isochronous transfer mode to have low latency and consistent delivery but I doubt that the ALSA drivers support it.

Regarding the logical to physical mapping of USB sound cards, a set of udev rules would allow you to give a useful and consistent device naming scheme based on the USB heirarchy or, if you wanted, serial numbers (if the devices have them) or other attributes. In any case, you should be able to use udev rules to stabilize the mapping of audio devices by their identity or their physical location (as you choose).

I know nothing about pyUSB but do see that it supports isochronous transfer mode. At a glance pyUSB would allow for very precise control but I suspect you'll do way more coding that you set out to do (you'd basically need to implement the better parts of a USB audio class driver in Python).

Hope that helps!

This is extemely helpful. Many thanks!Udev's new to me, and looks to be an ideal solution. Off to research making a USB audio driver just in case...
Paul O'Reilly

Audio over USB is fine if you don't mind latency, but I seriously doubt it can work with 20 channels, especially on 20 devices.

Get a few big Firewire interfaces (8 channels+), maybe from Presonus. Find something supported by the Linux sound system, you don't want to deal with any bus yourself. If you can, use a DAW application to get the audio. If processing is needed it's probably easier to write a plugin than start from scratch. I don't know of a good library to do multitrack recording in Python.

+1  A: 

I'd personally suggest you need some hardware like a digital mixing desk which will support all those inputs in the first place. I really doubt you'll easily get multiple mics working otherwise. And before you start writing any code to record all those inputs, checking if/how the PC can even handle such a scenario is the logical first step.

And I'd also hesitate to recommend Python here. For one thing this sounds like a case where performance might be critical, for another on *nix I'd not want to do anything low-level except in C/C++ (on Windows I'd probably say C++ or C#).

+2  A: 

For hardware, one suggestion is multiple sound cards. The other is a series of usb hubs and microphone adaptors (like these)

Those are also multiple sound cards: each one presents a USB Audio Device Class interface, independently clocked, which may cause you problems if you're trying to sync them.

I've never attempted to run anything like 20 of them at once, but my feeling is it's going to be highly unreliable. These things are cheap consumer kit that aren't designed for that kind of usage; though you wouldn't be troubling USB 2.0's bandwidth limit with them I think they'll stop working reliably long before that. For what it's worth the particular model you linked to has extremely poor reviews.

If you can, consider higher-end sound cards with multiple inputs. For example the Delta-1010LT is reasonably priced and apparently supported by ALSA. There are quite a few more 8+-input possibilities with external boxes (USB, Firewire, RME's stuff); ESI make a 16-input rack, but the driver situation for ALSA looks doubtful.

A single, synchronised device from which you can pull multiple channels of audio input in one go will be much easier to cope with than lots of separate soundcards. You still probably wouldn't want to be fiddling with the samples directly in Python, but you could hook up a higher-level processing/analysis toolkit to Python with something like PySndObj.


Just a tip: think of your 20 sound inputs as analog inputs and capture it using Analog to Digital converters, like, for example National Instruments cards.

I've even heard of professional sound mapping using NatInst hardware. And (for Windows at least, I don't know for Linux) the software support is excelent.

This Usb DAQ Device supports 14 SE (Single ended) Analog Inputs with only one USB port at 14 bits, 48 KS/s.

And yes, at least Labview have a Linux version.

Franklin Albricias

This seems like it's a couple of months late, but maybe someone else can benefit from it. As for identifying multiple USB devices and distinguishing one from another, that's fairly easy... usually.

Many of the cheapest USB devices will fail to have a unique serial number, and even some fairly expensive ones (the Zoom 4595 Aircard, for instance). If this is the case, there is no good way... whichever manages to fight its way to the front of the line will be /dev/n0, the next /dev/n1, and so forth.

But if they do have unique serials, then you can write udev rules that specify a certain serial number should be /dev/n4. Udev rules aren't for the weak, it's taken me weeks to master it, but can make these things possible.

John O

Software exists today that will do this for free or cheap. The challenge is getting the inputs.

If this is for a business and their business relies on it I suggest a Logic Express / Logic Pro or Pro Tools solution. Spend a couple of bucks and make it work right.

Free software that will work well are things like: Audacity (all platforms), Garageband (Mac), Ardour (Linux, Mac), etc.

Now to get twenty mono audio inputs into the system you should consider getting something with twenty inputs (or more) rather than running all 20 mics into a mixing board and recording the mix-down of one channel.