Capturing audio from soundcard!

Can anybody help me? When i compile this code no problems appears, however when i execute the program this is shown to:

Microsoft Windows XP [Version 5.1.2600]

(C) Copyright 1985-2001 Microsoft Corp.

c:\Sun\SDK\jdk\bin>java JCapture

javax.media.NotConfiguredError: setContentDescriptor cannot be called before con

figured

at com.sun.media.ProcessEngine.setContentDescriptor(ProcessEngine.java:3

42)

at com.sun.media.MediaProcessor.setContentDescriptor(MediaProcessor.java

:123)

at JCapture.doIt(JCapture.java:69)

at JCapture.main(JCapture.java:27)

Exception in thread "main" javax.media.NotConfiguredError: setContentDescriptor

cannot be called before configured

at com.sun.media.ProcessEngine.setContentDescriptor(ProcessEngine.java:3

42)

at com.sun.media.MediaProcessor.setContentDescriptor(MediaProcessor.java

:123)

at JCapture.doIt(JCapture.java:69)

at JCapture.main(JCapture.java:27)

The code is this:

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.util.Iterator;

import java.util.Vector;

import javax.media.CaptureDeviceInfo;

import javax.media.CaptureDeviceManager;

import javax.media.DataSink;

import javax.media.Manager;

import javax.media.MediaLocator;

import javax.media.Processor;

import javax.media.datasink.DataSinkEvent;

import javax.media.datasink.DataSinkListener;

import javax.media.datasink.EndOfStreamEvent;

import javax.media.protocol.DataSource;

import javax.media.protocol.FileTypeDescriptor;

public class JCapture

{

CaptureDeviceInfo captureDeviceInfo = null;

DataSink dataSink = null;

public static void main(String[] args)

{

JCapture jCapture = new JCapture();

jCapture.doIt();

System.exit(0);

}

private void doIt()

{

// retrieve list of available capture devices

Vector vector = CaptureDeviceManager.getDeviceList(null);

Iterator it = vector.iterator();

while(it.hasNext())

{

CaptureDeviceInfo deviceInfo = (CaptureDeviceInfo)it.next();

if("DirectSoundCapture".equals(deviceInfo.getName()))

{

captureDeviceInfo = deviceInfo;

break;

}

}

// exit if no capture devices found

if(captureDeviceInfo == null)

{

System.err.println("No capture devices found!");

System.exit(-1);

}

try

{

// get media locator from capture device

MediaLocator mediaLocator = captureDeviceInfo.getLocator();

// create processor

Processor p = Manager.createProcessor(mediaLocator);

// configure the processor

p.configure();

// set the content type

p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.WAVE));

// realise the processor

p.realize();

// get the output of processor

DataSource dataSource = p.getDataOutput();

// create medialocator with output file

MediaLocator dest = new MediaLocator("file://c:\\myFile.wav");

// create datasink passing in output source and medialocator specifying our output file

dataSink = Manager.createDataSink(dataSource,dest);

// create dataSink listener

dataSink.addDataSinkListener

(

// anonymous inner class to handle DataSinkEvents

new DataSinkListener()

{

// if end of media, close data writer

public void dataSinkUpdate(DataSinkEvent dataEvent)

{

// if capturing stopped, close DataSink

if(dataEvent instanceof EndOfStreamEvent)

{

dataSink.close();

}

}

}

);

// open the datasink

dataSink.open();

// start the datasink

dataSink.start();

// start the processor

p.start();

getConsolePress();

// stop the processor

p.stop();

// close the processor

p.close();

}

catch(Exception e)

{

e.printStackTrace();

System.exit(-1);

}

System.out.println("Finished!!");

}

public void getConsolePress() throws Exception

{

InputStreamReader isr = new InputStreamReader(System.in);

BufferedReader input = new BufferedReader(isr);

String line;

System.out.println("Press x to stop capturing...");

while (!(line = input.readLine()).equals("x"))

{

System.out.println("Press x to stop capturing...");

}

return;

}

}

[4572 byte] By [Pasteleiroa] at [2007-11-27 8:03:57]
# 1
please, can anybody help me?
Pasteleiroa at 2007-7-12 19:46:09 > top of Java-index,Security,Cryptography...
# 2

I compiled and ran your code and saw

the error you described, but could not fix it ..

OTOH - here is some code I was mucking

about with recently (it was adapated from an

example I found on a forum, but I cannot recall

where), it seemed to work quite well, without

ever creating a processor.

Maybe that might help?

import java.awt.FlowLayout;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JButton;

import javax.swing.JOptionPane;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.InputStream;

import java.io.FileOutputStream;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import javax.sound.sampled.AudioSystem;

import javax.sound.sampled.AudioFormat;

import javax.sound.sampled.AudioFileFormat;

import javax.sound.sampled.AudioInputStream;

import javax.sound.sampled.DataLine;

import javax.sound.sampled.SourceDataLine;

import javax.sound.sampled.TargetDataLine;

public class AudioRecorder extends JFrame{

boolean stopCapture = false;

ByteArrayOutputStream byteArrayOutputStream;

AudioFormat audioFormat;

TargetDataLine targetDataLine;

AudioInputStream audioInputStream;

SourceDataLine sourceDataLine;

File file;

// AudioFileFormat.Type fileType;

/** The recorder will request enough memory for this lengh

of time of audio recording.More might be possible.*/

static int minutes = 4;

/** channels - 1 for mono, 2 for stereo. */

static int channels = 2;

/** bytes - 1 means 8 bit, 2 means 16 bit, 3 means 24 bit. */

static int bytes = 2;

/** Samples per second, sample rate in Hertz. */

static int samplerate = 44100;

/** Default size of the audio array before expansion.

Guarantees there is 'minutes' of memory for recording

'bytes' of sound depth in 'channels' at 'samplerate'. */

static int size = samplerate*channels*bytes*60*minutes;

/** Make the temp buffer, for this fraction of a second. */

static int timeperiod = 20;

/** An arbitrary-size temporary holding

buffer

enough for 3 minutes of sampling in

stereo at 16 bit, 44100Hz */

//static byte tempBuffer[];

static byte tempBuffer[] = new byte[samplerate*channels*bytes/timeperiod];

public static void main(

String args[]){

if (args.length==0) {

new AudioRecorder(null);

} else {

new AudioRecorder(args[0]);

}

}//end main

public AudioRecorder(String outputFileName){//constructor

setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

setLocation(100,50);

final JButton captureBtn =

new JButton("Capture");

final JButton stopBtn =

new JButton("Stop");

final JButton playBtn =

new JButton("Save");

captureBtn.setEnabled(true);

stopBtn.setEnabled(false);

playBtn.setEnabled(false);

captureBtn.addActionListener(

new ActionListener(){

public void actionPerformed(

ActionEvent e){

captureBtn.setEnabled(false);

stopBtn.setEnabled(true);

playBtn.setEnabled(false);

captureAudio();

}

}

);

getContentPane().add(captureBtn);

stopBtn.addActionListener(

new ActionListener(){

public void actionPerformed(

ActionEvent e){

captureBtn.setEnabled(true);

stopBtn.setEnabled(false);

playBtn.setEnabled(true);

//Terminate the capturing of

// input data from the

// microphone.

stopCapture = true;

}//end actionPerformed

}//end ActionListener

);//end addActionListener()

getContentPane().add(stopBtn);

playBtn.addActionListener(

new ActionListener(){

public void actionPerformed(

ActionEvent e){

//Play back all of the data

// that was saved during

// capture.

saveAudio();

}//end actionPerformed

}//end ActionListener

);//end addActionListener()

getContentPane().add(playBtn);

getContentPane().setLayout(new FlowLayout());

setTitle("IMAR");

setDefaultCloseOperation(

EXIT_ON_CLOSE);

setSize(250,70);

setVisible(true);

if ( outputFileName==null ) {

JFileChooser fc = new JFileChooser();

int returnVal = fc.showSaveDialog(null);

if(returnVal == JFileChooser.APPROVE_OPTION) {

outputFileName = fc.getSelectedFile().toString();

} else {

outputFileName = "default.wav";

}

}

file = new File(outputFileName);

FileOutputStream fout;

try {

fout=new FileOutputStream(file);

} catch (FileNotFoundException e1) {

e1.printStackTrace();

}

}//end constructor

//This method captures audio input

// from a microphone and saves it in

// a ByteArrayOutputStream object.

private void captureAudio(){

try{

//Get everything set up for

// capture

audioFormat = getAudioFormat();

/*AudioFormat.Encoding[] encodings =

AudioSystem.getTargetEncodings(audioFormat);

for(int ii=0; ii<encodings.length; ii++) {

System.out.println( encodings[ii] );

}*/

DataLine.Info dataLineInfo =

new DataLine.Info(

TargetDataLine.class, audioFormat);

targetDataLine = (TargetDataLine)

AudioSystem.getLine(dataLineInfo);

targetDataLine.open(audioFormat);

targetDataLine.start();

System.out.println( "AR.cA: " + targetDataLine );

audioInputStream = new

AudioInputStream(targetDataLine);

//Create a thread to capture the

// microphone data and start it

// running.It will run until

// the Stop button is clicked.

CaptureThread ct = new CaptureThread();

Thread captureThread =

new Thread(ct);

captureThread.start();

} catch (Exception e) {

e.printStackTrace();

System.exit(0);

}//end catch

}//end captureAudio method

//This method plays back the audio

// data that has been saved in the

// ByteArrayOutputStream

private void saveAudio() {

try{

//Get everything set up for

// playback.

//Get the previously-saved data

// into a byte array object.

byte audioData[] =

byteArrayOutputStream.

toByteArray();

//Get an input stream on the

// byte array containing the data

InputStream byteArrayInputStream

= new ByteArrayInputStream(audioData);

AudioFormat audioFormat =

getAudioFormat();

AudioInputStream audioInputStreamTemp =

new AudioInputStream(

byteArrayInputStream,

audioFormat,

audioData.length/audioFormat.

getFrameSize());

audioInputStream =

AudioSystem.getAudioInputStream(

AudioFormat.Encoding.PCM_SIGNED,

audioInputStreamTemp );

DataLine.Info dataLineInfo =

new DataLine.Info(

SourceDataLine.class,

audioFormat);

sourceDataLine = (SourceDataLine)

AudioSystem.getLine(dataLineInfo);

sourceDataLine.open(audioFormat);

sourceDataLine.start();

//Create a thread to play back

// the data and start it

// running.It will run until

// all the data has been played

// back.

Thread saveThread =

new Thread(new SaveThread());

saveThread.start();

} catch (Exception e) {

e.printStackTrace();

System.exit(0);

}//end catch

}//end playAudio

//This method creates and returns an

// AudioFormat object for a given set

// of format parameters.If these

// parameters don't work well for

// you, try some of the other

// allowable parameter values, which

// are shown in comments following

// the declarations.

private AudioFormat getAudioFormat(){

float sampleRate = 44100.0F;

//8000,11025,16000,22050,44100

int sampleSizeInBits = channels*8;

//8,16

//int channels = 2;

//1,2

boolean signed = true;

//true,false

boolean bigEndian = false;

//true,false

return new AudioFormat(

sampleRate,

sampleSizeInBits,

channels,

signed,

bigEndian);

}//end getAudioFormat

//===================================//

/** Inner class to capture data from

microphone */

class CaptureThread extends Thread{

public void run(){

byteArrayOutputStream =

new ByteArrayOutputStream(size);

stopCapture = false;

try{//Loop until stopCapture is set

// by another thread that

// services the Stop button.

while(!stopCapture){

//Read data from the internal

// buffer of the data line.

int cnt = targetDataLine.read(

tempBuffer,

0,

tempBuffer.length);

if(cnt > 0){

//Save data in output stream

// object.

byteArrayOutputStream.write(

tempBuffer, 0, cnt);

}//end if

}//end while

byteArrayOutputStream.close();

}catch (Exception e) {

e.printStackTrace();

System.exit(0);

}//end catch

}//end run

}//end inner class CaptureThread

/** Inner class to play back the data

that was saved. */

class SaveThread

extends Thread {

public void run(){

try{

if (AudioSystem.isFileTypeSupported(

AudioFileFormat.Type.WAVE,

audioInputStream)) {

AudioSystem.write(audioInputStream,

AudioFileFormat.Type.WAVE, file);

}

JOptionPane.showMessageDialog(null,"Clip Saved!");

} catch (Exception e) {

e.printStackTrace();

System.exit(0);

}//end catch

}//end run

}//end inner class PlayThread

//===================================//

}//end outer class AudioCapture.java

AndrewThompson64a at 2007-7-12 19:46:09 > top of Java-index,Security,Cryptography...
# 3
Thankss!!i have just one more question! what is the format of the audio that i save? because i tried to save as music.wav and no soud was recorder! what shoul i do?
Pasteleiroa at 2007-7-12 19:46:09 > top of Java-index,Security,Cryptography...
# 4
and this program just capture the audio form de microfone, isn't it?
Pasteleiroa at 2007-7-12 19:46:09 > top of Java-index,Security,Cryptography...
# 5

2 notes:

That code I posted, is not mine, and although I'd

made a few tweaks to it, I had not bothered yet to

look into it more closely. It worked 'as is' for me,

and I did not have the time at that instant to go

delving into it.

On the other hand, here is an application I wrote..

http://www.physci.org/sound/audiotrace.html#download

It does not store the sound, just draws a trace on-screen.

While coding it - one of the major problems on two

of the three test machines, was detecting any sound.

As far as I recall (I could hunt down the forum

dicsussion if you are that interested) one of the

testers had to go into the config. of their computer

and enable a 'loopback' for it to work.

There was no obvious way in Java (without

resorting to JNI) to change that setting.

The early* code for it is here..

http://www.physci.org/test/oscilloscope/AudioTrace.java

* (I've improved the GUI in the version for

the public, but the code in the linked version

includes the important parts of getting

the lines.)

In any case, I think you should run that code

and check all lines to see if 'the basic' Java

can detect sound coming through the

microphone on that machine.

To do that, either compile & run the code linked

earlier, or install the built version linked first, and

go to..

View (menu)

Options (Menu Item)

in the 'Audio Trace display options' dialog..

select the 'Display all lines' checkbox and

cilck the OK button

Make sound into the microphone and check

that you can see the trace in one or more of

the lines. (At the moment, my machine shows

two lines, and all sound comes through both

of them!)

Message was edited by:

AndrewThompson64

AndrewThompson64a at 2007-7-12 19:46:09 > top of Java-index,Security,Cryptography...