Convert sample rates on the fly when reading a WAV file to an array of samples with Java

I have 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 values ​​with many values ​​for this purpose, encoded at a frame rate of 11025 Hz.

The source files have several different sampling 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 does not correctly handle different sample rates. Therefore, for a frame rate of 44100 Hz, I get four times more samples than for a frame rate of 11025 Hz. I would like the resulting sample array to use a frame rate of 11025 Hz, regardless of the frame rate of the source file. I tried to get Java to convert the frame rate for me while reading AudioInputStream, but I get an exception similar to the following:

 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 API tutorial: http://java.sun.com/docs/books/tutorial/sound/converters.html . It seems that the Java Sound API does not support such a conversion of my operating system (Windows 7). And I would like to avoid dependencies on any external libraries. Is there a way to do the sampling rate conversion myself?

+7
java windows audio signal-processing javasound
source share
2 answers

For sampling rates> 11025 Hz, you need to perform a down floppy, which is a two-step process. First you need to go through a low-pass filter to satisfy the Nyquist criterion, and then you can decite, for example. for 44.1 kHz sampling frequency data, you need a low-pass filter with a cutoff frequency of 5.5 kHz, and then you can throw 3 out of every 4 samples for a downsampling ratio of 4: 1. You will need a different filter for each downsampling ratio, which you want to support.

+6
source share

I believe that the accepted answer answers another question - it solves the same problem (lowering the audio sample), but in a different way (manually instead of the java sound API). I had the same and dug up.

The correct way (or the Java API method) for this is valid (as suggested in http://docs.oracle.com/javase/tutorial/sound/converters.html )

 AudioFormat outDataFormat = new AudioFormat((float) 8000.0, (int) 8, (int) 1, true, false); AudioInputStream lowResAIS = AudioSystem.getAudioInputStream(outDataFormat, inFileAIS); 

The problem is that standard java does not send with oversampling (or even stereo monitoring) code (or at least in the wrong part of the code - see http://www.jsresources.org/faq_audio.html#convert_sample_rate ).

The jsresources pages also point to the answers: just installing 2 plugins does the trick. The easiest way is to install these plugins in the Extensions directory, on OSX Lion this will do the trick (if you have wget):

 wget http://www.tritonus.org/tritonus_share-0.3.6.jar -O /Library/Java/Extensions/tritonus_share-0.3.6.jar wget http://www.tritonus.org/tritonus_remaining-0.3.6.jar -O /Library/Java/Extensions/tritonus_remaining-0.3.6.jar 

After adding these two jar files, everything worked (only one additional warning: if you want to change both the number of channels and the sampling frequency, it is still not supported as a single step).

+5
source share

All Articles