Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Sound API: Capturing sound output from a Target Port

Tags:

java

audio

I'm writing a simple piece of software that streams audio over LAN. I have all of the network parts implemented, but what I'm stumbling on is using the Java Sound API. I have successfully captured audio from the microphone, and line-in, but I can't seem to capture from any target ports, like the speakers. My question is, is it possible to capture from the Master target port? Here is the piece of code that works on initializing the line.

private boolean startCapture(){
    try{
        DataLine.Info info = new DataLine.Info( TargetDataLine.class, format);
        line = (TargetDataLine)AudioSystem.getLine(info);
        audioBuffer = new byte[bufferSize];
        line.open(format);
        line.start();
        return true;
    }catch(Exception e){
        System.out.println("Exception thrown when capturing audio:\n" + e);
        return false;
    }
}

Running the code like this will just use the microphone as my line. Here is info about my sound system. Most important is probably the fact that I'm running Linux.

Thanks in advance for any and all help you can give me.

like image 639
Kyle Kamperschroer Avatar asked Nov 06 '22 13:11

Kyle Kamperschroer


1 Answers

One issue with network sound is that the computers at each end may have slightly different sample rates due to differences between the sound card clocks. Computer clocks vary. If the sending computer is running slower than the receiving computer then, even if you do have a buffer, your buffer will slowly empty. If it is running faster then you'll slowly gain an excess of data. This person tried just what you were doing and saw dropouts. Note that buying more expensive sound cards will reduce his problem but not completely solve it, unless he does something like lock them to the GPS time signal. Your typical casual user won't do that.

Maybe for short transmissions you can get away with it. If you're doing voice for example and you stop transmitting when the speaker is quiet then you can synchronise your buffers when you start again. I wonder what it would do to latency. The "proper" solution requires re-sampling the audio at the receiving end to deal with the slight difference of sample rate.

For such small variation in frequency you could possibly get away with taking the nearest neighbour - effectively skipping or duplicating samples every so often. Digital Amateur radio software I've heard of uses linear interpolation between samples. You need to maintain a scaling factor and control it in order to ensure that you empty your buffer at the rate that new data comes in, but have a control loop that will not be too upset by network vagaries and not try to make sudden large changes.

I don't know whether you've taken this into account or not. I've seen people attempt this who have not. I except nowadays people would use an off-the-shelf audio conferencing library which takes care of this kind of thing. If you're interested in how to do it, the digital amateur radio community is a good place to look.

like image 137
Richard Corfield Avatar answered Nov 14 '22 21:11

Richard Corfield