/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.container.riff.type; import java.nio.ByteBuffer; import org.apache.log4j.Logger; import com.ttProject.container.riff.WaveFormatExCodecType; import com.ttProject.container.riff.RiffFormatUnit; import com.ttProject.container.riff.Type; import com.ttProject.frame.AudioAnalyzer; import com.ttProject.frame.AudioSelector; import com.ttProject.frame.CodecType; import com.ttProject.frame.IAnalyzer; import com.ttProject.frame.aac.AacDsiFrameAnalyzer; import com.ttProject.frame.aac.AacFrameAnalyzer; import com.ttProject.frame.adpcmimawav.AdpcmImaWavFrameAnalyzer; import com.ttProject.frame.mp3.Mp3FrameAnalyzer; import com.ttProject.frame.pcmalaw.PcmalawFrameAnalyzer; import com.ttProject.frame.pcmmulaw.PcmmulawFrameAnalyzer; import com.ttProject.frame.speex.SpeexFrameAnalyzer; import com.ttProject.frame.speex.SpeexFrameSelector; import com.ttProject.frame.speex.type.CommentFrame; import com.ttProject.frame.vorbis.VorbisFrameAnalyzer; import com.ttProject.nio.channels.ByteReadChannel; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.unit.extra.BitLoader; import com.ttProject.unit.extra.bit.Bit16; import com.ttProject.unit.extra.bit.Bit32; import com.ttProject.util.BufferUtil; /** * fmt * @author taktod */ public class Fmt extends RiffFormatUnit { /** logger */ @SuppressWarnings("unused") private Logger logger = Logger.getLogger(Fmt.class); private Bit16 wFormatTag = new Bit16(); private Bit16 nChannels = new Bit16(); private Bit32 nSamplePerSec = new Bit32(); private Bit32 nAvgBytesPerSec = new Bit32(); // byteRate byte / sec private Bit16 nBlockAlign = new Bit16(); private Bit16 wBitsPerSample = new Bit16(); private Bit16 cbSize = new Bit16(); private ByteBuffer extraInfo = null; // for the case of vorbis. // this extraInfo do have ogg's privateData information. /* * 02 1E 54 * 2 element * first is 0x1E header * second is 0x54 comment * third is else. setup */ /* * for speex * headerFrame only. commentFrame is created by somehow. */ /** frame Analyzer */ private IAnalyzer frameAnalyzer = null; /** * constructor */ public Fmt() { super(Type.FMT); } /** * {@inheritDoc} */ @Override public void minimumLoad(IReadChannel channel) throws Exception { super.minimumLoad(channel); BitLoader loader = new BitLoader(channel); loader.setLittleEndianFlg(true); loader.load(wFormatTag, nChannels, nSamplePerSec, nAvgBytesPerSec, nBlockAlign, wBitsPerSample, cbSize); } /** * {@inheritDoc} */ @Override public void load(IReadChannel channel) throws Exception { if(cbSize.get() != 0) { extraInfo = BufferUtil.safeRead(channel, cbSize.get()); } } /** * {@inheritDoc} */ @Override protected void requestUpdate() throws Exception { } /** * ref RiffCodecType * @return */ public WaveFormatExCodecType getRiffCodecType() { return WaveFormatExCodecType.getCodec(wFormatTag.get()); } /** * ref codecType * @return */ @Override public CodecType getCodecType() { return WaveFormatExCodecType.getCodec(wFormatTag.get()).getCodecType(); } /** * ref analyzer * @return */ @Override public IAnalyzer getFrameAnalyzer() throws Exception { if(frameAnalyzer != null) { return frameAnalyzer; } switch(getRiffCodecType()) { case IMA_ADPCM: frameAnalyzer = new AdpcmImaWavFrameAnalyzer(); break; case A_LAW: frameAnalyzer = new PcmalawFrameAnalyzer(); break; case U_LAW: frameAnalyzer = new PcmmulawFrameAnalyzer(); break; case AAC: if(extraInfo == null) { frameAnalyzer = new AacFrameAnalyzer(); } else { frameAnalyzer = new AacDsiFrameAnalyzer(); frameAnalyzer.setPrivateData(new ByteReadChannel(extraInfo)); } break; case MP3: frameAnalyzer = new Mp3FrameAnalyzer(); break; case VORBIS: frameAnalyzer = new VorbisFrameAnalyzer(); frameAnalyzer.setPrivateData(new ByteReadChannel(extraInfo)); break; case SPEEX: frameAnalyzer = new SpeexFrameAnalyzer(); frameAnalyzer.analyze(new ByteReadChannel(extraInfo)); SpeexFrameSelector speexFrameSelector = (SpeexFrameSelector)((AudioAnalyzer)frameAnalyzer).getSelector(); speexFrameSelector.setCommentFrame(new CommentFrame()); break; default: throw new RuntimeException("codec is unknown:."); } if(frameAnalyzer instanceof AudioAnalyzer) { AudioSelector selector = ((AudioAnalyzer)frameAnalyzer).getSelector(); selector.setBit(wBitsPerSample.get()); selector.setChannel(nChannels.get()); selector.setSampleRate(nSamplePerSec.get()); } return frameAnalyzer; } @Override public int getBlockSize() { return nBlockAlign.get(); } @Override public ByteBuffer getExtraInfo() { return extraInfo; } }