import java.io.*; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; import java.util.LinkedList; import javax.sound.sampled.*; public class AudioSampleReader { private AudioInputStream audioInputStream; private AudioFormat format; LinkedList<byte[]> bufferList = new LinkedList<byte[]>(); public AudioSampleReader(File file) throws UnsupportedAudioFileException, IOException { //bb = new FileInputStream(file).getChannel().map(MapMode.READ_ONLY, 0, file.length()); //bb.load(); audioInputStream = AudioSystem.getAudioInputStream(file); format = audioInputStream.getFormat(); } private void copyFromBuffer(byte[] cp, long start) { } public AudioFormat getFormat() { return format; } public long getSampleCount() { long total = (audioInputStream.getFrameLength() * format.getFrameSize() * 8) / format.getSampleSizeInBits(); return total / format.getChannels(); } public void getInterleavedSamples(long begin, long end, double[] samples) throws IOException, IllegalArgumentException { long nbSamples = end - begin; long nbBytes = nbSamples * (format.getSampleSizeInBits() / 8) * format.getChannels(); if (nbBytes > Integer.MAX_VALUE) throw new IllegalArgumentException("too many samples"); byte[] inBuffer = new byte[(int)nbBytes]; long bufstart = begin * (format.getSampleSizeInBits() / 8) * format.getChannels(); long bufend = end * (format.getSampleSizeInBits() / 8) * format.getChannels(); audioInputStream.read(inBuffer, 0, inBuffer.length); //System.err.println(bufstart); //bb.get(inBuffer, (int) bufstart, inBuffer.length); decodeBytes(inBuffer, samples); } public void getChannelSamples(int channel, double[] interleavedSamples, double[] channelSamples) { int nbChannels = format.getChannels(); for (int i = 0; i < channelSamples.length; i++) { channelSamples[i] = interleavedSamples[nbChannels*i + channel]; } } public void getStereoSamples(double[] leftSamples, double[] rightSamples) throws IOException { long sampleCount = getSampleCount(); double[] interleavedSamples = new double[(int)sampleCount*2]; getInterleavedSamples(0, sampleCount, interleavedSamples); for (int i = 0; i < leftSamples.length; i++) { leftSamples[i] = interleavedSamples[2*i]; rightSamples[i] = interleavedSamples[2*i+1]; } } private void decodeBytes(byte[] audioBytes, double[] audioSamples) { int sampleSizeInBytes = format.getSampleSizeInBits() / 8; int[] sampleBytes = new int[sampleSizeInBytes]; int k = 0; // index in audioBytes for (int i = 0; i < audioSamples.length; i++) { // collect sample byte in big-endian order if (format.isBigEndian()) { // bytes start with MSB for (int j = 0; j < sampleSizeInBytes; j++) { sampleBytes[j] = audioBytes[k++]; } } else { // bytes start with LSB for (int j = sampleSizeInBytes - 1; j >= 0; j--) { sampleBytes[j] = audioBytes[k++]; if (sampleBytes[j] != 0) j = j + 0; } } // get integer value from bytes int ival = 0; for (int j = 0; j < sampleSizeInBytes; j++) { ival += sampleBytes[j]; if (j < sampleSizeInBytes - 1) ival <<= 8; } // decode value double ratio = Math.pow(2., format.getSampleSizeInBits() - 1); double val = ((double) ival) / ratio; audioSamples[i] = val; } } }