I've got a collection of short WAV files that I would like to process in Java using various digital signal processing algorithms. I need to get an array of int valued samples for this purpose, encoded at the 11025 Hz frame rate.
The source files have several different sample rates, including 11025 Hz and 44100 Hz. Here's the code I'm trying to use to read them:
// read the WAV file
FileInputStream fileInputStream = new FileInputStream(new File("test.wav"));
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(fileInputStream );
// copy the AudioInputStream to a byte array called buffer
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int tempBytesRead = 0;
int byteCounter = 0;
while ((tempBytesRead = audioInputStream.read(data, 0, data.length)) != -1) {
bos.write(data, 0, tempBytesRead);
byteCounter += tempBytesRead;
}
bos.close();
byte[] buffer = bos.toByteArray();
AudioFileFormat audioFileFormat = new AudioFileFormat(AudioFileFormat.Type.WAVE, audioInputStream.getFormat(), (int)audioInputStream.getFrameLength());
// get the resulting sample array
int[] samples = new int[audioFileFormat.getFrameLength()];
for (int i = 0; i < samples.length; i++) {
samples[i] = getSampleValue(i); // the getSampleValue method reads the sample values from the "buffer" array, handling different encoding types like PCM unsigned/signed, mono/stereo, 8 bit/16 bit
}
// RESULT: the "samples" array
The problem is, that the code doesn't handle different sample rates properly. So for the 44100 Hz frame rate I get four times as many samples as for the 11025 Hz frame rate. I would like the resulting sample array to use the 11025 Hz frame rate, regardless of the frame rate of the source file. I tried to force Java to convert the frame rate for me when reading the AudioInputStream, but I get an exception similar to the following one:
java.lang.IllegalArgumentException: Unsupported conversion: PCM_SIGNED 11025.0 Hz, 16 bit, mono, 2 bytes/frame, 44100.0 frames/second, little-endian from PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:955)
I read the Java Sound API tutorial: http://java.sun.com/docs/books/tutorial/sound/converters.html. It seems that the Java Sound API doesn't support this kind of conversion of my operating system (Windows 7). And I would like to avoid dependencies on any external libraries. Is there any way to do the sampling rate conversion on my own?