Multichannel USB recording with Java Sound API?
Asked Answered
G

3

45

I'm trying to record/process some audio from three usb microphones with Java Sound on Snow Leopard (but can switch to Windows if it fixes things). Problem is, when I try to use the mixer that corresponds to the usb mic, Java Sound tells me that the line isn't supported. Specifically, it says this...

Available mixers:

Java Sound Audio Engine

USBMIC Serial# 041270067

Built-in Input Built-in Microphone

Soundflower (2ch)

Soundflower (16ch)

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Line unsupported: interface TargetDataLine supporting format PCM_SIGNED 96000.0 Hz, 8 bit, stereo, 2 bytes/frame,

...when I ask it to select the USBMIC mixer:

  Mixer mixer = AudioSystem.
          getMixer(mixerInfo[1]);

I have tried matching the audio format to the exact specifications of the microphones (16-bit, 44100Hz, stereo) and it didn't make any difference.

The problem is cropping up here:

 final TargetDataLine line = (TargetDataLine)
        mixer.getLine(info);

It would seem that the mixer and the TargetDataLine don't like each other. Is there some way to get these two to 'match' and get along?

The microphones that I'm using are admittedly a bit strange. They were made to be used in a karaoke video game called SingStar. The mics themselves have standard mono line-in connectors that plug into a little hub (two to a hub) that converts them into a single male usb connector. Strangeness aside, though, they seem to work perfectly fine with Audacity as separate channels, so multichannel recording with them is clearly possible, just maybe not in Java.

I've also considered using a program like Soundflower that shares audio between different programs. However, I'm not sure this will work as I can't see how to make the USB mics inputs to Soundflower and then pipe them into a Java. A quick experiment showed me that I could record audio in Audacity from the mics, pipe it out through Soundflower, and then process in my Java program. Still, what I would like to do is have it all happen in real time in Java.

Anybody familiar with this kind of problem?

Gyrocompass answered 21/11, 2010 at 19:6 Comment(3)
Hmm...Cant Audacity only record from one device at a time? Is that what you did?Krusche
I wouldn't count on the Java sound API being correct in more complex cases. Can you use a third party Java program to verify that the problem is not at the JRE level? Or maybe use a newer JRE? On Windows the USB Audio Device driver is a bit anemic as well.Commutator
It's been a few years since I've messed with sound.. This may help though: each sound device is going to have it's own internal clock. There are exceptions, and you'll see these as a clock input on the audio card/device. Devices that are running on their own clocks are going to drift out of sync. They may be in sync at the start of the recording but because the samples are taken at slightly different rates there will be drift. The longer the audio recording the more noticeable the drift will be.Stomach
T
4

I think that a simple way to do this would be using Soundflower and Soundflowerbed.

I can't see how to make the USB mics inputs to Soundflower and then pipe them into a Java.

It sounds like you have Soundflower installed already. Soundflowerbed is found in the same disk image as Soundflower and is a menubar application. It lets you route sound between applications which don't have controls built in for selecting sound devices. Install that from the disk image and click it to run.

All of the following will be using my Echo Audiofire 4 but in principle should work on any audio device.

Using Soundflowerbed

Open Soundflower and tick the audio device you want to use under Soundflower (16ch). As I'm a new user I can't post images but they are linked below. If I get the bounty then I will edit the post to include the images inline.

1

From here you would use Soundflower (16ch) as your audio input device in Java sound.

Creating an aggregate audio device

An alternative way to solve this if that didn't work is to create an aggregate device. Open Applications > Utilities > Audio Midi Setup and click the plus sign to create a new aggregate device.

2 Tick the device that you want to aggregate. You only want your USBMIC (As I'm a new SO user I can only post two images per answer so the next two are linked here).

3

The key part which may be giving you trouble is the clock on the device. If you select the Mac as the clock source then that may be more stable. 4

If this still doesn't work then you could try adding the Mac built-in audio to the aggregate device and making it the master clock by right clicking on the device you want to be the master.

5

Other options

Finally, I haven't used this before but Pulse Audio (Google it, I can't insert more links in this post) might be a possible solution for mixing your audio streams together. It looks quite heavyweight though.

Tare answered 15/10, 2011 at 20:35 Comment(2)
Thanks for the good effort Daniel Campton. Thing is the question was asked in 2010 so the asker might not be available to validate your answer. If however you can confirm (and maybe talk about or even give a Java example) that the sound recording device is now available/usable to the Java Audio API then I'll give you the bounty. (Obviously the bounty's yours if the asker choses your current answer)Cathrinecathryn
Unfortunately I'm not at all familiar with the Java Audio API so I can't give any more details of how it would work. I have had a look through the Java Audio API and I couldn't see how to change the audio input source. If I had the original askers code where he selects his USBMIC then I could probably work from that to make it work.Tare
H
2

According to my research, especially threads like this, the microphone you are using is most likely causing the problem. The thread states that the microphone is even a problem when it comes to switching games, so I am guessing that it will be a problem when switching platforms, too.

My suggestion is - if you have not tried this already - to use a different microphone! Most microphones I have messed around with have special chip controllers that convert data into the data compatible for the game system. Being that you are using this on an operating system for the computer, you are probably getting some very odd effects that you wouldn't get on a game system like Playstation or others.

Hopefully this helps! Happy coding!

Harness answered 15/10, 2011 at 20:4 Comment(0)
P
0

The AudioFormat doesn't match the TargetDataLine's supported format. I don't know if that was a typo or not but the Exception thrown says the TargetDataLine supports 8 bit audio and right below that you said you're using a 16 bit AudioFormat. It also supports up to 2 bytes per frame, how quickly and in what size chunks are you trying to read the data? Sorry if that doesn't help but I thought I'd point that out in case it was overlooked.

Pageboy answered 17/4, 2013 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.