views:

460

answers:

2

I'm using 4 USB sound cards (ASUS Xonar U1). I want to send to each one of them a different sound (the same text narrated in different languages). For now, what I do to get the sound mixers that I'm interested in, is something like this:

Info[] mixerInfo = AudioSystem.getMixerInfo();
int count = 0;
for (Info i : mixerInfo) {
    System.out.println("["+(count++)+"]" + i.getName() + " - " + i.getDescription()+" - "+i.getVendor());
}

This gives me something like the following:

[5] Device [plughw:1,0] - Direct Audio Device: USB Advanced Audio Device, USB Audio, USB Audio - ALSA (http://www.alsa-project.org)
[6] Device_1 [plughw:2,0] - Direct Audio Device: USB Advanced Audio Device, USB Audio, USB Audio - ALSA (http://www.alsa-project.org)
[7] Device_2 [plughw:3,0] - Direct Audio Device: USB Advanced Audio Device, USB Audio, USB Audio - ALSA (http://www.alsa-project.org)

For now, in my configuration file, I'm associating the sound cards to the Info[] index (the "count" variable).

The problem is if I change the USB port to which a sound card is connected. Then the Info[] array has a whole new order and I don't know anymore which sound card should play the language en_US and which pt_PT for instance.

Also, the "plughw:1,0" string changes without any noticeable pattern. If I have just one sound card it will always be "plughw:1,0" no matter to which port I connect it to.

If the computer is restarted the mixer Info[] also gets reordered sometimes.

I've also given a look at jUSB but the Device information for the sound cards is exactly the same for all of them and I wouldn't know how to map the USB information it gives me with the Java Sound API mixer Info.

So, does anyone know how to uniquely identify equal sound cards with the Java Sound API?

Alternatively, does anyone have another suggestion about which language/library I could use to write an application that outputs different audio files to 4 different USB sound cards in the same machine?

+1  A: 

Give a look at the BASS Audio Library, which is written in C. There's a JNI library, NativeBass, that's a bridge to use this natively in Java. You lose some cross-platform abilities, but the library is notably better performing, works very well with multiple outs, and I believe has better identification on each audio device.

(Installing NativeBass, you also need to download BASS itself, and merge the two /lib directories, which isn't completely documented.)

If I were going to stick with the solution you're using, I'd get an inexpensive USB hub, connect the audio USB to the hub, and connect the hub to the computer. That should initialize the audio in the same order each time, at least giving you a consistent ordering to work with in JavaSound.

Dean J
I should have mentioned that we need to use Linux. From what I saw, NativeBass doesn't work on Linux. Anyway, thank you for your answer, it gave us some insight. I especially liked the USB hub trick but I didn't have a chance to test it.
Tiago Alves
+1  A: 

Since we needed this to work in Linux, we ended up using this solution: http://alsa.opensrc.org/index.php/Udev

It assigns audio devices the same hwplug:x,y each time they're plugged in. More specifically, it assigns a fixed hwplug:x,y per USB port. Thus, we always know to which USB port a specific sound will be sent.

Tiago Alves