📄 cupl3.c
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
MP3 Decoder originally Copyright (C) 1995-1997 Xing Technology
Corp. http://www.xingtech.com
Portions Copyright (C) 1998-1999 EMusic.com
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: cupl3.c,v 1.8 1999/10/19 07:13:08 elrod Exp $
____________________________________________________________________________*/
/**** cupL3.c ***************************************************
unpack Layer III
mod 8/18/97 bugfix crc problem
mod 10/9/97 add band_limit12 for short blocks
mod 10/22/97 zero buf_ptrs in init
mod 5/15/98 mpeg 2.5
mod 8/19/98 decode 22 sf bands
******************************************************************/
/*---------------------------------------
TO DO: Test mixed blocks (mixed long/short)
No mixed blocks in mpeg-1 test stream being used for development
-----------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include "mhead.h" /* mpeg header structure */
#include "L3.h"
#include "jdw.h"
/*====================================================================*/
static int mp_sr20_table[2][4] =
{{441, 480, 320, -999}, {882, 960, 640, -999}};
static int mp_br_tableL3[2][16] =
{{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, /* mpeg 2 */
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}};
/*====================================================================*/
/*-- global band tables */
/*-- short portion is 3*x !! --*/
int nBand[2][22]; /* [long/short][cb] */
int sfBandIndex[2][22]; /* [long/short][cb] */
/*====================================================================*/
/*----------------*/
extern DEC_INFO decinfo;
/*----------------*/
static int mpeg25_flag;
int iframe;
/*-------*/
static int band_limit = (576);
static int band_limit21 = (576); // limit for sf band 21
static int band_limit12 = (576); // limit for sf band 12 short
int band_limit_nsb = 32; /* global for hybrid */
static int nsb_limit = 32;
static int gain_adjust = 0; /* adjust gain e.g. cvt to mono */
static int id;
static int ncbl_mixed; /* number of long cb's in mixed block 8 or 6 */
static int sr_index;
static int outvalues;
static int outbytes;
static int half_outbytes;
static int framebytes;
static int padframebytes;
static int crcbytes;
static int pad;
static int stereo_flag;
static int nchan;
static int ms_mode;
static int is_mode;
static unsigned int zero_level_pcm = 0;
/* cb_info[igr][ch], compute by dequant, used by joint */
static CB_INFO cb_info[2][2];
static IS_SF_INFO is_sf_info; /* MPEG-2 intensity stereo */
/*---------------------------------*/
/* main data bit buffer */
#define NBUF (8*1024)
#define BUF_TRIGGER (NBUF-1500)
static unsigned char buf[NBUF];
static int buf_ptr0 = 0;
static int buf_ptr1 = 0;
static int main_pos_bit;
/*---------------------------------*/
static SIDE_INFO side_info;
static SCALEFACT sf[2][2]; /* [gr][ch] */
static int nsamp[2][2]; /* must start = 0, for nsamp[igr_prev] */
/*- sample union of int/float sample[ch][gr][576] */
/* static SAMPLE sample[2][2][576]; */
extern SAMPLE sample[2][2][576];
static float yout[576]; /* hybrid out, sbt in */
typedef void (*SBT_FUNCTION) (float *sample, short *pcm, int ch);
void sbt_dual_L3(float *sample, short *pcm, int n);
static SBT_FUNCTION sbt_L3 = sbt_dual_L3;
typedef void (*XFORM_FUNCTION) (void *pcm, int igr);
static void Xform_dual(void *pcm, int igr);
static XFORM_FUNCTION Xform = Xform_dual;
IN_OUT L3audio_decode_MPEG1(unsigned char *bs, unsigned char *pcm);
IN_OUT L3audio_decode_MPEG2(unsigned char *bs, unsigned char *pcm);
typedef IN_OUT(*DECODE_FUNCTION) (unsigned char *bs, unsigned char *pcm);
static DECODE_FUNCTION decode_function = L3audio_decode_MPEG1;
/*====================================================================*/
int hybrid(void *xin, void *xprev, float *y,
int btype, int nlong, int ntot, int nprev);
int hybrid_sum(void *xin, void *xin_left, float *y,
int btype, int nlong, int ntot);
void sum_f_bands(void *a, void *b, int n);
void FreqInvert(float *y, int n);
void antialias(void *x, int n);
void ms_process(void *x, int n); /* sum-difference stereo */
void is_process_MPEG1(void *x, /* intensity stereo */
SCALEFACT * sf,
CB_INFO cb_info[2], /* [ch] */
int nsamp, int ms_mode);
void is_process_MPEG2(void *x, /* intensity stereo */
SCALEFACT * sf,
CB_INFO cb_info[2], /* [ch] */
IS_SF_INFO * is_sf_info,
int nsamp, int ms_mode);
void unpack_huff(void *xy, int n, int ntable);
int unpack_huff_quad(void *vwxy, int n, int nbits, int ntable);
void dequant(SAMPLE sample[], int *nsamp,
SCALEFACT * sf,
GR * gr,
CB_INFO * cb_info, int ncbl_mixed);
void unpack_sf_sub_MPEG1(SCALEFACT * scalefac, GR * gr,
int scfsi, /* bit flag */
int igr);
void unpack_sf_sub_MPEG2(SCALEFACT sf[], /* return intensity scale */
GR * grdat,
int is_and_ch, IS_SF_INFO * is_sf_info);
/*====================================================================*/
/* get bits from bitstream in endian independent way */
BITDAT bitdat; /* global for inline use by Huff */
/*------------- initialize bit getter -------------*/
static void bitget_init(unsigned char *buf)
{
bitdat.bs_ptr0 = bitdat.bs_ptr = buf;
bitdat.bits = 0;
bitdat.bitbuf = 0;
}
/*------------- initialize bit getter -------------*/
static void bitget_init_end(unsigned char *buf_end)
{
bitdat.bs_ptr_end = buf_end;
}
/*------------- get n bits from bitstream -------------*/
int bitget_bits_used()
{
int n; /* compute bits used from last init call */
n = ((bitdat.bs_ptr - bitdat.bs_ptr0) << 3) - bitdat.bits;
return n;
}
/*------------- check for n bits in bitbuf -------------*/
void bitget_check(int n)
{
if (bitdat.bits < n)
{
while (bitdat.bits <= 24)
{
bitdat.bitbuf = (bitdat.bitbuf << 8) | *bitdat.bs_ptr++;
bitdat.bits += 8;
}
}
}
/*------------- get n bits from bitstream -------------*/
unsigned int bitget(int n)
{
unsigned int x;
if (bitdat.bits < n)
{ /* refill bit buf if necessary */
while (bitdat.bits <= 24)
{
bitdat.bitbuf = (bitdat.bitbuf << 8) | *bitdat.bs_ptr++;
bitdat.bits += 8;
}
}
bitdat.bits -= n;
x = bitdat.bitbuf >> bitdat.bits;
bitdat.bitbuf -= x << bitdat.bits;
return x;
}
/*------------- get 1 bit from bitstream -------------*/
unsigned int bitget_1bit()
{
unsigned int x;
if (bitdat.bits <= 0)
{ /* refill bit buf if necessary */
while (bitdat.bits <= 24)
{
bitdat.bitbuf = (bitdat.bitbuf << 8) | *bitdat.bs_ptr++;
bitdat.bits += 8;
}
}
bitdat.bits--;
x = bitdat.bitbuf >> bitdat.bits;
bitdat.bitbuf -= x << bitdat.bits;
return x;
}
/*====================================================================*/
static void Xform_mono(void *pcm, int igr)
{
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
n1 = n2 = nsamp[igr][0]; /* total number bands */
if (side_info.gr[igr][0].block_type == 2)
{ /* long bands */
n1 = 0;
if (side_info.gr[igr][0].mixed_block_flag)
n1 = sfBandIndex[0][ncbl_mixed - 1];
}
if (n1 > band_limit)
n1 = band_limit;
if (n2 > band_limit)
n2 = band_limit;
igr_prev = igr ^ 1;
nsamp[igr][0] = hybrid(sample[0][igr], sample[0][igr_prev],
yout, side_info.gr[igr][0].block_type, n1, n2, nsamp[igr_prev][0]);
FreqInvert(yout, nsamp[igr][0]);
sbt_L3(yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
static void Xform_dual_right(void *pcm, int igr)
{
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
n1 = n2 = nsamp[igr][1]; /* total number bands */
if (side_info.gr[igr][1].block_type == 2)
{ /* long bands */
n1 = 0;
if (side_info.gr[igr][1].mixed_block_flag)
n1 = sfBandIndex[0][ncbl_mixed - 1];
}
if (n1 > band_limit)
n1 = band_limit;
if (n2 > band_limit)
n2 = band_limit;
igr_prev = igr ^ 1;
nsamp[igr][1] = hybrid(sample[1][igr], sample[1][igr_prev],
yout, side_info.gr[igr][1].block_type, n1, n2, nsamp[igr_prev][1]);
FreqInvert(yout, nsamp[igr][1]);
sbt_L3(yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
static void Xform_dual(void *pcm, int igr)
{
int ch;
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
igr_prev = igr ^ 1;
for (ch = 0; ch < nchan; ch++)
{
n1 = n2 = nsamp[igr][ch]; /* total number bands */
if (side_info.gr[igr][ch].block_type == 2)
{ /* long bands */
n1 = 0;
if (side_info.gr[igr][ch].mixed_block_flag)
n1 = sfBandIndex[0][ncbl_mixed - 1];
}
if (n1 > band_limit)
n1 = band_limit;
if (n2 > band_limit)
n2 = band_limit;
nsamp[igr][ch] = hybrid(sample[ch][igr], sample[ch][igr_prev],
yout, side_info.gr[igr][ch].block_type, n1, n2, nsamp[igr_prev][ch]);
FreqInvert(yout, nsamp[igr][ch]);
sbt_L3(yout, pcm, ch);
}
}
/*--------------------------------------------------------------------*/
static void Xform_dual_mono(void *pcm, int igr)
{
int igr_prev, n1, n2, n3;
/*--- hybrid + sbt ---*/
igr_prev = igr ^ 1;
if ((side_info.gr[igr][0].block_type == side_info.gr[igr][1].block_type)
&& (side_info.gr[igr][0].mixed_block_flag == 0)
&& (side_info.gr[igr][1].mixed_block_flag == 0))
{
n2 = nsamp[igr][0]; /* total number bands max of L R */
if (n2 < nsamp[igr][1])
n2 = nsamp[igr][1];
if (n2 > band_limit)
n2 = band_limit;
n1 = n2; /* n1 = number long bands */
if (side_info.gr[igr][0].block_type == 2)
n1 = 0;
sum_f_bands(sample[0][igr], sample[1][igr], n2);
n3 = nsamp[igr][0] = hybrid(sample[0][igr], sample[0][igr_prev],
yout, side_info.gr[igr][0].block_type, n1, n2, nsamp[igr_prev][0]);
}
else
{ /* transform and then sum (not tested - never happens in test) */
/*-- left chan --*/
n1 = n2 = nsamp[igr][0]; /* total number bands */
if (side_info.gr[igr][0].block_type == 2)
{
n1 = 0; /* long bands */
if (side_info.gr[igr][0].mixed_block_flag)
n1 = sfBandIndex[0][ncbl_mixed - 1];
}
n3 = nsamp[igr][0] = hybrid(sample[0][igr], sample[0][igr_prev],
yout, side_info.gr[igr][0].block_type, n1, n2, nsamp[igr_prev][0]);
/*-- right chan --*/
n1 = n2 = nsamp[igr][1]; /* total number bands */
if (side_info.gr[igr][1].block_type == 2)
{
n1 = 0; /* long bands */
if (side_info.gr[igr][1].mixed_block_flag)
n1 = sfBandIndex[0][ncbl_mixed - 1];
}
nsamp[igr][1] = hybrid_sum(sample[1][igr], sample[0][igr],
yout, side_info.gr[igr][1].block_type, n1, n2);
if (n3 < nsamp[igr][1])
n1 = nsamp[igr][1];
}
/*--------*/
FreqInvert(yout, n3);
sbt_L3(yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
/*====================================================================*/
static int unpack_side_MPEG1()
{
int prot;
int br_index;
int igr, ch;
int side_bytes;
/* decode partial header plus initial side info */
/* at entry bit getter points at id, sync skipped by caller */
id = bitget(1); /* id */
bitget(2); /* skip layer */
prot = bitget(1); /* bitget prot bit */
br_index = bitget(4);
sr_index = bitget(2);
pad = bitget(1);
bitget(1); /* skip to mode */
side_info.mode = bitget(2); /* mode */
side_info.mode_ext = bitget(2); /* mode ext */
if (side_info.mode != 1)
side_info.mode_ext = 0;
/* adjust global gain in ms mode to avoid having to mult by 1/sqrt(2) */
ms_mode = side_info.mode_ext >> 1;
is_mode = side_info.mode_ext & 1;
crcbytes = 0;
if (prot)
bitget(4); /* skip to data */
else
{
bitget(20); /* skip crc */
crcbytes = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -