History

avfilter/af_surround: implement smooth option/support

Paul B Mahol committed 3 years ago

Commit 52291d21 parent 3d330032 files · +24 −4Browse files

Unified · Split

2 files
  1. doc/filters.texi +6 −0
  2. libavfilter/af_surround.c +18 −4
doc/filters.texi+6−0
@@ -6670,6 +6670,12 @@ In @var{add} mode, LFE channel is created from input audio and added to output. · 6669 unmodified lines
6670In @var{sub} mode, LFE channel is created from input audio and added to output but6670In @var{sub} mode, LFE channel is created from input audio and added to output but
6671also all non-LFE output channels are subtracted with output LFE channel.6671also all non-LFE output channels are subtracted with output LFE channel.
6672 6672
6673@item smooth
6674Set temporal smoothness strength, used to gradually change factors when transforming
6675stereo sound in time. Allowed range is from @var{0.0} to @var{1.0}.
6676Useful to improve output quality with @var{focus} option values greater than @var{0.0}.
6677Default is @var{0.0}. Only values inside this range and without edges are effective.
6678
6673@item angle6679@item angle
6674Set angle of stereo surround transform, Allowed range is from @var{0} to @var{360}.6680Set angle of stereo surround transform, Allowed range is from @var{0} to @var{360}.
6675Default is @var{90}.6681Default is @var{90}.
libavfilter/af_surround.c+18−4
@@ -69,6 +69,7 @@ typedef struct AudioSurroundContext { · 68 unmodified lines
69 float f_i[SC_NB];69 float f_i[SC_NB];
70 float f_o[SC_NB];70 float f_o[SC_NB];
71 int lfe_mode;71 int lfe_mode;
72 float smooth;
72 float angle;73 float angle;
73 float focus;74 float focus;
74 int win_size;75 int win_size;
@@ -97,6 +98,7 @@ typedef struct AudioSurroundContext { · 22 unmodified lines
97 int nb_out_channels;98 int nb_out_channels;
98 99
99 AVFrame *factors;100 AVFrame *factors;
101 AVFrame *sfactors;
100 AVFrame *input_in;102 AVFrame *input_in;
101 AVFrame *input;103 AVFrame *input;
102 AVFrame *output;104 AVFrame *output;
@@ -297,13 +299,14 @@ static int config_output(AVFilterLink *outlink) · 194 unmodified lines
297 set_output_levels(ctx);299 set_output_levels(ctx);
298 300
299 s->factors = ff_get_audio_buffer(outlink, s->win_size + 2);301 s->factors = ff_get_audio_buffer(outlink, s->win_size + 2);
302 s->sfactors = ff_get_audio_buffer(outlink, s->win_size + 2);
300 s->output_ph = ff_get_audio_buffer(outlink, s->win_size + 2);303 s->output_ph = ff_get_audio_buffer(outlink, s->win_size + 2);
301 s->output_mag = ff_get_audio_buffer(outlink, s->win_size + 2);304 s->output_mag = ff_get_audio_buffer(outlink, s->win_size + 2);
302 s->output_out = ff_get_audio_buffer(outlink, s->win_size + 2);305 s->output_out = ff_get_audio_buffer(outlink, s->win_size + 2);
303 s->output = ff_get_audio_buffer(outlink, s->win_size + 2);306 s->output = ff_get_audio_buffer(outlink, s->win_size + 2);
304 s->overlap_buffer = ff_get_audio_buffer(outlink, s->win_size * 2);307 s->overlap_buffer = ff_get_audio_buffer(outlink, s->win_size * 2);
305 if (!s->overlap_buffer || !s->output || !s->output_out || !s->output_mag ||308 if (!s->overlap_buffer || !s->output || !s->output_out || !s->output_mag ||
306 !s->output_ph || !s->factors)309 !s->output_ph || !s->factors || !s->sfactors)
307 return AVERROR(ENOMEM);310 return AVERROR(ENOMEM);
308 311
309 s->rdft_size = s->win_size / 2 + 1;312 s->rdft_size = s->win_size / 2 + 1;
@@ -404,6 +407,7 @@ static int stereo_upmix(AVFilterContext *ctx, int ch) · 94 unmodified lines
404{407{
405 AudioSurroundContext *s = ctx->priv;408 AudioSurroundContext *s = ctx->priv;
406 float *dst = (float *)s->output->extended_data[ch];409 float *dst = (float *)s->output->extended_data[ch];
410 float *sfactor = (float *)s->sfactors->extended_data[ch];
407 float *factor = (float *)s->factors->extended_data[ch];411 float *factor = (float *)s->factors->extended_data[ch];
408 float *omag = (float *)s->output_mag->extended_data[ch];412 float *omag = (float *)s->output_mag->extended_data[ch];
409 float *oph = (float *)s->output_ph->extended_data[ch];413 float *oph = (float *)s->output_ph->extended_data[ch];
@@ -419,6 +423,7 @@ static int stereo_upmix(AVFilterContext *ctx, int ch) · 9 unmodified lines
419 const int chan = av_channel_layout_channel_from_index(&s->out_ch_layout, ch);423 const int chan = av_channel_layout_channel_from_index(&s->out_ch_layout, ch);
420 const float f_x = s->f_x[sc_map[chan]];424 const float f_x = s->f_x[sc_map[chan]];
421 const float f_y = s->f_y[sc_map[chan]];425 const float f_y = s->f_y[sc_map[chan]];
426 const float smooth = s->smooth;
422 427
423 switch (chan) {428 switch (chan) {
424 case AV_CHAN_FRONT_CENTER:429 case AV_CHAN_FRONT_CENTER:
@@ -501,6 +506,13 @@ static int stereo_upmix(AVFilterContext *ctx, int ch) · 76 unmodified lines
501 break;506 break;
502 }507 }
503 508
509 if (smooth > 0.f) {
510 for (int n = 0; n < rdft_size; n++)
511 sfactor[n] = smooth * factor[n] + (1.f - smooth) * sfactor[n];
512
513 factor = sfactor;
514 }
515
504 for (int n = 0; n < rdft_size; n++)516 for (int n = 0; n < rdft_size; n++)
505 omag[n] *= factor[n];517 omag[n] *= factor[n];
506 518
@@ -1076,9 +1088,9 @@ static void allchannels_spread(AVFilterContext *ctx) · 569 unmodified lines
1076static av_cold int init(AVFilterContext *ctx)1088static av_cold int init(AVFilterContext *ctx)
1077{1089{
1078 AudioSurroundContext *s = ctx->priv;1090 AudioSurroundContext *s = ctx->priv;
1079 float overlap;
1080 int64_t in_channel_layout, out_channel_layout;1091 int64_t in_channel_layout, out_channel_layout;
1081 int i, ret;1092 float overlap;
1093 int ret;
1082 1094
1083 if ((ret = av_channel_layout_from_string(&s->out_ch_layout, s->out_channel_layout_str)) < 0) {1095 if ((ret = av_channel_layout_from_string(&s->out_ch_layout, s->out_channel_layout_str)) < 0) {
1084 av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",1096 av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",
@@ -1203,7 +1215,7 @@ fail: · 118 unmodified lines
1203 if (s->overlap == 1)1215 if (s->overlap == 1)
1204 s->overlap = overlap;1216 s->overlap = overlap;
1205 1217
1206 for (i = 0; i < s->win_size; i++)1218 for (int i = 0; i < s->win_size; i++)
1207 s->window_func_lut[i] = sqrtf(s->window_func_lut[i] / s->win_size);1219 s->window_func_lut[i] = sqrtf(s->window_func_lut[i] / s->win_size);
1208 s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));1220 s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));
1209 1221
@@ -1354,6 +1366,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 144 unmodified lines
1354 AudioSurroundContext *s = ctx->priv;1366 AudioSurroundContext *s = ctx->priv;
1355 1367
1356 av_frame_free(&s->factors);1368 av_frame_free(&s->factors);
1369 av_frame_free(&s->sfactors);
1357 av_frame_free(&s->window);1370 av_frame_free(&s->window);
1358 av_frame_free(&s->input_in);1371 av_frame_free(&s->input_in);
1359 av_frame_free(&s->input);1372 av_frame_free(&s->input);
@@ -1417,6 +1430,7 @@ static const AVOption surround_options[] = { · 57 unmodified lines
1417 { "lfe_mode", "set LFE channel mode", OFFSET(lfe_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },1430 { "lfe_mode", "set LFE channel mode", OFFSET(lfe_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },
1418 { "add", "just add LFE channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },1431 { "add", "just add LFE channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },
1419 { "sub", "substract LFE channel with others", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 1, TFLAGS, "lfe_mode" },1432 { "sub", "substract LFE channel with others", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 1, TFLAGS, "lfe_mode" },
1433 { "smooth", "set temporal smoothness strength", OFFSET(smooth), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, TFLAGS },
1420 { "angle", "set soundfield transform angle", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl=90}, 0, 360, TFLAGS },1434 { "angle", "set soundfield transform angle", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl=90}, 0, 360, TFLAGS },
1421 { "focus", "set soundfield transform focus", OFFSET(focus), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS },1435 { "focus", "set soundfield transform focus", OFFSET(focus), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS },
1422 { "fc_in", "set front center channel input level", OFFSET(f_i[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },1436 { "fc_in", "set front center channel input level", OFFSET(f_i[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t