/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.frame.speex.type; import java.nio.ByteBuffer; import org.apache.log4j.Logger; import com.ttProject.frame.speex.SpeexFrame; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.util.BufferUtil; /** * speex frame * * speexでは、headerの部分が欠如しているらしい。(ffmpegの出力より) * これは推測ですが、どうやらspeexのoggファイル化したときにでる、header部分が固定化されているために、削除状態になっている感じ。 * aacのdeviceSpecificInfoが1つで固定なので、省略されている感じ。 * よってframe数はaudioTagごとに固定されているみたいです。 * その確認として、2つのaudioTagが合体しているaudioTagをつくって、再生したところ、はじめの音がこわれました。 * 正解な気がします。 * * 以上とりあえず推測 * * speexは1つのframeあたり320samplesで動作している模様です。 * speexを含むoggFileは * OggPage[headerFrame] * OggPage[commentFrame] * OggPage[frame,frame,frame,frame....] * OggPage[frame,frame,frame,frame....] * OggPage[frame,frame,frame,frame....] * という構成になっているみたい。 * * speex frame structure. * 1bit widebandBit * if widebandBit = 0 4bit modeId * else widebandBit = 1 3bit modeId * data... * * data size is depend on modeId. * for narrowband. * |id|bitsize| * | 0| 5| * | 1| 43| * | 2| 119| * | 3| 160| * | 4| 220| * | 5| 300| * | 6| 364| * | 7| 492| * | 8| 79| * * for wideband * |id|bitsize| * | 0| 4| * | 1| 36| * | 2| 112| * | 3| 192| * | 4| 352| * these bitsize contain widebandBit and modeId. * * for the frame unit. we can figure out with widebandBit. * * 011011011011 -> 011 011 011 011 * 010101010101 -> 01 01 01 01 01 01 * 000000 -> 0 0 0 0 0 0 * each unit contains 320 samples. * * @see http://www.speex.org/docs/manual/speex-manual.pdf * @author taktod */ public class Frame extends SpeexFrame { /** logger */ @SuppressWarnings("unused") private Logger logger = Logger.getLogger(Frame.class); /** frameBuffer */ private ByteBuffer frameBuffer = null; /** * {@inheritDoc} */ @Override public void minimumLoad(IReadChannel channel) throws Exception { super.setSize(channel.size()); frameBuffer = BufferUtil.safeRead(channel, channel.size()); super.update(); } /** * {@inheritDoc} */ @Override public void load(IReadChannel channel) throws Exception { } /** * {@inheritDoc} */ @Override protected void requestUpdate() throws Exception { if(frameBuffer == null) { throw new Exception("frameBuffer is null."); } super.setData(frameBuffer); } /** * {@inheritDoc} */ @Override public ByteBuffer getPackBuffer() throws Exception { return getData(); } }