00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "el_processor.h"
00020 #include <cstdlib>
00021 #include <cstring>
00022 #include <complex>
00023 #include <cmath>
00024 #include <vector>
00025 #ifdef USE_FFTW3
00026 #include "fftw3.h"
00027 #else
00028 extern "C" {
00029 #include "libavcodec/avfft.h"
00030 #include "libavcodec/fft.h"
00031 }
00032 typedef FFTSample FFTComplexArray[2];
00033 #endif
00034
00035
00036 #ifdef USE_FFTW3
00037 #pragma comment (lib,"libfftw3f-3.lib")
00038 #endif
00039
00040 typedef std::complex<float> cfloat;
00041
00042 static const float PI = 3.141592654;
00043 static const float epsilon = 0.000001;
00044 static const float center_level = 0.5*sqrt(0.5);
00045
00046
00047 class decoder_impl {
00048 public:
00049
00050
00051 decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
00052 #ifdef USE_FFTW3
00053
00054 lt = (float*)fftwf_malloc(sizeof(float)*N);
00055 rt = (float*)fftwf_malloc(sizeof(float)*N);
00056 dst = (float*)fftwf_malloc(sizeof(float)*N);
00057 dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
00058 dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
00059 src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
00060 loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
00061 loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
00062 store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE);
00063 #else
00064
00065 lt = (float*)av_malloc(sizeof(FFTSample)*N);
00066 rt = (float*)av_malloc(sizeof(FFTSample)*N);
00067 dftL = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
00068 dftR = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
00069 src = (FFTComplexArray*)av_malloc(sizeof(FFTComplex)*N*2);
00070 fftContextForward = (FFTContext*)av_malloc(sizeof(FFTContext));
00071 memset(fftContextForward, 0, sizeof(FFTContext));
00072 fftContextReverse = (FFTContext*)av_malloc(sizeof(FFTContext));
00073 memset(fftContextReverse, 0, sizeof(FFTContext));
00074 ff_fft_init(fftContextForward, 13, 0);
00075 ff_fft_init(fftContextReverse, 13, 1);
00076 #endif
00077
00078 frontR.resize(N);
00079 frontL.resize(N);
00080 avg.resize(N);
00081 surR.resize(N);
00082 surL.resize(N);
00083 trueavg.resize(N);
00084 xfs.resize(N);
00085 yfs.resize(N);
00086 inbuf[0].resize(N);
00087 inbuf[1].resize(N);
00088 for (unsigned c=0;c<6;c++) {
00089 outbuf[c].resize(N);
00090 filter[c].resize(N);
00091 }
00092 sample_rate(48000);
00093
00094 wnd.resize(N);
00095 for (unsigned k=0;k<N;k++)
00096 wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
00097 current_buf = 0;
00098 memset(inbufs, 0, sizeof(inbufs));
00099 memset(outbufs, 0, sizeof(outbufs));
00100
00101 surround_coefficients(0.8165,0.5774);
00102 phase_mode(0);
00103 separation(1,1);
00104 steering_mode(1);
00105 }
00106
00107
00108 ~decoder_impl() {
00109 #ifdef USE_FFTW3
00110
00111 fftwf_destroy_plan(store);
00112 fftwf_destroy_plan(loadR);
00113 fftwf_destroy_plan(loadL);
00114 fftwf_free(src);
00115 fftwf_free(dftR);
00116 fftwf_free(dftL);
00117 fftwf_free(dst);
00118 fftwf_free(rt);
00119 fftwf_free(lt);
00120 #else
00121 ff_fft_end(fftContextForward);
00122 ff_fft_end(fftContextReverse);
00123 av_free(src);
00124 av_free(dftR);
00125 av_free(dftL);
00126 av_free(rt);
00127 av_free(lt);
00128 av_free(fftContextForward);
00129 av_free(fftContextReverse);
00130 #endif
00131 }
00132
00133 float ** getInputBuffers()
00134 {
00135 inbufs[0] = &inbuf[0][current_buf*halfN];
00136 inbufs[1] = &inbuf[1][current_buf*halfN];
00137 return inbufs;
00138 }
00139
00140 float ** getOutputBuffers()
00141 {
00142 outbufs[0] = &outbuf[0][current_buf*halfN];
00143 outbufs[1] = &outbuf[1][current_buf*halfN];
00144 outbufs[2] = &outbuf[2][current_buf*halfN];
00145 outbufs[3] = &outbuf[3][current_buf*halfN];
00146 outbufs[4] = &outbuf[4][current_buf*halfN];
00147 outbufs[5] = &outbuf[5][current_buf*halfN];
00148 return outbufs;
00149 }
00150
00151
00152
00153
00154
00155 void decode(float center_width, float dimension, float adaption_rate) {
00156
00157 int index;
00158 index = current_buf*halfN;
00159 float *in_second[2] = {&inbuf[0][index],&inbuf[1][index]};
00160 current_buf ^= 1;
00161 index = current_buf*halfN;
00162 float *in_first[2] = {&inbuf[0][index],&inbuf[1][index]};
00163 add_output(in_first,in_second,center_width,dimension,adaption_rate,true);
00164
00165 }
00166
00167
00168 void flush() {
00169 for (unsigned k=0;k<N;k++) {
00170 for (unsigned c=0;c<6;c++)
00171 outbuf[c][k] = 0;
00172 inbuf[0][k] = 0;
00173 inbuf[1][k] = 0;
00174 }
00175 }
00176
00177
00178 void sample_rate(unsigned int srate) {
00179
00180 unsigned int cutoff = (30*N)/srate;
00181 for (unsigned f=0;f<=halfN;f++) {
00182 if (f<cutoff)
00183 filter[5][f] = 0.5*sqrt(0.5);
00184 else
00185 filter[5][f] = 0.0;
00186 }
00187 }
00188
00189
00190 void surround_coefficients(float a, float b) {
00191
00192 surround_high = a;
00193 surround_low = b;
00194 surround_balance = (a-b)/(a+b);
00195 surround_level = 1/(a+b);
00196
00197 cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0);
00198 A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n;
00199 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n;
00200 }
00201
00202
00203 void phase_mode(unsigned mode) {
00204 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
00205 phase_offsetL = modes[mode][0];
00206 phase_offsetR = modes[mode][1];
00207 }
00208
00209
00210 void steering_mode(bool mode) { linear_steering = mode; }
00211
00212
00213 void separation(float front, float rear) {
00214 front_separation = front;
00215 rear_separation = rear;
00216 }
00217
00218 private:
00219
00220 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
00221 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
00222 static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); }
00223 static inline float sqr(float x) { return x*x; }
00224
00225 static inline float min(float a, float b) { return a<b?a:b; }
00226 static inline float max(float a, float b) { return a>b?a:b; }
00227 static inline float clamp(float x) { return max(-1,min(1,x)); }
00228
00229
00230 void add_output(float *input1[2], float *input2[2], float center_width, float dimension, float adaption_rate, bool result=false) {
00231
00232 float *out[6] = {&outbuf[0][0],&outbuf[1][0],&outbuf[2][0],&outbuf[3][0],&outbuf[4][0],&outbuf[5][0]};
00233 block_decode(input1,input2,out,center_width,dimension,adaption_rate);
00234 }
00235
00236
00237 void block_decode(float *input1[2], float *input2[2], float *output[6], float center_width, float dimension, float adaption_rate) {
00238
00239
00240
00241 {
00242 float* pWnd = &wnd[0];
00243 float* pLt = <[0];
00244 float* pRt = &rt[0];
00245 float* pIn0 = input1[0];
00246 float* pIn1 = input1[1];
00247 for (unsigned k=0;k<halfN;k++) {
00248 *pLt++ = *pIn0++ * *pWnd;
00249 *pRt++ = *pIn1++ * *pWnd++;
00250 }
00251 pIn0 = input2[0];
00252 pIn1 = input2[1];
00253 for (unsigned k=0;k<halfN;k++) {
00254 *pLt++ = *pIn0++ * *pWnd;
00255 *pRt++ = *pIn1++ * *pWnd++;
00256 }
00257 }
00258
00259 #ifdef USE_FFTW3
00260
00261 fftwf_execute(loadL);
00262 fftwf_execute(loadR);
00263 #else
00264 ff_fft_permuteRC(fftContextForward, lt, (FFTComplex*)&dftL[0]);
00265 av_fft_calc(fftContextForward, (FFTComplex*)&dftL[0]);
00266
00267 ff_fft_permuteRC(fftContextForward, rt, (FFTComplex*)&dftR[0]);
00268 av_fft_calc(fftContextForward, (FFTComplex*)&dftR[0]);
00269 #endif
00270
00271
00272
00273 for (unsigned f=0;f<halfN;f++) {
00274
00275 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
00276 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
00277
00278
00279
00280
00281 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
00282 float phaseDiff = phaseL - phaseR;
00283 if (phaseDiff < -PI) phaseDiff += 2*PI;
00284 if (phaseDiff > PI) phaseDiff -= 2*PI;
00285 phaseDiff = abs(phaseDiff);
00286
00287 if (linear_steering) {
00288
00289
00290
00291 yfs[f] = get_yfs(ampDiff,phaseDiff);
00292 xfs[f] = get_xfs(ampDiff,yfs[f]);
00293
00294
00295 yfs[f] = clamp(yfs[f] - dimension);
00296
00297
00298 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
00299
00300
00301 float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
00302 float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
00303 float volume[5] = {
00304 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),
00305 front * center_level*((1-abs(xfs[f])) * (1-center_width)),
00306 front * (right * center_width + max(0, xfs[f]) * (1-center_width)),
00307 back * surround_level * left,
00308 back * surround_level * right
00309 };
00310
00311
00312 for (unsigned c=0;c<5;c++)
00313 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c];
00314
00315 } else {
00316
00317
00318
00319 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
00320 float phaseDiff = phaseL - phaseR;
00321 if (phaseDiff < -PI) phaseDiff += 2*PI;
00322 if (phaseDiff > PI) phaseDiff -= 2*PI;
00323 phaseDiff = abs(phaseDiff);
00324
00325
00326 xfs[f] = ampDiff;
00327
00328
00329 yfs[f] = 1 - (phaseDiff/PI)*2;
00330
00331 if (abs(xfs[f]) > surround_balance) {
00332
00333
00334 float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance);
00335 yfs[f] = (1-frontness) * yfs[f] + frontness * 1;
00336 }
00337
00338
00339 yfs[f] = clamp(yfs[f] - dimension);
00340
00341
00342 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
00343
00344
00345
00346 float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
00347 float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
00348 float volume[5] = {
00349 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),
00350 front * center_level*((1-abs(xfs[f])) * (1-center_width)),
00351 front * (right * center_width + max(0, xfs[f]) * (1-center_width)),
00352 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),
00353 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))
00354 };
00355
00356
00357 for (unsigned c=0;c<5;c++)
00358 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c];
00359 }
00360
00361
00362 frontL[f] = polar(ampL+ampR,phaseL);
00363 frontR[f] = polar(ampL+ampR,phaseR);
00364 avg[f] = frontL[f] + frontR[f];
00365 surL[f] = polar(ampL+ampR,phaseL+phase_offsetL);
00366 surR[f] = polar(ampL+ampR,phaseR+phase_offsetR);
00367 trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]);
00368 }
00369
00370
00371 apply_filter(&frontL[0],&filter[0][0],&output[0][0]);
00372 apply_filter(&avg[0], &filter[1][0],&output[1][0]);
00373 apply_filter(&frontR[0],&filter[2][0],&output[2][0]);
00374 apply_filter(&surL[0],&filter[3][0],&output[3][0]);
00375 apply_filter(&surR[0],&filter[4][0],&output[4][0]);
00376 apply_filter(&trueavg[0],&filter[5][0],&output[5][0]);
00377 }
00378
00379 #define FASTER_CALC
00380
00381 inline double get_yfs(double ampDiff, double phaseDiff) {
00382 double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2);
00383 #ifdef FASTER_CALC
00384 double tanX = tan(x);
00385 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
00386 + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX);
00387 #else
00388 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
00389 + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x));
00390 #endif
00391 }
00392
00393
00394 inline double get_xfs(double ampDiff, double yfs) {
00395 double x=ampDiff,y=yfs;
00396 #ifdef FASTER_CALC
00397 double tanX = tan(x);
00398 double tanY = tan(y);
00399 double asinX = asin(x);
00400 double sinX = sin(x);
00401 double sinY = sin(y);
00402 double x3 = x*x*x;
00403 double y2 = y*y;
00404 double y3 = y*y2;
00405 return 2.464833559224702*x - 423.52131153259404*x*y +
00406 67.8557858606918*x3*y + 788.2429425544392*x*y2 -
00407 79.97650354902909*x3*y2 - 513.8966153850349*x*y3 +
00408 35.68117670186306*x3*y3 + 13867.406173420834*y*asinX -
00409 2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX -
00410 12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX +
00411 1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX +
00412 12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY -
00413 91.21223198407546*tanX*tanY;
00414 #else
00415 return 2.464833559224702*x - 423.52131153259404*x*y +
00416 67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y -
00417 79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y +
00418 35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) -
00419 2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) -
00420 12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) +
00421 1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) +
00422 12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) -
00423 91.21223198407546*tan(x)*tan(y);
00424 #endif
00425 }
00426
00427
00428 void apply_filter(cfloat *signal, float *flt, float *target) {
00429
00430 unsigned f;
00431 for (f=0;f<=halfN;f++) {
00432 src[f][0] = signal[f].real() * flt[f];
00433 src[f][1] = signal[f].imag() * flt[f];
00434 }
00435 #ifdef USE_FFTW3
00436
00437 fftwf_execute(store);
00438
00439 float* pT1 = &target[current_buf*halfN];
00440 float* pWnd1 = &wnd[0];
00441 float* pDst1 = &dst[0];
00442 float* pT2 = &target[(current_buf^1)*halfN];
00443 float* pWnd2 = &wnd[halfN];
00444 float* pDst2 = &dst[halfN];
00445
00446 for (unsigned int k=0;k<halfN;k++)
00447 {
00448
00449 *pT1++ += *pWnd1++ * *pDst1++;
00450
00451 *pT2++ = *pWnd2++ * *pDst2++;
00452 }
00453 #else
00454
00455 for (f=1;f<halfN;f++) {
00456 src[N-f][0] = src[f][0];
00457 src[N-f][1] = -src[f][1];
00458 }
00459 av_fft_permute(fftContextReverse, (FFTComplex*)&src[0]);
00460 av_fft_calc(fftContextReverse, (FFTComplex*)&src[0]);
00461
00462 float* pT1 = &target[current_buf*halfN];
00463 float* pWnd1 = &wnd[0];
00464 float* pDst1 = &src[0][0];
00465 float* pT2 = &target[(current_buf^1)*halfN];
00466 float* pWnd2 = &wnd[halfN];
00467 float* pDst2 = &src[halfN][0];
00468
00469 for (unsigned int k=0;k<halfN;k++)
00470 {
00471
00472 *pT1++ += *pWnd1++ * *pDst1; pDst1 += 2;
00473
00474 *pT2++ = *pWnd2++ * *pDst2; pDst2 += 2;
00475 }
00476 #endif
00477 }
00478
00479 #ifndef USE_FFTW3
00480
00484 void ff_fft_permuteRC(FFTContext *s, FFTSample *r, FFTComplex *z)
00485 {
00486 int j, k, np;
00487 const uint16_t *revtab = s->revtab;
00488
00489
00490 np = 1 << s->nbits;
00491 for(j=0;j<np;j++) {
00492 k = revtab[j];
00493 z[k].re = r[j];
00494 z[k].im = 0.0;
00495 }
00496 }
00497
00503 void ff_fft_permuteCR(FFTContext *s, FFTComplex *z, FFTSample *r)
00504 {
00505 int j, k, np;
00506 FFTComplex tmp;
00507 const uint16_t *revtab = s->revtab;
00508
00509
00510 np = 1 << s->nbits;
00511 for(j=0;j<np;j++) {
00512 k = revtab[j];
00513 if (k < j) {
00514 r[k] = z[j].re;
00515 r[j] = z[k].re;
00516 }
00517 }
00518 }
00519 #endif
00520
00521 unsigned int N;
00522 unsigned int halfN;
00523 #ifdef USE_FFTW3
00524
00525 float *lt,*rt,*dst;
00526 fftwf_complex *dftL,*dftR,*src;
00527 fftwf_plan loadL,loadR,store;
00528 #else
00529 FFTContext *fftContextForward, *fftContextReverse;
00530 FFTSample *lt,*rt;
00531 FFTComplexArray *dftL,*dftR,*src;
00532 #endif
00533
00534 std::vector<cfloat> frontL,frontR,avg,surL,surR;
00535 std::vector<cfloat> trueavg;
00536 std::vector<float> xfs,yfs;
00537 std::vector<float> wnd;
00538 std::vector<float> filter[6];
00539 std::vector<float> inbuf[2];
00540 std::vector<float> outbuf[6];
00541
00542 float surround_high,surround_low;
00543 float surround_balance;
00544 float surround_level;
00545 float phase_offsetL, phase_offsetR;
00546 float front_separation;
00547 float rear_separation;
00548 bool linear_steering;
00549 cfloat A,B,C,D,E,F,G,H;
00550 int current_buf;
00551 float * inbufs[2];
00552 float * outbufs[6];
00553
00554 friend class fsurround_decoder;
00555 };
00556
00557
00558
00559
00560 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
00561
00562 fsurround_decoder::~fsurround_decoder() { delete impl; }
00563
00564 void fsurround_decoder::decode(float center_width, float dimension, float adaption_rate) {
00565 impl->decode(center_width,dimension,adaption_rate);
00566 }
00567
00568 void fsurround_decoder::flush() { impl->flush(); }
00569
00570 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
00571
00572 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
00573
00574 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
00575
00576 void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); }
00577
00578 float ** fsurround_decoder::getInputBuffers()
00579 {
00580 return impl->getInputBuffers();
00581 }
00582
00583 float ** fsurround_decoder::getOutputBuffers()
00584 {
00585 return impl->getOutputBuffers();
00586 }
00587
00588 void fsurround_decoder::sample_rate(unsigned int samplerate)
00589 {
00590 impl->sample_rate(samplerate);
00591 }