📄 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.19 2001/01/05 06:40:07 robert 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 "L3.h"
#include "mhead.h" /* mpeg header structure */
#include "jdw.h"
#include "protos.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 !! --*/
/*====================================================================*/
/*---------------------------------*/
/*---------------------------------*/
/*- sample union of int/float sample[ch][gr][576] */
/* Sample is the same as cup.sample */
void sbt_dual_L3(MPEG *m, float *sample, short *pcm, int n);
IN_OUT L3audio_decode_MPEG1(void *mv, unsigned char *bs, unsigned char *pcm);
IN_OUT L3audio_decode_MPEG2(void *mv, unsigned char *bs, unsigned char *pcm);
/*
static DECODE_FUNCTION decode_function = L3audio_decode_MPEG1;
*/
/*====================================================================*/
/* get bits from bitstream in endian independent way */
/*------------- initialize bit getter -------------*/
static void bitget_init(MPEG *m, unsigned char *buf)
{
m->cupl.bitdat.bs_ptr0 = m->cupl.bitdat.bs_ptr = buf;
m->cupl.bitdat.bits = 0;
m->cupl.bitdat.bitbuf = 0;
}
/*------------- initialize bit getter -------------*/
static void bitget_init_end(MPEG *m, unsigned char *buf_end)
{
m->cupl.bitdat.bs_ptr_end = buf_end;
}
/*------------- get n bits from bitstream -------------*/
int bitget_bits_used(MPEG *m)
{
int n; /* compute bits used from last init call */
n = ((m->cupl.bitdat.bs_ptr - m->cupl.bitdat.bs_ptr0) << 3) -
m->cupl.bitdat.bits;
return n;
}
/*------------- get n bits from bitstream -------------*/
unsigned int bitget(MPEG *m, int n)
{
unsigned int x;
if (m->cupl.bitdat.bits < n)
{ /* refill bit buf if necessary */
while (m->cupl.bitdat.bits <= 24)
{
m->cupl.bitdat.bitbuf = (m->cupl.bitdat.bitbuf << 8) |
*m->cupl.bitdat.bs_ptr++;
m->cupl.bitdat.bits += 8;
}
}
m->cupl.bitdat.bits -= n;
x = m->cupl.bitdat.bitbuf >> m->cupl.bitdat.bits;
m->cupl.bitdat.bitbuf -= x << m->cupl.bitdat.bits;
return x;
}
/*====================================================================*/
static void Xform_mono(void *mv, void *pcm, int igr)
{
MPEG *m = mv;
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
n1 = n2 = m->cupl.nsamp[igr][0]; /* total number bands */
if (m->cupl.side_info.gr[igr][0].block_type == 2)
{ /* long bands */
n1 = 0;
if (m->cupl.side_info.gr[igr][0].mixed_block_flag)
n1 = m->cupl.sfBandIndex[0][m->cupl.ncbl_mixed - 1];
}
if (n1 > m->cupl.band_limit)
n1 = m->cupl.band_limit;
if (n2 > m->cupl.band_limit)
n2 = m->cupl.band_limit;
igr_prev = igr ^ 1;
m->cupl.nsamp[igr][0] = hybrid(m,m->cupl.sample[0][igr], m->cupl.sample[0][igr_prev],
m->cupl.yout, m->cupl.side_info.gr[igr][0].block_type, n1, n2, m->cupl.nsamp[igr_prev][0]);
FreqInvert(m->cupl.yout, m->cupl.nsamp[igr][0]);
m->cupl.sbt_L3(m,m->cupl.yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
static void Xform_dual_right(void *mv, void *pcm, int igr)
{
MPEG *m = mv;
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
n1 = n2 = m->cupl.nsamp[igr][1]; /* total number bands */
if (m->cupl.side_info.gr[igr][1].block_type == 2)
{ /* long bands */
n1 = 0;
if (m->cupl.side_info.gr[igr][1].mixed_block_flag)
n1 = m->cupl.sfBandIndex[0][m->cupl.ncbl_mixed - 1];
}
if (n1 > m->cupl.band_limit)
n1 = m->cupl.band_limit;
if (n2 > m->cupl.band_limit)
n2 = m->cupl.band_limit;
igr_prev = igr ^ 1;
m->cupl.nsamp[igr][1] = hybrid(m,m->cupl.sample[1][igr], m->cupl.sample[1][igr_prev],
m->cupl.yout, m->cupl.side_info.gr[igr][1].block_type, n1, n2, m->cupl.nsamp[igr_prev][1]);
FreqInvert(m->cupl.yout, m->cupl.nsamp[igr][1]);
m->cupl.sbt_L3(m,m->cupl.yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
static void Xform_dual(void *mv, void *pcm, int igr)
{
MPEG *m = mv;
int ch;
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
igr_prev = igr ^ 1;
for (ch = 0; ch < m->cupl.nchan; ch++)
{
n1 = n2 = m->cupl.nsamp[igr][ch]; /* total number bands */
if (m->cupl.side_info.gr[igr][ch].block_type == 2)
{ /* long bands */
n1 = 0;
if (m->cupl.side_info.gr[igr][ch].mixed_block_flag)
n1 = m->cupl.sfBandIndex[0][m->cupl.ncbl_mixed - 1];
}
if (n1 > m->cupl.band_limit)
n1 = m->cupl.band_limit;
if (n2 > m->cupl.band_limit)
n2 = m->cupl.band_limit;
m->cupl.nsamp[igr][ch] = hybrid(m,m->cupl.sample[ch][igr], m->cupl.sample[ch][igr_prev],
m->cupl.yout, m->cupl.side_info.gr[igr][ch].block_type, n1, n2, m->cupl.nsamp[igr_prev][ch]);
FreqInvert(m->cupl.yout, m->cupl.nsamp[igr][ch]);
m->cupl.sbt_L3(m,m->cupl.yout, pcm, ch);
}
}
/*--------------------------------------------------------------------*/
static void Xform_dual_mono(void *mv, void *pcm, int igr)
{
MPEG *m = mv;
int igr_prev, n1, n2, n3;
/*--- hybrid + sbt ---*/
igr_prev = igr ^ 1;
if ((m->cupl.side_info.gr[igr][0].block_type == m->cupl.side_info.gr[igr][1].block_type)
&& (m->cupl.side_info.gr[igr][0].mixed_block_flag == 0)
&& (m->cupl.side_info.gr[igr][1].mixed_block_flag == 0))
{
n2 = m->cupl.nsamp[igr][0]; /* total number bands max of L R */
if (n2 < m->cupl.nsamp[igr][1])
n2 = m->cupl.nsamp[igr][1];
if (n2 > m->cupl.band_limit)
n2 = m->cupl.band_limit;
n1 = n2; /* n1 = number long bands */
if (m->cupl.side_info.gr[igr][0].block_type == 2)
n1 = 0;
sum_f_bands(m->cupl.sample[0][igr], m->cupl.sample[1][igr], n2);
n3 = m->cupl.nsamp[igr][0] = hybrid(m,m->cupl.sample[0][igr], m->cupl.sample[0][igr_prev],
m->cupl.yout, m->cupl.side_info.gr[igr][0].block_type, n1, n2, m->cupl.nsamp[igr_prev][0]);
}
else
{ /* transform and then sum (not tested - never happens in test) */
/*-- left chan --*/
n1 = n2 = m->cupl.nsamp[igr][0]; /* total number bands */
if (m->cupl.side_info.gr[igr][0].block_type == 2)
{
n1 = 0; /* long bands */
if (m->cupl.side_info.gr[igr][0].mixed_block_flag)
n1 = m->cupl.sfBandIndex[0][m->cupl.ncbl_mixed - 1];
}
n3 = m->cupl.nsamp[igr][0] = hybrid(m,m->cupl.sample[0][igr], m->cupl.sample[0][igr_prev],
m->cupl.yout, m->cupl.side_info.gr[igr][0].block_type, n1, n2, m->cupl.nsamp[igr_prev][0]);
/*-- right chan --*/
n1 = n2 = m->cupl.nsamp[igr][1]; /* total number bands */
if (m->cupl.side_info.gr[igr][1].block_type == 2)
{
n1 = 0; /* long bands */
if (m->cupl.side_info.gr[igr][1].mixed_block_flag)
n1 = m->cupl.sfBandIndex[0][m->cupl.ncbl_mixed - 1];
}
m->cupl.nsamp[igr][1] = hybrid_sum(m, m->cupl.sample[1][igr], m->cupl.sample[0][igr],
m->cupl.yout, m->cupl.side_info.gr[igr][1].block_type, n1, n2);
if (n3 < m->cupl.nsamp[igr][1])
n1 = m->cupl.nsamp[igr][1];
}
/*--------*/
FreqInvert(m->cupl.yout, n3);
m->cupl.sbt_L3(m,m->cupl.yout, pcm, 0);
}
/*--------------------------------------------------------------------*/
/*====================================================================*/
static int unpack_side_MPEG1(MPEG *m)
{
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 */
m->cupl.id = bitget(m, 1); /* id */
bitget(m, 2); /* skip layer */
prot = bitget(m, 1); /* bitget prot bit */
br_index = bitget(m, 4);
m->cupl.sr_index = bitget(m, 2);
m->cupl.pad = bitget(m, 1);
bitget(m, 1); /* skip to mode */
m->cupl.side_info.mode = bitget(m, 2); /* mode */
m->cupl.side_info.mode_ext = bitget(m, 2); /* mode ext */
if (m->cupl.side_info.mode != 1)
m->cupl.side_info.mode_ext = 0;
/* adjust global gain in ms mode to avoid having to mult by 1/sqrt(2) */
m->cupl.ms_mode = m->cupl.side_info.mode_ext >> 1;
m->cupl.is_mode = m->cupl.side_info.mode_ext & 1;
m->cupl.crcbytes = 0;
if (prot)
bitget(m, 4); /* skip to data */
else
{
bitget(m, 20); /* skip crc */
m->cupl.crcbytes = 2;
}
if (br_index > 0) /* framebytes fixed for free format */
{
m->cupl.framebytes =
2880 * mp_br_tableL3[m->cupl.id][br_index] / mp_sr20_table[m->cupl.id][m->cupl.sr_index];
}
m->cupl.side_info.main_data_begin = bitget(m, 9);
if (m->cupl.side_info.mode == 3)
{
m->cupl.side_info.private_bits = bitget(m, 5);
m->cupl.nchan = 1;
m->cupl.stereo_flag = 0;
side_bytes = (4 + 17);
/*-- with header --*/
}
else
{
m->cupl.side_info.private_bits = bitget(m, 3);
m->cupl.nchan = 2;
m->cupl.stereo_flag = 1;
side_bytes = (4 + 32);
/*-- with header --*/
}
for (ch = 0; ch < m->cupl.nchan; ch++)
m->cupl.side_info.scfsi[ch] = bitget(m, 4);
/* this always 0 (both igr) for short blocks */
for (igr = 0; igr < 2; igr++)
{
for (ch = 0; ch < m->cupl.nchan; ch++)
{
m->cupl.side_info.gr[igr][ch].part2_3_length = bitget(m, 12);
m->cupl.side_info.gr[igr][ch].big_values = bitget(m, 9);
if (m->cupl.side_info.gr[igr][ch].big_values > 288)
return -1;
m->cupl.side_info.gr[igr][ch].global_gain = bitget(m, 8) + m->cupl.gain_adjust;
if (m->cupl.ms_mode)
m->cupl.side_info.gr[igr][ch].global_gain -= 2;
m->cupl.side_info.gr[igr][ch].scalefac_compress = bitget(m, 4);
m->cupl.side_info.gr[igr][ch].window_switching_flag = bitget(m, 1);
if (m->cupl.side_info.gr[igr][ch].window_switching_flag)
{
m->cupl.side_info.gr[igr][ch].block_type = bitget(m, 2);
m->cupl.side_info.gr[igr][ch].mixed_block_flag = bitget(m, 1);
m->cupl.side_info.gr[igr][ch].table_select[0] = bitget(m, 5);
m->cupl.side_info.gr[igr][ch].table_select[1] = bitget(m, 5);
m->cupl.side_info.gr[igr][ch].subblock_gain[0] = bitget(m, 3);
m->cupl.side_info.gr[igr][ch].subblock_gain[1] = bitget(m, 3);
m->cupl.side_info.gr[igr][ch].subblock_gain[2] = bitget(m, 3);
/* region count set in terms of long block cb's/bands */
/* r1 set so r0+r1+1 = 21 (lookup produces 576 bands ) */
/* if(window_switching_flag) always 36 samples in region0 */
m->cupl.side_info.gr[igr][ch].region0_count = (8 - 1); /* 36 samples */
m->cupl.side_info.gr[igr][ch].region1_count = 20 - (8 - 1);
}
else
{
m->cupl.side_info.gr[igr][ch].mixed_block_flag = 0;
m->cupl.side_info.gr[igr][ch].block_type = 0;
m->cupl.side_info.gr[igr][ch].table_select[0] = bitget(m, 5);
m->cupl.side_info.gr[igr][ch].table_select[1] = bitget(m, 5);
m->cupl.side_info.gr[igr][ch].table_select[2] = bitget(m, 5);
m->cupl.side_info.gr[igr][ch].region0_count = bitget(m, 4);
m->cupl.side_info.gr[igr][ch].region1_count = bitget(m, 3);
}
m->cupl.side_info.gr[igr][ch].preflag = bitget(m, 1);
m->cupl.side_info.gr[igr][ch].scalefac_scale = bitget(m, 1);
m->cupl.side_info.gr[igr][ch].count1table_select = bitget(m, 1);
}
}
/* return bytes in header + side info */
return side_bytes;
}
/*====================================================================*/
static int unpack_side_MPEG2(MPEG *m, int igr)
{
int prot;
int br_index;
int ch;
int side_bytes;
/* decode partial header plus initial side info */
/* at entry bit getter points at id, sync skipped by caller */
m->cupl.id = bitget(m, 1); /* id */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -