|
@@ -90,6 +90,15 @@ typedef struct AudioSurroundContext { |
|
|
float mag_total, |
|
|
float mag_total, |
|
|
float x, float y, |
|
|
float x, float y, |
|
|
int n); |
|
|
int n); |
|
|
|
|
|
void (*upmix_5_0)(AVFilterContext *ctx, |
|
|
|
|
|
float c_re, float c_im, |
|
|
|
|
|
float mag_totall, float mag_totalr, |
|
|
|
|
|
float fl_phase, float fr_phase, |
|
|
|
|
|
float bl_phase, float br_phase, |
|
|
|
|
|
float sl_phase, float sr_phase, |
|
|
|
|
|
float xl, float yl, |
|
|
|
|
|
float xr, float yr, |
|
|
|
|
|
int n); |
|
|
void (*upmix_5_1)(AVFilterContext *ctx, |
|
|
void (*upmix_5_1)(AVFilterContext *ctx, |
|
|
float c_re, float c_im, |
|
|
float c_re, float c_im, |
|
|
float lfe_re, float lfe_im, |
|
|
float lfe_re, float lfe_im, |
|
@@ -764,6 +773,66 @@ static void upmix_7_1(AVFilterContext *ctx, |
|
|
dstrs[2 * n + 1] = rs_mag * sinf(r_phase); |
|
|
dstrs[2 * n + 1] = rs_mag * sinf(r_phase); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void upmix_7_1_5_0_side(AVFilterContext *ctx, |
|
|
|
|
|
float c_re, float c_im, |
|
|
|
|
|
float mag_totall, float mag_totalr, |
|
|
|
|
|
float fl_phase, float fr_phase, |
|
|
|
|
|
float bl_phase, float br_phase, |
|
|
|
|
|
float sl_phase, float sr_phase, |
|
|
|
|
|
float xl, float yl, |
|
|
|
|
|
float xr, float yr, |
|
|
|
|
|
int n) |
|
|
|
|
|
{ |
|
|
|
|
|
float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag; |
|
|
|
|
|
float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe; |
|
|
|
|
|
float lfe_mag, c_phase, mag_total = (mag_totall + mag_totalr) * 0.5; |
|
|
|
|
|
AudioSurroundContext *s = ctx->priv; |
|
|
|
|
|
|
|
|
|
|
|
dstl = (float *)s->output->extended_data[0]; |
|
|
|
|
|
dstr = (float *)s->output->extended_data[1]; |
|
|
|
|
|
dstc = (float *)s->output->extended_data[2]; |
|
|
|
|
|
dstlfe = (float *)s->output->extended_data[3]; |
|
|
|
|
|
dstlb = (float *)s->output->extended_data[4]; |
|
|
|
|
|
dstrb = (float *)s->output->extended_data[5]; |
|
|
|
|
|
dstls = (float *)s->output->extended_data[6]; |
|
|
|
|
|
dstrs = (float *)s->output->extended_data[7]; |
|
|
|
|
|
|
|
|
|
|
|
c_phase = atan2f(c_im, c_re); |
|
|
|
|
|
|
|
|
|
|
|
get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total); |
|
|
|
|
|
|
|
|
|
|
|
fl_mag = sqrtf(.5f * (xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall; |
|
|
|
|
|
fr_mag = sqrtf(.5f * (xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr; |
|
|
|
|
|
lb_mag = sqrtf(.5f * (-xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall; |
|
|
|
|
|
rb_mag = sqrtf(.5f * (-xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr; |
|
|
|
|
|
ls_mag = sqrtf(1.f - fabsf(xl)) * ((yl + 1.f) * .5f) * mag_totall; |
|
|
|
|
|
rs_mag = sqrtf(1.f - fabsf(xr)) * ((yr + 1.f) * .5f) * mag_totalr; |
|
|
|
|
|
|
|
|
|
|
|
dstl[2 * n ] = fl_mag * cosf(fl_phase); |
|
|
|
|
|
dstl[2 * n + 1] = fl_mag * sinf(fl_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstr[2 * n ] = fr_mag * cosf(fr_phase); |
|
|
|
|
|
dstr[2 * n + 1] = fr_mag * sinf(fr_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstc[2 * n ] = c_re; |
|
|
|
|
|
dstc[2 * n + 1] = c_im; |
|
|
|
|
|
|
|
|
|
|
|
dstlfe[2 * n ] = lfe_mag * cosf(c_phase); |
|
|
|
|
|
dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstlb[2 * n ] = lb_mag * cosf(bl_phase); |
|
|
|
|
|
dstlb[2 * n + 1] = lb_mag * sinf(bl_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstrb[2 * n ] = rb_mag * cosf(br_phase); |
|
|
|
|
|
dstrb[2 * n + 1] = rb_mag * sinf(br_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstls[2 * n ] = ls_mag * cosf(sl_phase); |
|
|
|
|
|
dstls[2 * n + 1] = ls_mag * sinf(sl_phase); |
|
|
|
|
|
|
|
|
|
|
|
dstrs[2 * n ] = rs_mag * cosf(sr_phase); |
|
|
|
|
|
dstrs[2 * n + 1] = rs_mag * sinf(sr_phase); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void upmix_7_1_5_1(AVFilterContext *ctx, |
|
|
static void upmix_7_1_5_1(AVFilterContext *ctx, |
|
|
float c_re, float c_im, |
|
|
float c_re, float c_im, |
|
|
float lfe_re, float lfe_im, |
|
|
float lfe_re, float lfe_im, |
|
@@ -918,6 +987,118 @@ static void filter_2_1(AVFilterContext *ctx) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void filter_5_0_side(AVFilterContext *ctx) |
|
|
|
|
|
{ |
|
|
|
|
|
AudioSurroundContext *s = ctx->priv; |
|
|
|
|
|
float *srcl, *srcr, *srcc, *srcsl, *srcsr; |
|
|
|
|
|
int n; |
|
|
|
|
|
|
|
|
|
|
|
srcl = (float *)s->input->extended_data[0]; |
|
|
|
|
|
srcr = (float *)s->input->extended_data[1]; |
|
|
|
|
|
srcc = (float *)s->input->extended_data[2]; |
|
|
|
|
|
srcsl = (float *)s->input->extended_data[3]; |
|
|
|
|
|
srcsr = (float *)s->input->extended_data[4]; |
|
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < s->buf_size; n++) { |
|
|
|
|
|
float fl_re = srcl[2 * n], fr_re = srcr[2 * n]; |
|
|
|
|
|
float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1]; |
|
|
|
|
|
float c_re = srcc[2 * n], c_im = srcc[2 * n + 1]; |
|
|
|
|
|
float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1]; |
|
|
|
|
|
float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1]; |
|
|
|
|
|
float fl_mag = hypotf(fl_re, fl_im); |
|
|
|
|
|
float fr_mag = hypotf(fr_re, fr_im); |
|
|
|
|
|
float fl_phase = atan2f(fl_im, fl_re); |
|
|
|
|
|
float fr_phase = atan2f(fr_im, fr_re); |
|
|
|
|
|
float sl_mag = hypotf(sl_re, sl_im); |
|
|
|
|
|
float sr_mag = hypotf(sr_re, sr_im); |
|
|
|
|
|
float sl_phase = atan2f(sl_im, sl_re); |
|
|
|
|
|
float sr_phase = atan2f(sr_im, sr_re); |
|
|
|
|
|
float phase_difl = fabsf(fl_phase - sl_phase); |
|
|
|
|
|
float phase_difr = fabsf(fr_phase - sr_phase); |
|
|
|
|
|
float mag_difl = (fl_mag - sl_mag) / (fl_mag + sl_mag); |
|
|
|
|
|
float mag_difr = (fr_mag - sr_mag) / (fr_mag + sr_mag); |
|
|
|
|
|
float mag_totall = hypotf(fl_mag, sl_mag); |
|
|
|
|
|
float mag_totalr = hypotf(fr_mag, sr_mag); |
|
|
|
|
|
float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re); |
|
|
|
|
|
float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re); |
|
|
|
|
|
float xl, yl; |
|
|
|
|
|
float xr, yr; |
|
|
|
|
|
|
|
|
|
|
|
if (phase_difl > M_PI) |
|
|
|
|
|
phase_difl = 2 * M_PI - phase_difl; |
|
|
|
|
|
|
|
|
|
|
|
if (phase_difr > M_PI) |
|
|
|
|
|
phase_difr = 2 * M_PI - phase_difr; |
|
|
|
|
|
|
|
|
|
|
|
stereo_position(mag_difl, phase_difl, &xl, &yl); |
|
|
|
|
|
stereo_position(mag_difr, phase_difr, &xr, &yr); |
|
|
|
|
|
|
|
|
|
|
|
s->upmix_5_0(ctx, c_re, c_im, |
|
|
|
|
|
mag_totall, mag_totalr, |
|
|
|
|
|
fl_phase, fr_phase, |
|
|
|
|
|
bl_phase, br_phase, |
|
|
|
|
|
sl_phase, sr_phase, |
|
|
|
|
|
xl, yl, xr, yr, n); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void filter_5_1_side(AVFilterContext *ctx) |
|
|
|
|
|
{ |
|
|
|
|
|
AudioSurroundContext *s = ctx->priv; |
|
|
|
|
|
float *srcl, *srcr, *srcc, *srclfe, *srcsl, *srcsr; |
|
|
|
|
|
int n; |
|
|
|
|
|
|
|
|
|
|
|
srcl = (float *)s->input->extended_data[0]; |
|
|
|
|
|
srcr = (float *)s->input->extended_data[1]; |
|
|
|
|
|
srcc = (float *)s->input->extended_data[2]; |
|
|
|
|
|
srclfe = (float *)s->input->extended_data[3]; |
|
|
|
|
|
srcsl = (float *)s->input->extended_data[4]; |
|
|
|
|
|
srcsr = (float *)s->input->extended_data[5]; |
|
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < s->buf_size; n++) { |
|
|
|
|
|
float fl_re = srcl[2 * n], fr_re = srcr[2 * n]; |
|
|
|
|
|
float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1]; |
|
|
|
|
|
float c_re = srcc[2 * n], c_im = srcc[2 * n + 1]; |
|
|
|
|
|
float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1]; |
|
|
|
|
|
float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1]; |
|
|
|
|
|
float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1]; |
|
|
|
|
|
float fl_mag = hypotf(fl_re, fl_im); |
|
|
|
|
|
float fr_mag = hypotf(fr_re, fr_im); |
|
|
|
|
|
float fl_phase = atan2f(fl_im, fl_re); |
|
|
|
|
|
float fr_phase = atan2f(fr_im, fr_re); |
|
|
|
|
|
float sl_mag = hypotf(sl_re, sl_im); |
|
|
|
|
|
float sr_mag = hypotf(sr_re, sr_im); |
|
|
|
|
|
float sl_phase = atan2f(sl_im, sl_re); |
|
|
|
|
|
float sr_phase = atan2f(sr_im, sr_re); |
|
|
|
|
|
float phase_difl = fabsf(fl_phase - sl_phase); |
|
|
|
|
|
float phase_difr = fabsf(fr_phase - sr_phase); |
|
|
|
|
|
float mag_difl = (fl_mag - sl_mag) / (fl_mag + sl_mag); |
|
|
|
|
|
float mag_difr = (fr_mag - sr_mag) / (fr_mag + sr_mag); |
|
|
|
|
|
float mag_totall = hypotf(fl_mag, sl_mag); |
|
|
|
|
|
float mag_totalr = hypotf(fr_mag, sr_mag); |
|
|
|
|
|
float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re); |
|
|
|
|
|
float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re); |
|
|
|
|
|
float xl, yl; |
|
|
|
|
|
float xr, yr; |
|
|
|
|
|
|
|
|
|
|
|
if (phase_difl > M_PI) |
|
|
|
|
|
phase_difl = 2 * M_PI - phase_difl; |
|
|
|
|
|
|
|
|
|
|
|
if (phase_difr > M_PI) |
|
|
|
|
|
phase_difr = 2 * M_PI - phase_difr; |
|
|
|
|
|
|
|
|
|
|
|
stereo_position(mag_difl, phase_difl, &xl, &yl); |
|
|
|
|
|
stereo_position(mag_difr, phase_difr, &xr, &yr); |
|
|
|
|
|
|
|
|
|
|
|
s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im, |
|
|
|
|
|
mag_totall, mag_totalr, |
|
|
|
|
|
fl_phase, fr_phase, |
|
|
|
|
|
bl_phase, br_phase, |
|
|
|
|
|
sl_phase, sr_phase, |
|
|
|
|
|
xl, yl, xr, yr, n); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void filter_5_1_back(AVFilterContext *ctx) |
|
|
static void filter_5_1_back(AVFilterContext *ctx) |
|
|
{ |
|
|
{ |
|
|
AudioSurroundContext *s = ctx->priv; |
|
|
AudioSurroundContext *s = ctx->priv; |
|
@@ -1063,6 +1244,26 @@ static int init(AVFilterContext *ctx) |
|
|
goto fail; |
|
|
goto fail; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
case AV_CH_LAYOUT_5POINT0: |
|
|
|
|
|
s->filter = filter_5_0_side; |
|
|
|
|
|
switch (s->out_channel_layout) { |
|
|
|
|
|
case AV_CH_LAYOUT_7POINT1: |
|
|
|
|
|
s->upmix_5_0 = upmix_7_1_5_0_side; |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
goto fail; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case AV_CH_LAYOUT_5POINT1: |
|
|
|
|
|
s->filter = filter_5_1_side; |
|
|
|
|
|
switch (s->out_channel_layout) { |
|
|
|
|
|
case AV_CH_LAYOUT_7POINT1: |
|
|
|
|
|
s->upmix_5_1 = upmix_7_1_5_1; |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
goto fail; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
case AV_CH_LAYOUT_5POINT1_BACK: |
|
|
case AV_CH_LAYOUT_5POINT1_BACK: |
|
|
s->filter = filter_5_1_back; |
|
|
s->filter = filter_5_1_back; |
|
|
switch (s->out_channel_layout) { |
|
|
switch (s->out_channel_layout) { |
|
|