File: //proc/1233/cwd/home/arjun/projects/buyercall/node_modules/lamejs/src/main/java/mpg/Interface.java
/*
* interface.c
*
* Copyright (C) 1999-2010 The L.A.M.E. project
*
* Initially written by Michael Hipp, see also AUTHORS and README.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* $Id: Interface.java,v 1.12 2011/08/27 18:57:09 kenchis Exp $ */
package mpg;
import mp3.VBRTag;
import mp3.VBRTagData;
import mpg.Decode.Factory;
import mpg.MPGLib.ProcessedBytes;
import mpg.MPGLib.buf;
import mpg.MPGLib.mpstr_tag;
public class Interface {
private VBRTag vbr;
private Common common;
public void setModules(VBRTag v, Common c) {
vbr = v;
common = c;
layer1.setModules(common, decode);
layer2.setModules(common);
layer3.setModules(common);
decode.setModules(tab, dct);
dct.setModules(tab);
}
protected Decode decode = new Decode();
private Layer1 layer1 = new Layer1() ;
private Layer2 layer2 = new Layer2();
private Layer3 layer3 = new Layer3();
private DCT64 dct = new DCT64();
private TabInit tab = new TabInit();
mpstr_tag
InitMP3()
{
mpstr_tag mp = new mpstr_tag();
mp.framesize = 0;
mp.num_frames = 0;
mp.enc_delay = -1;
mp.enc_padding = -1;
mp.vbr_header = false;
mp.header_parsed = false;
mp.side_parsed = false;
mp.data_parsed = false;
mp.free_format = false;
mp.old_free_format = false;
mp.ssize = 0;
mp.dsize = 0;
mp.fsizeold = -1;
mp.bsize = 0;
mp.head = mp.tail = null;
mp.fr.single = -1;
mp.bsnum = 0;
mp.wordpointer = mp.bsspace[mp.bsnum];
mp.wordpointerPos = 512;
mp.bitindex = 0;
mp.synth_bo = 1;
mp.sync_bitstream = 1;
tab.make_decode_tables(32767);
layer3.init_layer3(MPG123.SBLIMIT);
layer2.init_layer2();
return mp;
}
void
ExitMP3(mpstr_tag mp)
{
buf b, bn;
b = mp.tail;
while (b!=null) {
b.pnt=null;
bn = b.next;
b = bn;
}
}
buf
addbuf(mpstr_tag mp, byte []buf, int bufPos, int size)
{
buf nbuf;
nbuf = new buf();
nbuf.pnt = new byte[size];
nbuf.size = size;
System.arraycopy(buf, bufPos, nbuf.pnt, 0, size);
nbuf.next = null;
nbuf.prev = mp.head;
nbuf.pos = 0;
if (null==mp.tail) {
mp.tail = nbuf;
}
else {
mp.head.next = nbuf;
}
mp.head = nbuf;
mp.bsize += size;
return nbuf;
}
void
remove_buf(mpstr_tag mp)
{
buf buf = mp.tail;
mp.tail = buf.next;
if (mp.tail!=null)
mp.tail.prev = null;
else {
mp.tail = mp.head = null;
}
buf.pnt=null;
buf=null;
}
int
read_buf_byte(mpstr_tag mp)
{
int b;
int pos;
pos = mp.tail.pos;
while (pos >= mp.tail.size) {
remove_buf(mp);
if (null==mp.tail) {
throw new RuntimeException("hip: Fatal error! tried to read past mp buffer");
}
pos = mp.tail.pos;
}
b = mp.tail.pnt[pos] & 0xff;
mp.bsize--;
mp.tail.pos++;
return b;
}
void
read_head(mpstr_tag mp)
{
long head;
head = read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
mp.header = head;
}
void
copy_mp(mpstr_tag mp, int size, byte[]ptr, int ptrPos)
{
int len = 0;
while (len < size && mp.tail!=null) {
int nlen;
int blen = mp.tail.size - mp.tail.pos;
if ((size - len) <= blen) {
nlen = size - len;
}
else {
nlen = blen;
}
System.arraycopy(mp.tail.pnt, mp.tail.pos, ptr, ptrPos+len, nlen);
len += nlen;
mp.tail.pos += nlen;
mp.bsize -= nlen;
if (mp.tail.pos == mp.tail.size) {
remove_buf(mp);
}
}
}
/* number of bytes needed by GetVbrTag to parse header */
public static final int XING_HEADER_SIZE =194;
/*
traverse mp data structure without changing it
(just like sync_buffer)
pull out Xing bytes
call vbr header check code from LAME
if we find a header, parse it and also compute the VBR header size
if no header, do nothing.
bytes = number of bytes before MPEG header. skip this many bytes
before starting to read
return value: number of bytes in VBR header, including syncword
*/
int
check_vbr_header(mpstr_tag mp, int bytes)
{
int i, pos;
buf buf = mp.tail;
byte xing[]=new byte[XING_HEADER_SIZE];
pos = buf.pos;
/* skip to valid header */
for (i = 0; i < bytes; ++i) {
while (pos >= buf.size) {
buf = buf.next;
if (null==buf)
return -1; /* fatal error */
pos = buf.pos;
}
++pos;
}
/* now read header */
for (i = 0; i < XING_HEADER_SIZE; ++i) {
while (pos >= buf.size) {
buf = buf.next;
if (null==buf)
return -1; /* fatal error */
pos = buf.pos;
}
xing[i] = buf.pnt[pos];
++pos;
}
/* check first bytes for Xing header */
VBRTagData pTagData = vbr.getVbrTag(xing);
mp.vbr_header = pTagData != null;
if (mp.vbr_header) {
mp.num_frames = pTagData.frames;
mp.enc_delay = pTagData.encDelay;
mp.enc_padding = pTagData.encPadding;
/* fprintf(stderr,"hip: delays: %i %i \n",mp.enc_delay,mp.enc_padding); */
/* fprintf(stderr,"hip: Xing VBR header dectected. MP3 file has %i frames\n", pTagData.frames); */
if (pTagData.headersize < 1)
return 1;
return pTagData.headersize;
}
return 0;
}
int
sync_buffer(mpstr_tag mp, boolean free_match)
{
/* traverse mp structure without modifying pointers, looking
* for a frame valid header.
* if free_format, valid header must also have the same
* samplerate.
* return number of bytes in mp, before the header
* return -1 if header is not found
*/
int b[] = { 0, 0, 0, 0 };
int i, pos;
boolean h;
buf buf = mp.tail;
if (null==buf)
return -1;
pos = buf.pos;
for (i = 0; i < mp.bsize; i++) {
/* get 4 bytes */
b[0] = b[1];
b[1] = b[2];
b[2] = b[3];
while (pos >= buf.size) {
buf = buf.next;
pos = buf.pos;
}
b[3] = buf.pnt[pos] & 0xff;
++pos;
if (i >= 3) {
Frame fr = mp.fr;
long head;
head = b[0];
head <<= 8;
head |= b[1];
head <<= 8;
head |= b[2];
head <<= 8;
head |= b[3];
h = common.head_check(head, fr.lay);
if (h && free_match) {
/* just to be even more thorough, match the sample rate */
int mode, stereo, sampling_frequency, lsf;
boolean mpeg25;
if ((head & (1 << 20))!=0) {
lsf = (head & (1 << 19)) !=0 ? 0x0 : 0x1;
mpeg25 = false;
}
else {
lsf = 1;
mpeg25 = true;
}
mode = (int) ((head >> 6) & 0x3);
stereo = (mode == MPG123.MPG_MD_MONO) ? 1 : 2;
if (mpeg25)
sampling_frequency = (int) (6 + ((head >> 10) & 0x3));
else
sampling_frequency = (int) (((head >> 10) & 0x3) + (lsf * 3));
h = ((stereo == fr.stereo) && (lsf == fr.lsf) && (mpeg25 == fr.mpeg25) &&
(sampling_frequency == fr.sampling_frequency));
}
if (h) {
return i - 3;
}
}
}
return -1;
}
mpstr_tag
decode_reset()
{
return InitMP3(); /* Less error prone to just to reinitialise. */
}
int
audiodata_precedesframes(mpstr_tag mp)
{
if (mp.fr.lay == 3)
return layer3.layer3_audiodata_precedesframes(mp);
else
return 0; /* For Layer 1 & 2 the audio data starts at the frame that describes it, so no audio data precedes. */
}
interface ISynth {
<T>int synth_1to1_mono_ptr (mpstr_tag mp, float[] in, int inPos, T[] out, ProcessedBytes p, Factory<T> tFactory);
<T>int synth_1to1_ptr (mpstr_tag mp, float[] in, int inPos, int i, T[] out, ProcessedBytes p, Factory<T> tFactory);
}
<T>int
decodeMP3_clipchoice(mpstr_tag mp, byte[] in, int inPos, int isize, T[] out, ProcessedBytes done,
ISynth synth, Factory<T> tFactory)
{
int i, iret, bits, bytes;
if (in!=null && isize!=0 && addbuf(mp, in, inPos, isize) == null)
return MPGLib.MP3_ERR;
/* First decode header */
if (!mp.header_parsed) {
if (mp.fsizeold == -1 || mp.sync_bitstream!=0) {
int vbrbytes;
mp.sync_bitstream = 0;
/* This is the very first call. sync with anything */
/* bytes= number of bytes before header */
bytes = sync_buffer(mp, false);
/* now look for Xing VBR header */
if (mp.bsize >= bytes + XING_HEADER_SIZE) {
/* vbrbytes = number of bytes in entire vbr header */
vbrbytes = check_vbr_header(mp, bytes);
}
else {
/* not enough data to look for Xing header */
// #ifdef HIP_DEBUG
// fprintf(stderr, "hip: not enough data to look for Xing header\n");
// #endif
return MPGLib.MP3_NEED_MORE;
}
if (mp.vbr_header) {
/* do we have enough data to parse entire Xing header? */
if (bytes + vbrbytes > mp.bsize) {
/* fprintf(stderr,"hip: not enough data to parse entire Xing header\n"); */
return MPGLib.MP3_NEED_MORE;
}
/* read in Xing header. Buffer data in case it
* is used by a non zero main_data_begin for the next
* frame, but otherwise dont decode Xing header */
// #ifdef HIP_DEBUG
// fprintf(stderr, "hip: found xing header, skipping %i bytes\n", vbrbytes + bytes);
// #endif
for (i = 0; i < vbrbytes + bytes; ++i)
read_buf_byte(mp);
/* now we need to find another syncword */
/* just return and make user send in more data */
return MPGLib.MP3_NEED_MORE;
}
}
else {
/* match channels, samplerate, etc, when syncing */
bytes = sync_buffer(mp, true);
}
/* buffer now synchronized */
if (bytes < 0) {
/* fprintf(stderr,"hip: need more bytes %d\n", bytes); */
return MPGLib.MP3_NEED_MORE;
}
if (bytes > 0) {
/* there were some extra bytes in front of header.
* bitstream problem, but we are now resynced
* should try to buffer previous data in case new
* frame has nonzero main_data_begin, but we need
* to make sure we do not overflow buffer
*/
int size;
System.err.printf("hip: bitstream problem, resyncing skipping %d bytes...\n", bytes);
mp.old_free_format = false;
/* FIXME: correct ??? */
mp.sync_bitstream = 1;
/* skip some bytes, buffer the rest */
size = mp.wordpointerPos - 512;
if (size > MPG123.MAXFRAMESIZE) {
/* wordpointer buffer is trashed. probably cant recover, but try anyway */
System.err.printf("hip: wordpointer trashed. size=%i (%i) bytes=%i \n",
size, MPG123.MAXFRAMESIZE, bytes);
size = 0;
mp.wordpointer = mp.bsspace[mp.bsnum];
mp.wordpointerPos = 512;
}
/* buffer contains 'size' data right now
we want to add 'bytes' worth of data, but do not
exceed MAXFRAMESIZE, so we through away 'i' bytes */
i = (size + bytes) - MPG123.MAXFRAMESIZE;
for (; i > 0; --i) {
--bytes;
read_buf_byte(mp);
}
copy_mp(mp, bytes, mp.wordpointer, mp.wordpointerPos);
mp.fsizeold += bytes;
}
read_head(mp);
common.decode_header(mp.fr, mp.header);
mp.header_parsed = true;
mp.framesize = mp.fr.framesize;
mp.free_format = (mp.framesize == 0);
if (mp.fr.lsf!=0)
mp.ssize = (mp.fr.stereo == 1) ? 9 : 17;
else
mp.ssize = (mp.fr.stereo == 1) ? 17 : 32;
if (mp.fr.error_protection)
mp.ssize += 2;
mp.bsnum = 1 - mp.bsnum; /* toggle buffer */
mp.wordpointer = mp.bsspace[mp.bsnum];
mp.wordpointerPos = 512;
mp.bitindex = 0;
/* for very first header, never parse rest of data */
if (mp.fsizeold == -1) {
// #ifdef HIP_DEBUG
// fprintf(stderr, "hip: not parsing the rest of the data of the first header\n");
// #endif
return MPGLib.MP3_NEED_MORE;
}
} /* end of header parsing block */
/* now decode side information */
if (!mp.side_parsed) {
/* Layer 3 only */
if (mp.fr.lay == 3) {
if (mp.bsize < mp.ssize)
return MPGLib.MP3_NEED_MORE;
copy_mp(mp, mp.ssize, mp.wordpointer, mp.wordpointerPos);
if (mp.fr.error_protection)
common.getbits(mp, 16);
bits = layer3.do_layer3_sideinfo(mp);
/* bits = actual number of bits needed to parse this frame */
/* can be negative, if all bits needed are in the reservoir */
if (bits < 0)
bits = 0;
/* read just as many bytes as necessary before decoding */
mp.dsize = (bits + 7) / 8;
// #ifdef HIP_DEBUG
// fprintf(stderr,
// "hip: %d bits needed to parse layer III frame, number of bytes to read before decoding dsize = %d\n",
// bits, mp.dsize);
// #endif
/* this will force mpglib to read entire frame before decoding */
/* mp.dsize= mp.framesize - mp.ssize; */
}
else {
/* Layers 1 and 2 */
/* check if there is enough input data */
if (mp.fr.framesize > mp.bsize)
return MPGLib.MP3_NEED_MORE;
/* takes care that the right amount of data is copied into wordpointer */
mp.dsize = mp.fr.framesize;
mp.ssize = 0;
}
mp.side_parsed = true;
}
/* now decode main data */
iret = MPGLib.MP3_NEED_MORE;
if (!mp.data_parsed) {
if (mp.dsize > mp.bsize) {
return MPGLib.MP3_NEED_MORE;
}
copy_mp(mp, mp.dsize, mp.wordpointer, mp.wordpointerPos);
done.pb = 0;
/*do_layer3(&mp.fr,(unsigned char *) out,done); */
switch (mp.fr.lay) {
case 1:
if (mp.fr.error_protection)
common.getbits(mp, 16);
layer1.do_layer1(mp, out, done, tFactory);
break;
case 2:
if (mp.fr.error_protection)
common.getbits(mp, 16);
layer2.do_layer2(mp, out, done, synth, tFactory);
break;
case 3:
layer3.do_layer3(mp, out, done, synth, tFactory);
break;
default:
System.err.printf("hip: invalid layer %d\n", mp.fr.lay);
}
mp.wordpointer = mp.bsspace[mp.bsnum];
mp.wordpointerPos = 512 + mp.ssize + mp.dsize;
mp.data_parsed = true;
iret = MPGLib.MP3_OK;
}
/* remaining bits are ancillary data, or reservoir for next frame
* If free format, scan stream looking for next frame to determine
* mp.framesize */
if (mp.free_format) {
if (mp.old_free_format) {
/* free format. bitrate must not vary */
mp.framesize = mp.fsizeold_nopadding + (mp.fr.padding);
}
else {
bytes = sync_buffer(mp, true);
if (bytes < 0)
return iret;
mp.framesize = bytes + mp.ssize + mp.dsize;
mp.fsizeold_nopadding = mp.framesize - mp.fr.padding;
/*
fprintf(stderr,"hip: freeformat bitstream: estimated bitrate=%ikbs \n",
8*(4+mp.framesize)*freqs[mp.fr.sampling_frequency]/
(1000*576*(2-mp.fr.lsf)));
*/
}
}
/* buffer the ancillary data and reservoir for next frame */
bytes = mp.framesize - (mp.ssize + mp.dsize);
if (bytes > mp.bsize) {
return iret;
}
if (bytes > 0) {
int size;
copy_mp(mp, bytes, mp.wordpointer, mp.wordpointerPos);
mp.wordpointerPos += bytes;
size = mp.wordpointerPos - 512;
if (size > MPG123.MAXFRAMESIZE) {
System.err.printf("hip: fatal error. MAXFRAMESIZE not large enough.\n");
}
}
/* the above frame is completely parsed. start looking for next frame */
mp.fsizeold = mp.framesize;
mp.old_free_format = mp.free_format;
mp.framesize = 0;
mp.header_parsed = false;
mp.side_parsed = false;
mp.data_parsed = false;
return iret;
}
<T>int
decodeMP3(MPGLib.mpstr_tag mp, byte []in, int bufferPos, int isize, T []out, int osize, ProcessedBytes done, Factory<T> tFactory)
{
if (osize < 2304) {
System.err.printf("hip: Insufficient memory for decoding buffer %d\n", osize);
return MPGLib.MP3_ERR;
}
/* passing pointers to the functions which clip the samples */
ISynth synth = new ISynth() {
@Override
public <X> int synth_1to1_mono_ptr(mpstr_tag mp, float[] in,
int inPos, X[] out, ProcessedBytes p,
Factory<X> tFactory) {
return decode.synth_1to1_mono(mp, in, inPos, out, p, tFactory);
}
@Override
public <X> int synth_1to1_ptr(mpstr_tag mp, float[] in, int inPos,
int i, X[] out, ProcessedBytes p,
Factory<X> tFactory) {
return decode.synth_1to1(mp, in, inPos, i, out, p, tFactory);
}
};
return decodeMP3_clipchoice(mp, in, bufferPos, isize, out, done, synth, tFactory);
}
<T>int
decodeMP3_unclipped(MPGLib.mpstr_tag mp, byte []in, int bufferPos, int isize, T []out, int osize, ProcessedBytes done, Factory<T> tFactory)
{
/* we forbid input with more than 1152 samples per channel for output in unclipped mode */
if (osize < 1152 * 2) {
System.err.printf("hip: out space too small for unclipped mode\n");
return MPGLib.MP3_ERR;
}
ISynth synth = new ISynth() {
@Override
public <X>int synth_1to1_mono_ptr(mpstr_tag mp, float[] in,
int inPos, X[] out, ProcessedBytes p,
Factory<X> tFactory) {
return decode.synth_1to1_mono_unclipped(mp, in, inPos, out, p, tFactory);
}
@Override
public <X>int synth_1to1_ptr(mpstr_tag mp, float[] in, int inPos,
int i, X[] out, ProcessedBytes p,
Factory<X> tFactory) {
return decode.synth_1to1_unclipped(mp, in, inPos, i, out, p, tFactory);
}
};
/* passing pointers to the functions which don't clip the samples */
return decodeMP3_clipchoice(mp, in, bufferPos, isize, out, done, synth, tFactory);
}
}