/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.frame.opus.type;
import java.nio.ByteBuffer;
import java.util.List;
import org.apache.log4j.Logger;
import com.ttProject.frame.opus.OpusFrame;
import com.ttProject.nio.channels.IReadChannel;
import com.ttProject.unit.extra.BitConnector;
import com.ttProject.unit.extra.BitLoader;
import com.ttProject.unit.extra.bit.Bit16;
import com.ttProject.unit.extra.bit.Bit32;
import com.ttProject.unit.extra.bit.Bit8;
import com.ttProject.util.BufferUtil;
/**
* headerFrame for opus.
* for mkv this information is in codecPrivate.
* 8byte opusString OpusHead
* 1byte version
* 1byte channels
* 2byte preskip
* 4byte sampleRate
* 2byte outputGain
* 1byte channelMappingFamily
* nbyte mappingTable
* @author taktod
* @see http://tools.ietf.org/pdf/draft-ietf-codec-oggopus-03.pdf
*/
public class HeaderFrame extends OpusFrame {
/** logger */
private Logger logger = Logger.getLogger(HeaderFrame.class);
private String opusString = "OpusHead";
private Bit8 version = new Bit8(); // 1 fixed?
private Bit8 channels = new Bit8();
private Bit16 preSkip = new Bit16(); // デコードするときの遅延フレーム数か?サンプルだったら312になった
private Bit32 sampleRate = new Bit32(); // どうやら入力サンプルレートで出力時のではないっぽい。(どういうことだ?)出力時のサンプルレートはデコードの仕方でいろいろにできるっぽい。(8,12,16,24,48kHzが動作可能なものっぽい)
private Bit16 outputGain = new Bit16(); // 出力振幅の設定か?(10^(outputGain / 20.0*256)になるのか?)
private Bit8 channelMappingFamily = new Bit8();
// 以下のデータはoptionalChannelMappingTableからくるけど、channelMappingFamilyが0でもデータをいれておいた方がよさそう(デフォルトってやつ)
private int nbStreams;
private int nbCoupled;
private List<Integer> streamMap;
// Optional Channel Mapping Table
/*
channelMappingFamilyが0でない場合の動作
Bit8 nbStreamの数
Bit8 nbCoupled nbStreamより小さな値であるべき、nbCoupled + nbStreamsを足して255を超えたらストリームおおすぎ
channels > 2の場合はエラー
streams = 1
nbCoupled = チャンネル数 > 1ならかどうかで判断
stream_map[0] = 0
stream_map[1] = 1
*/
// mappingTableもあるかもしれないがほっとく。
public HeaderFrame() {
super.update();
}
@Override
public void minimumLoad(IReadChannel channel) throws Exception {
super.setReadPosition(channel.position());
super.setSize(channel.size());
BitLoader loader = new BitLoader(channel);
loader.setLittleEndianFlg(true);
loader.load(version, channels, preSkip, sampleRate,
outputGain, channelMappingFamily);
logger.info(channels.get());
logger.info(sampleRate.get());
if(channel.position() != channel.size()) {
throw new Exception("has mappingTable, please tell me to analyze information.");
}
super.update();
}
/**
* {@inheritDoc}
*/
@Override
public void load(IReadChannel channel) throws Exception {
}
/**
* {@inheritDoc}
*/
@Override
protected void requestUpdate() throws Exception {
BitConnector connector = new BitConnector();
connector.setLittleEndianFlg(true);
ByteBuffer buffer = ByteBuffer.wrap(opusString.getBytes());
super.setData(BufferUtil.connect(
buffer,
connector.connect(version, channels, preSkip, sampleRate, outputGain, channelMappingFamily)));
}
/**
* {@inheritDoc}
*/
@Override
public ByteBuffer getPackBuffer() throws Exception {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isComplete() {
return true;
}
}