Capturing speaker output in Java
Asked Answered
P

3

12

Using Java is it possible to capture the speaker output? This output is not being generated by my program but rather by other running applications. Can this be done with Java or will I need to resort to C/C++?

Prokopyevsk answered 10/7, 2011 at 23:14 Comment(4)
Regardless of what language you're using, you'll have to first find a library that can do this for you. Then it's just a matter of finding/generating the right language bindings for this library.Bifacial
I believe you can only do this with certain hardware. I know some soundblaster live cards support this, but other basic ones do not (particularly the crappier onboard cards).Certain
@casablanca: "you'll have to first find a library that can do this for you." Not Java. Java has had the Java Sound API since the 1.3 release. And if Java Sound fails to do the job (see my answer), it is unlikely that any (Java based) library would succeed, since it would logically be based on the Java Sound API.Elayne
@Andrew Thompson: I was hinting along the lines of JNI, since there obviously isn't a purely Java-based way to do this. Of course, that would break portability, but that's the only way of doing it in Java.Bifacial
E
8

I had a Java based app. that used Java Sound to tap into the sound flowing through the system to make a trace of it. It worked well on my own (Windows based) machine, but failed completely on some others.

It was determined that in order to get it working on those machines, would take nothing short of an audio loop-back in either software or hardware (e.g. connect a lead from the speaker 'out' jack to the microphone 'in' jack).

Since all I really wanted to do was plot the trace for music, and I figured how to play the target format (MP3) in Java, it became unnecessary to pursue the other option further.

(And I also heard that Java Sound on Mac. was horribly broken, but I never looked closely into it.)

Elayne answered 10/7, 2011 at 23:38 Comment(0)
B
4

Java is not the best tool when dealing with the OS. If you need/want to use it for this task, probably you will end using Java Native Interface (JNI), linking to libraries compiled in other languages (probably c/c++).

Briarwood answered 10/7, 2011 at 23:22 Comment(3)
Why is Java not the best tool when dealing with OS?Horal
Because the VM is a limit to what can be accessed, and as it is designed to allow compatibility among platforms it does not get into much detail: you cannot edit Windows registry, or use shared memory, send code to run at a GPU... not that you can't do this, but you need to add an external library written in other language using JNI.Briarwood
@Briarwood you cannot edit Windows registry I was surprised to find that false. See here. but you need to add an external library written in other language using JNI. LWJGL allows execution of OpenGL, -CL, AL, and others on the GPU without making JNI/JNA calls.Dreamadreamer
A
0

Take an AUX cable, connect to HEADPHONE JACK and other end to MICROPHONE JACK and run this code

https://www.codejava.net/coding/capture-and-record-sound-into-wav-file-with-java-sound-api

 import javax.sound.sampled.*;
    import java.io.*;

public class JavaSoundRecorder {
    // record duration, in milliseconds
    static final long RECORD_TIME = 60000;  // 1 minute

// path of the wav file
File wavFile = new File("E:/Test/RecordAudio.wav");

// format of audio file
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;

// the line from which audio data is captured
TargetDataLine line;

/**
 * Defines an audio format
 */
AudioFormat getAudioFormat() {
    float sampleRate = 16000;
    int sampleSizeInBits = 8;
    int channels = 2;
    boolean signed = true;
    boolean bigEndian = true;
    AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
                                         channels, signed, bigEndian);
    return format;
}

/**
 * Captures the sound and record into a WAV file
 */
void start() {
    try {
        AudioFormat format = getAudioFormat();
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

        // checks if system supports the data line
        if (!AudioSystem.isLineSupported(info)) {
            System.out.println("Line not supported");
            System.exit(0);
        }
        line = (TargetDataLine) AudioSystem.getLine(info);
        line.open(format);
        line.start();   // start capturing

        System.out.println("Start capturing...");

        AudioInputStream ais = new AudioInputStream(line);

        System.out.println("Start recording...");

        // start recording
        AudioSystem.write(ais, fileType, wavFile);

    } catch (LineUnavailableException ex) {
        ex.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

/**
 * Closes the target data line to finish capturing and recording
 */
void finish() {
    line.stop();
    line.close();
    System.out.println("Finished");
}

/**
 * Entry to run the program
 */
public static void main(String[] args) {
    final JavaSoundRecorder recorder = new JavaSoundRecorder();

    // creates a new thread that waits for a specified
    // of time before stopping
    Thread stopper = new Thread(new Runnable() {
        public void run() {
            try {
                Thread.sleep(RECORD_TIME);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            recorder.finish();
        }
    });

    stopper.start();

    // start recording
    recorder.start();
}

}

Ailsa answered 10/7, 2019 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.