Unified · Split
| @@ -92,11 +92,6 @@ typedef struct DeNoiseChannel { · 91 unmodified lines | ||
| 92 | 92 | double noise_band_avi[NB_PROFILE_BANDS]; |
| 93 | 93 | double noise_band_var[NB_PROFILE_BANDS]; |
| 94 | 94 | |
| 95 | − double sfm_threshold; | |
| 96 | − double sfm_alpha; | |
| 97 | − double sfm_results[3]; | |
| 98 | − int sfm_fail_flags[SFM_FLAGS_SIZE]; | |
| 99 | − int sfm_fail_total; | |
| 100 | 95 | double noise_reduction; |
| 101 | 96 | double last_noise_reduction; |
| 102 | 97 | double noise_floor; |
| @@ -155,7 +150,6 @@ typedef struct AudioFFTDeNoiseContext { · 52 unmodified lines | ||
| 155 | 150 | double window_weight; |
| 156 | 151 | double floor; |
| 157 | 152 | double sample_floor; |
| 158 | − double auto_floor; | |
| 159 | 153 | |
| 160 | 154 | int noise_band_edge[NB_PROFILE_BANDS + 2]; |
| 161 | 155 | int noise_band_count; |
| @@ -301,42 +295,6 @@ static double process_get_band_noise(AudioFFTDeNoiseContext *s, · 139 unmodified lines | ||
| 301 | 295 | return sum; |
| 302 | 296 | } |
| 303 | 297 | |
| 304 | −static void calculate_sfm(AudioFFTDeNoiseContext *s, | |
| 305 | − DeNoiseChannel *dnch, | |
| 306 | − int start, int end) | |
| 307 | −{ | |
| 308 | − double d1 = 0.0, d2 = 1.0; | |
| 309 | − int i = 0, j = 0; | |
| 310 | − | |
| 311 | − for (int k = start; k < end; k++) { | |
| 312 | − if (dnch->noisy_data[k] > s->sample_floor) { | |
| 313 | − j++; | |
| 314 | − d1 += dnch->noisy_data[k]; | |
| 315 | − d2 *= dnch->noisy_data[k]; | |
| 316 | − if (d2 > 1.0E100) { | |
| 317 | − d2 *= 1.0E-100; | |
| 318 | − i++; | |
| 319 | − } else if (d2 < 1.0E-100) { | |
| 320 | − d2 *= 1.0E100; | |
| 321 | − i--; | |
| 322 | − } | |
| 323 | − } | |
| 324 | − } | |
| 325 | − if (j > 1) { | |
| 326 | − d1 /= j; | |
| 327 | − dnch->sfm_results[0] = d1; | |
| 328 | − d2 = log(d2) + 230.2585 * i; | |
| 329 | − d2 /= j; | |
| 330 | − d1 = log(d1); | |
| 331 | − dnch->sfm_results[1] = d1; | |
| 332 | − dnch->sfm_results[2] = d1 - d2; | |
| 333 | − } else { | |
| 334 | − dnch->sfm_results[0] = s->auto_floor; | |
| 335 | − dnch->sfm_results[1] = dnch->sfm_threshold; | |
| 336 | − dnch->sfm_results[2] = dnch->sfm_threshold; | |
| 337 | − } | |
| 338 | −} | |
| 339 | − | |
| 340 | 298 | static double limit_gain(double a, double b) |
| 341 | 299 | { |
| 342 | 300 | if (a > 1.0) |
| @@ -346,116 +304,88 @@ static double limit_gain(double a, double b) · 3 unmodified lines | ||
| 346 | 304 | return 1.0; |
| 347 | 305 | } |
| 348 | 306 | |
| 307 | +static void spectral_flatness(AudioFFTDeNoiseContext *s, const double *const spectral, | |
| 308 | + double floor, int len, double *rnum, double *rden) | |
| 309 | +{ | |
| 310 | + double num = 0., den = 0.; | |
| 311 | + int size = 0; | |
| 312 | + | |
| 313 | + for (int n = 0; n < len; n++) { | |
| 314 | + const double v = spectral[n]; | |
| 315 | + if (v > floor) { | |
| 316 | + num += log(v); | |
| 317 | + den += v; | |
| 318 | + size++; | |
| 319 | + } | |
| 320 | + } | |
| 321 | + | |
| 322 | + size = FFMAX(size, 1); | |
| 323 | + | |
| 324 | + num /= size; | |
| 325 | + den /= size; | |
| 326 | + | |
| 327 | + num = exp(num); | |
| 328 | + | |
| 329 | + *rnum = num; | |
| 330 | + *rden = den; | |
| 331 | +} | |
| 332 | + | |
| 333 | +static void set_parameters(AudioFFTDeNoiseContext *s, DeNoiseChannel *dnch, int update_var, int update_auto_var); | |
| 334 | + | |
| 335 | +static double floor_offset(const double *S, int size, double mean) | |
| 336 | +{ | |
| 337 | + double offset = 0.0; | |
| 338 | + | |
| 339 | + for (int n = 0; n < size; n++) { | |
| 340 | + const double p = S[n] - mean; | |
| 341 | + | |
| 342 | + offset = fmax(offset, fabs(p)); | |
| 343 | + } | |
| 344 | + | |
| 345 | + return offset / mean; | |
| 346 | +} | |
| 347 | + | |
| 349 | 348 | static void process_frame(AVFilterContext *ctx, |
| 350 | 349 | AudioFFTDeNoiseContext *s, DeNoiseChannel *dnch, |
| 351 | 350 | AVComplexFloat *fft_data, |
| 352 | 351 | double *prior, double *prior_band_excit, int track_noise) |
| 353 | 352 | { |
| 354 | 353 | AVFilterLink *outlink = ctx->outputs[0]; |
| 355 | − const double sample_floor = s->sample_floor; | |
| 356 | 354 | const double *abs_var = dnch->abs_var; |
| 357 | 355 | const double ratio = outlink->frame_count_out ? s->ratio : 1.0; |
| 358 | 356 | const double rratio = 1. - ratio; |
| 359 | 357 | const int *bin2band = s->bin2band; |
| 358 | + double *noisy_data = dnch->noisy_data; | |
| 360 | 359 | double *band_excit = dnch->band_excit; |
| 361 | 360 | double *band_amt = dnch->band_amt; |
| 362 | 361 | double *gain = dnch->gain; |
| 363 | − int n = 0, i1; | |
| 364 | − | |
| 365 | − for (int i = 0; i < s->fft_length2; i++) { | |
| 366 | − double sqr_new_gain, new_gain, mag, mag_abs_var, new_mag_abs_var; | |
| 367 | 362 | |
| 368 | − mag = fft_data[i].re * fft_data[i].re + fft_data[i].im * fft_data[i].im; | |
| 369 | − if (mag > sample_floor) | |
| 370 | − n = i; | |
| 363 | + for (int i = 0; i < s->bin_count; i++) { | |
| 364 | + double sqr_new_gain, new_gain, power, mag, mag_abs_var, new_mag_abs_var; | |
| 371 | 365 | |
| 372 | − dnch->noisy_data[i] = mag; | |
| 373 | − mag_abs_var = mag / abs_var[i]; | |
| 366 | + noisy_data[i] = mag = hypot(fft_data[i].re, fft_data[i].im); | |
| 367 | + power = mag * mag; | |
| 368 | + mag_abs_var = power / abs_var[i]; | |
| 374 | 369 | new_mag_abs_var = ratio * prior[i] + rratio * fmax(mag_abs_var - 1.0, 0.0); |
| 375 | 370 | new_gain = new_mag_abs_var / (1.0 + new_mag_abs_var); |
| 376 | 371 | sqr_new_gain = new_gain * new_gain; |
| 377 | 372 | prior[i] = mag_abs_var * sqr_new_gain; |
| 378 | − dnch->clean_data[i] = mag * sqr_new_gain; | |
| 373 | + dnch->clean_data[i] = power * sqr_new_gain; | |
| 379 | 374 | gain[i] = new_gain; |
| 380 | 375 | } |
| 381 | 376 | |
| 382 | − if (n > s->fft_length2 - 2) { | |
| 383 | − n = s->bin_count; | |
| 384 | − i1 = s->noise_band_count; | |
| 385 | − } else { | |
| 386 | − i1 = 0; | |
| 387 | − for (int i = 0; i <= s->noise_band_count; i++) { | |
| 388 | − if (n > 1.1 * s->noise_band_edge[i]) { | |
| 389 | − i1 = i; | |
| 390 | − } | |
| 391 | − } | |
| 392 | − } | |
| 393 | − | |
| 394 | − if (track_noise && (i1 > s->noise_band_count / 2)) { | |
| 395 | − int j = FFMIN(n, s->noise_band_edge[i1]); | |
| 396 | − int m = 3, k; | |
| 397 | − | |
| 398 | − for (k = i1 - 1; k >= 0; k--) { | |
| 399 | − int i = s->noise_band_edge[k]; | |
| 400 | − calculate_sfm(s, dnch, i, j); | |
| 401 | − dnch->noise_band_sample[k] = dnch->sfm_results[0]; | |
| 402 | − if (dnch->sfm_results[2] + 0.013 * m * fmax(0.0, dnch->sfm_results[1] - 20.53) >= dnch->sfm_threshold) { | |
| 403 | − break; | |
| 404 | − } | |
| 405 | − j = i; | |
| 406 | − m++; | |
| 407 | − } | |
| 408 | − | |
| 409 | − if (k < i1 - 1) { | |
| 410 | − double sum = 0.0, min, max; | |
| 411 | − int i; | |
| 412 | − | |
| 413 | − for (i = i1 - 1; i > k; i--) { | |
| 414 | − min = log(dnch->noise_band_sample[i] / dnch->noise_band_auto_var[i]); | |
| 415 | − sum += min; | |
| 416 | − } | |
| 377 | + if (track_noise) { | |
| 378 | + double flatness, num, den; | |
| 417 | 379 | |
| 418 | − i = i1 - k - 1; | |
| 419 | − if (i < 5) { | |
| 420 | − min = 3.0E-4 * i * i; | |
| 421 | − } else { | |
| 422 | − min = 3.0E-4 * (8 * i - 16); | |
| 423 | − } | |
| 424 | − if (i < 3) { | |
| 425 | − max = 2.0E-4 * i * i; | |
| 426 | − } else { | |
| 427 | − max = 2.0E-4 * (4 * i - 4); | |
| 428 | − } | |
| 380 | + spectral_flatness(s, noisy_data, s->floor, s->bin_count, &num, &den); | |
| 429 | 381 | |
| 430 | − if (s->track_residual) { | |
| 431 | − if (dnch->last_noise_floor > dnch->last_residual_floor + 9) { | |
| 432 | − min *= 0.5; | |
| 433 | − max *= 0.75; | |
| 434 | − } else if (dnch->last_noise_floor > dnch->last_residual_floor + 6) { | |
| 435 | − min *= 0.4; | |
| 436 | − max *= 1.0; | |
| 437 | − } else if (dnch->last_noise_floor > dnch->last_residual_floor + 4) { | |
| 438 | − min *= 0.3; | |
| 439 | − max *= 1.3; | |
| 440 | − } else if (dnch->last_noise_floor > dnch->last_residual_floor + 2) { | |
| 441 | − min *= 0.2; | |
| 442 | − max *= 1.6; | |
| 443 | − } else if (dnch->last_noise_floor > dnch->last_residual_floor) { | |
| 444 | − min *= 0.1; | |
| 445 | − max *= 2.0; | |
| 446 | − } else { | |
| 447 | − min = 0.0; | |
| 448 | − max *= 2.5; | |
| 449 | − } | |
| 450 | − } | |
| 382 | + flatness = num / den; | |
| 383 | + if (flatness > 0.8) { | |
| 384 | + const double offset = floor_offset(noisy_data, s->bin_count, den); | |
| 385 | + const double new_floor = av_clipd(10.0 * log10(den) - 100.0 + offset, -90., -20.); | |
| 451 | 386 | |
| 452 | − sum = av_clipd(sum, -min, max); | |
| 453 | − sum = exp(sum); | |
| 454 | − for (int i = 0; i < NB_PROFILE_BANDS; i++) | |
| 455 | − dnch->noise_band_auto_var[i] *= sum; | |
| 456 | − } else if (dnch->sfm_results[2] >= dnch->sfm_threshold) { | |
| 457 | − dnch->sfm_fail_flags[s->block_count & SFM_FLAGS_MASK] = 1; | |
| 458 | − dnch->sfm_fail_total += 1; | |
| 387 | + dnch->noise_floor = 0.1 * new_floor + dnch->noise_floor * 0.9; | |
| 388 | + set_parameters(s, dnch, 1, 0); | |
| 459 | 389 | } |
| 460 | 390 | } |
| 461 | 391 | |
| @@ -495,7 +425,7 @@ static void process_frame(AVFilterContext *ctx, · 33 unmodified lines | ||
| 495 | 425 | } |
| 496 | 426 | } |
| 497 | 427 | |
| 498 | − for (int i = 0; i < s->fft_length2; i++) { | |
| 428 | + for (int i = 0; i < s->bin_count; i++) { | |
| 499 | 429 | const double new_gain = gain[i]; |
| 500 | 430 | |
| 501 | 431 | fft_data[i].re *= new_gain; |
| @@ -556,7 +486,6 @@ static void set_band_parameters(AudioFFTDeNoiseContext *s, · 54 unmodified lines | ||
| 556 | 486 | d4 = (m - i) / d2; |
| 557 | 487 | dnch->rel_var[m] = exp((d5 * d3 + band_noise * d4) * C); |
| 558 | 488 | } |
| 559 | − dnch->rel_var[s->fft_length2] = exp(band_noise * C); | |
| 560 | 489 | |
| 561 | 490 | for (i = 0; i < NB_PROFILE_BANDS; i++) |
| 562 | 491 | dnch->noise_band_auto_var[i] = dnch->max_var * exp((process_get_band_noise(s, dnch, i) - 2.0) * C); |
| @@ -667,7 +596,7 @@ static int config_input(AVFilterLink *inlink) · 104 unmodified lines | ||
| 667 | 596 | s->fft_length2 = 1 << (32 - ff_clz(s->window_length)); |
| 668 | 597 | s->fft_length = s->fft_length2; |
| 669 | 598 | s->buffer_length = s->fft_length * 2; |
| 670 | − s->bin_count = s->fft_length2 + 1; | |
| 599 | + s->bin_count = s->fft_length2 / 2 + 1; | |
| 671 | 600 | |
| 672 | 601 | s->band_centre[0] = 80; |
| 673 | 602 | for (i = 1; i < NB_PROFILE_BANDS; i++) { |
| @@ -712,7 +641,7 @@ static int config_input(AVFilterLink *inlink) · 38 unmodified lines | ||
| 712 | 641 | for (i = 0; i < s->bin_count; i++) |
| 713 | 642 | s->bin2band[i] = lrint(sdiv * freq2bark((0.5 * i * s->sample_rate) / s->fft_length2)); |
| 714 | 643 | |
| 715 | − s->number_of_bands = s->bin2band[s->fft_length2] + 1; | |
| 644 | + s->number_of_bands = s->bin2band[s->bin_count - 1] + 1; | |
| 716 | 645 | |
| 717 | 646 | s->band_alpha = av_calloc(s->number_of_bands, sizeof(*s->band_alpha)); |
| 718 | 647 | s->band_beta = av_calloc(s->number_of_bands, sizeof(*s->band_beta)); |
| @@ -745,19 +674,6 @@ static int config_input(AVFilterLink *inlink) · 26 unmodified lines | ||
| 745 | 674 | |
| 746 | 675 | reduce_mean(dnch->band_noise); |
| 747 | 676 | |
| 748 | − dnch->sfm_threshold = 0.8; | |
| 749 | − dnch->sfm_alpha = 0.05; | |
| 750 | − for (i = 0; i < SFM_FLAGS_SIZE; i++) | |
| 751 | − dnch->sfm_fail_flags[i] = 0; | |
| 752 | − | |
| 753 | − dnch->sfm_fail_total = 0; | |
| 754 | − j = FFMAX((int)(10.0 * (1.3 - dnch->sfm_threshold)), 1); | |
| 755 | − | |
| 756 | − for (i = 0; i < SFM_FLAGS_SIZE; i += j) { | |
| 757 | − dnch->sfm_fail_flags[i] = 1; | |
| 758 | − dnch->sfm_fail_total += 1; | |
| 759 | − } | |
| 760 | − | |
| 761 | 677 | dnch->amt = av_calloc(s->bin_count, sizeof(*dnch->amt)); |
| 762 | 678 | dnch->band_amt = av_calloc(s->number_of_bands, sizeof(*dnch->band_amt)); |
| 763 | 679 | dnch->band_excit = av_calloc(s->number_of_bands, sizeof(*dnch->band_excit)); |
| @@ -884,7 +800,6 @@ static int config_input(AVFilterLink *inlink) · 120 unmodified lines | ||
| 884 | 800 | s->window_weight = 0.5 * sum; |
| 885 | 801 | s->floor = (1LL << 48) * exp(-23.025558369790467) * s->window_weight; |
| 886 | 802 | s->sample_floor = s->floor * exp(4.144600506562284); |
| 887 | − s->auto_floor = s->floor * exp(6.907667510937141); | |
| 888 | 803 | |
| 889 | 804 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { |
| 890 | 805 | DeNoiseChannel *dnch = &s->dnch[ch]; |
| @@ -965,7 +880,6 @@ static void sample_noise_block(AudioFFTDeNoiseContext *s, · 74 unmodified lines | ||
| 965 | 880 | |
| 966 | 881 | mag2 = fmax(mag2, s->sample_floor); |
| 967 | 882 | |
| 968 | − dnch->noisy_data[i] = mag2; | |
| 969 | 883 | var += mag2; |
| 970 | 884 | n++; |
| 971 | 885 | } |
| @@ -1034,7 +948,7 @@ static void set_noise_profile(AudioFFTDeNoiseContext *s, · 62 unmodified lines | ||
| 1034 | 948 | for (int m = 0; m < NB_PROFILE_BANDS; m++) |
| 1035 | 949 | temp[m] -= d1; |
| 1036 | 950 | |
| 1037 | − new_noise_floor = round(d1) + 2.5; | |
| 951 | + new_noise_floor = d1; | |
| 1038 | 952 | |
| 1039 | 953 | if (new_profile) { |
| 1040 | 954 | av_log(s, AV_LOG_INFO, "bn="); |
| @@ -1066,16 +980,6 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 25 unmodified lines | ||
| 1066 | 980 | double *dst = dnch->out_samples; |
| 1067 | 981 | float *fft_in = dnch->fft_in; |
| 1068 | 982 | |
| 1069 | − if (s->track_noise) { | |
| 1070 | − int i = s->block_count & SFM_FLAGS_MASK; | |
| 1071 | − | |
| 1072 | − if (dnch->sfm_fail_flags[i]) | |
| 1073 | − dnch->sfm_fail_total--; | |
| 1074 | − dnch->sfm_fail_flags[i] = 0; | |
| 1075 | − dnch->sfm_threshold *= 1.0 - dnch->sfm_alpha; | |
| 1076 | − dnch->sfm_threshold += dnch->sfm_alpha * ((1.0 / SFM_FLAGS_SIZE) * dnch->sfm_fail_total); | |
| 1077 | − } | |
| 1078 | − | |
| 1079 | 983 | for (int m = 0; m < window_length; m++) |
| 1080 | 984 | fft_in[m] = window[m] * src[m] * (1LL << 23); |
| 1081 | 985 | |
| @@ -1098,25 +1002,6 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 16 unmodified lines | ||
| 1098 | 1002 | return 0; |
| 1099 | 1003 | } |
| 1100 | 1004 | |
| 1101 | −static void get_auto_noise_levels(AudioFFTDeNoiseContext *s, | |
| 1102 | − DeNoiseChannel *dnch, | |
| 1103 | − double *levels) | |
| 1104 | −{ | |
| 1105 | − if (s->noise_band_count > 0) { | |
| 1106 | − for (int i = 0; i < s->noise_band_count; i++) { | |
| 1107 | − levels[i] = 10.0 * log10(dnch->noise_band_auto_var[i] / s->floor) - 100.0; | |
| 1108 | − } | |
| 1109 | − if (s->noise_band_count < NB_PROFILE_BANDS) { | |
| 1110 | − for (int i = s->noise_band_count; i < NB_PROFILE_BANDS; i++) | |
| 1111 | − levels[i] = levels[i - 1]; | |
| 1112 | − } | |
| 1113 | − } else { | |
| 1114 | − for (int i = 0; i < NB_PROFILE_BANDS; i++) { | |
| 1115 | − levels[i] = -100.0; | |
| 1116 | − } | |
| 1117 | − } | |
| 1118 | −} | |
| 1119 | − | |
| 1120 | 1005 | static int output_frame(AVFilterLink *inlink, AVFrame *in) |
| 1121 | 1006 | { |
| 1122 | 1007 | AVFilterContext *ctx = inlink->dst; |
| @@ -1139,10 +1024,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) · 16 unmodified lines | ||
| 1139 | 1024 | |
| 1140 | 1025 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { |
| 1141 | 1026 | DeNoiseChannel *dnch = &s->dnch[ch]; |
| 1142 | − double levels[NB_PROFILE_BANDS]; | |
| 1143 | 1027 | |
| 1144 | − get_auto_noise_levels(s, dnch, levels); | |
| 1145 | − set_noise_profile(s, dnch, levels, 0); | |
| 1146 | 1028 | average += dnch->noise_floor; |
| 1147 | 1029 | max = fmax(max, dnch->noise_floor); |
| 1148 | 1030 | min = fmin(min, dnch->noise_floor); |