internal int InitGainAnalysis(ReplayGain rgData, long samplefreq) { if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { return(INIT_GAIN_ANALYSIS_ERROR); } rgData.linpre = MAX_ORDER; rgData.rinpre = MAX_ORDER; rgData.lstep = MAX_ORDER; rgData.rstep = MAX_ORDER; rgData.lout = MAX_ORDER; rgData.rout = MAX_ORDER; Arrays.Fill(rgData.B, 0); return(INIT_GAIN_ANALYSIS_OK); }
internal float GetTitleGain(ReplayGain rgData) { var retval = analyzeResult(rgData.A, rgData.A.Length); for (var i = 0; i < rgData.A.Length; i++) { rgData.B[i] += rgData.A[i]; rgData.A[i] = 0; } for (var 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.0f; } rgData.totsamp = 0; rgData.lsum = rgData.rsum = 0.0; return(retval); }
internal int AnalyzeSamples( ReplayGain rgData, float[] left_samples, int left_samplesPos, float[] right_samples, int right_samplesPos, int num_samples, int num_channels) { int curleft; float[] curleftBase; int curright; float[] currightBase; int batchsamples; int cursamples; int cursamplepos; if (num_samples == 0) { return(GAIN_ANALYSIS_OK); } cursamplepos = 0; batchsamples = num_samples; switch (num_channels) { case 1: right_samples = left_samples; right_samplesPos = left_samplesPos; break; case 2: break; default: return(GAIN_ANALYSIS_ERROR); } if (num_samples < MAX_ORDER) { Array.Copy(left_samples, left_samplesPos, rgData.linprebuf, MAX_ORDER, num_samples); Array.Copy(right_samples, right_samplesPos, rgData.rinprebuf, MAX_ORDER, num_samples); } else { Array.Copy(left_samples, left_samplesPos, rgData.linprebuf, MAX_ORDER, MAX_ORDER); Array.Copy(right_samples, right_samplesPos, rgData.rinprebuf, MAX_ORDER, MAX_ORDER); } while (batchsamples > 0) { cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow - rgData.totsamp : batchsamples; if (cursamplepos < MAX_ORDER) { curleft = rgData.linpre + cursamplepos; curleftBase = rgData.linprebuf; curright = rgData.rinpre + cursamplepos; currightBase = rgData.rinprebuf; if (cursamples > MAX_ORDER - cursamplepos) { cursamples = MAX_ORDER - cursamplepos; } } else { curleft = left_samplesPos + cursamplepos; curleftBase = left_samples; curright = right_samplesPos + cursamplepos; currightBase = right_samples; } filterYule( curleftBase, curleft, rgData.lstepbuf, rgData.lstep + rgData.totsamp, cursamples, ABYule[rgData.freqindex]); filterYule( currightBase, curright, rgData.rstepbuf, rgData.rstep + rgData.totsamp, cursamples, ABYule[rgData.freqindex]); filterButter( rgData.lstepbuf, rgData.lstep + rgData.totsamp, rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, ABButter[rgData.freqindex]); filterButter( rgData.rstepbuf, rgData.rstep + rgData.totsamp, rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, ABButter[rgData.freqindex]); curleft = rgData.lout + rgData.totsamp; /* Get the squared values */ curleftBase = rgData.loutbuf; curright = rgData.rout + rgData.totsamp; currightBase = rgData.routbuf; var i = cursamples % 8; while (i-- != 0) { rgData.lsum += fsqr(curleftBase[curleft++]); rgData.rsum += fsqr(currightBase[curright++]); } i = cursamples / 8; while (i-- != 0) { rgData.lsum += fsqr(curleftBase[curleft + 0]) + fsqr(curleftBase[curleft + 1]) + fsqr(curleftBase[curleft + 2]) + fsqr(curleftBase[curleft + 3]) + fsqr(curleftBase[curleft + 4]) + fsqr(curleftBase[curleft + 5]) + fsqr(curleftBase[curleft + 6]) + fsqr(curleftBase[curleft + 7]); curleft += 8; rgData.rsum += fsqr(currightBase[curright + 0]) + fsqr(currightBase[curright + 1]) + fsqr(currightBase[curright + 2]) + fsqr(currightBase[curright + 3]) + fsqr(currightBase[curright + 4]) + fsqr(currightBase[curright + 5]) + fsqr(currightBase[curright + 6]) + fsqr(currightBase[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 */ var val = STEPS_per_dB * 10.0 * Math.Log10((rgData.lsum + rgData.rsum) / rgData.totsamp * 0.5 + 1e-37); var ival = val <= 0 ? 0 : (int)val; if (ival >= rgData.A.Length) { ival = rgData.A.Length - 1; } rgData.A[ival]++; rgData.lsum = rgData.rsum = 0.0; Array.Copy(rgData.loutbuf, rgData.totsamp, rgData.loutbuf, 0, MAX_ORDER); Array.Copy(rgData.routbuf, rgData.totsamp, rgData.routbuf, 0, MAX_ORDER); Array.Copy(rgData.lstepbuf, rgData.totsamp, rgData.lstepbuf, 0, MAX_ORDER); Array.Copy(rgData.rstepbuf, rgData.totsamp, rgData.rstepbuf, 0, MAX_ORDER); rgData.totsamp = 0; } if (rgData.totsamp > rgData.sampleWindow) { return(GAIN_ANALYSIS_ERROR); } } if (num_samples < MAX_ORDER) { Array.Copy(rgData.linprebuf, num_samples, rgData.linprebuf, 0, MAX_ORDER - num_samples); Array.Copy(rgData.rinprebuf, num_samples, rgData.rinprebuf, 0, MAX_ORDER - num_samples); Array.Copy(left_samples, left_samplesPos, rgData.linprebuf, MAX_ORDER - num_samples, num_samples); Array.Copy(right_samples, right_samplesPos, rgData.rinprebuf, MAX_ORDER - num_samples, num_samples); } else { Array.Copy(left_samples, left_samplesPos + num_samples - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); Array.Copy(right_samples, right_samplesPos + num_samples - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); } return(GAIN_ANALYSIS_OK); }
/// <returns> /// INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if /// not /// </returns> private int ResetSampleFrequency(ReplayGain rgData, long samplefreq) { /* zero out initial values */ for (var 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.0f; } switch ((int)samplefreq) { case 48000: rgData.freqindex = 0; break; case 44100: rgData.freqindex = 1; break; case 32000: rgData.freqindex = 2; break; case 24000: rgData.freqindex = 3; break; case 22050: rgData.freqindex = 4; break; case 16000: rgData.freqindex = 5; break; case 12000: rgData.freqindex = 6; break; case 11025: rgData.freqindex = 7; break; case 8000: rgData.freqindex = 8; break; default: return(INIT_GAIN_ANALYSIS_ERROR); } rgData.sampleWindow = (int)((samplefreq * RMS_WINDOW_TIME_NUMERATOR + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); rgData.lsum = 0.0; rgData.rsum = 0.0; rgData.totsamp = 0; Arrays.Fill(rgData.A, 0); return(INIT_GAIN_ANALYSIS_OK); }