/*
* Copyright (C) 2011 in-somnia
*
* This file is part of JAAD.
*
* JAAD is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* JAAD is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.adts;
import java.io.DataInputStream;
import java.io.IOException;
import net.sourceforge.jaad.aac.ChannelConfiguration;
import net.sourceforge.jaad.aac.SampleFrequency;
class ADTSFrame {
//fixed
private boolean id, protectionAbsent, privateBit, copy, home;
private int layer, profile, sampleFrequency, channelConfiguration;
//variable
private boolean copyrightIDBit, copyrightIDStart;
private int frameLength, adtsBufferFullness, rawDataBlockCount;
//error check
private int[] rawDataBlockPosition;
private int crcCheck;
//decoder specific info
private byte[] info;
ADTSFrame(DataInputStream in) throws IOException {
readHeader(in);
if(!protectionAbsent) crcCheck = in.readUnsignedShort();
if(rawDataBlockCount==0) {
//raw_data_block();
}
else {
int i;
//header error check
if(!protectionAbsent) {
rawDataBlockPosition = new int[rawDataBlockCount];
for(i = 0; i<rawDataBlockCount; i++) {
rawDataBlockPosition[i] = in.readUnsignedShort();
}
crcCheck = in.readUnsignedShort();
}
//raw data blocks
for(i = 0; i<rawDataBlockCount; i++) {
//raw_data_block();
if(!protectionAbsent) crcCheck = in.readUnsignedShort();
}
}
}
private void readHeader(DataInputStream in) throws IOException {
//fixed header:
//1 bit ID, 2 bits layer, 1 bit protection absent
int i = in.read();
id = ((i>>3)&0x1)==1;
layer = (i>>1)&0x3;
protectionAbsent = (i&0x1)==1;
if(!protectionAbsent) System.out.println("\t\tCRC!!!");
//2 bits profile, 4 bits sample frequency, 1 bit private bit
i = in.read();
profile = ((i>>6)&0x3)+1;
sampleFrequency = (i>>2)&0xF;
privateBit = ((i>>1)&0x1)==1;
//3 bits channel configuration, 1 bit copy, 1 bit home
i = (i<<8)|in.read();
channelConfiguration = ((i>>6)&0x7);
copy = ((i>>5)&0x1)==1;
home = ((i>>4)&0x1)==1;
//int emphasis = in.readBits(2);
//variable header:
//1 bit copyrightIDBit, 1 bit copyrightIDStart, 13 bits frame length,
//11 bits adtsBufferFullness, 2 bits rawDataBlockCount
copyrightIDBit = ((i>>3)&0x1)==1;
copyrightIDStart = ((i>>2)&0x1)==1;
i = (i<<16)|in.readUnsignedShort();
frameLength = (i>>5)&0x1FFF;
i = (i<<8)|in.read();
adtsBufferFullness = (i>>2)&0x7FF;
rawDataBlockCount = i&0x3;
}
int getFrameLength() {
return frameLength-(protectionAbsent ? 7 : 9);
}
byte[] createDecoderSpecificInfo() {
if(info==null) {
//5 bits profile, 4 bits sample frequency, 4 bits channel configuration
info = new byte[2];
info[0] = (byte) (profile<<3);
info[0] |= (sampleFrequency>>1)&0x7;
info[1] = (byte) ((sampleFrequency&0x1)<<7);
info[1] |= (channelConfiguration<<3);
/*1 bit frame length flag, 1 bit depends on core coder,
1 bit extension flag (all three currently 0)*/
}
return info;
}
int getSampleFrequency() {
return SampleFrequency.forInt(sampleFrequency).getFrequency();
}
int getChannelCount() {
return ChannelConfiguration.forInt(channelConfiguration).getChannelCount();
}
}