📄 mp3dec.c
字号:
} else {
/*
Long block, use this formula:
xr[i] = sign(is[i])*|is[i]|^(4/3)*2^0.25*(global_gain - 210) *
2 ^ -(scalefac_multiplier * (scalefac_l[band] + preflag *
pretab[band]))
global_gain is already in *xr
The preflag when set applies a pre-emphasis value from
the pretab table.
*/
/* xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info->scalefac_scale)
* ((*scalefac)[ch].l[cb]
+ gr_info->preflag * pretab[cb]));
*/
t = (1 + gr->scalefac_scale) * (gr->scalefac_l[band]
+ gr->preflag * pretab[band]);
if(t >= 32) { /* Only 32 values in the table */
myxr = (mpfloat)0.0f;
} else
myxr *= Granule_pow2table_m05[t];
ISCALE(myxr);
}
}
/* apply the sign(is[i]) * |is[i]| ^ (4/3) formula */
sign = (*is < 0) ? 1 : 0;
t = sign ? -*is : *is; /* t = abs(is) */
if(t >= 200)
t = 199;
*xr = myxr * Granule_powerscaling[t];
/* *xr = myxr * (mpfloat)pow((float)t, (4.0f / 3.0f)); */
ISCALE(*xr);
/* restore the sign */
if(sign)
*xr = -*xr;
/* advance input and output */
xr++;
is++;
/* check if we pass into the next window in short blocks */
if(j && !--j) {
j = windowlength;
window++;
needc = 1;
}
}
}
/* apply the selected stereo processing to the 2 xr channels, producing
a left and right output in lr.
*/
void
Granule_process_stereo(Granule *gr, Granule *grch1,
Granule_floatfreqs xr[2],
Granule_floatfreqs lr[2], Frame *f)
{
int sfb;
int i, j, sb, ch;
/* extract some stuff from the frame header */
int stereo = f->channels;
/* get the correct band-boundaries table */
struct Frame_band *bands = &Frame_bands[f->sampling_frequency];
/* decode what stereo mode we should process */
int i_stereo = (f->mode == MODE_JOINT_STEREO) &&
(f->mode_extension & 0x1);
int ms_stereo = (f->mode == MODE_JOINT_STEREO) &&
(f->mode_extension & 0x2);
/* ration and positions for stereo processing */
int is_pos[576];
mpfloat is_ratio[576];
/* the following HUGE chunk of code decodes the stereo positions and
rations in case of special stereo modes that don't transmit using
normal left-right signals */
/* clear the position table */
for(i = 0; i < 576; i++)
is_pos[i] = 7;
if ((stereo == 2) && i_stereo) {
/* Intensity stereo mode */
if (gr->window_switching_flag && (gr->block_type == BLOCKTYPE_3WIN)) {
if(gr->mixed_block_flag) {
int max_sfb = 0;
/* mixed block */
/* in the short block part of the spectrum, find the highest
non-zero frequency - process each window separately */
for (j = 0; j < 3; j++) {
int sfbcnt;
sfbcnt = 2;
for(sfb = 12; sfb >= 3; sfb--) {
int lines;
/* find the last frequency line with a non-zero value */
lines = bands->s[sfb+1] - bands->s[sfb];
i = 3 * bands->s[sfb] + (j + 1) * lines - 1;
while(lines > 0) {
if(xr[1][i] != 0.0f ) {
sfbcnt = sfb;
sfb = -10;
lines = -10;
}
lines--;
i--;
}
}
sfb = sfbcnt + 1;
if (sfb > max_sfb)
max_sfb = sfb;
while(sfb < 12) {
sb = bands->s[sfb+1] - bands->s[sfb];
i = 3 * bands->s[sfb] + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = grch1->scalefac_s[sfb][j];
if (is_pos[i] != 7)
/* ## tabelize this tan */
is_ratio[i] = tan(is_pos[i] * (PI / 12));
i++;
}
sfb++;
}
sb = bands->s[11] - bands->s[10];
sfb = 3 * bands->s[10] + j * sb;
sb = bands->s[12] - bands->s[11];
i = 3 * bands->s[11] + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = is_pos[sfb];
is_ratio[i] = is_ratio[sfb];
i++;
}
}
if (max_sfb <= 3) {
/* find the last non-zero frequency line in the lowest
3 subbands */
i = 2 * 18 + 17;
sb = -1;
while (i >= 0) {
if (xr[1][i] != (mpfloat)0.0f) {
sb = i;
break;
}
i--;
}
i = 0;
while(bands->l[i] <= sb)
i++;
sfb = i;
i = bands->l[i];
for (; sfb < 8; sfb++) {
sb = bands->l[sfb + 1] - bands->l[sfb];
for (; sb > 0; sb--) {
is_pos[i] = grch1->scalefac_l[sfb];
if(is_pos[i] != 7)
/* ## tabelize this */
is_ratio[i] = tan(is_pos[i] * (PI / 12));
i++;
}
}
}
} else {
/* this is a pure short block */
for(j = 0; j < 3; j++) {
int sfbcnt;
sfbcnt = -1;
for(sfb = 12; sfb >= 0; sfb--) {
int lines;
lines = bands->s[sfb + 1] - bands->s[sfb];
i = 3 * bands->s[sfb] + (j + 1) * lines - 1;
while (lines > 0) {
if(xr[1][i] != 0.0 ) {
sfbcnt = sfb;
sfb = -10;
lines = -10;
}
lines--;
i--;
}
}
sfb = sfbcnt + 1;
while(sfb < 12) {
sb = bands->s[sfb + 1] - bands->s[sfb];
i = 3 * bands->s[sfb] + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = grch1->scalefac_s[sfb][j];
if (is_pos[i] != 7)
/* ## tabelize this */
is_ratio[i] = tan(is_pos[i] * (PI / 12));
i++;
}
sfb++;
}
sb = bands->s[11] - bands->s[10];
sfb = 3 * bands->s[10] + j * sb;
sb = bands->s[12] - bands->s[11];
i = 3 * bands->s[11] + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = is_pos[sfb];
is_ratio[i] = is_ratio[sfb];
i++;
}
}
}
} else {
/* long block */
/* find the highest non-zero frequency */
i = 31 * 18 + 17;
sb = 0;
while (i >= 0) {
if(xr[1][i] != 0.0) {
sb = i;
break;
}
i--;
}
i = 0;
while(bands->l[i] <= sb)
i++;
sfb = i;
i = bands->l[i];
for (; sfb < 21; sfb++) {
sb = bands->l[sfb + 1] - bands->l[sfb];
for (; sb > 0; sb--) {
is_pos[i] = grch1->scalefac_l[sfb];
if (is_pos[i] != 7)
/* ## tabelize this */
is_ratio[i] = tan(is_pos[i] * (PI / 12));
i++;
}
}
sfb = bands->l[20];
for (sb = 576 - bands->l[21]; sb > 0; sb--) {
is_pos[i] = is_pos[sfb];
is_ratio[i] = is_ratio[sfb];
i++;
}
}
}
/* prepare for making output */
for(ch = 0;ch < 2; ch++)
for(i = 0; i < 576; i++)
lr[ch][i] = (mpfloat)0.0f;
/* do the stereo matrixing */
if(stereo == 2)
for(i = 0; i < 576; i++) {
if( is_pos[i] == 7 ) {
if(ms_stereo) {
lr[0][i] = (xr[0][i] + xr[1][i]) / 1.41421356;
lr[1][i] = (xr[0][i] - xr[1][i]) / 1.41421356;
} else {
/* dual-channel mode, the most common, just copy */
lr[0][i] = xr[0][i];
lr[1][i] = xr[1][i];
}
} else if (i_stereo) {
lr[0][i] = xr[0][i] * (mpfloat)(is_ratio[i] / (1.0f + is_ratio[i]));
lr[1][i] = xr[0][i] * (mpfloat)(1.0f / (1.0f + is_ratio[i]));
ISCALE(lr[0][i]);
ISCALE(lr[1][i]);
} else {
#ifndef DSP
printf("Illegal stereo mode!\n");
#endif
}
} else
/* single channel mode */
for(i = 0; i < 576; i++)
lr[0][i] = xr[0][i];
}
void
Granule_reorder(Granule *gr, Granule_floatfreqs xr,
Granule_floatfreqs xr2, Frame *f)
{
/* get the correct band-boundaries table */
struct Frame_band *bands = &Frame_bands[f->sampling_frequency];
int sfb, bandstart, bandsize;
int window, i, src, dst;
/* check the block type - we only reorder short and mixed blocks */
if(gr->window_switching_flag && gr->block_type == BLOCKTYPE_3WIN) {
for(i = 0; i < 576; i++)
xr2[i] = (mpfloat)0.0f;
if(gr->mixed_block_flag) {
/* lowest 2 subbands are long blocks - pass through */
for(i = 0; i < 2 * 18; i++)
xr2[i] = xr[i];
/* reorder all 3-window bands */
bandstart = bands->s[3];
bandsize = bands->s[4] - bandstart;
for(sfb = 3; sfb < 13; sfb++) {
src = bandstart * 3;
for(window = 0; window < 3; window++)
dst = bandstart * 3 + window;
for(i = 0; i < bandsize; i++) {
xr2[dst] = xr[src++];
dst += 3;
}
bandstart = bands->s[sfb];
bandsize = bands->s[sfb + 1] - bandstart;
}
} else {
/* short block, reorder everything */
bandstart = 0;
bandsize = bands->s[1];
for(sfb = 0; sfb < 13; sfb++) {
src = bandstart * 3;
for(window = 0; window < 3; window++) {
dst = bandstart * 3 + window;
for(i = 0; i < bandsize; i++) {
xr2[dst] = xr[src++];
dst += 3;
}
}
bandstart = bands->s[sfb + 1];
bandsize = bands->s[sfb + 2] - bandstart;
}
}
} else
/* long block, pass through */
for(i = 0; i < 576; i++)
xr2[i] = xr[i];
}
/* make some alias reduction */
#ifndef DSP
void
Granule_antialias(Granule *gr, Granule_floatfreqs xr)
{
int i, topband, subband, upper, lower;
mpfloat u, l;
if(gr->window_switching_flag && gr->block_type == BLOCKTYPE_3WIN)
if(!gr->mixed_block_flag)
return; /* dont antialias short blocks */
else
topband = 2-1; /* only antialias the long part of a mixed block */
else
topband = NUM_SUBBANDS - 1;
/* for each subband-pair, do 8 alias-reduction butterflies */
upper = 17;
lower = 18;
for(subband = 0; subband < topband; subband++) {
for(i = 0; i < 8; i++) {
u = xr[upper];
l = xr[lower];
xr[upper] = u * Granule_alias_cs[i] -
l * Granule_alias_ca[i];
ISCALE(xr[upper]);
xr[lower] = l * Granule_alias_cs[i] +
u * Granule_alias_ca[i];
ISCALE(xr[lower]);
upper--;
lower++;
}
upper += 26;
lower += 10;
}
}
#endif
/* Every odd time sample of every odd subband is multiplied by -1 to
compensate for the frequency inversion of the polyphase synthesis
*/
void
Granule_freqinverse(Granule *gr, Granule_floatfreqs x)
{
int sb, dct;
x = &x[NUM_DCTBANDS];
for(sb = 1; sb < NUM_SUBBANDS; sb += 2) {
for(dct = 1; dct < NUM_DCTBANDS; dct += 2)
x[dct] = -x[dct];
x = &x[2 * NUM_DCTBANDS];
}
}
void
Granule_subband_synthesis(Granule *gr, int ch, Granule_floatfreqs s,
PCMSample *S)
{
int i, j, t, k;
mpfloat band[32];
mpfloat *v, sum, *a, *b;
if(ch)
S = &S[1];
/* We have 18 time-vectors of 32 subband magnitudes each. For every
vector of 32 magnitudes, the subband synthesis generates 32
PCM samples, so the result of 18 of these is 18*32=576 samples.
*/
/* go through each time window */
for(t = 0; t < 18; t++) {
/* extract the subband strengths */
v = &s[t];
for(i = 0; i < 32; i++) {
band[i] = *v;
v = &v[18];
}
/* advance the buffer position */
Granule_sbsynth_Vptr[ch] = (Granule_sbsynth_Vptr[ch] - 64) & 0x3ff;
v = &Granule_sbsynth_V[ch][Granule_sbsynth_Vptr[ch]];
fast_idct(band, v);
/* 32*16=512 mac's */
S = windowing(ch, S);
}
}
/* 18 * (4096+1024) = 92160 MAC's per call, with 2 calls per frame and
38 frames per second this is 7 million MAC's per second.
18 * (384 * 2 + 1024) = 32256 MAC's per call using Lee's fast DCT! That
is just 2.4 million MAC's per second!
We need a buffer of 1024 floats per channel.
*/
void
Granule_subband_synthesis2(Granule *gr, Granule_floatfreqs s1,
Granule_floatfreqs s2,
PCMSample *S)
{
int i, j, t, k, isum1, isum2;
mpfloat band[64];
mpfloat *v, *v2, sum, sum2, *a, *b;
/* We have 18 time-vectors of 32 subband magnitudes each. For every
vector of 32 magnitudes, the subband synthesis generates 32
PCM samples, so the result of 18 of these is 18*32=576 samples.
*/
/* go through each time window */
for(t = 0; t < 18; t++) {
/* extract the subband strengths */
v = &s1[t];
v2 = &s2[t];
for(i = 0; i < 32; i++) {
band[i] = *v;
band[i+32] = *v2;
v = &v[18];
v2 = &v2[18];
}
/* advance the buffer position */
Granule_sbsynth_Vptr[0] = (Granule_sbsynth_Vptr[0] - 64) & 0x3ff;
v = &Granule_sbsynth_V[0][Granule_sbsynth_Vptr[0]];
/* calculate 64 values for each channel and insert them into the 1024 wide buffer */
fast_idct(band, v);
fast_idct(&band[32], &v[1024]);
/* 32*16*2=1024 mac's */
/* windowing - calculate 32 samples. each sample is the sum of 16 terms */
/* 15 */
/* Sj = E W(j+32i) */
/* i=0 */
#ifdef USE_INLINE_ASM
__asm {
push edi
// grab the sample pointer
mov edi, S
xor ebx, ebx // loop counter
ALIGN 4
window_loop:
lea ecx, [Granule_sbsynth_D + ebx*4] // ecx = &Granule_sbsynth_D[j]
mov eax, ebx
add eax, [Granule_sbsynth_Vptr] // eax = j + Granule_sbsynth_Vptr[0]
fldz // sum1 = 0.0
fldz // sum2 = 0.0
xor edx, edx // filt_lp1 counter
ALIGN 4
filt_lp1:
fld [ecx] // get the window coefficient (D)
fld st(0) // duplicate it
fmul dword ptr [Granule_sbsynth_V + eax*4] // multiply by Granule_sbsynth_V[eax]
faddp st(3), st
fmul dword ptr [Granule_sbsynth_V + 4096 + eax*4] // same for channel 2
faddp st(1), st
add eax, 96
and eax, 0x3ff
fld [128 + ecx] // get the next D
fld st(0) // dup it
fmul dword ptr [Granule_sbsynth_V + eax*4]
faddp st(3), st
fmul dword ptr [Granule_sbsynth_V + 4096 + eax*4]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -