www.pudn.com > bladeenc-0.90.0-src.zip > l3psy.c
/* (c) Copyright 1998, 1999 - Tord Jansson ======================================= This file is part of the BladeEnc MP3 Encoder, based on ISO's reference code for MPEG Layer 3 compression, and might contain smaller or larger sections that are directly taken from ISO's reference code. All changes to the ISO reference code herein are either copyrighted by Tord Jansson (tord.jansson@swipnet.se) or sublicensed to Tord Jansson by a third party. BladeEnc is free software; you can redistribute this file and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. */ #include#include "common.h" #include "encoder.h" #include "l3psy.h" #include "l3side.h" #define maximum(x,y) ( (x>y) ? x : y ) #define minimum(x,y) ( (x crit_band[j]) j++; fthr[i]=j-1+(temp1-crit_band[j-1])/(crit_band[j]-crit_band[j-1]); } partition[0] = 0; /* temp2 is the counter of the number of frequency lines in each partition */ temp2 = 1; cbval[0]=fthr[0]; bval_lo=fthr[0]; for(i=1;i 0.33) { partition[i]=partition[i-1]+1; cbval[partition[i-1]] = cbval[partition[i-1]]/temp2; cbval[partition[i]] = fthr[i]; bval_lo = fthr[i]; numlines[partition[i-1]] = temp2; temp2 = 1; } else { partition[i]=partition[i-1]; cbval[partition[i]] += fthr[i]; temp2++; } } numlines[partition[i-1]] = temp2; cbval[partition[i-1]] = cbval[partition[i-1]]/temp2; /************************************************************************ * Now compute the spreading function, s[j][i], the value of the spread-* * ing function, centered at band j, for band i, store for later use * ************************************************************************/ for(j=0;j =0.5 && temp1<=2.5) { temp2 = temp1 - 0.5; temp2 = 8.0 * (temp2*temp2 - 2.0 * temp2); } else temp2 = 0; temp1 += 0.474; temp3 = 15.811389+7.5*temp1-17.5*sqrt((double) (1.0+temp1*temp1)); if(temp3 <= -100) s[i][j] = 0; else { temp3 = (temp2 + temp3)*LN_TO_LOG10; s[i][j] = exp(temp3); } } } /* Calculate Tone Masking Noise values */ for(j=0;j 24.5) ? temp1 : 24.5; /* Calculate normalization factors for the net spreading functions */ rnorm[j] = 0; for(i=0;i = 0 ) { eb[tp] += energy[j]; cb[tp] += cw[j] * energy[j]; } } /********************************************************************** * convolve the partitioned energy and unpredictability * * with the spreading function, s3_l[b][k] * ******************************************************************** */ for ( b = 0; b < CBANDS; b++ ) { ecb[b] = 0.0; ctb[b] = 0.0; } for ( b = 0;b < CBANDS; b++ ) { for ( k = 0; k < CBANDS; k++ ) { ecb[b] += s3_l[b][k] * eb[k]; /* sprdngf for Layer III */ ctb[b] += s3_l[b][k] * cb[k]; } } /* calculate the tonality of each threshold calculation partition */ /* calculate the SNR in each threshhold calculation partition */ for ( b = 0; b < CBANDS; b++ ) { double cbb,tbb; if (ecb[b] != 0.0 ) { cbb = ctb[b]/ecb[b]; if (cbb <0.01) cbb = 0.01; cbb = log( cbb); } else cbb = 0.0 ; tbb = -0.299 - 0.43*cbb; /* conv1=-0.299, conv2=-0.43 */ tbb = minimum( 1.0, maximum( 0.0, tbb) ) ; /* 0 thr[b]+1.0 : for non sound portition */ #define switch_pe 1800 blocktype = NORM_TYPE; if ( *pe < switch_pe ) { /* no attack : use long blocks */ switch( blocktype_old[chn] ) { case NORM_TYPE: case STOP_TYPE: blocktype = NORM_TYPE; break; case SHORT_TYPE: blocktype = STOP_TYPE; break; /* case START_TYPE: fprintf( stderr, "Error in block selecting\n" ); abort(); break; problem */ } /* threshold calculation (part 2) */ for ( sb = 0; sb < SBMAX_l; sb++ ) { en[sb] = w1_l[sb] * eb[bu_l[sb]] + w2_l[sb] * eb[bo_l[sb]]; thm[sb] = w1_l[sb] *thr[bu_l[sb]] + w2_l[sb] * thr[bo_l[sb]]; for ( b = bu_l[sb]+1; b < bo_l[sb]; b++ ) { en[sb] += eb[b]; thm[sb] += thr[b]; } if ( en[sb] != 0.0 ) ratio[chn][sb] = thm[sb]/en[sb]; else ratio[chn][sb] = 0.0; } } else { /* attack : use short blocks */ blocktype = SHORT_TYPE; if ( blocktype_old[chn] == NORM_TYPE ) blocktype_old[chn] = START_TYPE; if ( blocktype_old[chn] == STOP_TYPE ) blocktype_old[chn] = SHORT_TYPE ; /* threshold calculation for short blocks */ for ( sblock = 0; sblock < 3; sblock++ ) { for ( b = 0; b < CBANDS_s; b++ ) { eb[b] = 0.0; ecb[b] = 0.0; } for ( j = 0; j < HBLKSIZE_s; j++ ) eb[partition_s[j]] += energy_s[sblock][j]; for ( b = 0; b < CBANDS_s; b++ ) for ( k = 0; k < CBANDS_s; k++ ) ecb[b] += s3_l[b][k] * eb[k]; for ( b = 0; b < CBANDS_s; b++ ) { nb[b] = ecb[b] * norm_l[b] * exp( (double) SNR_s[b] * LN_TO_LOG10 ); thr[b] = maximum (qthr_s[b],nb[b]); } for ( sb = 0; sb < SBMAX_s; sb++ ) { en[sb] = w1_s[sb] * eb[bu_s[sb]] + w2_s[sb] * eb[bo_s[sb]]; thm[sb] = w1_s[sb] *thr[bu_s[sb]] + w2_s[sb] * thr[bo_s[sb]]; for ( b = bu_s[sb]+1; b < bo_s[sb]; b++ ) { en[sb] += eb[b]; thm[sb] += thr[b]; } if ( en[sb] != 0.0 ) ratio_s[chn][sb][sblock] = thm[sb]/en[sb]; else ratio_s[chn][sb][sblock] = 0.0; } } } cod_info->block_type = blocktype_old[chn]; blocktype_old[chn] = blocktype; if ( cod_info->block_type == NORM_TYPE ) cod_info->window_switching_flag = 0; else cod_info->window_switching_flag = 1; cod_info->mixed_block_flag = 0; } /*____ L3para_read() __________________________________________________________*/ void L3para_read( int sfreq, int *numlines, int *partition_l, double *minval, double *qthr_l, double *norm_l, double (*s3_l)[63], int *partition_s, double *qthr_s, double *norm_s, double *SNR, int *cbw_l, int *bu_l, int *bo_l, double *w1_l, double *w2_l, int *cbw_s, int *bu_s, int *bo_s, double *w1_s, double *w2_s ) { static double bval_l[CBANDS], bval_s[CBANDS]; int cbmax, cbmax_tp; static double s3_s[CBANDS][CBANDS]; int sbmax ; int i,j,k,k2, part_max ; psyDataElem * rpa1; psyDataElem2 * rpa2; psyDataElem3 * rpa3; /* Read long block data */ switch( sfreq ) { case 32000: rpa1 = psy_longBlock__32000_58; cbmax_tp = 59; break; case 44100: rpa1 = psy_longBlock_44100_62; cbmax_tp = 63; break; case 48000: rpa1 = psy_longBlock_48000_61; cbmax_tp = 62; break; default: return; /* Just to avoid compiler warnings */ } cbmax = cbmax_tp; for(i=0,k2=0;i lines; minval[i] = rpa1->minVal; qthr_l[i] = rpa1->qthr; norm_l[i] = rpa1->norm; bval_l[i] = rpa1->bVal; rpa1++; for(k=0;k =i) tempx = (bval_l[i] - bval_l[j])*3.0; else tempx = (bval_l[i] - bval_l[j])*1.5; /* if (j>=i) tempx = (bval_l[j] - bval_l[i])*3.0; else tempx = (bval_l[j] - bval_l[i])*1.5; */ if(tempx>=0.5 && tempx<=2.5) { temp = tempx - 0.5; x = 8.0 * (temp*temp - 2.0 * temp); } else x = 0.0; tempx += 0.474; tempy = 15.811389 + 7.5*tempx - 17.5*sqrt(1.0+tempx*tempx); if (tempy <= -60.0) s3_l[i][j] = 0.0; else s3_l[i][j] = exp( (x + tempy)*LN_TO_LOG10 ); } } /* Read short block data */ switch( sfreq ) { case 32000: rpa2 = psy_shortBlock_32000_41; cbmax_tp = 42; break; case 44100: rpa2 = psy_shortBlock_44100_38; cbmax_tp = 39; break; case 48000: rpa2 = psy_shortBlock_48000_37; cbmax_tp = 38; break; default: return; /* Just to avoid compiler warnings */ } cbmax = cbmax_tp; for(i=0,k2=0;i lines; qthr_s[i] = rpa2->qthr; norm_s[i] = rpa2->norm; SNR[i] = rpa2->snr; bval_s[i] = rpa2->bVal; rpa2++; for(k=0;k =i) tempx = (bval_s[i] - bval_s[j])*3.0; else tempx = (bval_s[i] - bval_s[j])*1.5; if(tempx>=0.5 && tempx<=2.5) { temp = tempx - 0.5; x = 8.0 * (temp*temp - 2.0 * temp); } else x = 0.0; tempx += 0.474; tempy = 15.811389 + 7.5*tempx - 17.5*sqrt(1.0+tempx*tempx); if (tempy <= -60.0) s3_s[i][j] = 0.0; else s3_s[i][j] = exp( (x + tempy)*LN_TO_LOG10 ); } } /* Read long block data for converting threshold calculation partitions to scale factor bands */ switch( sfreq ) { case 32000: rpa3 = psy_data3_32000_20; sbmax = 21; break; case 44100: rpa3 = psy_data3_44100_20; sbmax = 21; break; case 48000: rpa3 = psy_data3_48000_20; sbmax = 21; break; default: return; /* Just to avoid compiler warnings */ } for(i=0;i cbw; bu_l[i] = rpa3->bu; bo_l[i] = rpa3->bo; w1_l[i] = rpa3->w1; w2_l[i] = rpa3->w2; rpa3++; } /* Read short block data for converting threshold calculation partitions to scale factor bands */ switch( sfreq ) { case 32000: rpa3 = psy_data4_32000_11; sbmax = 12; break; case 44100: rpa3 = psy_data4_44100_11; sbmax = 12; break; case 48000: rpa3 = psy_data4_48000_11; sbmax = 12; break; } for(i=0;i cbw; bu_s[i] = rpa3->bu; bo_s[i] = rpa3->bo; w1_s[i] = rpa3->w1; w2_s[i] = rpa3->w2; rpa3++; } }