#include <stdint.h>
#include <string.h>
#include "decoder.h"
#include "Log.h"

#define I(x) (int)(x)

typedef struct
{
	uint32_t tag;
	union
	{
		struct
		{
			uint32_t dummy2;
			uint8_t  frames[4];
			uint32_t filesize;
		} xing;
		struct
		{
			uint8_t  dummy[6];
			uint8_t  filesize[4];
			uint8_t  frames[4];
		} vbri;
	} type;
} vbr_hdr;


/***************************************************************
 *
 * This module contains the core of the decoder ie all the
 * computational routines. (Layer I and II only)
 * Functions are common to both layer unless
 * otherwise specified.
 *
 ***************************************************************/

extern void subbandsynthesis_2(int* bufPtr1, int* bufPtr2, int* bandp);
extern int subbandsynthesis_3(int16_t* samples, const int* winp, int* bufp, int step, int offset);

/*****************************************************************
 *
 * The following routines decode the system information
 *
 ****************************************************************/

/*****************************************************************
 *
 * The following are the subband synthesis routines. They apply
 * to both layer I and layer II stereo or mono. The user has to
 * decide what parameters are to be passed to the routines.
 *
 ***************************************************************/

/*************************************************************
 *
 *   Pass the subband sample through the synthesis window
 *
 **************************************************************/

// Han window 512 points transformed as follow:
// - window(i)=-window(511-i) so we could truncate to 256 points.
// - but if we integrate the sign of multiplications for polyphase filter
// - we need to keep 16 extra points because of case for output point 16
// - reorganised HanBuf (inverted row and columns) avoid the use of modulo in accesses
//   but it requires to duplicate each block of 16 values in Han window

// 1 is 2^24
static const int window[512+32] =
{

  I(0x00000000) ,I(0xffffe300) ,I(0x0000d500) ,I(0xfffe3500) ,I(0x0007f500) ,I(0xffebdf00) ,I(0x0019ae00) ,I(0xff6d8f00) ,I(0x01251e00) ,I(0x00927100) ,I(0x0019ae00) ,I(0x00142100) ,I(0x0007f500) ,I(0x0001cb00) ,I(0x0000d500) ,I(0x00001d00)
 ,I(0x00000000) ,I(0xffffe300) ,I(0x0000d500) ,I(0xfffe3500) ,I(0x0007f500) ,I(0xffebdf00) ,I(0x0019ae00) ,I(0xff6d8f00) ,I(0x01251e00) ,I(0x00927100) ,I(0x0019ae00) ,I(0x00142100) ,I(0x0007f500) ,I(0x0001cb00) ,I(0x0000d500) ,I(0x00001d00)
 ,I(0xffffff00) ,I(0xffffe100) ,I(0x0000da00) ,I(0xfffdf900) ,I(0x0007d000) ,I(0xffea7300) ,I(0x00174700) ,I(0xff665800) ,I(0x0124f000) ,I(0x008b3800) ,I(0x001bde00) ,I(0x0012b400) ,I(0x00080f00) ,I(0x00019100) ,I(0x0000d000) ,I(0x00001a00)
 ,I(0xffffff00) ,I(0xffffe100) ,I(0x0000da00) ,I(0xfffdf900) ,I(0x0007d000) ,I(0xffea7300) ,I(0x00174700) ,I(0xff665800) ,I(0x0124f000) ,I(0x008b3800) ,I(0x001bde00) ,I(0x0012b400) ,I(0x00080f00) ,I(0x00019100) ,I(0x0000d000) ,I(0x00001a00)
 ,I(0xffffff00) ,I(0xffffdd00) ,I(0x0000de00) ,I(0xfffdbb00) ,I(0x0007a000) ,I(0xffe90900) ,I(0x0014a800) ,I(0xff5f2800) ,I(0x01246800) ,I(0x0083ff00) ,I(0x001dd800) ,I(0x00114900) ,I(0x00082000) ,I(0x00015b00) ,I(0x0000ca00) ,I(0x00001800)
 ,I(0xffffff00) ,I(0xffffdd00) ,I(0x0000de00) ,I(0xfffdbb00) ,I(0x0007a000) ,I(0xffe90900) ,I(0x0014a800) ,I(0xff5f2800) ,I(0x01246800) ,I(0x0083ff00) ,I(0x001dd800) ,I(0x00114900) ,I(0x00082000) ,I(0x00015b00) ,I(0x0000ca00) ,I(0x00001800)
 ,I(0xffffff00) ,I(0xffffda00) ,I(0x0000e100) ,I(0xfffd7b00) ,I(0x00076500) ,I(0xffe7a300) ,I(0x0011d100) ,I(0xff580200) ,I(0x01238600) ,I(0x007ccb00) ,I(0x001f9c00) ,I(0x000fdf00) ,I(0x00082700) ,I(0x00012600) ,I(0x0000c400) ,I(0x00001500)
 ,I(0xffffff00) ,I(0xffffda00) ,I(0x0000e100) ,I(0xfffd7b00) ,I(0x00076500) ,I(0xffe7a300) ,I(0x0011d100) ,I(0xff580200) ,I(0x01238600) ,I(0x007ccb00) ,I(0x001f9c00) ,I(0x000fdf00) ,I(0x00082700) ,I(0x00012600) ,I(0x0000c400) ,I(0x00001500)
 ,I(0xffffff00) ,I(0xffffd700) ,I(0x0000e300) ,I(0xfffd3900) ,I(0x00071e00) ,I(0xffe64300) ,I(0x000ec000) ,I(0xff50eb00) ,I(0x01224900) ,I(0x0075a000) ,I(0x00212c00) ,I(0x000e7900) ,I(0x00082500) ,I(0x0000f400) ,I(0x0000be00) ,I(0x00001300)
 ,I(0xffffff00) ,I(0xffffd700) ,I(0x0000e300) ,I(0xfffd3900) ,I(0x00071e00) ,I(0xffe64300) ,I(0x000ec000) ,I(0xff50eb00) ,I(0x01224900) ,I(0x0075a000) ,I(0x00212c00) ,I(0x000e7900) ,I(0x00082500) ,I(0x0000f400) ,I(0x0000be00) ,I(0x00001300)
 ,I(0xffffff00) ,I(0xffffd300) ,I(0x0000e400) ,I(0xfffcf500) ,I(0x0006cb00) ,I(0xffe4e900) ,I(0x000b7700) ,I(0xff49e700) ,I(0x0120b400) ,I(0x006e8100) ,I(0x00228800) ,I(0x000d1700) ,I(0x00081b00) ,I(0x0000c500) ,I(0x0000b700) ,I(0x00001100)
 ,I(0xffffff00) ,I(0xffffd300) ,I(0x0000e400) ,I(0xfffcf500) ,I(0x0006cb00) ,I(0xffe4e900) ,I(0x000b7700) ,I(0xff49e700) ,I(0x0120b400) ,I(0x006e8100) ,I(0x00228800) ,I(0x000d1700) ,I(0x00081b00) ,I(0x0000c500) ,I(0x0000b700) ,I(0x00001100)
 ,I(0xffffff00) ,I(0xffffcf00) ,I(0x0000e400) ,I(0xfffcb000) ,I(0x00066c00) ,I(0xffe39900) ,I(0x0007f500) ,I(0xff42fa00) ,I(0x011ec700) ,I(0x00677200) ,I(0x0023b300) ,I(0x000bbc00) ,I(0x00080900) ,I(0x00009900) ,I(0x0000b000) ,I(0x00001000)
 ,I(0xffffff00) ,I(0xffffcf00) ,I(0x0000e400) ,I(0xfffcb000) ,I(0x00066c00) ,I(0xffe39900) ,I(0x0007f500) ,I(0xff42fa00) ,I(0x011ec700) ,I(0x00677200) ,I(0x0023b300) ,I(0x000bbc00) ,I(0x00080900) ,I(0x00009900) ,I(0x0000b000) ,I(0x00001000)
 ,I(0xfffffe00) ,I(0xffffcb00) ,I(0x0000e300) ,I(0xfffc6900) ,I(0x0005ff00) ,I(0xffe25300) ,I(0x00043a00) ,I(0xff3c2700) ,I(0x011c8300) ,I(0x00607600) ,I(0x0024ad00) ,I(0x000a6700) ,I(0x0007f000) ,I(0x00006f00) ,I(0x0000a900) ,I(0x00000e00)
 ,I(0xfffffe00) ,I(0xffffcb00) ,I(0x0000e300) ,I(0xfffc6900) ,I(0x0005ff00) ,I(0xffe25300) ,I(0x00043a00) ,I(0xff3c2700) ,I(0x011c8300) ,I(0x00607600) ,I(0x0024ad00) ,I(0x000a6700) ,I(0x0007f000) ,I(0x00006f00) ,I(0x0000a900) ,I(0x00000e00)
 ,I(0xfffffe00) ,I(0xffffc600) ,I(0x0000e000) ,I(0xfffc2100) ,I(0x00058600) ,I(0xffe11a00) ,I(0x00004600) ,I(0xff357300) ,I(0x0119e900) ,I(0x00599100) ,I(0x00257800) ,I(0x00091a00) ,I(0x0007d100) ,I(0x00004800) ,I(0x0000a100) ,I(0x00000d00)
 ,I(0xfffffe00) ,I(0xffffc600) ,I(0x0000e000) ,I(0xfffc2100) ,I(0x00058600) ,I(0xffe11a00) ,I(0x00004600) ,I(0xff357300) ,I(0x0119e900) ,I(0x00599100) ,I(0x00257800) ,I(0x00091a00) ,I(0x0007d100) ,I(0x00004800) ,I(0x0000a100) ,I(0x00000d00)
 ,I(0xfffffe00) ,I(0xffffc100) ,I(0x0000dd00) ,I(0xfffbd800) ,I(0x00050000) ,I(0xffdfef00) ,I(0xfffc1a00) ,I(0xff2ee200) ,I(0x0116fc00) ,I(0x0052c500) ,I(0x00261600) ,I(0x0007d600) ,I(0x0007aa00) ,I(0x00002400) ,I(0x00009a00) ,I(0x00000b00)
 ,I(0xfffffe00) ,I(0xffffc100) ,I(0x0000dd00) ,I(0xfffbd800) ,I(0x00050000) ,I(0xffdfef00) ,I(0xfffc1a00) ,I(0xff2ee200) ,I(0x0116fc00) ,I(0x0052c500) ,I(0x00261600) ,I(0x0007d600) ,I(0x0007aa00) ,I(0x00002400) ,I(0x00009a00) ,I(0x00000b00)
 ,I(0xfffffe00) ,I(0xffffbc00) ,I(0x0000d700) ,I(0xfffb8f00) ,I(0x00046b00) ,I(0xffded500) ,I(0xfff7b600) ,I(0xff287600) ,I(0x0113be00) ,I(0x004c1600) ,I(0x00268700) ,I(0x00069c00) ,I(0x00077f00) ,I(0x00000200) ,I(0x00009300) ,I(0x00000a00)
 ,I(0xfffffe00) ,I(0xffffbc00) ,I(0x0000d700) ,I(0xfffb8f00) ,I(0x00046b00) ,I(0xffded500) ,I(0xfff7b600) ,I(0xff287600) ,I(0x0113be00) ,I(0x004c1600) ,I(0x00268700) ,I(0x00069c00) ,I(0x00077f00) ,I(0x00000200) ,I(0x00009300) ,I(0x00000a00)
 ,I(0xfffffd00) ,I(0xffffb700) ,I(0x0000d000) ,I(0xfffb4600) ,I(0x0003ca00) ,I(0xffddcd00) ,I(0xfff31c00) ,I(0xff223600) ,I(0x01102f00) ,I(0x00458700) ,I(0x0026cf00) ,I(0x00056c00) ,I(0x00074e00) ,I(0xffffe300) ,I(0x00008b00) ,I(0x00000900)
 ,I(0xfffffd00) ,I(0xffffb700) ,I(0x0000d000) ,I(0xfffb4600) ,I(0x0003ca00) ,I(0xffddcd00) ,I(0xfff31c00) ,I(0xff223600) ,I(0x01102f00) ,I(0x00458700) ,I(0x0026cf00) ,I(0x00056c00) ,I(0x00074e00) ,I(0xffffe300) ,I(0x00008b00) ,I(0x00000900)
 ,I(0xfffffd00) ,I(0xffffb100) ,I(0x0000c800) ,I(0xfffafd00) ,I(0x00031a00) ,I(0xffdcda00) ,I(0xffee4b00) ,I(0xff1c2300) ,I(0x010c5400) ,I(0x003f1b00) ,I(0x0026ee00) ,I(0x00044700) ,I(0x00071900) ,I(0xffffc700) ,I(0x00008400) ,I(0x00000800)
 ,I(0xfffffd00) ,I(0xffffb100) ,I(0x0000c800) ,I(0xfffafd00) ,I(0x00031a00) ,I(0xffdcda00) ,I(0xffee4b00) ,I(0xff1c2300) ,I(0x010c5400) ,I(0x003f1b00) ,I(0x0026ee00) ,I(0x00044700) ,I(0x00071900) ,I(0xffffc700) ,I(0x00008400) ,I(0x00000800)
 ,I(0xfffffc00) ,I(0xffffab00) ,I(0x0000bd00) ,I(0xfffab400) ,I(0x00025d00) ,I(0xffdbfd00) ,I(0xffe94600) ,I(0xff164200) ,I(0x01082d00) ,I(0x0038d400) ,I(0x0026e700) ,I(0x00032e00) ,I(0x0006df00) ,I(0xffffad00) ,I(0x00007d00) ,I(0x00000700)
 ,I(0xfffffc00) ,I(0xffffab00) ,I(0x0000bd00) ,I(0xfffab400) ,I(0x00025d00) ,I(0xffdbfd00) ,I(0xffe94600) ,I(0xff164200) ,I(0x01082d00) ,I(0x0038d400) ,I(0x0026e700) ,I(0x00032e00) ,I(0x0006df00) ,I(0xffffad00) ,I(0x00007d00) ,I(0x00000700)
 ,I(0xfffffc00) ,I(0xffffa500) ,I(0x0000b100) ,I(0xfffa6c00) ,I(0x00019200) ,I(0xffdb3800) ,I(0xffe40e00) ,I(0xff109700) ,I(0x0103be00) ,I(0x0032b400) ,I(0x0026bc00) ,I(0x00022100) ,I(0x0006a200) ,I(0xffff9600) ,I(0x00007500) ,I(0x00000700)
 ,I(0xfffffc00) ,I(0xffffa500) ,I(0x0000b100) ,I(0xfffa6c00) ,I(0x00019200) ,I(0xffdb3800) ,I(0xffe40e00) ,I(0xff109700) ,I(0x0103be00) ,I(0x0032b400) ,I(0x0026bc00) ,I(0x00022100) ,I(0x0006a200) ,I(0xffff9600) ,I(0x00007500) ,I(0x00000700)
 ,I(0xfffffb00) ,I(0xffff9f00) ,I(0x0000a300) ,I(0xfffa2600) ,I(0x0000b900) ,I(0xffda8f00) ,I(0xffdea400) ,I(0xff0b2400) ,I(0x00ff0a00) ,I(0x002cbf00) ,I(0x00266e00) ,I(0x00012000) ,I(0x00066200) ,I(0xffff8100) ,I(0x00006f00) ,I(0x00000600)
 ,I(0xfffffb00) ,I(0xffff9f00) ,I(0x0000a300) ,I(0xfffa2600) ,I(0x0000b900) ,I(0xffda8f00) ,I(0xffdea400) ,I(0xff0b2400) ,I(0x00ff0a00) ,I(0x002cbf00) ,I(0x00266e00) ,I(0x00012000) ,I(0x00066200) ,I(0xffff8100) ,I(0x00006f00) ,I(0x00000600)
 ,I(0xfffffb00) ,I(0xffff9800) ,I(0x00009200) ,I(0xfff9e100) ,I(0xffffd300) ,I(0xffda0100) ,I(0xffd90900) ,I(0xff05ed00) ,I(0x00fa1300) ,I(0x0026f700) ,I(0x0025ff00) ,I(0x00002d00) ,I(0x00061f00) ,I(0xffff6e00) ,I(0x00006800) ,I(0x00000500)
 ,I(0xfffffb00) ,I(0xffff9800) ,I(0x00009200) ,I(0xfff9e100) ,I(0xffffd300) ,I(0xffda0100) ,I(0xffd90900) ,I(0xff05ed00) ,I(0x00fa1300) ,I(0x0026f700) ,I(0x0025ff00) ,I(0x00002d00) ,I(0x00061f00) ,I(0xffff6e00) ,I(0x00006800) ,I(0x00000500)};

int SubBandSynthesis(stream* S, int* bandPtr, int channel, int16_t* samples, int step)
{
	int		o1, o2;
	int*		HanPtr1;
	int*		HanPtr2;

	o1 = (S->HanOffset[channel] - 1) & 0xf;
	o2 = (o1+1) & 0xf;
	S->HanOffset[channel] = o1;
	if (o1 & 1)
	{
		HanPtr1 = &(S->Hanbuf[channel][1][o2]);
		HanPtr2 = &(S->Hanbuf[channel][0][o1]);
	}
	else
	{
		HanPtr1 = &(S->Hanbuf[channel][0][o1]);
		HanPtr2 = &(S->Hanbuf[channel][1][o2]);
	}

	// Determine only indexes 0-16 and 32,33-48 because (17-31) = - (15-0) and (49-63) = (47-33)
	subbandsynthesis_2(HanPtr1, HanPtr2, bandPtr);

	if (o1 & 1)
	{
		return subbandsynthesis_3(samples, window + 16 - o2, S->Hanbuf[channel][1], step, o2);
	}

	return subbandsynthesis_3(samples, window + 16 - o1, S->Hanbuf[channel][0], step, o1);
}

/*****************************************************************************
*
*  CRC error protection package
*
*****************************************************************************/
/*
#define 	CRC16_POLYNOMIAL	0x8005

static void out_clear(sndbuf* sndb, int size)
{
	int free = 1 + (sndb->last - sndb->free);

	if (free > size) free = size;
	memset(sndb->free, 0, free << 1);
	sndb->free += free;
	if (sndb->free > sndb->last)
		sndb->free = sndb->data;
	size -= free;
	if (size)
	{
		memset(sndb->data, 0, size << 1);
		sndb->free += size;
	}
}

static void update_CRC(unsigned int data, unsigned int length, unsigned int *crc)
{
	unsigned int	masking = 1 << length;
	unsigned int	carry;

	while((masking >>= 1))
	{
		carry = *crc & 0x8000;
		*crc <<= 1;
		if (!carry ^ !(data & masking))
			*crc ^= CRC16_POLYNOMIAL;
	}

	*crc &= 0xffff;
}

static unsigned int calc_CRC(const bytebuf* bs, int bits)
{
	unsigned int new_crc = 0xffff;
	char* start;
	int imax;

	// assumes, we have just read the CRC
	start = bs->start - 4;
	if (start < bs->data) start += bs->size;
	update_CRC(*start, 8, &new_crc);
	start = bs->start - 3;
	if (start < bs->data) start += bs->size;
	update_CRC(*start, 8, &new_crc);

	// bytes to read
	imax = bits >> 3;

	for (start = bs->start; imax; imax--)
	{
		update_CRC(*start, 8, &new_crc);
		start = (start < bs->last) ? start + 1 : bs->data;
	}
	// bits to read
	imax = bits & 7;
	if (imax) update_CRC((*start) >> (8 - imax) , imax, &new_crc);

	return new_crc;
}
*/
/*****************************************************************************
*
*  End of CRC error protection package
*
*****************************************************************************/

/*
 * This function seeks for a byte aligned sync word in the bit stream and
 * places the bit stream pointer right after the sync.
 * This function returns 1 if the sync was found otherwise it returns 0
 */

// 2: MPEG-2.5, 1: MPEG-1, 0: MPEG-2 LSF
static const int s_freq[3][4] =
{
	{22050, 24000, 16000, 0},
	{44100, 48000, 32000, 0},
	{11025, 12000,  8000, 0}
};

// 1: MPEG-1, 0: MPEG-2 LSF and MPEG-2.5
static const int bitrate[2][3][15] =
{
	{
	{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256},
	{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160},
	{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}
	},
	{
	{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
	{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
	{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
	}
};

static const int samplesPerFrame[3] = {384, 1152, 1152};

static const int Slots[3] = {12000, 144000, 144000};

// 1 if found, 0 otherwise
int seek_header(stream* S, bytebuf* bs, frame_params* fr_ps, const mp3info* ref)
{
	int count;
	int remain;
	unsigned int val;

	// align on byte boundary
	if (bs->bitindex)
	{
		bs->bitindex = 0;
		bs->start = (bs->start < bs->last) ? bs->start + 1 : bs->data;
		bs_fixcount(bs);
	}

	remain = bs->count >> 3;
	remain -= 3;

	count = remain - 1;

	if (remain <= 0)
		return 0;

	val = 0;
	do
	{
		// locate sync start
		do
		{
			val = *bs->start;
			bs->start = (bs->start < bs->last) ? bs->start + 1 : bs->data;
			remain--;
		} while ((val != 0xff)  && (remain));
		if (val == 0xff)
		{
			// Byte 2
			val = *bs->start;
			if (((val & 0xe0) != 0xe0)  // not sync end
			||  ((val & 0x18) == 0x08)  // not MPEG 1, 2, 2.5
			||  ((val & 0x06) == 0x00)) // not LAYER 1, 2, 3
				continue;
			bs->start = (bs->start < bs->last) ? bs->start + 1 : bs->data;
			fr_ps->version = (val >> 3) & 1;
			if (!(val & 0x10)) fr_ps->version = 2;
			fr_ps->lay = 4 - ((val >> 1) & 3);
			fr_ps->error_protection = !(val & 1);
			// Byte 3
			val = *bs->start;
			bs->start = (bs->start < bs->last) ? bs->start + 1 : bs->data;
			fr_ps->bitrate_index = val >> 4;
			fr_ps->samplerate_index = (val >> 2) & 3;
			// check valid bitrate and samplerate as they define the number
			// of bytes that follow in the frame
			if (!fr_ps->bitrate_index
			||  fr_ps->bitrate_index == 15
			||  fr_ps->samplerate_index == 3)
			{
				bs->start -= 2;
				if (bs->start < bs->data) bs->start += bs->size;
				S->prev_frame_corrupted = 1;
				continue;
			}
			fr_ps->padding = (val >> 1) & 1;
			fr_ps->extension = val & 1;
			// Byte 4
			val = *bs->start;
			bs->start = (bs->start < bs->last) ? bs->start + 1 : bs->data;
			fr_ps->mode = val >> 6;
			fr_ps->mode_ext = (val >> 4) & 3;
			if (fr_ps->mode != MPG_MD_JOINT_STEREO)
				fr_ps->mode_ext = 0;
			fr_ps->copyright = (val >> 3) & 1;
			fr_ps->original = (val >> 2) & 1;
			fr_ps->emphasis = val & 3;

			fr_ps->channels = (fr_ps->mode == MPG_MD_MONO) ? 1 : 2;
			fr_ps->samplerate = s_freq[fr_ps->version][fr_ps->samplerate_index];

			if (ref->version >= -1)
			{
				if (((ref->version >= 0) && (fr_ps->version != ref->version))
				||  (fr_ps->lay != ref->layer)
				||  (fr_ps->samplerate != ref->samplerate)
				||  (fr_ps->channels != ref->channels))
				{
					Log("Bad header?\n");
					Log("Vers: %d - %d\n", fr_ps->version, ref->version);
					Log("Layer: %d - %d\n", fr_ps->lay, ref->layer);
					Log("Rate: %d - %d\n", fr_ps->samplerate, ref->samplerate);
					Log("Channels: %d - %d\n", fr_ps->channels, ref->channels);
					S->prev_frame_corrupted = 1;

					// if was confirmed, lock onto that values else try the new ones
					if (ref->version >= 0)
					{
						bs->start -= 3;
						if (bs->start < bs->data) bs->start += bs->size;

						continue;
					}
				}
			}

			// Header seems valid
			if (count != remain)
			{
				Log("Skipped %d bytes\n", count - remain);
				// spurious skip
				if (count - remain > 256)
					S->prev_frame_corrupted = 1;
			}

			val = fr_ps->version;
			if (val > 1) val = 0;
			fr_ps->bitrate = bitrate[val][fr_ps->lay-1][fr_ps->bitrate_index];
			fr_ps->samplesPerFrame = samplesPerFrame[fr_ps->lay-1];
			fr_ps->bytesInFrame = Slots[fr_ps->lay-1] * fr_ps->bitrate / fr_ps->samplerate;
			if ((fr_ps->version != MPEG_AUDIO_ID) && (fr_ps->lay == 3))
				fr_ps->bytesInFrame >>= 1;
			if (fr_ps->padding)
				fr_ps->bytesInFrame++;
			if (fr_ps->lay == 1)
				fr_ps->bytesInFrame *= 4;
			fr_ps->bytesInFrame -= 4; // header size

			bs_fixcount(bs);
			return 1;
		}
	} while(remain);

	if (count != remain) Log("Skipped %d bytes without header\n", count - remain);

	bs_fixcount(bs);
	return 0;
}

void oneframe(stream* S);
void do_layer1(stream* S);
void do_layer2(stream* S);
void do_layer3(stream* S);
void hdr_to_frps(layer12* layer, const frame_params* fr_ps);
/*
static const int crc_layer2[5] = {142, 154, 42, 62, 135};

static const int crc_layer3[3][2] = {{72, 136}, {136, 256}, {72, 136}};
*/
static const char XingID[] = "Xing";
static const char VBRIID[] = "VBRI";

void oneframe(stream* S)
{
	unsigned int	old_crc;
//	unsigned int	new_crc;
//	unsigned int	crc_size;
	unsigned int	endsize = bs_bytecount(&S->mp3b) - S->fr_ps.bytesInFrame;
	unsigned int	size;

	S->frameNum++;

	// Get info in 2 phases, one is enough but some files without VBR headr
	// alternates 2 bitrates, so having a mean bitrate is better
	if (S->mp3i.version == -1)
	{
		if ((S->fr_ps.lay == S->mp3i.layer)
		&&  (S->fr_ps.samplerate == S->mp3i.samplerate)
		&&  (S->fr_ps.channels == S->mp3i.channels))
		{
			S->mp3i.version = S->fr_ps.version;
			S->mp3i.bitrate += S->fr_ps.bitrate;
			S->mp3i.bitrate >>= 1;
		}
		else
		{
			// there is corruption somewhere
			S->mp3i.version = -2;
		}

	}

	if (S->mp3i.version == -2)
	{
		vbr_hdr* vbr;
		int offset;

		S->mp3i.layer   = S->fr_ps.lay;
		S->mp3i.bitrate = S->fr_ps.bitrate;
		S->mp3i.samplerate = S->fr_ps.samplerate;
		S->mp3i.channels = S->fr_ps.channels;
		S->mp3i.version = -1;

		// Check Xing header
		if (S->fr_ps.version == 1)
		{
			if (S->fr_ps.mode == 3)
				offset = 17;
			else    offset = 32;
		}
		else
		{
			if (S->fr_ps.mode == 3)
				offset = 9;
			else    offset = 17;
		}
		bs_peekBytes(&S->mp3b, &S->l.skipbuf[0], offset + sizeof(*vbr));
		memmove(&S->l.skipbuf[0], &S->l.skipbuf[offset], sizeof(*vbr));
		vbr = (vbr_hdr*) &S->l.skipbuf[0];
		if (vbr->tag == *((int*) XingID))
		{
			// Nr of frames written the wrong way
			S->mp3i.vbr_frames = (vbr->type.xing.frames[0] << 24)
					   + (vbr->type.xing.frames[1] << 16)
					   + (vbr->type.xing.frames[2] << 8)
					   +  vbr->type.xing.frames[3];
		}
		else if (vbr->tag == *((int*) VBRIID))
		{
			// Nr of frames written the wrong way
			S->mp3i.vbr_frames = (vbr->type.vbri.frames[0] << 24)
					   + (vbr->type.vbri.frames[1] << 16)
					   + (vbr->type.vbri.frames[2] << 8)
					   +  vbr->type.vbri.frames[3];
		}

		if (S->mp3i.layer == 3)
			init_layer3(&S->l.lay3);
		else
			init_layer12(&S->l.lay12);
	}

	if (S->mp3i.layer != 3)
		hdr_to_frps(&S->l.lay12, &S->fr_ps);

	if (S->fr_ps.error_protection)
	{
		old_crc = bs_getbits(&S->mp3b, 16);

// Removed CRC check because of files with a constant CRC of 0 !!!!
/*		switch(S->fr_ps.lay)
		{
			case 1:
				crc_size = 128*S->fr_ps.channels;
			break;
			case 2:
				crc_size = crc_layer2[S->layer_data.lay12.tab_num]*S->fr_ps.channels;
			break;
			case 3:
				crc_size = crc_layer3[S->fr_ps.version][S->fr_ps.channels - 1];
			break;
		}

		new_crc = calc_CRC(&S->mp3b, crc_size);

		if (new_crc != old_crc)
		{
			Log("Bad CRC %d instead of %d at frame %d\n", new_crc, old_crc, S->frameNum);

			out_clear(&S->sndb, S->fr_ps.samplesPerFrame);
			bs_keepBytes(&S->mp3b, endsize);
			return;
		}
*/	}


	switch(S->fr_ps.lay)
	{
		case 1:
			do_layer1(S);
		break;
		case 2:
			do_layer2(S);
		break;
		case 3:
			do_layer3(S);
		break;
	}

	// skip unused bytes in frame, to avoid a sync detection in it
	size = bs_bytecount(&S->mp3b);

	if (size < endsize)
		Log("%d bytes read to far in frame %d\n", endsize - size, S->frameNum);

	if (size > endsize)
		bs_keepBytes(&S->mp3b, endsize);
}
