package org.jcodec.codecs.wav; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.jcodec.common.AudioCodecMeta; import org.jcodec.common.AudioFormat; import org.jcodec.common.Codec; import org.jcodec.common.Demuxer; import org.jcodec.common.DemuxerTrack; import org.jcodec.common.DemuxerTrackMeta; import org.jcodec.common.TrackType; import org.jcodec.common.io.NIOUtils; import org.jcodec.common.io.SeekableByteChannel; import org.jcodec.common.model.Packet; import org.jcodec.common.model.Packet.FrameType; /** * A demuxer for a wav file. * * * @author Stan Vitvitskiy */ public class WavDemuxer implements Demuxer, DemuxerTrack { // How many audio frames will be read per packet. One frame is all samples // for all channels, i.e. for the 5.1 16bit format one frame will be 12 // bytes. private static final int FRAMES_PER_PKT = 1024; private SeekableByteChannel ch; private WavHeader header; private long dataSize; private short frameSize; private int frameNo; private long pts; public WavDemuxer(SeekableByteChannel ch) throws IOException { this.ch = ch; header = WavHeader.readChannel(ch); dataSize = ch.size() - ch.position(); frameSize = header.getFormat().getFrameSize(); } @Override public void close() throws IOException { ch.close(); } @Override public Packet nextFrame() throws IOException { ByteBuffer data = NIOUtils.fetchFromChannel(ch, frameSize * FRAMES_PER_PKT); if (!data.hasRemaining()) return null; long oldPts = pts; int duration = data.remaining() / frameSize; pts += duration; return Packet.createPacket(data, oldPts, header.getFormat().getFrameRate(), data.remaining() / frameSize, frameNo++, FrameType.KEY, null); } @Override public DemuxerTrackMeta getMeta() { AudioFormat format = header.getFormat(); AudioCodecMeta audioCodecMeta = new AudioCodecMeta(format); long totalFrames = dataSize / format.getFrameSize(); return new DemuxerTrackMeta(TrackType.AUDIO, Codec.PCM, (double) totalFrames / format.getFrameRate(), null, (int) totalFrames, null, null, audioCodecMeta); } @Override public List<? extends DemuxerTrack> getTracks() { List<DemuxerTrack> result = new ArrayList<DemuxerTrack>(); result.add(this); return result; } @Override public List<? extends DemuxerTrack> getVideoTracks() { List<DemuxerTrack> result = new ArrayList<DemuxerTrack>(); return result; } @Override public List<? extends DemuxerTrack> getAudioTracks() { return getTracks(); } }