📄 gain_analysis.c
字号:
case 8000: rgData->freqindex = 8; break; default: return INIT_GAIN_ANALYSIS_ERROR; } rgData->sampleWindow = (samplefreq * RMS_WINDOW_TIME_NUMERATOR + RMS_WINDOW_TIME_DENOMINATOR-1) / RMS_WINDOW_TIME_DENOMINATOR; rgData->lsum = 0.; rgData->rsum = 0.; rgData->totsamp = 0; memset ( rgData->A, 0, sizeof(rgData->A) ); return INIT_GAIN_ANALYSIS_OK;}intInitGainAnalysis (replaygain_t* rgData, long samplefreq ){ if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { return INIT_GAIN_ANALYSIS_ERROR; } rgData->linpre = rgData->linprebuf + MAX_ORDER; rgData->rinpre = rgData->rinprebuf + MAX_ORDER; rgData->lstep = rgData->lstepbuf + MAX_ORDER; rgData->rstep = rgData->rstepbuf + MAX_ORDER; rgData->lout = rgData->loutbuf + MAX_ORDER; rgData->rout = rgData->routbuf + MAX_ORDER; memset ( rgData->B, 0, sizeof(rgData->B) ); return INIT_GAIN_ANALYSIS_OK;}/* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */static __inline double fsqr(const double d){ return d*d;}intAnalyzeSamples (replaygain_t* rgData, const Float_t* left_samples, const Float_t* right_samples, size_t num_samples, int num_channels ){ const Float_t* curleft; const Float_t* curright; long batchsamples; long cursamples; long cursamplepos; int i; if ( num_samples == 0 ) return GAIN_ANALYSIS_OK; cursamplepos = 0; batchsamples = num_samples; switch ( num_channels) { case 1: right_samples = left_samples; case 2: break; default: return GAIN_ANALYSIS_ERROR; } if ( num_samples < MAX_ORDER ) { memcpy ( rgData->linprebuf + MAX_ORDER, left_samples , num_samples * sizeof(Float_t) ); memcpy ( rgData->rinprebuf + MAX_ORDER, right_samples, num_samples * sizeof(Float_t) ); } else { memcpy ( rgData->linprebuf + MAX_ORDER, left_samples, MAX_ORDER * sizeof(Float_t) ); memcpy ( rgData->rinprebuf + MAX_ORDER, right_samples, MAX_ORDER * sizeof(Float_t) ); } while ( batchsamples > 0 ) { cursamples = batchsamples > rgData->sampleWindow - rgData->totsamp ? rgData->sampleWindow - rgData->totsamp : batchsamples; if ( cursamplepos < MAX_ORDER ) { curleft = rgData->linpre+cursamplepos; curright = rgData->rinpre+cursamplepos; if (cursamples > MAX_ORDER - cursamplepos ) cursamples = MAX_ORDER - cursamplepos; } else { curleft = left_samples + cursamplepos; curright = right_samples + cursamplepos; } YULE_FILTER ( curleft , rgData->lstep + rgData->totsamp, cursamples, ABYule[rgData->freqindex]); YULE_FILTER ( curright, rgData->rstep + rgData->totsamp, cursamples, ABYule[rgData->freqindex]); BUTTER_FILTER ( rgData->lstep + rgData->totsamp, rgData->lout + rgData->totsamp, cursamples, ABButter[rgData->freqindex]); BUTTER_FILTER ( rgData->rstep + rgData->totsamp, rgData->rout + rgData->totsamp, cursamples, ABButter[rgData->freqindex]); curleft = rgData->lout + rgData->totsamp; /* Get the squared values */ curright = rgData->rout + rgData->totsamp; i = cursamples % 8; while (i--) { rgData->lsum += fsqr(*curleft++); rgData->rsum += fsqr(*curright++); } i = cursamples / 8; while (i--) { rgData->lsum += fsqr(curleft[0]) + fsqr(curleft[1]) + fsqr(curleft[2]) + fsqr(curleft[3]) + fsqr(curleft[4]) + fsqr(curleft[5]) + fsqr(curleft[6]) + fsqr(curleft[7]); curleft += 8; rgData->rsum += fsqr(curright[0]) + fsqr(curright[1]) + fsqr(curright[2]) + fsqr(curright[3]) + fsqr(curright[4]) + fsqr(curright[5]) + fsqr(curright[6]) + fsqr(curright[7]); curright += 8; } batchsamples -= cursamples; cursamplepos += cursamples; rgData->totsamp += cursamples; if ( rgData->totsamp == rgData->sampleWindow ) { /* Get the Root Mean Square (RMS) for this set of samples */ double val = STEPS_per_dB * 10. * log10 ( (rgData->lsum+rgData->rsum) / rgData->totsamp * 0.5 + 1.e-37 ); int ival = (int) val; if ( ival < 0 ) ival = 0; if ( ival >= sizeof(rgData->A)/sizeof(*(rgData->A)) ) ival = sizeof(rgData->A)/sizeof(*(rgData->A)) - 1; rgData->A [ival]++; rgData->lsum = rgData->rsum = 0.; memmove ( rgData->loutbuf , rgData->loutbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t) ); memmove ( rgData->routbuf , rgData->routbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t) ); memmove ( rgData->lstepbuf, rgData->lstepbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t) ); memmove ( rgData->rstepbuf, rgData->rstepbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t) ); rgData->totsamp = 0; } if ( rgData->totsamp > rgData->sampleWindow ) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */ return GAIN_ANALYSIS_ERROR; } if ( num_samples < MAX_ORDER ) { memmove ( rgData->linprebuf, rgData->linprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(Float_t) ); memmove ( rgData->rinprebuf, rgData->rinprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(Float_t) ); memcpy ( rgData->linprebuf + MAX_ORDER - num_samples, left_samples, num_samples * sizeof(Float_t) ); memcpy ( rgData->rinprebuf + MAX_ORDER - num_samples, right_samples, num_samples * sizeof(Float_t) ); } else { memcpy ( rgData->linprebuf, left_samples + num_samples - MAX_ORDER, MAX_ORDER * sizeof(Float_t) ); memcpy ( rgData->rinprebuf, right_samples + num_samples - MAX_ORDER, MAX_ORDER * sizeof(Float_t) ); } return GAIN_ANALYSIS_OK;}static Float_tanalyzeResult ( uint32_t* Array, size_t len ){ uint32_t elems; int32_t upper; size_t i; elems = 0; for ( i = 0; i < len; i++ ) elems += Array[i]; if ( elems == 0 ) return GAIN_NOT_ENOUGH_SAMPLES; upper = (int32_t) ceil (elems * (1. - RMS_PERCENTILE)); for ( i = len; i-- > 0; ) { if ( (upper -= Array[i]) <= 0 ) break; } return (Float_t) ((Float_t)PINK_REF - (Float_t)i / (Float_t)STEPS_per_dB);}Float_tGetTitleGain (replaygain_t* rgData){ Float_t retval; int i; retval = analyzeResult ( rgData->A, sizeof(rgData->A)/sizeof(*(rgData->A)) ); for ( i = 0; i < sizeof(rgData->A)/sizeof(*(rgData->A)); i++ ) { rgData->B[i] += rgData->A[i]; rgData->A[i] = 0; } for ( i = 0; i < MAX_ORDER; i++ ) rgData->linprebuf[i] = rgData->lstepbuf[i] = rgData->loutbuf[i] = rgData->rinprebuf[i] = rgData->rstepbuf[i] = rgData->routbuf[i] = 0.f; rgData->totsamp = 0; rgData->lsum = rgData->rsum = 0.; return retval;}Float_tGetAlbumGain (replaygain_t* rgData){ return analyzeResult ( rgData->B, sizeof(rgData->B)/sizeof(*(rgData->B)) );}/* end of gain_analysis.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -