OutOfMemoryError with wav file bigger than 30kb

OS: Ubuntu 7.04

Java version 1.5.0_12

I'm trying to run the simplest of examples here, just playing a wav file:

import java.io.*;

import java.util.*;

import javax.sound.sampled.*;

publicclass Main{

publicstaticvoid main(String[] argv){

try{

// From file

AudioInputStream stream = AudioSystem.getAudioInputStream(new File("/home/iii/iii1.wav"));

// At present, ALAW and ULAW encodings must be converted

// to PCM_SIGNED before it can be played

AudioFormat format = stream.getFormat();

if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED){

format =new AudioFormat(

AudioFormat.Encoding.PCM_SIGNED,

format.getSampleRate(),

format.getSampleSizeInBits()*2,

format.getChannels(),

format.getFrameSize()*2,

format.getFrameRate(),

true);// big endian

stream = AudioSystem.getAudioInputStream(format, stream);

}

// Create the clip

DataLine.Info info =new DataLine.Info(

Clip.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()));

Clip clip = (Clip) AudioSystem.getLine(info);

// This method does not return until the audio file is completely loaded

clip.open(stream);

// Start playing

clip.start();

Thread.sleep( 5000 );

}catch(Exception e){

e.printStackTrace();

}

}

}

And all this works fine if the wav file is smaller than around 30KB. Otherwise I get:

Exception in thread"main" java.lang.OutOfMemoryError: Java heap space

at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1127)

at Main.main(Main.java:39)

(that is the clip.open(stream);

line)

Unfortunately very few wav files are small enough for this code to have any practical value. For the sake of the experiment I run it with say -Xms256m -Xmx512m (the machine has 2GB RAM) which are ridiculously high for such a simple program but there is no difference. The same code on a Windows XP box plays a bit bigger files (around 70KB) but behaves oddly with .wav files bigger than say 100KB. It doesn't throw OutOfMemory or any other exceptions but just won't play them.

Appreciate your help! If the above code isn't good can you point me to or paste some java example which will hopefully use javax.sound.sampled and be able to open wav files of size at least 200KB.

Thank you...

[3548 byte] By [pepper_bga] at [2007-11-27 11:00:28]
# 1

Clips are objects for very small wave-files. You should open SourceDataLine to use bigger files. See API for SourceDataLine - maybe just changing the object is enough.

By the way ... Quick look tells me that there is a bug in your code. Take a look at what happens, if you open PCM unsigned encoded file... Is the bit size correct?

finn_hippiea at 2007-7-29 12:29:52 > top of Java-index,Security,Cryptography...
# 2

Great, that works! Here is the code which does it:

import java.io.*;

import java.util.*;

import javax.sound.sampled.*;

public class Main {

private static final int BUFFER_SIZE=128000;

public static void main(String[] argv) {

try {

// From file

AudioInputStream stream = AudioSystem.getAudioInputStream(new File("/home/iii/iii.wav"));

// At present, ALAW and ULAW encodings must be converted

// to PCM_SIGNED before it can be played

AudioFormat format = stream.getFormat();

if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {

format = new AudioFormat(

AudioFormat.Encoding.PCM_SIGNED,

format.getSampleRate(),

format.getSampleSizeInBits()*2,

format.getChannels(),

format.getFrameSize()*2,

format.getFrameRate(),

true);// big endian

stream = AudioSystem.getAudioInputStream(format, stream);

}

// Create the dataLine

DataLine.Info info = new DataLine.Info(

SourceDataLine.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()));

SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(info);

// This method does not return until the audio file is completely loaded

dataLine.open(stream.getFormat());

// Start playing

dataLine.start();

byte[] buffer=new byte[BUFFER_SIZE];

int r=stream.read(buffer,0,BUFFER_SIZE);

while(r!=-1){

if(r>0){

dataLine.write(buffer,0,r);

}

r=stream.read(buffer,0,BUFFER_SIZE);

}

dataLine.drain();

dataLine.close();

} catch(Exception e) {

e.printStackTrace();

}

}

}

Not sure what is the bit size problem you are referring to. Is it the *2 thing? No idea why is it there, both examples I borrowed from had it. I kinda read it that if you interpret the sign bit as data, stuff doubles. It is weird though, it works with and without it...

Thank you so much for your help...

pepper_bga at 2007-7-29 12:29:52 > top of Java-index,Security,Cryptography...