Skip to content

Instantly share code, notes, and snippets.

@nicolamontecchio
Created December 26, 2013 16:02
Show Gist options
  • Save nicolamontecchio/8135423 to your computer and use it in GitHub Desktop.
Save nicolamontecchio/8135423 to your computer and use it in GitHub Desktop.
package com.nicolamontecchio.chroma;
import java.io.*;
import javax.sound.sampled.*;
/**
* Read an audio file. Provided that the appropriate packages are in the classpath, mp3 and ogg should be readable too. The safest route is to read from a MONO, WAV file.
*/
public class AudioReader {
private AudioInputStream signedBigEndianInputStream = null;
private AudioInputStream originalAudioInputStream = null;
public AudioReader(File inputfile) throws UnsupportedAudioFileException, IOException {
originalAudioInputStream = AudioSystem.getAudioInputStream(inputfile);
AudioFormat destaf = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
originalAudioInputStream.getFormat().getSampleRate(),
16, originalAudioInputStream.getFormat().getChannels(),
16 / 8 * originalAudioInputStream.getFormat().getChannels(),
originalAudioInputStream.getFormat().getSampleRate(), true);
signedBigEndianInputStream = AudioSystem.getAudioInputStream(destaf, originalAudioInputStream);
}
/**
* Read next n samples (at most) from file (convert automatically to MONO). Return as double[].
*/
public double[] readDoubleSamples(int n) throws IOException {
int channels = signedBigEndianInputStream.getFormat().getChannels();
int ss = signedBigEndianInputStream.getFormat().getSampleSizeInBits();
int ssB = ss / 8; // in bytes
// System.out.println(String.format("fl: %d, ss: %d, ssB: %d, samplerate: %f",
// fl, ss, ssB, signedBigEndianInputStream.getFormat().getSampleRate()));
byte[] b = new byte[n * channels * ssB];
int read = signedBigEndianInputStream.read(b);
double[] res = new double[read / ssB / channels];
for (int i = 0; i < res.length; i++)
res[i] = 0;
for (int i = 0; i < res.length * channels; i++) {
double val = 0;
switch (ss) {
case 8:
val = ((b[i * ssB] & 0xFF) - 128) / 128.0;
break;
case 16:
val = ((b[i * ssB + 0] << 8) | (b[i * ssB + 1] & 0xFF)) / 32768.0;
break;
case 24:
val = ((b[i * ssB + 0] << 16) | ((b[i * ssB + 1] & 0xFF) << 8)
| (b[i * ssB + 2] & 0xFF)) / 8388606.0;
break;
case 32:
val = ((b[i * ssB + 0] << 24) | ((b[i * ssB + 1] & 0xFF) << 16)
| ((b[i * ssB + 2] & 0xFF) << 8) | (b[i * ssB + 3] & 0xFF)) / 2147483648.0;
break;
}
res[i/channels] += val / channels;
}
return res;
}
public float getSampleRate() {
return signedBigEndianInputStream.getFormat().getSampleRate();
}
public void close() throws IOException {
signedBigEndianInputStream.close();
originalAudioInputStream.close();
}
}
@MananGupta00
Copy link

Hello,
if its not too much too ask, can u please give a working demo(through driver class)?
Like i am confused what to pass (samples per second or total samples in whole audio) as 'n' in readDoubleSamples.
PS. I am a noob.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment