mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avfilter/af_surround: add some more layouts
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
460df96904
commit
69cbebbd3d
@ -90,6 +90,15 @@ typedef struct AudioSurroundContext {
|
||||
float mag_total,
|
||||
float x, float y,
|
||||
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,
|
||||
float c_re, float c_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);
|
||||
}
|
||||
|
||||
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,
|
||||
float c_re, float c_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)
|
||||
{
|
||||
AudioSurroundContext *s = ctx->priv;
|
||||
@ -1063,6 +1244,26 @@ static int init(AVFilterContext *ctx)
|
||||
goto fail;
|
||||
}
|
||||
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:
|
||||
s->filter = filter_5_1_back;
|
||||
switch (s->out_channel_layout) {
|
||||
|
Loading…
Reference in New Issue
Block a user