package org.jcodec.codecs.wav;
import org.jcodec.audio.AudioSource;
import org.jcodec.common.AudioFormat;
import org.jcodec.common.AudioUtil;
import org.jcodec.common.io.NIOUtils;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.channels.ReadableByteChannel;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* Reads integer samples from the wav file
*
* @author The JCodec project
*/
public class WavInput implements Closeable {
protected WavHeader header;
protected byte[] prevBuf;
protected ReadableByteChannel _in;
protected AudioFormat format;
public WavInput(ReadableByteChannel _in) throws IOException {
this.header = WavHeader.readChannel(_in);
this.format = header.getFormat();
this._in = _in;
}
public int read(ByteBuffer buf) throws IOException {
int maxRead = format.framesToBytes(format.bytesToFrames(buf.remaining()));
return NIOUtils.readL(_in, buf, maxRead);
}
public void close() throws IOException {
_in.close();
}
public WavHeader getHeader() {
return header;
}
public AudioFormat getFormat() {
return format;
}
/**
* Manages file resource on top of WavInput
*/
public static class WavFile extends WavInput {
public WavFile(File f) throws IOException {
super(NIOUtils.readableChannel(f));
}
@Override
public void close() throws IOException {
super.close();
_in.close();
}
}
/**
* Supports more high-level float and integer input on top of WavInput
*/
public static class Source implements AudioSource, Closeable {
private WavInput src;
private AudioFormat format;
private int pos;
public Source(WavInput src) {
this.src = src;
this.format = src.getFormat();
}
public AudioFormat getFormat() {
return src.getFormat();
}
public void close() throws IOException {
src.close();
}
public int read(int[] samples, int max) throws IOException {
// Safety net
max = Math.min(max, samples.length);
ByteBuffer bb = ByteBuffer.allocate(format.samplesToBytes(max));
int read = src.read(bb);
bb.flip();
AudioUtil.toInt(format, bb, samples);
return format.bytesToFrames(read);
}
public int readFloat(FloatBuffer samples) throws IOException {
ByteBuffer bb = ByteBuffer.allocate(format.samplesToBytes(samples.remaining()));
int i = src.read(bb);
if (i == -1)
return -1;
bb.flip();
AudioUtil.toFloat(format, bb, samples);
int read = format.bytesToFrames(i);
pos += read;
return read;
}
}
}