28#include "libavutil/mem.h"
29#include "libavutil/tx.h"
36static const float PI = 3.141592654;
41T
sqr(T x) {
return x*x; }
48 explicit Impl(
unsigned blocksize=8192)
52 m_dftL((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2)),
53 m_dftR((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2)),
54 m_src ((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2))
71 for (
unsigned c=0;c<6;c++) {
78 for (
unsigned k=0;k<
m_n;k++)
121 void decode(
float center_width,
float dimension,
float adaption_rate) {
128 add_output(in_first,in_second,center_width,dimension,adaption_rate,
true);
134 for (
unsigned k=0;k<
m_n;k++) {
145 unsigned int cutoff = (30*
m_n)/srate;
146 for (
unsigned f=0;f<=
m_halfN;f++) {
167 m_a = (v-o)*n;
m_b = (o-u)*n;
m_c = (-o-v)*n;
m_d = (o+u)*n;
168 m_e = (o+v)*n;
m_f = (o+u)*n;
m_g = (o-v)*n;
m_h = (o-u)*n;
173 const std::array<std::array<float,2>,4> modes {{ {0,0}, {0,
PI}, {
PI,0}, {-
PI/2,
PI/2} }};
190 static float amplitude(AVComplexFloat z) {
return std::hypot(z.re, z.im); }
191 static float phase(AVComplexFloat z) {
return std::atan2(z.im, z.re); }
200 block_decode(input1,input2,out,center_width,dimension,adaption_rate);
213 for (
unsigned k = 0; k <
m_halfN; k++)
215 m_dftL[k] = (AVComplexFloat){ .re = input1[0][k] *
m_wnd[k], .im = 0 };
216 m_dftR[k] = (AVComplexFloat){ .re = input1[1][k] *
m_wnd[k], .im = 0 };
228 for (
unsigned f=0;f<
m_halfN;f++) {
239 float phaseDiff = phaseL - phaseR;
240 if (phaseDiff < -
PI) phaseDiff += 2*
PI;
241 if (phaseDiff >
PI) phaseDiff -= 2*
PI;
242 phaseDiff = std::abs(phaseDiff);
258 float left = (1-
m_xFs[f])/2;
259 float right = (1+
m_xFs[f])/2;
260 float front = (1+
m_yFs[f])/2;
262 std::array<float, 5> volume
264 front * (left * center_width + std::max(0.0F, -
m_xFs[f]) * (1.0F - center_width) ),
266 front * (right * center_width + std::max(0.0F,
m_xFs[f]) * (1.0F - center_width) ),
272 for (
unsigned c=0;c<5;c++)
273 m_filter[c][f] = ((1-adaption_rate)*
m_filter[c][f]) + (adaption_rate*volume[c]);
282 m_yFs[f] = 1 - ((phaseDiff/
PI)*2);
288 m_yFs[f] = ((1-frontness) *
m_yFs[f]) + (frontness * 1);
299 float left = (1-
m_xFs[f])/2;
300 float right = (1+
m_xFs[f])/2;
301 float front = (1+
m_yFs[f])/2;
303 std::array<float, 5> volume
305 front * (left * center_width + std::max(0.0F, -
m_xFs[f]) * (1.0F-center_width)),
307 front * (right * center_width + std::max(0.0F,
m_xFs[f]) * (1.0F-center_width)),
313 for (
unsigned c=0;c<5;c++)
314 m_filter[c][f] = ((1-adaption_rate)*
m_filter[c][f]) + (adaption_rate*volume[c]);
337 static double get_yfs(
double ampDiff,
double phaseDiff) {
338 double x = 1-(((1-
sqr(ampDiff))*phaseDiff)/
M_PI*2);
340 double tanX = tan(x);
341 return 0.16468622925824683 + (0.5009268347818189*x) - (0.06462757726992101*x*x)
342 + (0.09170680403453149*x*x*x) + (0.2617754892323973*tanX) - (0.04180413533856156*
sqr(tanX));
344 return 0.16468622925824683 + (0.5009268347818189*x) - (0.06462757726992101*x*x)
345 + (0.09170680403453149*x*x*x) + (0.2617754892323973*tan(x)) - (0.04180413533856156*
sqr(tan(x)));
350 static double get_xfs(
double ampDiff,
double yfs) {
354 double tanX = tan(x);
355 double tanY = tan(y);
356 double asinX = asin(x);
357 double sinX = sin(x);
358 double sinY = sin(y);
362 return (2.464833559224702*x) - (423.52131153259404*x*y) +
363 (67.8557858606918*
x3*y) + (788.2429425544392*x*y2) -
364 (79.97650354902909*
x3*y2) - (513.8966153850349*x*y3) +
365 (35.68117670186306*
x3*y3) + (13867.406173420834*y*asinX) -
366 (2075.8237075786396*y2*asinX) - (908.2722068360281*y3*asinX) -
367 (12934.654772878019*asinX*sinY) - (13216.736529661162*y*tanX) +
368 (1288.6463247741938*y2*tanX) + (1384.372969378453*y3*tanX) +
369 (12699.231471126128*sinY*tanX) + (95.37131275594336*sinX*tanY) -
370 (91.21223198407546*tanX*tanY);
372 return (2.464833559224702*x) - (423.52131153259404*x*y) +
373 (67.8557858606918*x*x*x*y) + (788.2429425544392*x*y*y) -
374 (79.97650354902909*x*x*x*y*y) - (513.8966153850349*x*y*y*y) +
375 (35.68117670186306*x*x*x*y*y*y) + (13867.406173420834*y*asin(x)) -
376 (2075.8237075786396*y*y*asin(x)) - (908.2722068360281*y*y*y*asin(x)) -
377 (12934.654772878019*asin(x)*sin(y)) - (13216.736529661162*y*tan(x)) +
378 (1288.6463247741938*y*y*tan(x)) + (1384.372969378453*y*y*y*tan(x)) +
379 (12699.231471126128*sin(y)*tan(x)) + (95.37131275594336*sin(x)*tan(y)) -
380 (91.21223198407546*tan(x)*tan(y));
395 for (
unsigned f = 0; f <=
m_halfN; f++)
397 m_src[f].re = signal[f].real() * flt[f];
398 m_src[f].im = signal[f].imag() * flt[f];
401 for (
unsigned f = 1; f <
m_halfN; f++)
409 for (
unsigned int k = 0; k <
m_halfN; k++)
std::vector< cfloat > m_surL
Impl(unsigned blocksize=8192)
void surround_coefficients(float a, float b)
std::vector< float > m_wnd
std::vector< cfloat > m_frontR
AVTXContext * m_fftContext
static float amplitude(AVComplexFloat z)
static float clamp_unit_mag(float x)
Clamp the input to the interval [-1, 1], i.e. clamp the magnitude to the unit interval [0,...
void sample_rate(unsigned int srate)
std::array< std::vector< float >, 6 > m_filter
std::vector< cfloat > m_trueavg
std::vector< float > m_yFs
void phase_mode(unsigned mode)
void block_decode(InputBufs input1, InputBufs input2, OutputBufs output, float center_width, float dimension, float adaption_rate)
static double get_yfs(double ampDiff, double phaseDiff)
void add_output(InputBufs input1, InputBufs input2, float center_width, float dimension, float adaption_rate, bool=false)
std::array< std::vector< float >, 2 > m_inbuf
std::array< std::vector< float >, 6 > m_outbuf
static float phase(AVComplexFloat z)
void steering_mode(bool mode)
static constexpr float kScale
std::vector< float > m_xFs
void decode(float center_width, float dimension, float adaption_rate)
static double get_xfs(double ampDiff, double yfs)
void apply_filter(cfloat *signal, const float *flt, float *target)
Filter the complex source signal in the frequency domain and add it to the time domain target signal.
void separation(float front, float rear)
std::vector< cfloat > m_surR
std::vector< cfloat > m_avg
AVTXContext * m_ifftContext
float ** getOutputBuffers()
std::vector< cfloat > m_frontL
static cfloat polar(float a, float p)
AVComplexFloat * m_src
Used only in apply_filter.
float ** getInputBuffers()
float ** getInputBuffers()
void steering_mode(bool mode)
fsurround_decoder(unsigned blocksize=8192)
void decode(float center_width=1, float dimension=0, float adaption_rate=1)
void separation(float front, float rear)
void surround_coefficients(float a, float b)
void sample_rate(unsigned int samplerate)
float ** getOutputBuffers()
void phase_mode(unsigned mode)
static const float center_level
std::array< float *, 6 > OutputBufs
std::array< float *, 2 > InputBufs
std::complex< float > cfloat
static const float epsilon
static eu8 clamp(eu8 value, eu8 low, eu8 high)