#include "mppenc.h" /* V A R I A B L E N */ float __SCF [128 + 6]; // tabellierte Skalenfaktoren float __invSCF [128 + 6]; // invertierte Skalenfaktoren // Quantisierungs-Koeffizienten: step/65536 bzw. (2*D[Res]+1)/65536 static const float __A [1 + 18] = { 0.0000762939453125f, 0.0000000000000000f, 0.0000457763671875f, 0.0000762939453125f, 0.0001068115234375f, 0.0001373291015625f, 0.0002288818359375f, 0.0004730224609375f, 0.0009613037109375f, 0.0019378662109375f, 0.0038909912109375f, 0.0077972412109375f, 0.0156097412109375f, 0.0312347412109375f, 0.0624847412109375f, 0.1249847412109375f, 0.2499847412109375f, 0.4999847412109375f }; // Requantisierungs-Koeffizienten: 65536/step bzw. 1/A[Res] static const float __C [1 + 18] = { 13107.200000000001f, 65535.000000000000f, 21845.333333333332f, 13107.200000000001f, 9362.285714285713f, 7281.777777777777f, 4369.066666666666f, 2114.064516129032f, 1040.253968253968f, 516.031496062992f, 257.003921568627f, 128.250489236790f, 64.062561094819f, 32.015632633121f, 16.003907203907f, 8.000976681723f, 4.000244155527f, 2.000061037018f, 1.000015259022f }; // Requantisierungs-Offset: 2*D+1 = steps of quantizer static const int __D [1 + 18] = { 2, 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; #define A (__A + 1) #define C (__C + 1) #define D (__D + 1) // Generierung der Skalenfaktoren und ihrer Inversen void Init_Skalenfaktoren ( void ) { int n; for ( n = -6; n < 128; n++ ) { SCF[n] = (float) ( pow(10.,-0.1*(n-1)/1.26) ); invSCF[n] = (float) ( pow(10., 0.1*(n-1)/1.26) ); } } #pragma warning ( disable : 4305 ) static float NoiseInjectionCompensation1D [18] = { #if 1 1.f, 0.884621, 0.935711, 0.970829, 0.987941, 0.994315, 0.997826, 0.999744, 1., 1., 1., 1., 1., 1., 1., 1., 1., 1. #else 1., 0.907073, // -1...+1 0.946334, // -2...+2 0.974793, // -3...+3 0.987647, // -4...+4 0.994330, // -7...+7 0.997846, // -15...+15 1., // -31...+31 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., #endif } ; static float NoiseInjectionCompensation2D [18] [32] = { { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, { 0.931595, 0.891390, 0.852494, 0.872420, 0.904053, 0.933716, 0.958976, 0.977719, 0.993979, 1.009011, 1.020961, 1.029564, 1.026582, 1.026753, 1.035573, 1.053251, 1.073429, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, }, { 0.878264, 0.882351, 0.904261, 0.930843, 0.949243, 0.966741, 0.980500, 0.988182, 0.993361, 0.997112, 0.998918, 0.999501, 1.003179, 1.007445, 1.008678, 0.995890, 0.991015, 0.988019, 0.985479, 0.987646, 1.003605, 1.029301, 1.040511, 1.061531, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, }, { 0.866977, 0.943500, 0.941561, 0.953049, 0.967274, 0.980476, 0.988678, 0.993240, 0.996376, 0.998513, 0.999545, 0.999775, 1.000898, 1.003954, 1.006308, 1.004932, 1.002867, 1.002922, 1.003624, 1.005487, 1.003919, 1.008022, 0.987693, 1.000358, 1.017461, 1.039166, 1.056053, 1.068191, 1.068191, 1.068191, 1.068191, 1.068191, }, { 0.880390, 0.976713, 0.976180, 0.976596, 0.982011, 0.988786, 0.993619, 0.996641, 0.998824, 1.000297, 1.001195, 1.001718, 1.002395, 1.003503, 1.005617, 1.005072, 1.002409, 1.003703, 1.003412, 1.003318, 1.005290, 1.007112, 1.014370, 1.010040, 1.000780, 1.005700, 1.020505, 1.030123, 1.030123, 1.030123, 1.030123, 1.030123, }, { 0.916894, 0.987164, 0.988734, 0.992318, 0.995268, 0.996932, 0.998141, 0.999072, 0.999674, 1.000104, 1.000292, 1.000386, 1.000399, 1.000222, 1.000671, 1.002127, 1.000137, 1.000046, 0.999644, 0.999156, 1.000568, 1.000098, 0.993764, 0.993954, 0.998971, 1.002835, 1.002972, 0.995376, 1.001643, 1.001643, 1.001643, 1.001643, }, { 0.982771, 0.995034, 0.997118, 0.998294, 0.998652, 0.999016, 0.999382, 0.999598, 0.999746, 0.999851, 0.999837, 0.999881, 0.999847, 1.000154, 0.999885, 1.000222, 0.999963, 1.000934, 0.999804, 0.999927, 1.000379, 0.997574, 0.997943, 0.998748, 0.998151, 0.997458, 1.000319, 1.001091, 0.998461, 0.996151, 1.005969, 1.005969, }, { 0.997150, 0.999903, 0.999424, 0.999537, 0.999661, 0.999753, 0.999851, 0.999903, 0.999928, 0.999963, 0.999969, 0.999941, 0.999974, 0.999967, 0.999996, 0.999975, 0.999966, 0.999704, 0.999946, 0.999894, 0.999905, 1.000840, 1.000716, 1.000799, 1.000406, 0.999912, 1.000153, 0.999789, 1.000495, 1.000495, 1.001167, 1.001347, }, { 0.995524, 0.999983, 1.000044, 0.999965, 0.999970, 0.999974, 0.999986, 0.999995, 0.999996, 1.000011, 0.999997, 1.000010, 1.000010, 1.000026, 1.000006, 1.000148, 1.000048, 0.999999, 1.000161, 1.000193, 0.999797, 1.000145, 0.999974, 1.000039, 0.999731, 0.999985, 1.000563, 1.000256, 1.000637, 1.000050, 1.002013, 1.001053, }, { 0.994796, 0.999833, 1.000003, 1.000012, 0.999986, 0.999991, 0.999991, 1.000000, 1.000004, 0.999999, 1.000005, 1.000004, 1.000008, 0.999996, 1.000027, 1.000097, 0.999951, 0.999938, 0.999989, 1.000001, 1.000048, 0.999935, 1.000068, 1.000134, 0.999961, 1.000198, 0.999956, 0.999957, 0.999844, 1.000087, 0.999708, 1.000198, }, { 0.996046, 0.999902, 1.000019, 1.000017, 0.999983, 0.999997, 1.000002, 0.999993, 0.999999, 1.000003, 1.000001, 1.000015, 1.000004, 1.000006, 0.999987, 0.999993, 0.999992, 1.000029, 1.000064, 0.999997, 1.000044, 1.000044, 0.999919, 0.999875, 1.000011, 0.999897, 0.999905, 0.999996, 0.999934, 0.999968, 1.000008, 0.999902, }, { 0.998703, 0.999963, 1.000021, 1.000006, 1.000008, 1.000000, 1.000003, 0.999994, 0.999990, 0.999990, 1.000003, 1.000009, 1.000001, 0.999999, 1.000001, 1.000009, 0.999999, 0.999988, 1.000003, 0.999971, 1.000005, 1.000042, 0.999924, 0.999995, 0.999998, 0.999988, 0.999961, 0.999942, 1.000046, 1.000061, 1.000112, 1.000052, }, { 0.999872, 1.000001, 1.000004, 0.999998, 0.999999, 0.999998, 0.999992, 0.999990, 0.999991, 1.000000, 1.000000, 1.000000, 1.000002, 0.999996, 1.000004, 1.000011, 0.999963, 1.000016, 1.000050, 0.999996, 0.999998, 1.000006, 0.999990, 0.999948, 0.999974, 1.000060, 1.000014, 0.999987, 0.999986, 0.999917, 0.999973, 1.000035, }, { 1.000366, 1.000006, 0.999996, 0.999995, 0.999998, 0.999996, 0.999991, 1.000001, 0.999990, 0.999996, 1.000010, 0.999999, 1.000002, 1.000000, 0.999996, 0.999990, 1.000014, 0.999978, 1.000011, 0.999983, 0.999988, 0.999971, 0.999997, 0.999989, 0.999986, 0.999958, 1.000005, 0.999992, 0.999975, 0.999975, 0.999975, 0.999975, }, { 0.999736, 0.999995, 1.000002, 1.000004, 0.999999, 1.000000, 1.000003, 1.000000, 1.000007, 0.999992, 0.999997, 0.999998, 0.999998, 0.999997, 1.000007, 1.000012, 1.000004, 0.999995, 0.999996, 1.000009, 1.000003, 1.000008, 1.000001, 1.000003, 1.000011, 1.000019, 0.999991, 0.999970, 0.999970, 0.999970, 0.999970, 0.999965, }, { 0.999970, 1.000000, 1.000000, 1.000000, 1.000001, 1.000000, 1.000000, 0.999999, 1.000001, 1.000000, 0.999999, 0.999999, 0.999999, 1.000007, 1.000005, 1.000002, 0.999999, 0.999999, 1.000000, 0.999997, 0.999999, 1.000001, 1.000001, 0.999988, 0.999988, 0.999984, 0.999995, 0.999986, 0.999986, 0.999986, 0.999986, 0.999986, }, { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, }; #pragma warning ( default : 4305 ) void NoiseInjectionComp ( void ) { int i; for ( i = 0; i < sizeof(NoiseInjectionCompensation1D)/sizeof(*NoiseInjectionCompensation1D); i++ ) NoiseInjectionCompensation1D [i] = 1.f; for ( i = 0; i < sizeof(NoiseInjectionCompensation2D)/sizeof(**NoiseInjectionCompensation2D); i++ ) NoiseInjectionCompensation2D [0][i] = 1.f; } // Quantisiert ein Subband und berechnet iSNR float ISNR_Schaetzer ( const float* input, const float SNRcomp, const int res ) { int k; float fac = A [res]; float invfac = C [res]; float Signal = 1.e-30f; float Fehler = 1.e-30f; float tmp ; float tmp2 ; // Summation der absoluten Leistung und des quadratischen Fehlers for ( k = 0; k < 36; k++ ) { tmp2 = input[k] * NoiseInjectionCompensation1D [res]; Signal += tmp2 * tmp2; // q = ftol(in), korrektes Runden tmp = tmp2 * fac + 0xFF8000; tmp = (*(int*) & tmp - 0x4B7F8000) * invfac - tmp2; Fehler += tmp * tmp; } // Anwendung von SNRcomp nur, falls SNR > 1 !! return Signal > Fehler ? Fehler / (SNRcomp * Signal) : Fehler / Signal; } #ifdef BUGBUG double _old; double _new; double _tmp; double _Sum [18]; long _Cnt [18]; double __Sum [18][33]; long __Cnt [18][33]; void rep ( double _old, double _new, int res ) { int i; _Sum [res] += sqrt (_old / _new ); _Cnt [res] ++ ; i = _old * ( 32. / 36 / 32767 / 32767); // printf ("Res=%u, old=%f, new=%f, X=%f, %3u:", res, _old, _new, X[res], i ); fflush (stdout); __Sum [res][i] += sqrt (_old / _new ); __Cnt [res][i] ++ ; } void reppr ( void ) { int i, j; printf ("\n\n==================\n"); for ( i = 0; i < 18; i++ ) if ( _Cnt[i] ) printf ("%2u: %12.6f\n", i, _Sum[i]/_Cnt[i] ); for ( i = 0; i < 18; i++ ) for ( j = 0; j <= 32; j++ ) if ( __Cnt[i][j] ) printf ("%2u[%2u]: %9.6f (%8lu)\n", i, j, __Sum[i][j]/__Cnt[i][j], __Cnt[i][j] ); } #endif // Linearer Quantisierer für ein Subband void QuantizeSubband ( unsigned int* qu_output, const float* input, const int res, float* errors ) { int n; int offset = D [res]; float mult = A [res] * NoiseInjectionCompensation1D [res]; float tmp; for ( n = 0; n < 36; n++, input++, qu_output++ ) { // q = ftol(in), korrektes Runden tmp = *input * mult + 0xFF8000; *qu_output = (unsigned int)(*(int*) & tmp - 0x4B7F8000 + offset); // Begrenzung auf 0...2D if ((unsigned int)*qu_output > (unsigned int)2*offset ) { *qu_output = mini( *qu_output, 2*offset); *qu_output = maxi( *qu_output, 0); } #ifdef BUGBUG _old += *input * *input; _tmp = (int)(*qu_output - offset) * C[res]; _new += _tmp * _tmp; #endif } #ifdef BUGBUG rep ( _old, _new, res ); _old = _new = 0; #endif } // NoiseShaper für ein Subband void QuantizeSubbandWithNoiseShaping ( unsigned int* qu_output, const float* input, const int res, float* errors, const float* FIR ) { #define E(x) *((int*)errors+(x)) float signal; float tmp; float mult = A [res]; float invmult = C [res]; int offset = D [res]; int n; int quant; E(0) = E(1) = E(2) = E(3) = E(4) = E(5) = 0; // arghh, das gibt ja Knackser an jeder Framegrenze for ( n = 0; n < 36; n++, input++, qu_output++ ) { signal = *input * NoiseInjectionCompensation1D [res] - (FIR[5]*errors[n+0] + FIR[4]*errors[n+1] + FIR[3]*errors[n+2] + FIR[2]*errors[n+3] + FIR[1]*errors[n+4] + FIR[0]*errors[n+5]); // quant = ftol(signal), korrektes Runden tmp = signal * mult + 0xFF8000; quant = *(int*) & tmp - 0x4B7F8000; // Berechnung des aktuellen Fehlers und Speichern für Fehlerrückführung errors [n + 6] = invmult * quant - signal * NoiseInjectionCompensation1D [res]; // Begrenzung auf +/-D quant = minf ( quant, +offset ); quant = maxf ( quant, -offset ); *qu_output = (unsigned int)(quant + offset); #ifdef BUGBUG _old += *input * *input; _tmp = invmult * quant; _new += _tmp * _tmp; #endif } #ifdef BUGBUG rep ( _old, _new, res ); _old = _new = 0; #endif } /* end of quant.c */ // pfk@schnecke.offl.uni-jena.de@EMAIL, Andree.Buschmann@web.de@EMAIL, BuschmannA@becker.de@EMAIL, miyaguch@eskimo.com@EMAIL, r3mix@irc.openprojects.net@EMAIL, dibrom@users.sourceforge.net@EMAIL, m.p.bakker-10@student.utwente.nl@EMAIL, djmrob@essex.ac.uk@EMAIL, dim@psytel-research.co.yu@EMAIL, lerch@zplane.de@EMAIL, takehiro@users.sourceforge.net@EMAIL, aleidinger@users.sourceforge.net@EMAIL, Robert.Hegemann@gmx.de@EMAIL, bouvigne@mp3-tech.org@EMAIL, monty@xiph.org@EMAIL, Pumpkinz99@aol.com@EMAIL, spase@outerspase.net@EMAIL, mt@wildpuppy.com@EMAIL, juha.laaksonheimo@tut.fi@EMAIL, speek@myrealbox.com@EMAIL, w.speek@12move.nl@EMAIL, martin@spueler.de@EMAIL, nicolaus.berglmeir@t-online.de@EMAIL, thomas.a.juerges@ruhr-uni-bochum.de@EMAIL, HelH@mpex.net@EMAIL, garf@roadum.demon.co.uk@EMAIL, gcp@sjeng.org@EMAIL, mike@naivesoftware.com@EMAIL, case@mobiili.net@EMAIL, steve.lhomme@free.fr@EMAIL, walter@binity.com@EMAIL