29#include "libavutil/mem.h"
30#include "libavutil/tx.h"
37static const float PI = std::numbers::pi;
42T
sqr(T x) {
return x*x; }
49 explicit Impl(
unsigned blocksize=8192)
53 m_dftL((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2)),
54 m_dftR((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2)),
55 m_src ((AVComplexFloat*)av_malloc(sizeof(AVComplexFloat) *
m_n * 2))
72 for (
unsigned c=0;c<6;c++) {
79 for (
unsigned k=0;k<
m_n;k++)
86 std::numbers::inv_sqrt3);
123 void decode(
float center_width,
float dimension,
float adaption_rate) {
130 add_output(in_first,in_second,center_width,dimension,adaption_rate,
true);
136 for (
unsigned k=0;k<
m_n;k++) {
147 unsigned int cutoff = (30*
m_n)/srate;
148 for (
unsigned f=0;f<=
m_halfN;f++) {
169 m_a = (v-o)*n;
m_b = (o-u)*n;
m_c = (-o-v)*n;
m_d = (o+u)*n;
170 m_e = (o+v)*n;
m_f = (o+u)*n;
m_g = (o-v)*n;
m_h = (o-u)*n;
175 const std::array<std::array<float,2>,4> modes {{ {0,0}, {0,
PI}, {
PI,0}, {-
PI/2,
PI/2} }};
192 static float amplitude(AVComplexFloat z) {
return std::hypot(z.re, z.im); }
193 static float phase(AVComplexFloat z) {
return std::atan2(z.im, z.re); }
202 block_decode(input1,input2,out,center_width,dimension,adaption_rate);
215 for (
unsigned k = 0; k <
m_halfN; k++)
217 m_dftL[k] = (AVComplexFloat){ .re = input1[0][k] *
m_wnd[k], .im = 0 };
218 m_dftR[k] = (AVComplexFloat){ .re = input1[1][k] *
m_wnd[k], .im = 0 };
230 for (
unsigned f=0;f<
m_halfN;f++) {
241 float phaseDiff = phaseL - phaseR;
242 if (phaseDiff < -
PI) phaseDiff += 2*
PI;
243 if (phaseDiff >
PI) phaseDiff -= 2*
PI;
244 phaseDiff = std::abs(phaseDiff);
260 float left = (1-
m_xFs[f])/2;
261 float right = (1+
m_xFs[f])/2;
262 float front = (1+
m_yFs[f])/2;
264 std::array<float, 5> volume
266 front * (left * center_width + std::max(0.0F, -
m_xFs[f]) * (1.0F - center_width) ),
268 front * (right * center_width + std::max(0.0F,
m_xFs[f]) * (1.0F - center_width) ),
274 for (
unsigned c=0;c<5;c++)
275 m_filter[c][f] = ((1-adaption_rate)*
m_filter[c][f]) + (adaption_rate*volume[c]);
284 m_yFs[f] = 1 - ((phaseDiff/
PI)*2);
290 m_yFs[f] = ((1-frontness) *
m_yFs[f]) + (frontness * 1);
301 float left = (1-
m_xFs[f])/2;
302 float right = (1+
m_xFs[f])/2;
303 float front = (1+
m_yFs[f])/2;
305 std::array<float, 5> volume
307 front * (left * center_width + std::max(0.0F, -
m_xFs[f]) * (1.0F-center_width)),
309 front * (right * center_width + std::max(0.0F,
m_xFs[f]) * (1.0F-center_width)),
315 for (
unsigned c=0;c<5;c++)
316 m_filter[c][f] = ((1-adaption_rate)*
m_filter[c][f]) + (adaption_rate*volume[c]);
339 static double get_yfs(
double ampDiff,
double phaseDiff) {
340 double x = 1-(((1-
sqr(ampDiff))*phaseDiff)/
M_PI*2);
342 double tanX = tan(x);
343 return 0.16468622925824683 + (0.5009268347818189*x) - (0.06462757726992101*x*x)
344 + (0.09170680403453149*x*x*x) + (0.2617754892323973*tanX) - (0.04180413533856156*
sqr(tanX));
346 return 0.16468622925824683 + (0.5009268347818189*x) - (0.06462757726992101*x*x)
347 + (0.09170680403453149*x*x*x) + (0.2617754892323973*tan(x)) - (0.04180413533856156*
sqr(tan(x)));
352 static double get_xfs(
double ampDiff,
double yfs) {
356 double tanX = tan(x);
357 double tanY = tan(y);
358 double asinX = asin(x);
359 double sinX = sin(x);
360 double sinY = sin(y);
364 return (2.464833559224702*x) - (423.52131153259404*x*y) +
365 (67.8557858606918*
x3*y) + (788.2429425544392*x*y2) -
366 (79.97650354902909*
x3*y2) - (513.8966153850349*x*y3) +
367 (35.68117670186306*
x3*y3) + (13867.406173420834*y*asinX) -
368 (2075.8237075786396*y2*asinX) - (908.2722068360281*y3*asinX) -
369 (12934.654772878019*asinX*sinY) - (13216.736529661162*y*tanX) +
370 (1288.6463247741938*y2*tanX) + (1384.372969378453*y3*tanX) +
371 (12699.231471126128*sinY*tanX) + (95.37131275594336*sinX*tanY) -
372 (91.21223198407546*tanX*tanY);
374 return (2.464833559224702*x) - (423.52131153259404*x*y) +
375 (67.8557858606918*x*x*x*y) + (788.2429425544392*x*y*y) -
376 (79.97650354902909*x*x*x*y*y) - (513.8966153850349*x*y*y*y) +
377 (35.68117670186306*x*x*x*y*y*y) + (13867.406173420834*y*asin(x)) -
378 (2075.8237075786396*y*y*asin(x)) - (908.2722068360281*y*y*y*asin(x)) -
379 (12934.654772878019*asin(x)*sin(y)) - (13216.736529661162*y*tan(x)) +
380 (1288.6463247741938*y*y*tan(x)) + (1384.372969378453*y*y*y*tan(x)) +
381 (12699.231471126128*sin(y)*tan(x)) + (95.37131275594336*sin(x)*tan(y)) -
382 (91.21223198407546*tan(x)*tan(y));
397 for (
unsigned f = 0; f <=
m_halfN; f++)
399 m_src[f].re = signal[f].real() * flt[f];
400 m_src[f].im = signal[f].imag() * flt[f];
403 for (
unsigned f = 1; f <
m_halfN; f++)
411 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 std::vector< uint32_t > back
static eu8 clamp(eu8 value, eu8 low, eu8 high)