History

avfilter/af_afftdn: add double sample format support

Paul B Mahol committed 4 years ago

Commit 1f9f0dc1 parent 1af00511 file · +172 −50Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/af_afftdn.c+172−50
@@ -81,8 +81,8 @@ typedef struct DeNoiseChannel { · 80 unmodified lines
81 double *abs_var;81 double *abs_var;
82 double *rel_var;82 double *rel_var;
83 double *min_abs_var;83 double *min_abs_var;
84 float *fft_in;84 void *fft_in;
85 AVComplexFloat *fft_out;85 void *fft_out;
86 AVTXContext *fft, *ifft;86 AVTXContext *fft, *ifft;
87 av_tx_fn tx_fn, itx_fn;87 av_tx_fn tx_fn, itx_fn;
88 88
@@ -105,6 +105,9 @@ typedef struct DeNoiseChannel { · 16 unmodified lines
105typedef struct AudioFFTDeNoiseContext {105typedef struct AudioFFTDeNoiseContext {
106 const AVClass *class;106 const AVClass *class;
107 107
108 int format;
109 size_t sample_size;
110
108 float noise_reduction;111 float noise_reduction;
109 float noise_floor;112 float noise_floor;
110 int noise_type;113 int noise_type;
@@ -347,7 +350,6 @@ static double floor_offset(const double *S, int size, double mean) · 236 unmodified lines
347 350
348static void process_frame(AVFilterContext *ctx,351static void process_frame(AVFilterContext *ctx,
349 AudioFFTDeNoiseContext *s, DeNoiseChannel *dnch,352 AudioFFTDeNoiseContext *s, DeNoiseChannel *dnch,
350 AVComplexFloat *fft_data,
351 double *prior, double *prior_band_excit, int track_noise)353 double *prior, double *prior_band_excit, int track_noise)
352{354{
353 AVFilterLink *outlink = ctx->outputs[0];355 AVFilterLink *outlink = ctx->outputs[0];
@@ -359,12 +361,22 @@ static void process_frame(AVFilterContext *ctx, · 5 unmodified lines
359 double *band_excit = dnch->band_excit;361 double *band_excit = dnch->band_excit;
360 double *band_amt = dnch->band_amt;362 double *band_amt = dnch->band_amt;
361 double *smoothed_gain = dnch->smoothed_gain;363 double *smoothed_gain = dnch->smoothed_gain;
364 AVComplexDouble *fft_data_dbl = dnch->fft_out;
365 AVComplexFloat *fft_data_flt = dnch->fft_out;
362 double *gain = dnch->gain;366 double *gain = dnch->gain;
363 367
364 for (int i = 0; i < s->bin_count; i++) {368 for (int i = 0; i < s->bin_count; i++) {
365 double sqr_new_gain, new_gain, power, mag, mag_abs_var, new_mag_abs_var;369 double sqr_new_gain, new_gain, power, mag, mag_abs_var, new_mag_abs_var;
366 370
367 noisy_data[i] = mag = hypot(fft_data[i].re, fft_data[i].im);371 switch (s->format) {
372 case AV_SAMPLE_FMT_FLTP:
373 noisy_data[i] = mag = hypot(fft_data_flt[i].re, fft_data_flt[i].im);
374 break;
375 case AV_SAMPLE_FMT_DBLP:
376 noisy_data[i] = mag = hypot(fft_data_dbl[i].re, fft_data_dbl[i].im);
377 break;
378 }
379
368 power = mag * mag;380 power = mag * mag;
369 mag_abs_var = power / abs_var[i];381 mag_abs_var = power / abs_var[i];
370 new_mag_abs_var = ratio * prior[i] + rratio * fmax(mag_abs_var - 1.0, 0.0);382 new_mag_abs_var = ratio * prior[i] + rratio * fmax(mag_abs_var - 1.0, 0.0);
@@ -446,11 +458,23 @@ static void process_frame(AVFilterContext *ctx, · 75 unmodified lines
446 }458 }
447 }459 }
448 460
449 for (int i = 0; i < s->bin_count; i++) {461 switch (s->format) {
450 const double new_gain = smoothed_gain[i];462 case AV_SAMPLE_FMT_FLTP:
463 for (int i = 0; i < s->bin_count; i++) {
464 const float new_gain = smoothed_gain[i];
465
466 fft_data_flt[i].re *= new_gain;
467 fft_data_flt[i].im *= new_gain;
468 }
469 break;
470 case AV_SAMPLE_FMT_DBLP:
471 for (int i = 0; i < s->bin_count; i++) {
472 const double new_gain = smoothed_gain[i];
451 473
452 fft_data[i].re *= new_gain;474 fft_data_dbl[i].re *= new_gain;
453 fft_data[i].im *= new_gain;475 fft_data_dbl[i].im *= new_gain;
476 }
477 break;
454 }478 }
455}479}
456 480
@@ -603,8 +627,29 @@ static int config_input(AVFilterLink *inlink) · 146 unmodified lines
603{627{
604 AVFilterContext *ctx = inlink->dst;628 AVFilterContext *ctx = inlink->dst;
605 AudioFFTDeNoiseContext *s = ctx->priv;629 AudioFFTDeNoiseContext *s = ctx->priv;
630 size_t complex_sample_size;
606 double wscale, sar, sum, sdiv;631 double wscale, sar, sum, sdiv;
607 int i, j, k, m, n, ret;632 int i, j, k, m, n, ret, tx_type;
633 double dscale = 1.;
634 float fscale = 1.f;
635 void *scale;
636
637 s->format = inlink->format;
638
639 switch (s->format) {
640 case AV_SAMPLE_FMT_FLTP:
641 s->sample_size = sizeof(float);
642 complex_sample_size = sizeof(AVComplexFloat);
643 tx_type = AV_TX_FLOAT_RDFT;
644 scale = &fscale;
645 break;
646 case AV_SAMPLE_FMT_DBLP:
647 s->sample_size = sizeof(double);
648 complex_sample_size = sizeof(AVComplexDouble);
649 tx_type = AV_TX_DOUBLE_RDFT;
650 scale = &dscale;
651 break;
652 }
608 653
609 s->dnch = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->dnch));654 s->dnch = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->dnch));
610 if (!s->dnch)655 if (!s->dnch)
@@ -671,7 +716,6 @@ static int config_input(AVFilterLink *inlink) · 60 unmodified lines
671 716
672 for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {717 for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {
673 DeNoiseChannel *dnch = &s->dnch[ch];718 DeNoiseChannel *dnch = &s->dnch[ch];
674 float scale = 1.f;
675 719
676 switch (s->noise_type) {720 switch (s->noise_type) {
677 case WHITE_NOISE:721 case WHITE_NOISE:
@@ -708,12 +752,12 @@ static int config_input(AVFilterLink *inlink) · 30 unmodified lines
708 dnch->abs_var = av_calloc(s->bin_count, sizeof(*dnch->abs_var));752 dnch->abs_var = av_calloc(s->bin_count, sizeof(*dnch->abs_var));
709 dnch->rel_var = av_calloc(s->bin_count, sizeof(*dnch->rel_var));753 dnch->rel_var = av_calloc(s->bin_count, sizeof(*dnch->rel_var));
710 dnch->min_abs_var = av_calloc(s->bin_count, sizeof(*dnch->min_abs_var));754 dnch->min_abs_var = av_calloc(s->bin_count, sizeof(*dnch->min_abs_var));
711 dnch->fft_in = av_calloc(s->fft_length2, sizeof(*dnch->fft_in));755 dnch->fft_in = av_calloc(s->fft_length2, s->sample_size);
712 dnch->fft_out = av_calloc(s->fft_length2 + 1, sizeof(*dnch->fft_out));756 dnch->fft_out = av_calloc(s->fft_length2 + 1, complex_sample_size);
713 ret = av_tx_init(&dnch->fft, &dnch->tx_fn, AV_TX_FLOAT_RDFT, 0, s->fft_length2, &scale, 0);757 ret = av_tx_init(&dnch->fft, &dnch->tx_fn, tx_type, 0, s->fft_length2, scale, 0);
714 if (ret < 0)758 if (ret < 0)
715 return ret;759 return ret;
716 ret = av_tx_init(&dnch->ifft, &dnch->itx_fn, AV_TX_FLOAT_RDFT, 1, s->fft_length2, &scale, 0);760 ret = av_tx_init(&dnch->ifft, &dnch->itx_fn, tx_type, 1, s->fft_length2, scale, 0);
717 if (ret < 0)761 if (ret < 0)
718 return ret;762 return ret;
719 dnch->spread_function = av_calloc(s->number_of_bands * s->number_of_bands,763 dnch->spread_function = av_calloc(s->number_of_bands * s->number_of_bands,
@@ -861,17 +905,33 @@ static void sample_noise_block(AudioFFTDeNoiseContext *s, · 141 unmodified lines
861 DeNoiseChannel *dnch,905 DeNoiseChannel *dnch,
862 AVFrame *in, int ch)906 AVFrame *in, int ch)
863{907{
864 float *src = (float *)in->extended_data[ch];908 double *src_dbl = (double *)in->extended_data[ch];
909 float *src_flt = (float *)in->extended_data[ch];
865 double mag2, var = 0.0, avr = 0.0, avi = 0.0;910 double mag2, var = 0.0, avr = 0.0, avi = 0.0;
911 AVComplexDouble *fft_out_dbl = dnch->fft_out;
912 AVComplexFloat *fft_out_flt = dnch->fft_out;
913 double *fft_in_dbl = dnch->fft_in;
914 float *fft_in_flt = dnch->fft_in;
866 int edge, j, k, n, edgemax;915 int edge, j, k, n, edgemax;
867 916
868 for (int i = 0; i < s->window_length; i++)917 switch (s->format) {
869 dnch->fft_in[i] = s->window[i] * src[i] * (1LL << 23);918 case AV_SAMPLE_FMT_FLTP:
870 919 for (int i = 0; i < s->window_length; i++)
871 for (int i = s->window_length; i < s->fft_length2; i++)920 fft_in_flt[i] = s->window[i] * src_flt[i] * (1LL << 23);
872 dnch->fft_in[i] = 0.0;921
922 for (int i = s->window_length; i < s->fft_length2; i++)
923 fft_in_flt[i] = 0.f;
924 break;
925 case AV_SAMPLE_FMT_DBLP:
926 for (int i = 0; i < s->window_length; i++)
927 fft_in_dbl[i] = s->window[i] * src_dbl[i] * (1LL << 23);
928
929 for (int i = s->window_length; i < s->fft_length2; i++)
930 fft_in_dbl[i] = 0.;
931 break;
932 }
873 933
874 dnch->tx_fn(dnch->fft, dnch->fft_out, dnch->fft_in, sizeof(float));934 dnch->tx_fn(dnch->fft, dnch->fft_out, dnch->fft_in, sizeof(s->sample_size));
875 935
876 edge = s->noise_band_edge[0];936 edge = s->noise_band_edge[0];
877 j = edge;937 j = edge;
@@ -896,10 +956,21 @@ static void sample_noise_block(AudioFFTDeNoiseContext *s, · 18 unmodified lines
896 avr = 0.0;956 avr = 0.0;
897 avi = 0.0;957 avi = 0.0;
898 }958 }
899 avr += dnch->fft_out[n].re;959
900 avi += dnch->fft_out[n].im;960 switch (s->format) {
901 mag2 = dnch->fft_out[n].re * dnch->fft_out[n].re +961 case AV_SAMPLE_FMT_FLTP:
902 dnch->fft_out[n].im * dnch->fft_out[n].im;962 avr += fft_out_flt[n].re;
963 avi += fft_out_flt[n].im;
964 mag2 = fft_out_flt[n].re * fft_out_flt[n].re +
965 fft_out_flt[n].im * fft_out_flt[n].im;
966 break;
967 case AV_SAMPLE_FMT_DBLP:
968 avr += fft_out_dbl[n].re;
969 avi += fft_out_dbl[n].im;
970 mag2 = fft_out_dbl[n].re * fft_out_dbl[n].re +
971 fft_out_dbl[n].im * fft_out_dbl[n].im;
972 break;
973 }
903 974
904 mag2 = fmax(mag2, s->sample_floor);975 mag2 = fmax(mag2, s->sample_floor);
905 976
@@ -980,27 +1051,48 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 74 unmodified lines
980 1051
981 for (int ch = start; ch < end; ch++) {1052 for (int ch = start; ch < end; ch++) {
982 DeNoiseChannel *dnch = &s->dnch[ch];1053 DeNoiseChannel *dnch = &s->dnch[ch];
983 const float *src = (const float *)in->extended_data[ch];1054 const double *src_dbl = (const double *)in->extended_data[ch];
1055 const float *src_flt = (const float *)in->extended_data[ch];
984 double *dst = dnch->out_samples;1056 double *dst = dnch->out_samples;
985 float *fft_in = dnch->fft_in;1057 double *fft_in_dbl = dnch->fft_in;
1058 float *fft_in_flt = dnch->fft_in;
986 1059
987 for (int m = 0; m < window_length; m++)1060 switch (s->format) {
988 fft_in[m] = window[m] * src[m] * (1LL << 23);1061 case AV_SAMPLE_FMT_FLTP:
1062 for (int m = 0; m < window_length; m++)
1063 fft_in_flt[m] = window[m] * src_flt[m] * (1LL << 23);
989 1064
990 for (int m = window_length; m < s->fft_length2; m++)1065 for (int m = window_length; m < s->fft_length2; m++)
991 fft_in[m] = 0;1066 fft_in_flt[m] = 0.f;
1067 break;
1068 case AV_SAMPLE_FMT_DBLP:
1069 for (int m = 0; m < window_length; m++)
1070 fft_in_dbl[m] = window[m] * src_dbl[m] * (1LL << 23);
992 1071
993 dnch->tx_fn(dnch->fft, dnch->fft_out, fft_in, sizeof(float));1072 for (int m = window_length; m < s->fft_length2; m++)
1073 fft_in_dbl[m] = 0.;
1074 break;
1075 }
994 1076
995 process_frame(ctx, s, dnch, dnch->fft_out,1077 dnch->tx_fn(dnch->fft, dnch->fft_out, dnch->fft_in, sizeof(s->sample_size));
1078
1079 process_frame(ctx, s, dnch,
996 dnch->prior,1080 dnch->prior,
997 dnch->prior_band_excit,1081 dnch->prior_band_excit,
998 s->track_noise);1082 s->track_noise);
999 1083
1000 dnch->itx_fn(dnch->ifft, fft_in, dnch->fft_out, sizeof(float));1084 dnch->itx_fn(dnch->ifft, dnch->fft_in, dnch->fft_out, sizeof(s->sample_size));
1001 1085
1002 for (int m = 0; m < window_length; m++)1086 switch (s->format) {
1003 dst[m] += s->window[m] * fft_in[m] / (1LL << 23);1087 case AV_SAMPLE_FMT_FLTP:
1088 for (int m = 0; m < window_length; m++)
1089 dst[m] += s->window[m] * fft_in_flt[m] / (1LL << 23);
1090 break;
1091 case AV_SAMPLE_FMT_DBLP:
1092 for (int m = 0; m < window_length; m++)
1093 dst[m] += s->window[m] * fft_in_dbl[m] / (1LL << 23);
1094 break;
1095 }
1004 }1096 }
1005 1097
1006 return 0;1098 return 0;
@@ -1016,11 +1108,14 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) · 9 unmodified lines
1016 AVFrame *out;1108 AVFrame *out;
1017 1109
1018 for (int ch = 0; ch < s->channels; ch++) {1110 for (int ch = 0; ch < s->channels; ch++) {
1019 float *src = (float *)s->winframe->extended_data[ch];1111 uint8_t *src = (uint8_t *)s->winframe->extended_data[ch];
1020 1112
1021 memmove(src, &src[s->sample_advance], offset * sizeof(float));1113 memmove(src, src + s->sample_advance * s->sample_size,
1022 memcpy(&src[offset], in->extended_data[ch], in->nb_samples * sizeof(float));1114 offset * s->sample_size);
1023 memset(&src[offset + in->nb_samples], 0, (s->sample_advance - in->nb_samples) * sizeof(float));1115 memcpy(src + offset * s->sample_size, in->extended_data[ch],
1116 in->nb_samples * s->sample_size);
1117 memset(src + s->sample_size * (offset + in->nb_samples), 0,
1118 (s->sample_advance - in->nb_samples) * s->sample_size);
1024 }1119 }
1025 1120
1026 if (s->track_noise) {1121 if (s->track_noise) {
@@ -1107,21 +1202,47 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) · 80 unmodified lines
1107 for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {1202 for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {
1108 DeNoiseChannel *dnch = &s->dnch[ch];1203 DeNoiseChannel *dnch = &s->dnch[ch];
1109 double *src = dnch->out_samples;1204 double *src = dnch->out_samples;
1110 const float *orig = (const float *)s->winframe->extended_data[ch];1205 const double *orig_dbl = (const double *)s->winframe->extended_data[ch];
1111 float *dst = (float *)out->extended_data[ch];1206 const float *orig_flt = (const float *)s->winframe->extended_data[ch];
1207 double *dst_dbl = (double *)out->extended_data[ch];
1208 float *dst_flt = (float *)out->extended_data[ch];
1112 1209
1113 switch (output_mode) {1210 switch (output_mode) {
1114 case IN_MODE:1211 case IN_MODE:
1115 for (int m = 0; m < out->nb_samples; m++)1212 switch (s->format) {
1116 dst[m] = orig[m];1213 case AV_SAMPLE_FMT_FLTP:
1214 for (int m = 0; m < out->nb_samples; m++)
1215 dst_flt[m] = orig_flt[m];
1216 break;
1217 case AV_SAMPLE_FMT_DBLP:
1218 for (int m = 0; m < out->nb_samples; m++)
1219 dst_dbl[m] = orig_dbl[m];
1220 break;
1221 }
1117 break;1222 break;
1118 case OUT_MODE:1223 case OUT_MODE:
1119 for (int m = 0; m < out->nb_samples; m++)1224 switch (s->format) {
1120 dst[m] = src[m];1225 case AV_SAMPLE_FMT_FLTP:
1226 for (int m = 0; m < out->nb_samples; m++)
1227 dst_flt[m] = src[m];
1228 break;
1229 case AV_SAMPLE_FMT_DBLP:
1230 for (int m = 0; m < out->nb_samples; m++)
1231 dst_dbl[m] = src[m];
1232 break;
1233 }
1121 break;1234 break;
1122 case NOISE_MODE:1235 case NOISE_MODE:
1123 for (int m = 0; m < out->nb_samples; m++)1236 switch (s->format) {
1124 dst[m] = orig[m] - src[m];1237 case AV_SAMPLE_FMT_FLTP:
1238 for (int m = 0; m < out->nb_samples; m++)
1239 dst_flt[m] = orig_flt[m] - src[m];
1240 break;
1241 case AV_SAMPLE_FMT_DBLP:
1242 for (int m = 0; m < out->nb_samples; m++)
1243 dst_dbl[m] = orig_dbl[m] - src[m];
1244 break;
1245 }
1125 break;1246 break;
1126 default:1247 default:
1127 if (in != out)1248 if (in != out)
@@ -1129,6 +1250,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) · 1 unmodified line
1129 av_frame_free(&out);1250 av_frame_free(&out);
1130 return AVERROR_BUG;1251 return AVERROR_BUG;
1131 }1252 }
1253
1132 memmove(src, src + s->sample_advance, (s->window_length - s->sample_advance) * sizeof(*src));1254 memmove(src, src + s->sample_advance, (s->window_length - s->sample_advance) * sizeof(*src));
1133 memset(src + (s->window_length - s->sample_advance), 0, s->sample_advance * sizeof(*src));1255 memset(src + (s->window_length - s->sample_advance), 0, s->sample_advance * sizeof(*src));
1134 }1256 }
@@ -1251,7 +1373,7 @@ const AVFilter ff_af_afftdn = { · 116 unmodified lines
1251 .uninit = uninit,1373 .uninit = uninit,
1252 FILTER_INPUTS(inputs),1374 FILTER_INPUTS(inputs),
1253 FILTER_OUTPUTS(outputs),1375 FILTER_OUTPUTS(outputs),
1254 FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_FLTP),1376 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP),
1255 .process_command = process_command,1377 .process_command = process_command,
1256 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |1378 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
1257 AVFILTER_FLAG_SLICE_THREADS,1379 AVFILTER_FLAG_SLICE_THREADS,

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