Sound Recording - Runs out of memory  
Author Message
jackson marshmallow





PostPosted: 2003-7-18 16:49:00 Top

java-programmer, Sound Recording - Runs out of memory I think you may find examples from this website very helpful:
http://www.jsresources.org

Regards,

JM

"Christiaan" <email***@***.com> wrote in message
news:email***@***.com...
> Hi,
>
> Here is a simple sound recording program to record sounds via your
> mic.The problem is that you read the sound bytes into a
> ByteArrayOutputStream and if it becomes to big you get -
> java.lang.OutOfMemoryError.
>
> What can I do to overcome this , I have tried to write the incomming
> bytes to file 1st and then from the file into the audioInputStream ,
> but I couldn't get that to work - here is my code (I used jdk1.3 and
> jdk1.4):
>
>
>
> If you copy the code into a IDE the place where the exception are
> thrown are on line 236.
>
> /*
> Christiaan Pansegrouw
> 22/05/2003
> Simple Sound Recording app
> Contains a start & stop buttom & saves to a wave file -
> "userHomeDir"\SimpleMicRecording\SimpleSound.wav
>
> */
>
> import javax.swing.*;
> import java.awt.*;
> import java.awt.event.*;
> import javax.sound.sampled.*;
> import java.io.*;
>
>
>
>
> public class LaunchSimpleSound
> {
> public static void main(String [] args)
> {
> SimpleSound ss = new SimpleSound();
> }
> }
>
>
> class SimpleSound extends JFrame implements ActionListener
> {
>
> private String userHomeDir = System.getProperty("user.home");
> private String fileSeperator =
> System.getProperty("file.separator");
>
> private JPanel mainPanel;
> private JButton cmdStartRecord;
> private JButton cmdStopRecord;
> AudioInputStream audioInputStream;
> double duration;
> Capture capture = new Capture();
>
> public SimpleSound()
> {
> makeGUI();
>
> }
>
>
> public void makeGUI()
> {
> mainPanel = new JPanel();
> cmdStartRecord = new JButton("Start");
> cmdStopRecord = new JButton("Stop");
> cmdStopRecord.setEnabled(false);
>
>
> cmdStartRecord.addActionListener(this);
> cmdStopRecord.addActionListener(this);
>
>
> mainPanel.add(cmdStartRecord);
> mainPanel.add(cmdStopRecord);
>
> Container c = this.getContentPane();
>
> c.add(mainPanel , BorderLayout.CENTER);
> this.pack();
> this.setDefaultCloseOperation(EXIT_ON_CLOSE);
> this.setVisible(true);
>
> }
>
>
> public void actionPerformed(ActionEvent ae)
> {
> Object source = ae.getSource();
>
> if (source == cmdStartRecord)
> {
> cmdStartRecord.setEnabled(false);
> cmdStopRecord.setEnabled(true);
> capture.start();
>
> }
> else
> {
> cmdStartRecord.setEnabled(true);
> cmdStopRecord.setEnabled(false);
> capture.stop();
> // SaveToFile();
> }
> }
>
>
> public void SaveToFile()
> {
> if (audioInputStream == null)
> {
> System.out.println("Nothing to save ->someting bad happend !!!");
> System.out.println("cashing & burning . .. .");
> System.exit(0);
> }
> else
> {
>
> }
>
> try
> {
> audioInputStream.reset();
> }
> catch(Exception e)
> {
> System.out.println("Unable to reset audioStream in save method");
> System.out.println("Exitting . .. .");
> System.exit(0);
> }
> File x = new File(userHomeDir + fileSeperator +
> "SimpleMicRecording" + fileSeperator + "SimpleSound.wav");
> if (!(x.exists())){
> File dirs = x.getParentFile();
> dirs.mkdir();
> }
> File file = new File(userHomeDir + fileSeperator +
> "SimpleMicRecording" + fileSeperator + "SimpleSound.wav");
> try
> {
> if (AudioSystem.write(audioInputStream , AudioFileFormat.Type.WAVE
> , file) == -1)
> {
> System.out.println("Error");
> }
> }
> catch(Exception e)
> {
> System.out.println("Oh-no!!!");
> }
> }
>
> class Capture implements Runnable
> {
> private AudioFormat.Encoding encoding;
> private float rate;
> private int sampleSize;
> private int channels;
> private int frameSize;
> private boolean bigEndian;
>
>
>
> TargetDataLine line; //define a line - a line from witch audio can
> be read
> Thread thread;
>
> public void start()
> {
> thread = new Thread(this);
> thread.setName("Capture Audio");
> thread.start();
> }
>
>
> public void stop()
> {
> thread = null;
> }
>
> public void run()
> {
> duration = 0;
> audioInputStream = null;
>
> setupFormat();
>
> //define the required attributes for the line &
> //make sure a compatible line is supported
> AudioFormat format = new
> AudioFormat(AudioFormat.Encoding.PCM_SIGNED ,44100, 16,2 , 4 ,44100 ,
> true);
>
> //does not want to work !!!!????
> //AudioFormat format = new AudioFormat(encoding , rate , sampleSize
> , channels , frameSize , rate , bigEndian);
>
> DataLine.Info info = new DataLine.Info(TargetDataLine.class ,
> format);
>
> if (!AudioSystem.isLineSupported(info))
> {
> System.out.println("Line matching " + info +" not supported");
> System.out.println("Exitting the application . . .");
> System.exit(0);
> }
>
> //get & open target data line for capture
>
> try
> {
> line = (TargetDataLine) AudioSystem.getLine(info);
> line.open(format , line.getBufferSize());
> }
> catch(LineUnavailableException ex)
> {
> System.out.println("Unable to open the line");
> System.out.println("Exitting application . . .");
> System.exit(0);
> }
> catch(SecurityException ex)
> {
> System.out.println("A security exception occured");
> System.out.println("Exitting application . . .");
> System.exit(0);
> }
> catch(Exception ex)
> {
> System.out.println("Some exception occured");
> System.out.println("Exitting application . . .");
> System.exit(0);
> }
>
> ByteArrayOutputStream out = new ByteArrayOutputStream();
> int frameSizeInBytes = format.getFrameSize();
> int bufferLengthInFrames = line.getBufferSize() / 8;
> int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
> byte [] data = new byte[bufferLengthInBytes];
> int numBytesRead;
>
> line.start();
>
> //while the thread is running , write whatever is comming
> //through the line(TargetDataLine) , to the ByteArrayOutputStream
> while (thread != null)
> {
> //Reads audio data from the data line's input buffer
> //if eoi then break out of the while-loop
>
> //The number of bytes to be read must represent an integral
> //number of sample frames, such that:
> // [ bytes read ] % [frame size in bytes ] == 0
> if ((numBytesRead = line.read(data , 0 , bufferLengthInBytes)) ==
> -1)
> {
> break;
> }
> //here is the problem
> out.write(data ,0 , numBytesRead);
> }
>
>
> //we reached the end of the stream . stop & close the line
> line.stop();
> line.close();
> line = null;
>
> //stop & close the output stream
> try
> {
> //Flushes this output stream and forces any buffered
> //output bytes to be written out. The general contract
> //of flush is that calling it is an indication that, if
> //any bytes previously written have been buffered by the
> //implementation of the output stream, such bytes should
> //immediately be written to their intended destination.
> out.flush();
> out.close();
> }
> catch(IOException ex)
> {
> System.out.println("IO Error occurered (flussing the
> BufferArrayOutputStream)");
> System.out.println(" . . . but carring on");
> }
>
> //load bytes in to audio input stream for saving
>
> byte audioBytes[] = out.toByteArray();
> ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
> audioInputStream = new AudioInputStream(bais , format ,
> audioBytes.length / frameSizeInBytes);
>
> long milliseconds =
> (long)((audioInputStream.getFrameLength() * 1000) /
> format.getFrameRate());
> duration = milliseconds / 1000.0;
>
>
> try
> {
> audioInputStream.reset();
> }
> catch(Exception e)
> {
> System.out.println("Error resetting audioInputStream");
> System.out.println("Exitting application . . .. ");
> System.exit(0);
> }
>
> if (audioInputStream == null)
> {
> System.out.println("?????????");
> }
> SaveToFile();
>
> }
>
> private void setupFormat()
> {
> AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
> rate = (float)44100;
> sampleSize = 16;
> channels = 2;
> frameSize = (sampleSize/8)*channels;
> bigEndian = true;
> }
> }
> }