/*
* @(#)AudioFormat.java - parse Audioheaders, basic class
*
* Copyright (c) 2003-2008 by dvb.matt, All Rights Reserved.
*
* This file is part of ProjectX, a free Java based demux utility.
* By the authors, ProjectX is intended for educational purposes only,
* as a non-commercial test project.
*
* The part of audio parsing was derived from the MPEG/Audio
* Software Simulation Group's audio codec and ATSC A/52 in a special modified manner.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.sourceforge.dvb.projectx.audio;
import java.io.RandomAccessFile;
import java.io.IOException;
import net.sourceforge.dvb.projectx.parser.CommonParsing;
import net.sourceforge.dvb.projectx.common.Common;
public class AudioFormat extends Object {
private AudioFormat impl = null;
/**
*
*/
public AudioFormat(int type)
{
setNewType(type);
}
/**
*
*/
public AudioFormat(byte[] frame)
{
//unused, meant for autodetection
}
/**
*
*/
public AudioFormat()
{
init();
}
/**
*
*/
public void setNewType(int type)
{
switch (type)
{
case CommonParsing.DTS_AUDIO:
impl = new AudioFormatDTS();
break;
case CommonParsing.AC3_AUDIO:
impl = new AudioFormatAC3();
break;
case CommonParsing.LPCM_AUDIO:
impl = new AudioFormatLPCM();
break;
case CommonParsing.WAV_AUDIO:
impl = new AudioFormatWAV();
break;
case CommonParsing.MPEG_AUDIO:
impl = new AudioFormatMPA();
break;
case CommonParsing.AAC_AUDIO:
impl = new AudioFormatAAC();//
break;
}
}
private boolean INTEL;
private int ID;
private int Layer;
private int Protection_bit;
private int Private_bit;
private int Bitrate;
private int Sampling_frequency;
private int Padding_bit;
private int Mode;
private int Mode_extension;
private int Copyright;
private int Original;
private int Channel;
private int Emphasis;
private int Size;
private int Size_base;
private double Time_length;
private int nID;
private int nLayer;
private int nProtection_bit;
private int nPrivate_bit;
private int nBitrate;
private int nSampling_frequency;
private int nPadding_bit;
private int nMode;
private int nMode_extension;
private int nCopyright;
private int nOriginal;
private int nChannel;
private int nEmphasis;
private int nSize;
private int nSize_base;
private double nTime_length;
private int lID;
private int lLayer;
private int lProtection_bit;
private int lPrivate_bit;
private int lBitrate;
private int lSampling_frequency;
private int lPadding_bit;
private int lMode;
private int lMode_extension;
private int lCopyright;
private int lOriginal;
private int lChannel;
private int lEmphasis;
private int lSize;
private int lSize_base;
private double lTime_length;
/**
*
*/
public void init()
{
setINTEL(false);
setID(0);
setLayer(0);
setProtectionBit(0);
setPrivateBit(0);
setBitrate(0);
setSamplingFrequency(0);
setPaddingBit(0);
setPrivateBit(0);
setMode(0);
setModeExtension(0);
setCopyright(0);
setOriginal(0);
setChannel(0);
setEmphasis(0);
setSize(0);
setSizeBase(0);
setFrameTimeLength(0.0);
}
/**
*
*/
public boolean isINTEL()
{
return (impl == null ? INTEL : impl.isINTEL());
}
/**
*
*/
public void setINTEL(boolean b)
{
if (impl != null)
impl.setINTEL(b);
INTEL = b;
}
/**
*
*/
public int getID()
{
return (impl == null ? ID : impl.getID());
}
/**
*
*/
public void setID(int val)
{
if (impl != null)
impl.setID(val);
ID = val;
}
/**
*
*/
public int getLayer()
{
return (impl == null ? Layer : impl.getLayer());
}
/**
*
*/
public void setLayer(int val)
{
if (impl != null)
impl.setLayer(val);
Layer = val;
}
/**
*
*/
public int getBitrate()
{
return (impl == null ? Bitrate : impl.getBitrate());
}
/**
*
*/
public void setBitrate(int val)
{
if (impl != null)
impl.setBitrate(val);
Bitrate = val;
}
/**
*
*/
public int getSamplingFrequency()
{
return (impl == null ? Sampling_frequency : impl.getSamplingFrequency());
}
/**
*
*/
public void setSamplingFrequency(int val)
{
if (impl != null)
impl.setSamplingFrequency(val);
Sampling_frequency = val;
}
/**
*
*/
public int getMode()
{
return (impl == null ? Mode : impl.getMode());
}
/**
*
*/
public void setMode(int val)
{
if (impl != null)
impl.setMode(val);
Mode = val;
}
/**
*
*/
public int getModeExtension()
{
return (impl == null ? Mode_extension : impl.getModeExtension());
}
/**
*
*/
public void setModeExtension(int val)
{
if (impl != null)
impl.setModeExtension(val);
Mode_extension = val;
}
/**
*
*/
public int getEmphasis()
{
return (impl == null ? Emphasis : impl.getEmphasis());
}
/**
*
*/
public void setEmphasis(int val)
{
if (impl != null)
impl.setEmphasis(val);
Emphasis = val;
}
/**
*
*/
public int getSize()
{
return (impl == null ? Size : impl.getSize());
}
/**
*
*/
public void setSize(int val)
{
if (impl != null)
impl.setSize(val);
Size = val;
}
/**
*
*/
public int getSizeBase()
{
return (impl == null ? Size_base : impl.getSizeBase());
}
/**
*
*/
public void setSizeBase(int val)
{
if (impl != null)
impl.setSizeBase(val); //slackalan 250312
//setSizeBase(val);
Size_base = val;
}
/**
*
*/
public int getChannel()
{
return (impl == null ? Channel : impl.getChannel());
}
/**
*
*/
public void setChannel(int val)
{
if (impl != null)
impl.setChannel(val);
Channel = val;
}
/**
*
*/
public int getPaddingBit()
{
return (impl == null ? Padding_bit : impl.getPaddingBit());
}
/**
*
*/
public void setPaddingBit(int val)
{
if (impl != null)
impl.setPaddingBit(val);
Padding_bit = val;
}
/**
*
*/
public int getPrivateBit()
{
return (impl == null ? Private_bit : impl.getPrivateBit());
}
/**
*
*/
public void setPrivateBit(int val)
{
if (impl != null)
impl.setPrivateBit(val);
Private_bit = val;
}
/**
*
*/
public int getOriginal()
{
return (impl == null ? Original : impl.getOriginal());
}
/**
*
*/
public void setOriginal(int val)
{
if (impl != null)
impl.setOriginal(val);
Original = val;
}
/**
*
*/
public int getCopyright()
{
return (impl == null ? Copyright : impl.getCopyright());
}
/**
*
*/
public void setCopyright(int val)
{
if (impl != null)
impl.setCopyright(val);
Copyright = val;
}
/**
*
*/
public int getProtectionBit()
{
return (impl == null ? Protection_bit : impl.getProtectionBit());
}
/**
*
*/
public void setProtectionBit(int val)
{
if (impl != null)
impl.setProtectionBit(val);
Protection_bit = val;
}
/**
*
*/
public double getFrameTimeLength()
{
return (impl == null ? Time_length : impl.getFrameTimeLength());
}
/**
*
*/
public void setFrameTimeLength(double val)
{
if (impl != null)
impl.setFrameTimeLength(val);
Time_length = val;
}
///////
/**
*
*/
public int getLastID()
{
return (impl == null ? lID : impl.getLastID());
}
/**
*
*/
public void setLastID(int val)
{
if (impl != null)
impl.setLastID(val);
lID = val;
}
/**
*
*/
public int getLastLayer()
{
return (impl == null ? lLayer : impl.getLastLayer());
}
/**
*
*/
public void setLastLayer(int val)
{
if (impl != null)
impl.setLastLayer(val);
lLayer = val;
}
/**
*
*/
public int getLastBitrate()
{
return (impl == null ? lBitrate : impl.getLastBitrate());
}
/**
*
*/
public void setLastBitrate(int val)
{
if (impl != null)
impl.setLastBitrate(val);
lBitrate = val;
}
/**
*
*/
public int getLastSamplingFrequency()
{
return (impl == null ? lSampling_frequency : impl.getLastSamplingFrequency());
}
/**
*
*/
public void setLastSamplingFrequency(int val)
{
if (impl != null)
impl.setLastSamplingFrequency(val);
lSampling_frequency = val;
}
/**
*
*/
public int getLastMode()
{
return (impl == null ? lMode : impl.getLastMode());
}
/**
*
*/
public void setLastMode(int val)
{
if (impl != null)
impl.setLastMode(val);
lMode = val;
}
/**
*
*/
public int getLastModeExtension()
{
return (impl == null ? lMode_extension : impl.getLastModeExtension());
}
/**
*
*/
public void setLastModeExtension(int val)
{
if (impl != null)
impl.setLastModeExtension(val);
lMode_extension = val;
}
/**
*
*/
public int getLastEmphasis()
{
return (impl == null ? lEmphasis : impl.getLastEmphasis());
}
/**
*
*/
public void setLastEmphasis(int val)
{
if (impl != null)
impl.setLastEmphasis(val);
lEmphasis = val;
}
/**
*
*/
public int getLastSize()
{
return (impl == null ? lSize : impl.getLastSize());
}
/**
*
*/
public void setLastSize(int val)
{
if (impl != null)
impl.setLastSize(val);
lSize = val;
}
/**
*
*/
public int getLastSizeBase()
{
return (impl == null ? lSize_base : impl.getLastSizeBase());
}
/**
*
*/
public void setLastSizeBase(int val)
{
if (impl != null)
impl.setLastSizeBase(val);
lSize_base = val;
}
/**
*
*/
public int getLastChannel()
{
return (impl == null ? lChannel : impl.getLastChannel());
}
/**
*
*/
public void setLastChannel(int val)
{
if (impl != null)
impl.setLastChannel(val);
lChannel = val;
}
/**
*
*/
public int getLastPaddingBit()
{
return (impl == null ? lPadding_bit : impl.getLastPaddingBit());
}
/**
*
*/
public void setLastPaddingBit(int val)
{
if (impl != null)
impl.setLastPaddingBit(val);
lPadding_bit = val;
}
/**
*
*/
public int getLastPrivateBit()
{
return (impl == null ? lPrivate_bit : impl.getLastPrivateBit());
}
/**
*
*/
public void setLastPrivateBit(int val)
{
if (impl != null)
impl.setLastPrivateBit(val);
lPrivate_bit = val;
}
/**
*
*/
public int getLastOriginal()
{
return (impl == null ? lOriginal : impl.getLastOriginal());
}
/**
*
*/
public void setLastOriginal(int val)
{
if (impl != null)
impl.setLastOriginal(val);
lOriginal = val;
}
/**
*
*/
public int getLastCopyright()
{
return (impl == null ? lCopyright : impl.getLastCopyright());
}
/**
*
*/
public void setLastCopyright(int val)
{
if (impl != null)
impl.setLastCopyright(val);
lCopyright = val;
}
/**
*
*/
public int getLastProtectionBit()
{
return (impl == null ? lProtection_bit : impl.getLastProtectionBit());
}
/**
*
*/
public void setLastProtectionBit(int val)
{
if (impl != null)
impl.setLastProtectionBit(val);
lProtection_bit = val;
}
/**
*
*/
public double getLastFrameTimeLength()
{
return (impl == null ? lTime_length : impl.getLastFrameTimeLength());
}
/**
*
*/
public void setLastFrameTimeLength(double val)
{
if (impl != null)
impl.setLastFrameTimeLength(val);
lTime_length = val;
}
///////
/**
*
*/
public int getNextID()
{
return (impl == null ? nID : impl.getNextID());
}
/**
*
*/
public void setNextID(int val)
{
if (impl != null)
impl.setNextID(val);
nID = val;
}
/**
*
*/
public int getNextLayer()
{
return (impl == null ? nLayer : impl.getNextLayer());
}
/**
*
*/
public void setNextLayer(int val)
{
if (impl != null)
impl.setNextLayer(val);
nLayer = val;
}
/**
*
*/
public int getNextBitrate()
{
return (impl == null ? nBitrate : impl.getNextBitrate());
}
/**
*
*/
public void setNextBitrate(int val)
{
if (impl != null)
impl.setNextBitrate(val);
nBitrate = val;
}
/**
*
*/
public int getNextSamplingFrequency()
{
return (impl == null ? nSampling_frequency : impl.getNextSamplingFrequency());
}
/**
*
*/
public void setNextSamplingFrequency(int val)
{
if (impl != null)
impl.setNextSamplingFrequency(val);
nSampling_frequency = val;
}
/**
*
*/
public int getNextMode()
{
return (impl == null ? nMode : impl.getNextMode());
}
/**
*
*/
public void setNextMode(int val)
{
if (impl != null)
impl.setNextMode(val);
nMode = val;
}
/**
*
*/
public int getNextModeExtension()
{
return (impl == null ? nMode_extension : impl.getNextModeExtension());
}
/**
*
*/
public void setNextModeExtension(int val)
{
if (impl != null)
impl.setNextModeExtension(val);
nMode_extension = val;
}
/**
*
*/
public int getNextEmphasis()
{
return (impl == null ? nEmphasis : impl.getNextEmphasis());
}
/**
*
*/
public void setNextEmphasis(int val)
{
if (impl != null)
impl.setNextEmphasis(val);
nEmphasis = val;
}
/**
*
*/
public int getNextSize()
{
return (impl == null ? nSize : impl.getNextSize());
}
/**
*
*/
public void setNextSize(int val)
{
if (impl != null)
impl.setNextSize(val);
nSize = val;
}
/**
*
*/
public int getNextSizeBase()
{
return (impl == null ? nSize_base : impl.getNextSizeBase());
}
/**
*
*/
public void setNextSizeBase(int val)
{
if (impl != null)
impl.setNextSizeBase(val);
nSize_base = val;
}
/**
*
*/
public int getNextChannel()
{
return (impl == null ? nChannel : impl.getNextChannel());
}
/**
*
*/
public void setNextChannel(int val)
{
if (impl != null)
impl.setNextChannel(val);
nChannel = val;
}
/**
*
*/
public int getNextPaddingBit()
{
return (impl == null ? nPadding_bit : impl.getNextPaddingBit());
}
/**
*
*/
public void setNextPaddingBit(int val)
{
if (impl != null)
impl.setNextPaddingBit(val);
nPadding_bit = val;
}
/**
*
*/
public int getNextPrivateBit()
{
return (impl == null ? nPrivate_bit : impl.getNextPrivateBit());
}
/**
*
*/
public void setNextPrivateBit(int val)
{
if (impl != null)
impl.setNextPrivateBit(val);
nPrivate_bit = val;
}
/**
*
*/
public int getNextOriginal()
{
return (impl == null ? nOriginal : impl.getNextOriginal());
}
/**
*
*/
public void setNextOriginal(int val)
{
if (impl != null)
impl.setNextOriginal(val);
nOriginal = val;
}
/**
*
*/
public int getNextCopyright()
{
return (impl == null ? nCopyright : impl.getNextCopyright());
}
/**
*
*/
public void setNextCopyright(int val)
{
if (impl != null)
impl.setNextCopyright(val);
nCopyright = val;
}
/**
*
*/
public int getNextProtectionBit()
{
return (impl == null ? nProtection_bit : impl.getNextProtectionBit());
}
/**
*
*/
public void setNextProtectionBit(int val)
{
if (impl != null)
impl.setNextProtectionBit(val);
nProtection_bit = val;
}
/**
*
*/
public double getNextFrameTimeLength()
{
return (impl == null ? nTime_length : impl.getNextFrameTimeLength());
}
/**
*
*/
public void setNextFrameTimeLength(double val)
{
if (impl != null)
impl.setNextFrameTimeLength(val);
nTime_length = val;
}
//////
/**
*
*/
public int parseHeader(byte[] data, int offset, int endoffset)
{
int ret = 0;
if (impl != null)
{
for (int i = 0; i < endoffset; i++)
if ((ret = parseHeader(data, offset + i)) < 0)
continue;
}
return ret;
}
/**
*
*/
public int parseHeader(byte[] frame, int offset)
{
return (impl == null ? 0 : impl.parseHeader(frame, offset));
}
/**
*
*/
public int parseNextHeader(byte[] frame, int offset)
{
return (impl == null ? 0 : impl.parseNextHeader(frame, offset));
}
/**
* save last header
*/
public void saveHeader()
{
setLastID(getID());
setLastLayer(getLayer());
setLastProtectionBit(getProtectionBit());
setLastPrivateBit(getPrivateBit());
setLastBitrate(getBitrate());
setLastSamplingFrequency(getSamplingFrequency());
setLastPaddingBit(getPaddingBit());
setLastPrivateBit(getPrivateBit());
setLastMode(getMode());
setLastModeExtension(getModeExtension());
setLastCopyright(getCopyright());
setLastOriginal(getOriginal());
setLastChannel(getChannel());
setLastEmphasis(getEmphasis());
setLastSize(getSize());
setLastSizeBase(getSizeBase());
setLastFrameTimeLength(getFrameTimeLength());
}
/**
*
*/
public int compareHeader()
{
return (impl == null ? 0 : impl.compareHeader());
}
/**
*
*/
public String displayHeader()
{
return (impl == null ? "" : impl.displayHeader());
}
/**
* save and display last header
*/
public String saveAndDisplayHeader()
{
saveHeader();
return displayHeader();
}
/**
*
*/
public byte[] editFrame(byte[] frame, int mode)
{
return (impl == null ? frame : impl.editFrame(frame, mode));
}
/**
*
*/
public byte[][] convertFrame(byte[] frame, int mode)
{
if (impl == null)
return (new byte[][]{ frame, new byte[0] });
return impl.convertFrame(frame, mode);
// return (impl == null ? frame : impl.convertFrame(frame, mode));
}
/**
*
*/
public void removeCRC(byte[] frame, boolean remove)
{
if (impl != null)
impl.removeCRC(frame, remove);
}
/**
*
*/
public int validateCRC(byte[] frame, int offset, int len)
{
return (impl == null ? 0 : impl.validateCRC(frame, offset, len));
}
/**
*
*/
public void setAncillaryDataDecoder(boolean b1, boolean b2)
{
if (impl != null)
impl.setAncillaryDataDecoder(b1, b2);
}
/**
*
*/
public String decodeAncillaryData(byte[] frame, double frametime)
{
return (impl == null ? null : impl.decodeAncillaryData(frame, frametime));
}
/**
*
*/
public void parseRiffData(byte[] frame, int channel)
{
if (impl != null)
impl.parseRiffData(frame, channel);
}
/**
*
*/
public void initExtraWaveHeader(boolean bool_ACM, boolean bool_BWF, boolean bool_AC3)
{
if (impl != null)
impl.initExtraWaveHeader(bool_ACM, bool_BWF, bool_AC3);
}
/**
*
*/
public byte[] getExtraWaveHeader(int channel, boolean placeholder)
{
return (impl == null ? (new byte[0]) : impl.getExtraWaveHeader(channel, placeholder));
}
/**
*
*/
public void setExtraWaveData(int[] array, int channel)
{
if (impl != null)
impl.setExtraWaveData(array, channel);
}
/**
*
*/
public void setExtraWaveLength(long filelength, long timelength, int channel)
{
if (impl != null)
impl.setExtraWaveLength(filelength, timelength, channel);
}
/**
* returns RIFF
*/
public byte[] getRiffHeader()
{
return (new byte[] {
0x52, 0x49, 0x46, 0x46, //'RIFF'
0, 0, 0, 0, // all size LSB
0x57, 0x41, 0x56, 0x45, //'WAVE'
0x66, 0x6D, 0x74, 0x20, //'fmt '
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
0x64, 0x61, 0x74, 0x61, // 'data'
0, 0, 0, 0 // data size LSB
});
}
/**
* updates std RIFF
*/
public void fillStdRiffHeader(String file, long time_len)
{
try {
RandomAccessFile riff = new RandomAccessFile(file, "rw");
int len = (int) riff.length() - 8;
int bitrate = 1411200;
riff.seek(4);
riff.writeInt(littleEndian(len, 4, true)); //data+chunksize
riff.seek(16);
riff.writeInt(littleEndian(0x10, 4, true)); //chunk length
riff.writeShort(littleEndian(1, 2, true)); //pcm
riff.writeShort((short)littleEndian(2, 2, true)); //channels
riff.writeInt(littleEndian(44100, 4, true)); //sample_freq
riff.writeInt(littleEndian(bitrate / 8, 4, true)); //byterate
riff.writeShort((short)littleEndian(4, 2, true)); //blockalign
riff.writeShort((short)littleEndian(16, 2, true)); //bits_per_sample
riff.seek(40);
riff.writeInt(littleEndian(len - 36, 4, true)); //data-size
riff.close();
} catch (IOException e) {
Common.setExceptionMessage(e);
}
}
/**
* updates RIFF
* returns playtime as int
*/
public long fillRiffHeader(String file)
{
long value = 0;
try {
RandomAccessFile riff = new RandomAccessFile(file, "rw");
int len = (int)riff.length() - 8;
riff.seek(3);
if (!isINTEL())
riff.write((byte)'X');
riff.seek(4);
riff.writeInt(littleEndian(len, 4)); //data+chunksize
riff.seek(16);
riff.writeInt(littleEndian(0x10, 4)); //chunk length
riff.writeShort(littleEndian(1, 2)); //pcm
riff.writeShort((short)littleEndian(lChannel, 2)); //channels
riff.writeInt(littleEndian(lSampling_frequency, 4)); //sample_freq
riff.writeInt(littleEndian(lBitrate / 8, 4)); //byterate
riff.writeShort((short)littleEndian(lMode, 2)); //blockalign
riff.writeShort((short)littleEndian(lSize, 2)); //bits_per_sample
riff.seek(40);
riff.writeInt(littleEndian(len - 36, 4)); //data-size
riff.close();
value = (8000L * (len - 36)) / lBitrate;
} catch (IOException e) {
Common.setExceptionMessage(e);
}
return value;
}
/**
*
*/
public int littleEndian(byte[] data, int offset, int len, boolean reverse)
{
int value = 0;
for (int a = 0; a < len; a++)
value |= reverse ? ((0xFF & data[offset + a])<<(a * 8)) : ((0xFF & data[offset + a])<<((len - 1 - a) * 8));
return value;
}
/**
*
*/
public int getValue(byte[] data, int offset, int len, boolean reverse)
{
return littleEndian(data, offset, len, reverse);
}
/**
*
*/
public void setValue(byte[] array, int offset, int len, boolean bytereordering, int value)
{
for (int i = 0; bytereordering && i < len; i++)
array[i + offset] = (byte)(0xFF & (value>>>(i * 8)));
for (int i = 0, j = len - 1; !bytereordering && i < len; i++, j--)
array[i + offset] = (byte)(0xFF & (value>>>(j * 8)));
}
/**
*
*/
public int littleEndian(int data, int len)
{
return littleEndian(data, len, isINTEL());
}
/**
*
*/
public int littleEndian(int data, int len, boolean b)
{
if (!b)
return data;
if (len == 4)
return ( (0xFF & data>>>24) | (0xFF & data>>>16)<<8 | (0xFF & data>>>8)<<16 | (0xFF & data)<<24 );
else
return ( (0xFF & data>>>8) | (0xFF & data)<<8 );
}
/**
*
*/
public int getBits(byte buf[], int BitPos[], int N)
{
int Pos, Val;
Pos = BitPos[0]>>>3;
Val = (0xFF & buf[Pos])<<24 |
(0xFF & buf[Pos+1])<<16 |
(0xFF & buf[Pos+2])<<8 |
(0xFF & buf[Pos+3]);
Val <<= BitPos[0] & 7;
Val >>>= 32-N;
BitPos[0] += N;
return Val;
}
}