Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing audio streams in JAVA

Tags:

java

windows

I am new to Java, and although I have mastered the syntaxes and constructs, I am having difficult time in getting processed digital audio samples from a mic.

What I am trying to achieve is very simple, while in the long run, I am trying to create a very simple spectrogram, but just to understand/master the audio manipulation process I am trying to start from scratch.


Here is my problem

When a microphone detects a single beep or any sound, I want to capture that binary data, and just simply display it, in its raw format.


Is that really too much to ask from JAVA?

I have read about analog/digital signals, FFT, matlab and I have searched many links in so like these one:

Is there a way of recording audio of streaming broadcast from a webpage?

Working with audio in Java

OpenAL playback captured audio data c++

and the famous introduction from oracle

http://docs.oracle.com/javase/tutorial/sound/capturing.html

and this is actually a good tutorial http://www.developer.com/java/other/article.php/3380031/Spectrum-Analysis-using-Java-Sampling-Frequency-Folding-Frequency-and-the-FFT-Algorithm.htm

But they all fall short of providing a solution to my answer.

I am not asking for a code, although it would it would be awesome, just to read every line and understand about the mechanics involved, but a simple hint would be nice as well.


And here is a simple code, to capture bytes, but only from an existing wav file

import java.io.FileInputStream;
import java.io.IOException;

public class Boo{
    public static void main(String[] arguments){
        try {
            FileInputStream file = new FileInputStream("beep.wav");
            boolean eof = false;
            int count = 0;
            while(!eof){
                int input = file.read();
                System.out.print(input + "");
                if(input == -1)
                    eof = true;
                else 
                    count++;
            }
            file.close();
            System.out.println("\nBytes read: " + count);
        }catch (IOException e){
            System.out.println("Error - " + e.toString());
        }
    }
}

After Bounty

-For better clarity-

All I am trying to make it just a simple program to read from mic. and show the binary data of the sound it caputures in a real time.

Think of it like a spectrogram, when sound is captured the graph goes up and down depending on the variety of the signal level, but in this case, there is no need to convert the binary data to audio graph, just only to show any raw data itself. No need to write/read files. Just capture from mic, and show what is read from the mic.

If the above provides to be difficult, as I have searched all over the web, and couldn't find anything helpful, you can just give me guides/directions.. thanks

like image 720
blue thief Avatar asked Dec 06 '22 07:12

blue thief


1 Answers

javax.sound.sampled package should have all you need.

Example:

    int duration = 5; // sample for 5 seconds
    TargetDataLine line = null;
    // find a DataLine that can be read
    // (maybe hardcode this if you have multiple microphones)
    Info[] mixerInfo = AudioSystem.getMixerInfo();
    for (int i = 0; i < mixerInfo.length; i++) {
        Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
        Line.Info[] targetLineInfo = mixer.getTargetLineInfo();
        if (targetLineInfo.length > 0) {
            line = (TargetDataLine) mixer.getLine(targetLineInfo[0]);
            break;
        }
    }
    if (line == null)
        throw new UnsupportedOperationException("No recording device found");
    AudioFormat af = new AudioFormat(11000, 8, 1, true, false);
    line.open(af);
    line.start();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buf = new byte[(int)af.getSampleRate() * af.getFrameSize()];
    long end = System.currentTimeMillis() + 1000 * duration;
    int len;
    while (System.currentTimeMillis() < end && ((len = line.read(buf, 0, buf.length)) != -1)) {
        baos.write(buf, 0, len);
    }
    line.stop();
    line.close();
    baos.close();

Afterwards, you can dig the bytes out of your byte array output stream. Or you can of course process them inside the while loop if you prefer.

like image 185
mihi Avatar answered Dec 21 '22 01:12

mihi