FFmpeg
Loading...
Searching...
No Matches
af_arnndn.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Gregor Richards
3 * Copyright (c) 2017 Mozilla
4 * Copyright (c) 2005-2009 Xiph.Org Foundation
5 * Copyright (c) 2007-2008 CSIRO
6 * Copyright (c) 2008-2011 Octasic Inc.
7 * Copyright (c) Jean-Marc Valin
8 * Copyright (c) 2019 Paul B Mahol
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * - Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "libavutil/avassert.h"
35#include "libavutil/file_open.h"
36#include "libavutil/float_dsp.h"
37#include "libavutil/mem.h"
39#include "libavutil/opt.h"
40#include "libavutil/tx.h"
41#include "avfilter.h"
42#include "audio.h"
43#include "filters.h"
44#include "formats.h"
45
46#define FRAME_SIZE_SHIFT 2
47#define FRAME_SIZE (120<<FRAME_SIZE_SHIFT)
48#define WINDOW_SIZE (2*FRAME_SIZE)
49#define FREQ_SIZE (FRAME_SIZE + 1)
50
51#define PITCH_MIN_PERIOD 60
52#define PITCH_MAX_PERIOD 768
53#define PITCH_FRAME_SIZE 960
54#define PITCH_BUF_SIZE (PITCH_MAX_PERIOD+PITCH_FRAME_SIZE)
55
56#define SQUARE(x) ((x)*(x))
57
58#define NB_BANDS 22
59
60#define CEPS_MEM 8
61#define NB_DELTA_CEPS 6
62
63#define NB_FEATURES (NB_BANDS+3*NB_DELTA_CEPS+2)
64
65#define WEIGHTS_SCALE (1.f/256)
66
67#define MAX_NEURONS 128
68
69#define ACTIVATION_TANH 0
70#define ACTIVATION_SIGMOID 1
71#define ACTIVATION_RELU 2
72
73#define Q15ONE 1.0f
74
75typedef struct DenseLayer {
76 const float *bias;
77 const float *input_weights;
82
83typedef struct GRULayer {
84 const float *bias;
85 const float *input_weights;
86 const float *recurrent_weights;
90} GRULayer;
91
111
118
135
152
153#define F_ACTIVATION_TANH 0
154#define F_ACTIVATION_SIGMOID 1
155#define F_ACTIVATION_RELU 2
156
157static void rnnoise_model_free(RNNModel *model)
158{
159#define FREE_MAYBE(ptr) do { if (ptr) free(ptr); } while (0)
160#define FREE_DENSE(name) do { \
161 if (model->name) { \
162 av_free((void *) model->name->input_weights); \
163 av_free((void *) model->name->bias); \
164 av_free((void *) model->name); \
165 } \
166 } while (0)
167#define FREE_GRU(name) do { \
168 if (model->name) { \
169 av_free((void *) model->name->input_weights); \
170 av_free((void *) model->name->recurrent_weights); \
171 av_free((void *) model->name->bias); \
172 av_free((void *) model->name); \
173 } \
174 } while (0)
175
176 if (!model)
177 return;
178 FREE_DENSE(input_dense);
179 FREE_GRU(vad_gru);
180 FREE_GRU(noise_gru);
181 FREE_GRU(denoise_gru);
182 FREE_DENSE(denoise_output);
183 FREE_DENSE(vad_output);
184 av_free(model);
185}
186
187static int rnnoise_model_from_file(FILE *f, RNNModel **rnn)
188{
189 RNNModel *ret = NULL;
190 DenseLayer *input_dense;
191 GRULayer *vad_gru;
192 GRULayer *noise_gru;
193 GRULayer *denoise_gru;
194 DenseLayer *denoise_output;
195 DenseLayer *vad_output;
196 int in;
197
198 if (fscanf(f, "rnnoise-nu model file version %d\n", &in) != 1 || in != 1)
199 return AVERROR_INVALIDDATA;
200
201 ret = av_calloc(1, sizeof(RNNModel));
202 if (!ret)
203 return AVERROR(ENOMEM);
204
205#define ALLOC_LAYER(type, name) \
206 name = av_calloc(1, sizeof(type)); \
207 if (!name) { \
208 rnnoise_model_free(ret); \
209 return AVERROR(ENOMEM); \
210 } \
211 ret->name = name
212
213 ALLOC_LAYER(DenseLayer, input_dense);
214 ALLOC_LAYER(GRULayer, vad_gru);
215 ALLOC_LAYER(GRULayer, noise_gru);
216 ALLOC_LAYER(GRULayer, denoise_gru);
217 ALLOC_LAYER(DenseLayer, denoise_output);
218 ALLOC_LAYER(DenseLayer, vad_output);
219
220#define INPUT_VAL(name, min) do { \
221 if (fscanf(f, "%d", &in) != 1 || in < (min) || in > 128) { \
222 rnnoise_model_free(ret); \
223 return AVERROR(EINVAL); \
224 } \
225 name = in; \
226 } while (0)
227
228#define INPUT_ACTIVATION(name) do { \
229 int activation; \
230 INPUT_VAL(activation, 0); \
231 switch (activation) { \
232 case F_ACTIVATION_SIGMOID: \
233 name = ACTIVATION_SIGMOID; \
234 break; \
235 case F_ACTIVATION_RELU: \
236 name = ACTIVATION_RELU; \
237 break; \
238 default: \
239 name = ACTIVATION_TANH; \
240 } \
241 } while (0)
242
243#define INPUT_ARRAY(name, len) do { \
244 float *values = av_calloc((len), sizeof(float)); \
245 if (!values) { \
246 rnnoise_model_free(ret); \
247 return AVERROR(ENOMEM); \
248 } \
249 name = values; \
250 for (int i = 0; i < (len); i++) { \
251 if (fscanf(f, "%d", &in) != 1) { \
252 rnnoise_model_free(ret); \
253 return AVERROR(EINVAL); \
254 } \
255 values[i] = in; \
256 } \
257 } while (0)
258
259#define INPUT_ARRAY3(name, len0, len1, len2) do { \
260 float *values = av_calloc(FFALIGN((len0), 4) * FFALIGN((len1), 4) * (len2), sizeof(float)); \
261 if (!values) { \
262 rnnoise_model_free(ret); \
263 return AVERROR(ENOMEM); \
264 } \
265 name = values; \
266 for (int k = 0; k < (len0); k++) { \
267 for (int i = 0; i < (len2); i++) { \
268 for (int j = 0; j < (len1); j++) { \
269 if (fscanf(f, "%d", &in) != 1) { \
270 rnnoise_model_free(ret); \
271 return AVERROR(EINVAL); \
272 } \
273 values[j * (len2) * FFALIGN((len0), 4) + i * FFALIGN((len0), 4) + k] = in; \
274 } \
275 } \
276 } \
277 } while (0)
278
279#define NEW_LINE() do { \
280 int c; \
281 while ((c = fgetc(f)) != EOF) { \
282 if (c == '\n') \
283 break; \
284 } \
285 } while (0)
286
287#define INPUT_DENSE(name) do { \
288 INPUT_VAL(name->nb_inputs, 1); \
289 INPUT_VAL(name->nb_neurons, 1); \
290 ret->name ## _size = name->nb_neurons; \
291 INPUT_ACTIVATION(name->activation); \
292 NEW_LINE(); \
293 INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons); \
294 NEW_LINE(); \
295 INPUT_ARRAY(name->bias, name->nb_neurons); \
296 NEW_LINE(); \
297 } while (0)
298
299#define INPUT_GRU(name) do { \
300 INPUT_VAL(name->nb_inputs, 1); \
301 INPUT_VAL(name->nb_neurons, 1); \
302 ret->name ## _size = name->nb_neurons; \
303 INPUT_ACTIVATION(name->activation); \
304 NEW_LINE(); \
305 INPUT_ARRAY3(name->input_weights, name->nb_inputs, name->nb_neurons, 3); \
306 NEW_LINE(); \
307 INPUT_ARRAY3(name->recurrent_weights, name->nb_neurons, name->nb_neurons, 3); \
308 NEW_LINE(); \
309 INPUT_ARRAY(name->bias, name->nb_neurons * 3); \
310 NEW_LINE(); \
311 } while (0)
312
313 INPUT_DENSE(input_dense);
314 INPUT_GRU(vad_gru);
315 INPUT_GRU(noise_gru);
316 INPUT_GRU(denoise_gru);
317 INPUT_DENSE(denoise_output);
318 INPUT_DENSE(vad_output);
319
320 if (input_dense->nb_inputs != NB_FEATURES ||
321 vad_gru->nb_inputs != input_dense->nb_neurons ||
322 noise_gru->nb_inputs != input_dense->nb_neurons + vad_gru->nb_neurons + NB_FEATURES ||
323 denoise_gru->nb_inputs != vad_gru->nb_neurons + noise_gru->nb_neurons + NB_FEATURES ||
324 denoise_output->nb_inputs != denoise_gru->nb_neurons ||
325 denoise_output->nb_neurons != NB_BANDS ||
326 vad_output->nb_inputs != vad_gru->nb_neurons ||
327 vad_output->nb_neurons != 1) {
329 return AVERROR(EINVAL);
330 }
331
332 *rnn = ret;
333
334 return 0;
335}
336
338 AVFilterFormatsConfig **cfg_in,
339 AVFilterFormatsConfig **cfg_out)
340{
341 static const enum AVSampleFormat sample_fmts[] = {
344 };
345 int ret, sample_rates[] = { 48000, -1 };
346
347 ret = ff_set_sample_formats_from_list2(ctx, cfg_in, cfg_out, sample_fmts);
348 if (ret < 0)
349 return ret;
350
351 return ff_set_common_samplerates_from_list2(ctx, cfg_in, cfg_out, sample_rates);
352}
353
354static int config_input(AVFilterLink *inlink)
355{
356 AVFilterContext *ctx = inlink->dst;
357 AudioRNNContext *s = ctx->priv;
358 int ret = 0;
359
360 s->channels = inlink->ch_layout.nb_channels;
361
362 if (!s->st)
363 s->st = av_calloc(s->channels, sizeof(DenoiseState));
364 if (!s->st)
365 return AVERROR(ENOMEM);
366
367 for (int i = 0; i < s->channels; i++) {
368 DenoiseState *st = &s->st[i];
369
370 st->rnn[0].model = s->model[0];
371 st->rnn[0].vad_gru_state = av_calloc(FFALIGN(s->model[0]->vad_gru_size, 16), sizeof(float));
372 st->rnn[0].noise_gru_state = av_calloc(FFALIGN(s->model[0]->noise_gru_size, 16), sizeof(float));
373 st->rnn[0].denoise_gru_state = av_calloc(FFALIGN(s->model[0]->denoise_gru_size, 16), sizeof(float));
374 if (!st->rnn[0].vad_gru_state ||
375 !st->rnn[0].noise_gru_state ||
376 !st->rnn[0].denoise_gru_state)
377 return AVERROR(ENOMEM);
378 }
379
380 for (int i = 0; i < s->channels; i++) {
381 DenoiseState *st = &s->st[i];
382 float scale = 1.f;
383
384 if (!st->tx)
385 ret = av_tx_init(&st->tx, &st->tx_fn, AV_TX_FLOAT_FFT, 0, WINDOW_SIZE, &scale, 0);
386 if (ret < 0)
387 return ret;
388
389 if (!st->txi)
390 ret = av_tx_init(&st->txi, &st->txi_fn, AV_TX_FLOAT_FFT, 1, WINDOW_SIZE, &scale, 0);
391 if (ret < 0)
392 return ret;
393 }
394
395 return ret;
396}
397
398static void biquad(float *y, float mem[2], const float *x,
399 const float *b, const float *a, int N)
400{
401 for (int i = 0; i < N; i++) {
402 float xi, yi;
403
404 xi = x[i];
405 yi = x[i] + mem[0];
406 mem[0] = mem[1] + (b[0]*xi - a[0]*yi);
407 mem[1] = (b[1]*xi - a[1]*yi);
408 y[i] = yi;
409 }
410}
411
412#define RNN_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
413#define RNN_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst))))
414#define RNN_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
415
416static void forward_transform(DenoiseState *st, AVComplexFloat *out, const float *in)
417{
420
421 for (int i = 0; i < WINDOW_SIZE; i++) {
422 x[i].re = in[i];
423 x[i].im = 0;
424 }
425
426 st->tx_fn(st->tx, y, x, sizeof(AVComplexFloat));
427
429}
430
431static void inverse_transform(DenoiseState *st, float *out, const AVComplexFloat *in)
432{
435
436 RNN_COPY(x, in, FREQ_SIZE);
437
438 for (int i = FREQ_SIZE; i < WINDOW_SIZE; i++) {
439 x[i].re = x[WINDOW_SIZE - i].re;
440 x[i].im = -x[WINDOW_SIZE - i].im;
441 }
442
443 st->txi_fn(st->txi, y, x, sizeof(AVComplexFloat));
444
445 for (int i = 0; i < WINDOW_SIZE; i++)
446 out[i] = y[i].re / WINDOW_SIZE;
447}
448
449static const uint8_t eband5ms[] = {
450/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 20k*/
451 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
452};
453
454static void compute_band_energy(float *bandE, const AVComplexFloat *X)
455{
456 float sum[NB_BANDS] = {0};
457
458 for (int i = 0; i < NB_BANDS - 1; i++) {
459 int band_size;
460
461 band_size = (eband5ms[i + 1] - eband5ms[i]) << FRAME_SIZE_SHIFT;
462 for (int j = 0; j < band_size; j++) {
463 float tmp, frac = (float)j / band_size;
464
465 tmp = SQUARE(X[(eband5ms[i] << FRAME_SIZE_SHIFT) + j].re);
466 tmp += SQUARE(X[(eband5ms[i] << FRAME_SIZE_SHIFT) + j].im);
467 sum[i] += (1.f - frac) * tmp;
468 sum[i + 1] += frac * tmp;
469 }
470 }
471
472 sum[0] *= 2;
473 sum[NB_BANDS - 1] *= 2;
474
475 for (int i = 0; i < NB_BANDS; i++)
476 bandE[i] = sum[i];
477}
478
479static void compute_band_corr(float *bandE, const AVComplexFloat *X, const AVComplexFloat *P)
480{
481 float sum[NB_BANDS] = { 0 };
482
483 for (int i = 0; i < NB_BANDS - 1; i++) {
484 int band_size;
485
486 band_size = (eband5ms[i + 1] - eband5ms[i]) << FRAME_SIZE_SHIFT;
487 for (int j = 0; j < band_size; j++) {
488 float tmp, frac = (float)j / band_size;
489
490 tmp = X[(eband5ms[i]<<FRAME_SIZE_SHIFT) + j].re * P[(eband5ms[i]<<FRAME_SIZE_SHIFT) + j].re;
491 tmp += X[(eband5ms[i]<<FRAME_SIZE_SHIFT) + j].im * P[(eband5ms[i]<<FRAME_SIZE_SHIFT) + j].im;
492 sum[i] += (1 - frac) * tmp;
493 sum[i + 1] += frac * tmp;
494 }
495 }
496
497 sum[0] *= 2;
498 sum[NB_BANDS-1] *= 2;
499
500 for (int i = 0; i < NB_BANDS; i++)
501 bandE[i] = sum[i];
502}
503
504static void frame_analysis(AudioRNNContext *s, DenoiseState *st, AVComplexFloat *X, float *Ex, const float *in)
505{
506 LOCAL_ALIGNED_32(float, x, [WINDOW_SIZE]);
507
511 s->fdsp->vector_fmul(x, x, s->window, WINDOW_SIZE);
512 forward_transform(st, X, x);
514}
515
517{
518 LOCAL_ALIGNED_32(float, x, [WINDOW_SIZE]);
519 const float *src = st->history;
520 const float mix = s->mix;
521 const float imix = 1.f - FFMAX(mix, 0.f);
522
523 inverse_transform(st, x, y);
524 s->fdsp->vector_fmul(x, x, s->window, WINDOW_SIZE);
525 s->fdsp->vector_fmac_scalar(x, st->synthesis_mem, 1.f, FRAME_SIZE);
528
529 for (int n = 0; n < FRAME_SIZE; n++)
530 out[n] = out[n] * mix + src[n] * imix;
531}
532
533static inline void xcorr_kernel(const float *x, const float *y, float sum[4], int len)
534{
535 float y_0, y_1, y_2, y_3 = 0;
536 int j;
537
538 y_0 = *y++;
539 y_1 = *y++;
540 y_2 = *y++;
541
542 for (j = 0; j < len - 3; j += 4) {
543 float tmp;
544
545 tmp = *x++;
546 y_3 = *y++;
547 sum[0] += tmp * y_0;
548 sum[1] += tmp * y_1;
549 sum[2] += tmp * y_2;
550 sum[3] += tmp * y_3;
551 tmp = *x++;
552 y_0 = *y++;
553 sum[0] += tmp * y_1;
554 sum[1] += tmp * y_2;
555 sum[2] += tmp * y_3;
556 sum[3] += tmp * y_0;
557 tmp = *x++;
558 y_1 = *y++;
559 sum[0] += tmp * y_2;
560 sum[1] += tmp * y_3;
561 sum[2] += tmp * y_0;
562 sum[3] += tmp * y_1;
563 tmp = *x++;
564 y_2 = *y++;
565 sum[0] += tmp * y_3;
566 sum[1] += tmp * y_0;
567 sum[2] += tmp * y_1;
568 sum[3] += tmp * y_2;
569 }
570
571 if (j++ < len) {
572 float tmp = *x++;
573
574 y_3 = *y++;
575 sum[0] += tmp * y_0;
576 sum[1] += tmp * y_1;
577 sum[2] += tmp * y_2;
578 sum[3] += tmp * y_3;
579 }
580
581 if (j++ < len) {
582 float tmp=*x++;
583
584 y_0 = *y++;
585 sum[0] += tmp * y_1;
586 sum[1] += tmp * y_2;
587 sum[2] += tmp * y_3;
588 sum[3] += tmp * y_0;
589 }
590
591 if (j < len) {
592 float tmp=*x++;
593
594 y_1 = *y++;
595 sum[0] += tmp * y_2;
596 sum[1] += tmp * y_3;
597 sum[2] += tmp * y_0;
598 sum[3] += tmp * y_1;
599 }
600}
601
602static inline float celt_inner_prod(const float *x,
603 const float *y, int N)
604{
605 float xy = 0.f;
606
607 for (int i = 0; i < N; i++)
608 xy += x[i] * y[i];
609
610 return xy;
611}
612
613static void celt_pitch_xcorr(const float *x, const float *y,
614 float *xcorr, int len, int max_pitch)
615{
616 int i;
617
618 for (i = 0; i < max_pitch - 3; i += 4) {
619 float sum[4] = { 0, 0, 0, 0};
620
621 xcorr_kernel(x, y + i, sum, len);
622
623 xcorr[i] = sum[0];
624 xcorr[i + 1] = sum[1];
625 xcorr[i + 2] = sum[2];
626 xcorr[i + 3] = sum[3];
627 }
628 /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
629 for (; i < max_pitch; i++) {
630 xcorr[i] = celt_inner_prod(x, y + i, len);
631 }
632}
633
634static int celt_autocorr(const float *x, /* in: [0...n-1] samples x */
635 float *ac, /* out: [0...lag-1] ac values */
636 const float *window,
637 int overlap,
638 int lag,
639 int n)
640{
641 int fastN = n - lag;
642 int shift;
643 const float *xptr;
644 float xx[PITCH_BUF_SIZE>>1];
645
646 if (overlap == 0) {
647 xptr = x;
648 } else {
649 for (int i = 0; i < n; i++)
650 xx[i] = x[i];
651 for (int i = 0; i < overlap; i++) {
652 xx[i] = x[i] * window[i];
653 xx[n-i-1] = x[n-i-1] * window[i];
654 }
655 xptr = xx;
656 }
657
658 shift = 0;
659 celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1);
660
661 for (int k = 0; k <= lag; k++) {
662 float d = 0.f;
663
664 for (int i = k + fastN; i < n; i++)
665 d += xptr[i] * xptr[i-k];
666 ac[k] += d;
667 }
668
669 return shift;
670}
671
672static void celt_lpc(float *lpc, /* out: [0...p-1] LPC coefficients */
673 const float *ac, /* in: [0...p] autocorrelation values */
674 int p)
675{
676 float r, error = ac[0];
677
678 RNN_CLEAR(lpc, p);
679 if (ac[0] != 0) {
680 for (int i = 0; i < p; i++) {
681 /* Sum up this iteration's reflection coefficient */
682 float rr = 0;
683 for (int j = 0; j < i; j++)
684 rr += (lpc[j] * ac[i - j]);
685 rr += ac[i + 1];
686 r = -rr/error;
687 /* Update LPC coefficients and total error */
688 lpc[i] = r;
689 for (int j = 0; j < (i + 1) >> 1; j++) {
690 float tmp1, tmp2;
691 tmp1 = lpc[j];
692 tmp2 = lpc[i-1-j];
693 lpc[j] = tmp1 + (r*tmp2);
694 lpc[i-1-j] = tmp2 + (r*tmp1);
695 }
696
697 error = error - (r * r *error);
698 /* Bail out once we get 30 dB gain */
699 if (error < .001f * ac[0])
700 break;
701 }
702 }
703}
704
705static void celt_fir5(const float *x,
706 const float *num,
707 float *y,
708 int N,
709 float *mem)
710{
711 float num0, num1, num2, num3, num4;
712 float mem0, mem1, mem2, mem3, mem4;
713
714 num0 = num[0];
715 num1 = num[1];
716 num2 = num[2];
717 num3 = num[3];
718 num4 = num[4];
719 mem0 = mem[0];
720 mem1 = mem[1];
721 mem2 = mem[2];
722 mem3 = mem[3];
723 mem4 = mem[4];
724
725 for (int i = 0; i < N; i++) {
726 float sum = x[i];
727
728 sum += (num0*mem0);
729 sum += (num1*mem1);
730 sum += (num2*mem2);
731 sum += (num3*mem3);
732 sum += (num4*mem4);
733 mem4 = mem3;
734 mem3 = mem2;
735 mem2 = mem1;
736 mem1 = mem0;
737 mem0 = x[i];
738 y[i] = sum;
739 }
740
741 mem[0] = mem0;
742 mem[1] = mem1;
743 mem[2] = mem2;
744 mem[3] = mem3;
745 mem[4] = mem4;
746}
747
748static void pitch_downsample(float *x[], float *x_lp,
749 int len, int C)
750{
751 float ac[5];
752 float tmp=Q15ONE;
753 float lpc[4], mem[5]={0,0,0,0,0};
754 float lpc2[5];
755 float c1 = .8f;
756
757 for (int i = 1; i < len >> 1; i++)
758 x_lp[i] = .5f * (.5f * (x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]);
759 x_lp[0] = .5f * (.5f * (x[0][1])+x[0][0]);
760 if (C==2) {
761 for (int i = 1; i < len >> 1; i++)
762 x_lp[i] += (.5f * (.5f * (x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]));
763 x_lp[0] += .5f * (.5f * (x[1][1])+x[1][0]);
764 }
765
766 celt_autocorr(x_lp, ac, NULL, 0, 4, len>>1);
767
768 /* Noise floor -40 dB */
769 ac[0] *= 1.0001f;
770 /* Lag windowing */
771 for (int i = 1; i <= 4; i++) {
772 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
773 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
774 }
775
776 celt_lpc(lpc, ac, 4);
777 for (int i = 0; i < 4; i++) {
778 tmp = .9f * tmp;
779 lpc[i] = (lpc[i] * tmp);
780 }
781 /* Add a zero */
782 lpc2[0] = lpc[0] + .8f;
783 lpc2[1] = lpc[1] + (c1 * lpc[0]);
784 lpc2[2] = lpc[2] + (c1 * lpc[1]);
785 lpc2[3] = lpc[3] + (c1 * lpc[2]);
786 lpc2[4] = (c1 * lpc[3]);
787 celt_fir5(x_lp, lpc2, x_lp, len>>1, mem);
788}
789
790static inline void dual_inner_prod(const float *x, const float *y01, const float *y02,
791 int N, float *xy1, float *xy2)
792{
793 float xy01 = 0, xy02 = 0;
794
795 for (int i = 0; i < N; i++) {
796 xy01 += (x[i] * y01[i]);
797 xy02 += (x[i] * y02[i]);
798 }
799
800 *xy1 = xy01;
801 *xy2 = xy02;
802}
803
804static float compute_pitch_gain(float xy, float xx, float yy)
805{
806 return xy / sqrtf(1.f + xx * yy);
807}
808
809static const uint8_t second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
810static float remove_doubling(float *x, int maxperiod, int minperiod, int N,
811 int *T0_, int prev_period, float prev_gain)
812{
813 int k, i, T, T0;
814 float g, g0;
815 float pg;
816 float xy,xx,yy,xy2;
817 float xcorr[3];
818 float best_xy, best_yy;
819 int offset;
820 int minperiod0;
821 float yy_lookup[PITCH_MAX_PERIOD+1];
822
823 minperiod0 = minperiod;
824 maxperiod /= 2;
825 minperiod /= 2;
826 *T0_ /= 2;
827 prev_period /= 2;
828 N /= 2;
829 x += maxperiod;
830 if (*T0_>=maxperiod)
831 *T0_=maxperiod-1;
832
833 T = T0 = *T0_;
834 dual_inner_prod(x, x, x-T0, N, &xx, &xy);
835 yy_lookup[0] = xx;
836 yy=xx;
837 for (i = 1; i <= maxperiod; i++) {
838 yy = yy+(x[-i] * x[-i])-(x[N-i] * x[N-i]);
839 yy_lookup[i] = FFMAX(0, yy);
840 }
841 yy = yy_lookup[T0];
842 best_xy = xy;
843 best_yy = yy;
844 g = g0 = compute_pitch_gain(xy, xx, yy);
845 /* Look for any pitch at T/k */
846 for (k = 2; k <= 15; k++) {
847 int T1, T1b;
848 float g1;
849 float cont=0;
850 float thresh;
851 T1 = (2*T0+k)/(2*k);
852 if (T1 < minperiod)
853 break;
854 /* Look for another strong correlation at T1b */
855 if (k==2)
856 {
857 if (T1+T0>maxperiod)
858 T1b = T0;
859 else
860 T1b = T0+T1;
861 } else
862 {
863 T1b = (2*second_check[k]*T0+k)/(2*k);
864 }
865 dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2);
866 xy = .5f * (xy + xy2);
867 yy = .5f * (yy_lookup[T1] + yy_lookup[T1b]);
868 g1 = compute_pitch_gain(xy, xx, yy);
869 if (FFABS(T1-prev_period)<=1)
870 cont = prev_gain;
871 else if (FFABS(T1-prev_period)<=2 && 5 * k * k < T0)
872 cont = prev_gain * .5f;
873 else
874 cont = 0;
875 thresh = FFMAX(.3f, (.7f * g0) - cont);
876 /* Bias against very high pitch (very short period) to avoid false-positives
877 due to short-term correlation */
878 if (T1<3*minperiod)
879 thresh = FFMAX(.4f, (.85f * g0) - cont);
880 else if (T1<2*minperiod)
881 thresh = FFMAX(.5f, (.9f * g0) - cont);
882 if (g1 > thresh)
883 {
884 best_xy = xy;
885 best_yy = yy;
886 T = T1;
887 g = g1;
888 }
889 }
890 best_xy = FFMAX(0, best_xy);
891 if (best_yy <= best_xy)
892 pg = Q15ONE;
893 else
894 pg = best_xy/(best_yy + 1);
895
896 for (k = 0; k < 3; k++)
897 xcorr[k] = celt_inner_prod(x, x-(T+k-1), N);
898 if ((xcorr[2]-xcorr[0]) > .7f * (xcorr[1]-xcorr[0]))
899 offset = 1;
900 else if ((xcorr[0]-xcorr[2]) > (.7f * (xcorr[1] - xcorr[2])))
901 offset = -1;
902 else
903 offset = 0;
904 if (pg > g)
905 pg = g;
906 *T0_ = 2*T+offset;
907
908 if (*T0_<minperiod0)
909 *T0_=minperiod0;
910 return pg;
911}
912
913static void find_best_pitch(float *xcorr, float *y, int len,
914 int max_pitch, int *best_pitch)
915{
916 float best_num[2];
917 float best_den[2];
918 float Syy = 1.f;
919
920 best_num[0] = -1;
921 best_num[1] = -1;
922 best_den[0] = 0;
923 best_den[1] = 0;
924 best_pitch[0] = 0;
925 best_pitch[1] = 1;
926
927 for (int j = 0; j < len; j++)
928 Syy += y[j] * y[j];
929
930 for (int i = 0; i < max_pitch; i++) {
931 if (xcorr[i]>0) {
932 float num;
933 float xcorr16;
934
935 xcorr16 = xcorr[i];
936 /* Considering the range of xcorr16, this should avoid both underflows
937 and overflows (inf) when squaring xcorr16 */
938 xcorr16 *= 1e-12f;
939 num = xcorr16 * xcorr16;
940 if ((num * best_den[1]) > (best_num[1] * Syy)) {
941 if ((num * best_den[0]) > (best_num[0] * Syy)) {
942 best_num[1] = best_num[0];
943 best_den[1] = best_den[0];
944 best_pitch[1] = best_pitch[0];
945 best_num[0] = num;
946 best_den[0] = Syy;
947 best_pitch[0] = i;
948 } else {
949 best_num[1] = num;
950 best_den[1] = Syy;
951 best_pitch[1] = i;
952 }
953 }
954 }
955 Syy += y[i+len]*y[i+len] - y[i] * y[i];
956 Syy = FFMAX(1, Syy);
957 }
958}
959
960static void pitch_search(const float *x_lp, float *y,
961 int len, int max_pitch, int *pitch)
962{
963 int lag;
964 int best_pitch[2]={0,0};
965 int offset;
966
967 float x_lp4[WINDOW_SIZE];
968 float y_lp4[WINDOW_SIZE];
969 float xcorr[WINDOW_SIZE];
970
971 lag = len+max_pitch;
972
973 /* Downsample by 2 again */
974 for (int j = 0; j < len >> 2; j++)
975 x_lp4[j] = x_lp[2*j];
976 for (int j = 0; j < lag >> 2; j++)
977 y_lp4[j] = y[2*j];
978
979 /* Coarse search with 4x decimation */
980
981 celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2);
982
983 find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch);
984
985 /* Finer search with 2x decimation */
986 for (int i = 0; i < max_pitch >> 1; i++) {
987 float sum;
988 xcorr[i] = 0;
989 if (FFABS(i-2*best_pitch[0])>2 && FFABS(i-2*best_pitch[1])>2)
990 continue;
991 sum = celt_inner_prod(x_lp, y+i, len>>1);
992 xcorr[i] = FFMAX(-1, sum);
993 }
994
995 find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch);
996
997 /* Refine by pseudo-interpolation */
998 if (best_pitch[0] > 0 && best_pitch[0] < (max_pitch >> 1) - 1) {
999 float a, b, c;
1000
1001 a = xcorr[best_pitch[0] - 1];
1002 b = xcorr[best_pitch[0]];
1003 c = xcorr[best_pitch[0] + 1];
1004 if (c - a > .7f * (b - a))
1005 offset = 1;
1006 else if (a - c > .7f * (b-c))
1007 offset = -1;
1008 else
1009 offset = 0;
1010 } else {
1011 offset = 0;
1012 }
1013
1014 *pitch = 2 * best_pitch[0] - offset;
1015}
1016
1017static void dct(AudioRNNContext *s, float *out, const float *in)
1018{
1019 for (int i = 0; i < NB_BANDS; i++) {
1020 float sum;
1021
1022 sum = s->fdsp->scalarproduct_float(in, s->dct_table[i], FFALIGN(NB_BANDS, 4));
1023 out[i] = sum * sqrtf(2.f / 22);
1024 }
1025}
1026
1028 float *Ex, float *Ep, float *Exp, float *features, const float *in)
1029{
1030 float E = 0;
1031 float *ceps_0, *ceps_1, *ceps_2;
1032 float spec_variability = 0;
1033 LOCAL_ALIGNED_32(float, Ly, [FFALIGN(NB_BANDS, 4)]);
1034 LOCAL_ALIGNED_32(float, p, [WINDOW_SIZE]);
1035 float pitch_buf[PITCH_BUF_SIZE>>1];
1036 int pitch_index;
1037 float gain;
1038 float *(pre[1]);
1039 float tmp[NB_BANDS];
1040 float follow, logMax;
1041
1042 frame_analysis(s, st, X, Ex, in);
1045 pre[0] = &st->pitch_buf[0];
1046 pitch_downsample(pre, pitch_buf, PITCH_BUF_SIZE, 1);
1047 pitch_search(pitch_buf+(PITCH_MAX_PERIOD>>1), pitch_buf, PITCH_FRAME_SIZE,
1048 PITCH_MAX_PERIOD-3*PITCH_MIN_PERIOD, &pitch_index);
1049 pitch_index = PITCH_MAX_PERIOD-pitch_index;
1050
1052 PITCH_FRAME_SIZE, &pitch_index, st->last_period, st->last_gain);
1053 st->last_period = pitch_index;
1054 st->last_gain = gain;
1055
1056 for (int i = 0; i < WINDOW_SIZE; i++)
1057 p[i] = st->pitch_buf[PITCH_BUF_SIZE-WINDOW_SIZE-pitch_index+i];
1058
1059 s->fdsp->vector_fmul(p, p, s->window, WINDOW_SIZE);
1060 forward_transform(st, P, p);
1062 compute_band_corr(Exp, X, P);
1063
1064 for (int i = 0; i < NB_BANDS; i++)
1065 Exp[i] = Exp[i] / sqrtf(.001f+Ex[i]*Ep[i]);
1066
1067 memset(Exp + NB_BANDS, 0, (FFALIGN(NB_BANDS, 4) - NB_BANDS) * sizeof(*Exp));
1068 dct(s, tmp, Exp);
1069
1070 for (int i = 0; i < NB_DELTA_CEPS; i++)
1071 features[NB_BANDS+2*NB_DELTA_CEPS+i] = tmp[i];
1072
1073 features[NB_BANDS+2*NB_DELTA_CEPS] -= 1.3;
1074 features[NB_BANDS+2*NB_DELTA_CEPS+1] -= 0.9;
1075 features[NB_BANDS+3*NB_DELTA_CEPS] = .01*(pitch_index-300);
1076 logMax = -2;
1077 follow = -2;
1078
1079 for (int i = 0; i < NB_BANDS; i++) {
1080 Ly[i] = log10f(1e-2f + Ex[i]);
1081 Ly[i] = FFMAX(logMax-7, FFMAX(follow-1.5, Ly[i]));
1082 logMax = FFMAX(logMax, Ly[i]);
1083 follow = FFMAX(follow-1.5, Ly[i]);
1084 E += Ex[i];
1085 }
1086
1087 if (E < 0.04f) {
1088 /* If there's no audio, avoid messing up the state. */
1089 RNN_CLEAR(features, NB_FEATURES);
1090 return 1;
1091 }
1092
1093 memset(Ly + NB_BANDS, 0, (FFALIGN(NB_BANDS, 4) - NB_BANDS) * sizeof(*Ly));
1094 dct(s, features, Ly);
1095 features[0] -= 12;
1096 features[1] -= 4;
1097 ceps_0 = st->cepstral_mem[st->memid];
1098 ceps_1 = (st->memid < 1) ? st->cepstral_mem[CEPS_MEM+st->memid-1] : st->cepstral_mem[st->memid-1];
1099 ceps_2 = (st->memid < 2) ? st->cepstral_mem[CEPS_MEM+st->memid-2] : st->cepstral_mem[st->memid-2];
1100
1101 for (int i = 0; i < NB_BANDS; i++)
1102 ceps_0[i] = features[i];
1103
1104 st->memid++;
1105 for (int i = 0; i < NB_DELTA_CEPS; i++) {
1106 features[i] = ceps_0[i] + ceps_1[i] + ceps_2[i];
1107 features[NB_BANDS+i] = ceps_0[i] - ceps_2[i];
1108 features[NB_BANDS+NB_DELTA_CEPS+i] = ceps_0[i] - 2*ceps_1[i] + ceps_2[i];
1109 }
1110 /* Spectral variability features. */
1111 if (st->memid == CEPS_MEM)
1112 st->memid = 0;
1113
1114 for (int i = 0; i < CEPS_MEM; i++) {
1115 float mindist = 1e15f;
1116 for (int j = 0; j < CEPS_MEM; j++) {
1117 float dist = 0.f;
1118 for (int k = 0; k < NB_BANDS; k++) {
1119 float tmp;
1120
1121 tmp = st->cepstral_mem[i][k] - st->cepstral_mem[j][k];
1122 dist += tmp*tmp;
1123 }
1124
1125 if (j != i)
1126 mindist = FFMIN(mindist, dist);
1127 }
1128
1129 spec_variability += mindist;
1130 }
1131
1132 features[NB_BANDS+3*NB_DELTA_CEPS+1] = spec_variability/CEPS_MEM-2.1;
1133
1134 return 0;
1135}
1136
1137static void interp_band_gain(float *g, const float *bandE)
1138{
1139 memset(g, 0, sizeof(*g) * FREQ_SIZE);
1140
1141 for (int i = 0; i < NB_BANDS - 1; i++) {
1142 const int band_size = (eband5ms[i + 1] - eband5ms[i]) << FRAME_SIZE_SHIFT;
1143
1144 for (int j = 0; j < band_size; j++) {
1145 float frac = (float)j / band_size;
1146
1147 g[(eband5ms[i] << FRAME_SIZE_SHIFT) + j] = (1.f - frac) * bandE[i] + frac * bandE[i + 1];
1148 }
1149 }
1150}
1151
1152static void pitch_filter(AVComplexFloat *X, const AVComplexFloat *P, const float *Ex, const float *Ep,
1153 const float *Exp, const float *g)
1154{
1155 float newE[NB_BANDS];
1156 float r[NB_BANDS];
1157 float norm[NB_BANDS];
1158 float rf[FREQ_SIZE] = {0};
1159 float normf[FREQ_SIZE]={0};
1160
1161 for (int i = 0; i < NB_BANDS; i++) {
1162 if (Exp[i]>g[i]) r[i] = 1;
1163 else r[i] = SQUARE(Exp[i])*(1-SQUARE(g[i]))/(.001 + SQUARE(g[i])*(1-SQUARE(Exp[i])));
1164 r[i] = sqrtf(av_clipf(r[i], 0, 1));
1165 r[i] *= sqrtf(Ex[i]/(1e-8+Ep[i]));
1166 }
1167 interp_band_gain(rf, r);
1168 for (int i = 0; i < FREQ_SIZE; i++) {
1169 X[i].re += rf[i]*P[i].re;
1170 X[i].im += rf[i]*P[i].im;
1171 }
1172 compute_band_energy(newE, X);
1173 for (int i = 0; i < NB_BANDS; i++) {
1174 norm[i] = sqrtf(Ex[i] / (1e-8+newE[i]));
1175 }
1176 interp_band_gain(normf, norm);
1177 for (int i = 0; i < FREQ_SIZE; i++) {
1178 X[i].re *= normf[i];
1179 X[i].im *= normf[i];
1180 }
1181}
1182
1183static const float tansig_table[201] = {
1184 0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f,
1185 0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f,
1186 0.379949f, 0.413644f, 0.446244f, 0.477700f, 0.507977f,
1187 0.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f,
1188 0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f,
1189 0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f,
1190 0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f,
1191 0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.915420f,
1192 0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f,
1193 0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f,
1194 0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f,
1195 0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f,
1196 0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f,
1197 0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f,
1198 0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f,
1199 0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f,
1200 0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f,
1201 0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f,
1202 0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f,
1203 0.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f,
1204 0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f,
1205 0.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f,
1206 0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f,
1207 0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f,
1208 0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f,
1209 0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f,
1210 0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f,
1211 0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f,
1212 0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.999980f,
1213 0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f,
1214 0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f,
1215 0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f,
1216 0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f,
1217 0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f,
1218 0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f,
1219 0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f,
1220 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
1221 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
1222 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
1223 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
1224 1.000000f,
1225};
1226
1227static inline float tansig_approx(float x)
1228{
1229 float y, dy;
1230 float sign=1;
1231 int i;
1232
1233 /* Tests are reversed to catch NaNs */
1234 if (!(x<8))
1235 return 1;
1236 if (!(x>-8))
1237 return -1;
1238 /* Another check in case of -ffast-math */
1239
1240 if (isnan(x))
1241 return 0;
1242
1243 if (x < 0) {
1244 x=-x;
1245 sign=-1;
1246 }
1247 i = (int)floor(.5f+25*x);
1248 x -= .04f*i;
1249 y = tansig_table[i];
1250 dy = 1-y*y;
1251 y = y + x*dy*(1 - y*x);
1252 return sign*y;
1253}
1254
1255static inline float sigmoid_approx(float x)
1256{
1257 return .5f + .5f*tansig_approx(.5f*x);
1258}
1259
1260static void compute_dense(const DenseLayer *layer, float *output, const float *input)
1261{
1262 const int N = layer->nb_neurons, M = layer->nb_inputs, stride = N;
1263
1264 for (int i = 0; i < N; i++) {
1265 /* Compute update gate. */
1266 float sum = layer->bias[i];
1267
1268 for (int j = 0; j < M; j++)
1269 sum += layer->input_weights[j * stride + i] * input[j];
1270
1271 output[i] = WEIGHTS_SCALE * sum;
1272 }
1273
1274 if (layer->activation == ACTIVATION_SIGMOID) {
1275 for (int i = 0; i < N; i++)
1276 output[i] = sigmoid_approx(output[i]);
1277 } else if (layer->activation == ACTIVATION_TANH) {
1278 for (int i = 0; i < N; i++)
1279 output[i] = tansig_approx(output[i]);
1280 } else if (layer->activation == ACTIVATION_RELU) {
1281 for (int i = 0; i < N; i++)
1282 output[i] = FFMAX(0, output[i]);
1283 } else {
1284 av_assert0(0);
1285 }
1286}
1287
1288static void compute_gru(AudioRNNContext *s, const GRULayer *gru, float *state, const float *input)
1289{
1290 LOCAL_ALIGNED_32(float, z, [MAX_NEURONS]);
1291 LOCAL_ALIGNED_32(float, r, [MAX_NEURONS]);
1292 LOCAL_ALIGNED_32(float, h, [MAX_NEURONS]);
1293 const int M = gru->nb_inputs;
1294 const int N = gru->nb_neurons;
1295 const int AN = FFALIGN(N, 4);
1296 const int AM = FFALIGN(M, 4);
1297 const int stride = 3 * AN, istride = 3 * AM;
1298
1299 for (int i = 0; i < N; i++) {
1300 /* Compute update gate. */
1301 float sum = gru->bias[i];
1302
1303 sum += s->fdsp->scalarproduct_float(gru->input_weights + i * istride, input, AM);
1304 sum += s->fdsp->scalarproduct_float(gru->recurrent_weights + i * stride, state, AN);
1305 z[i] = sigmoid_approx(WEIGHTS_SCALE * sum);
1306 }
1307
1308 for (int i = 0; i < N; i++) {
1309 /* Compute reset gate. */
1310 float sum = gru->bias[N + i];
1311
1312 sum += s->fdsp->scalarproduct_float(gru->input_weights + AM + i * istride, input, AM);
1313 sum += s->fdsp->scalarproduct_float(gru->recurrent_weights + AN + i * stride, state, AN);
1314 r[i] = sigmoid_approx(WEIGHTS_SCALE * sum);
1315 }
1316
1317 for (int i = 0; i < N; i++) {
1318 /* Compute output. */
1319 float sum = gru->bias[2 * N + i];
1320
1321 sum += s->fdsp->scalarproduct_float(gru->input_weights + 2 * AM + i * istride, input, AM);
1322 for (int j = 0; j < N; j++)
1323 sum += gru->recurrent_weights[2 * AN + i * stride + j] * state[j] * r[j];
1324
1325 if (gru->activation == ACTIVATION_SIGMOID)
1326 sum = sigmoid_approx(WEIGHTS_SCALE * sum);
1327 else if (gru->activation == ACTIVATION_TANH)
1328 sum = tansig_approx(WEIGHTS_SCALE * sum);
1329 else if (gru->activation == ACTIVATION_RELU)
1330 sum = FFMAX(0, WEIGHTS_SCALE * sum);
1331 else
1332 av_assert0(0);
1333 h[i] = z[i] * state[i] + (1.f - z[i]) * sum;
1334 }
1335
1336 RNN_COPY(state, h, N);
1337}
1338
1339static void compute_rnn(AudioRNNContext *s, RNNState *rnn, float *gains, float *vad, const float *input)
1340{
1341 LOCAL_ALIGNED_32(float, dense_out, [MAX_NEURONS]);
1342 LOCAL_ALIGNED_32(float, noise_input, [MAX_NEURONS * 3]);
1343 LOCAL_ALIGNED_32(float, denoise_input, [MAX_NEURONS * 3]);
1344
1345 memset(dense_out, 0, MAX_NEURONS * sizeof(float));
1346 memset(noise_input, 0, MAX_NEURONS * 3 * sizeof(float));
1347 memset(denoise_input, 0, MAX_NEURONS * 3 * sizeof(float));
1348 compute_dense(rnn->model->input_dense, dense_out, input);
1349 compute_gru(s, rnn->model->vad_gru, rnn->vad_gru_state, dense_out);
1350 compute_dense(rnn->model->vad_output, vad, rnn->vad_gru_state);
1351
1352 memcpy(noise_input, dense_out, rnn->model->input_dense_size * sizeof(float));
1353 memcpy(noise_input + rnn->model->input_dense_size,
1354 rnn->vad_gru_state, rnn->model->vad_gru_size * sizeof(float));
1355 memcpy(noise_input + rnn->model->input_dense_size + rnn->model->vad_gru_size,
1356 input, NB_FEATURES * sizeof(float));
1357
1358 compute_gru(s, rnn->model->noise_gru, rnn->noise_gru_state, noise_input);
1359
1360 memcpy(denoise_input, rnn->vad_gru_state, rnn->model->vad_gru_size * sizeof(float));
1361 memcpy(denoise_input + rnn->model->vad_gru_size,
1362 rnn->noise_gru_state, rnn->model->noise_gru_size * sizeof(float));
1363 memcpy(denoise_input + rnn->model->vad_gru_size + rnn->model->noise_gru_size,
1364 input, NB_FEATURES * sizeof(float));
1365
1366 compute_gru(s, rnn->model->denoise_gru, rnn->denoise_gru_state, denoise_input);
1368}
1369
1370static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, const float *in,
1371 int disabled)
1372{
1375 float x[FRAME_SIZE];
1376 float Ex[NB_BANDS], Ep[NB_BANDS];
1377 LOCAL_ALIGNED_32(float, Exp, [FFALIGN(NB_BANDS, 4)]);
1378 float features[NB_FEATURES];
1379 float g[NB_BANDS];
1380 float gf[FREQ_SIZE];
1381 float vad_prob = 0;
1382 float *history = st->history;
1383 static const float a_hp[2] = {-1.99599, 0.99600};
1384 static const float b_hp[2] = {-2, 1};
1385 int silence;
1386
1387 biquad(x, st->mem_hp_x, in, b_hp, a_hp, FRAME_SIZE);
1388 silence = compute_frame_features(s, st, X, P, Ex, Ep, Exp, features, x);
1389
1390 if (!silence && !disabled) {
1391 compute_rnn(s, &st->rnn[0], g, &vad_prob, features);
1392 pitch_filter(X, P, Ex, Ep, Exp, g);
1393 for (int i = 0; i < NB_BANDS; i++) {
1394 float alpha = .6f;
1395
1396 g[i] = FFMAX(g[i], alpha * st->lastg[i]);
1397 st->lastg[i] = g[i];
1398 }
1399
1400 interp_band_gain(gf, g);
1401
1402 for (int i = 0; i < FREQ_SIZE; i++) {
1403 X[i].re *= gf[i];
1404 X[i].im *= gf[i];
1405 }
1406 }
1407
1408 frame_synthesis(s, st, out, X);
1409 memcpy(history, in, FRAME_SIZE * sizeof(*history));
1410
1411 return vad_prob;
1412}
1413
1414typedef struct ThreadData {
1415 AVFrame *in, *out;
1416} ThreadData;
1417
1418static int rnnoise_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1419{
1420 AudioRNNContext *s = ctx->priv;
1421 ThreadData *td = arg;
1422 AVFrame *in = td->in;
1423 AVFrame *out = td->out;
1424 const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs);
1425 const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs);
1426
1427 for (int ch = start; ch < end; ch++) {
1428 rnnoise_channel(s, &s->st[ch],
1429 (float *)out->extended_data[ch],
1430 (const float *)in->extended_data[ch],
1431 ctx->is_disabled);
1432 }
1433
1434 return 0;
1435}
1436
1437static int filter_frame(AVFilterLink *inlink, AVFrame *in)
1438{
1439 AVFilterContext *ctx = inlink->dst;
1440 AVFilterLink *outlink = ctx->outputs[0];
1441 AVFrame *out = NULL;
1442 ThreadData td;
1443
1445 if (!out) {
1446 av_frame_free(&in);
1447 return AVERROR(ENOMEM);
1448 }
1450
1451 td.in = in; td.out = out;
1454
1455 av_frame_free(&in);
1456 return ff_filter_frame(outlink, out);
1457}
1458
1460{
1461 AVFilterLink *inlink = ctx->inputs[0];
1462 AVFilterLink *outlink = ctx->outputs[0];
1463 AVFrame *in = NULL;
1464 int ret;
1465
1466 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
1467
1468 ret = ff_inlink_consume_samples(inlink, FRAME_SIZE, FRAME_SIZE, &in);
1469 if (ret < 0)
1470 return ret;
1471
1472 if (ret > 0)
1473 return filter_frame(inlink, in);
1474
1475 FF_FILTER_FORWARD_STATUS(inlink, outlink);
1476 FF_FILTER_FORWARD_WANTED(outlink, inlink);
1477
1478 return FFERROR_NOT_READY;
1479}
1480
1482{
1483 AudioRNNContext *s = ctx->priv;
1484 int ret;
1485 FILE *f;
1486
1487 if (!s->model_name)
1488 return AVERROR(EINVAL);
1489 f = avpriv_fopen_utf8(s->model_name, "r");
1490 if (!f) {
1491 av_log(ctx, AV_LOG_ERROR, "Failed to open model file: %s\n", s->model_name);
1492 return AVERROR(EINVAL);
1493 }
1494
1495 ret = rnnoise_model_from_file(f, model);
1496 fclose(f);
1497 if (!*model || ret < 0)
1498 return ret;
1499
1500 return 0;
1501}
1502
1504{
1505 AudioRNNContext *s = ctx->priv;
1506 int ret;
1507
1508 s->fdsp = avpriv_float_dsp_alloc(0);
1509 if (!s->fdsp)
1510 return AVERROR(ENOMEM);
1511
1512 ret = open_model(ctx, &s->model[0]);
1513 if (ret < 0)
1514 return ret;
1515
1516 for (int i = 0; i < FRAME_SIZE; i++) {
1517 s->window[i] = sin(.5*M_PI*sin(.5*M_PI*(i+.5)/FRAME_SIZE) * sin(.5*M_PI*(i+.5)/FRAME_SIZE));
1518 s->window[WINDOW_SIZE - 1 - i] = s->window[i];
1519 }
1520
1521 for (int i = 0; i < NB_BANDS; i++) {
1522 for (int j = 0; j < NB_BANDS; j++) {
1523 s->dct_table[j][i] = cosf((i + .5f) * j * M_PI / NB_BANDS);
1524 if (j == 0)
1525 s->dct_table[j][i] *= sqrtf(.5);
1526 }
1527 }
1528
1529 return 0;
1530}
1531
1532static void free_model(AVFilterContext *ctx, int n)
1533{
1534 AudioRNNContext *s = ctx->priv;
1535
1536 rnnoise_model_free(s->model[n]);
1537 s->model[n] = NULL;
1538
1539 for (int ch = 0; ch < s->channels && s->st; ch++) {
1540 av_freep(&s->st[ch].rnn[n].vad_gru_state);
1541 av_freep(&s->st[ch].rnn[n].noise_gru_state);
1542 av_freep(&s->st[ch].rnn[n].denoise_gru_state);
1543 }
1544}
1545
1546static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1547 char *res, int res_len, int flags)
1548{
1549 AudioRNNContext *s = ctx->priv;
1550 int ret;
1551
1552 ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1553 if (ret < 0)
1554 return ret;
1555
1556 ret = open_model(ctx, &s->model[1]);
1557 if (ret < 0)
1558 return ret;
1559
1560 FFSWAP(RNNModel *, s->model[0], s->model[1]);
1561 for (int ch = 0; ch < s->channels; ch++)
1562 FFSWAP(RNNState, s->st[ch].rnn[0], s->st[ch].rnn[1]);
1563
1564 ret = config_input(ctx->inputs[0]);
1565 if (ret < 0) {
1566 for (int ch = 0; ch < s->channels; ch++)
1567 FFSWAP(RNNState, s->st[ch].rnn[0], s->st[ch].rnn[1]);
1568 FFSWAP(RNNModel *, s->model[0], s->model[1]);
1569 return ret;
1570 }
1571
1572 free_model(ctx, 1);
1573 return 0;
1574}
1575
1577{
1578 AudioRNNContext *s = ctx->priv;
1579
1580 av_freep(&s->fdsp);
1581 free_model(ctx, 0);
1582 for (int ch = 0; ch < s->channels && s->st; ch++) {
1583 av_tx_uninit(&s->st[ch].tx);
1584 av_tx_uninit(&s->st[ch].txi);
1585 }
1586 av_freep(&s->st);
1587}
1588
1589static const AVFilterPad inputs[] = {
1590 {
1591 .name = "default",
1592 .type = AVMEDIA_TYPE_AUDIO,
1593 .config_props = config_input,
1594 },
1595};
1596
1597#define OFFSET(x) offsetof(AudioRNNContext, x)
1598#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1599
1600static const AVOption arnndn_options[] = {
1601 { "model", "set model name", OFFSET(model_name), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, AF },
1602 { "m", "set model name", OFFSET(model_name), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, AF },
1603 { "mix", "set output vs input mix", OFFSET(mix), AV_OPT_TYPE_FLOAT, {.dbl=1.0},-1, 1, AF },
1604 { NULL }
1605};
1606
1608
1610 .p.name = "arnndn",
1611 .p.description = NULL_IF_CONFIG_SMALL("Reduce noise from speech using Recurrent Neural Networks."),
1612 .p.priv_class = &arnndn_class,
1615 .priv_size = sizeof(AudioRNNContext),
1616 .activate = activate,
1617 .init = init,
1618 .uninit = uninit,
1622 .process_command = process_command,
1623};
static enum AVSampleFormat sample_fmts[]
Definition adpcmenc.c:933
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition aeval.c:246
static const AVFilterPad inputs[]
Definition af_aap.c:299
static int config_input(AVFilterLink *inlink)
#define AF
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static float compute_pitch_gain(float xy, float xx, float yy)
Definition af_arnndn.c:804
static int compute_frame_features(AudioRNNContext *s, DenoiseState *st, AVComplexFloat *X, AVComplexFloat *P, float *Ex, float *Ep, float *Exp, float *features, const float *in)
Definition af_arnndn.c:1027
#define WEIGHTS_SCALE
Definition af_arnndn.c:65
static const uint8_t second_check[16]
Definition af_arnndn.c:809
static void dual_inner_prod(const float *x, const float *y01, const float *y02, int N, float *xy1, float *xy2)
Definition af_arnndn.c:790
#define ACTIVATION_TANH
Definition af_arnndn.c:69
static float remove_doubling(float *x, int maxperiod, int minperiod, int N, int *T0_, int prev_period, float prev_gain)
Definition af_arnndn.c:810
static void inverse_transform(DenoiseState *st, float *out, const AVComplexFloat *in)
Definition af_arnndn.c:431
#define CEPS_MEM
Definition af_arnndn.c:60
static int celt_autocorr(const float *x, float *ac, const float *window, int overlap, int lag, int n)
Definition af_arnndn.c:634
static void forward_transform(DenoiseState *st, AVComplexFloat *out, const float *in)
Definition af_arnndn.c:416
static void pitch_downsample(float *x[], float *x_lp, int len, int C)
Definition af_arnndn.c:748
#define FREE_DENSE(name)
static int rnnoise_model_from_file(FILE *f, RNNModel **rnn)
Definition af_arnndn.c:187
#define ACTIVATION_SIGMOID
Definition af_arnndn.c:70
static int open_model(AVFilterContext *ctx, RNNModel **model)
Definition af_arnndn.c:1481
#define ALLOC_LAYER(type, name)
#define FREQ_SIZE
Definition af_arnndn.c:49
#define FRAME_SIZE_SHIFT
Definition af_arnndn.c:46
static float celt_inner_prod(const float *x, const float *y, int N)
Definition af_arnndn.c:602
static void free_model(AVFilterContext *ctx, int n)
Definition af_arnndn.c:1532
static void pitch_filter(AVComplexFloat *X, const AVComplexFloat *P, const float *Ex, const float *Ep, const float *Exp, const float *g)
Definition af_arnndn.c:1152
static int config_input(AVFilterLink *inlink)
Definition af_arnndn.c:354
#define RNN_CLEAR(dst, n)
Definition af_arnndn.c:413
#define PITCH_MAX_PERIOD
Definition af_arnndn.c:52
static void frame_synthesis(AudioRNNContext *s, DenoiseState *st, float *out, const AVComplexFloat *y)
Definition af_arnndn.c:516
static float sigmoid_approx(float x)
Definition af_arnndn.c:1255
#define NB_BANDS
Definition af_arnndn.c:58
#define Q15ONE
Definition af_arnndn.c:73
#define MAX_NEURONS
Definition af_arnndn.c:67
static void compute_gru(AudioRNNContext *s, const GRULayer *gru, float *state, const float *input)
Definition af_arnndn.c:1288
#define INPUT_DENSE(name)
static void interp_band_gain(float *g, const float *bandE)
Definition af_arnndn.c:1137
#define RNN_COPY(dst, src, n)
Definition af_arnndn.c:414
#define PITCH_MIN_PERIOD
Definition af_arnndn.c:51
#define INPUT_GRU(name)
static void compute_band_corr(float *bandE, const AVComplexFloat *X, const AVComplexFloat *P)
Definition af_arnndn.c:479
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition af_arnndn.c:1437
#define PITCH_FRAME_SIZE
Definition af_arnndn.c:53
static void celt_lpc(float *lpc, const float *ac, int p)
Definition af_arnndn.c:672
static void dct(AudioRNNContext *s, float *out, const float *in)
Definition af_arnndn.c:1017
#define SQUARE(x)
Definition af_arnndn.c:56
static const AVOption arnndn_options[]
Definition af_arnndn.c:1600
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition af_arnndn.c:337
static int rnnoise_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition af_arnndn.c:1418
#define WINDOW_SIZE
Definition af_arnndn.c:48
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition af_arnndn.c:1546
static int activate(AVFilterContext *ctx)
Definition af_arnndn.c:1459
static void compute_band_energy(float *bandE, const AVComplexFloat *X)
Definition af_arnndn.c:454
static void frame_analysis(AudioRNNContext *s, DenoiseState *st, AVComplexFloat *X, float *Ex, const float *in)
Definition af_arnndn.c:504
#define NB_DELTA_CEPS
Definition af_arnndn.c:61
#define RNN_MOVE(dst, src, n)
Definition af_arnndn.c:412
static av_cold void uninit(AVFilterContext *ctx)
Definition af_arnndn.c:1576
static float rnnoise_channel(AudioRNNContext *s, DenoiseState *st, float *out, const float *in, int disabled)
Definition af_arnndn.c:1370
const FFFilter ff_af_arnndn
Definition af_arnndn.c:1609
static void rnnoise_model_free(RNNModel *model)
Definition af_arnndn.c:157
static void celt_fir5(const float *x, const float *num, float *y, int N, float *mem)
Definition af_arnndn.c:705
#define ACTIVATION_RELU
Definition af_arnndn.c:71
#define OFFSET(x)
Definition af_arnndn.c:1597
static void compute_dense(const DenseLayer *layer, float *output, const float *input)
Definition af_arnndn.c:1260
#define FREE_GRU(name)
static void compute_rnn(AudioRNNContext *s, RNNState *rnn, float *gains, float *vad, const float *input)
Definition af_arnndn.c:1339
static void celt_pitch_xcorr(const float *x, const float *y, float *xcorr, int len, int max_pitch)
Definition af_arnndn.c:613
static float tansig_approx(float x)
Definition af_arnndn.c:1227
#define PITCH_BUF_SIZE
Definition af_arnndn.c:54
static void xcorr_kernel(const float *x, const float *y, float sum[4], int len)
Definition af_arnndn.c:533
static void find_best_pitch(float *xcorr, float *y, int len, int max_pitch, int *best_pitch)
Definition af_arnndn.c:913
static void pitch_search(const float *x_lp, float *y, int len, int max_pitch, int *pitch)
Definition af_arnndn.c:960
#define NB_FEATURES
Definition af_arnndn.c:63
static const uint8_t eband5ms[]
Definition af_arnndn.c:449
static const float tansig_table[201]
Definition af_arnndn.c:1183
#define FRAME_SIZE
Definition af_arnndn.c:47
@ biquad
Definition af_biquads.c:79
#define N
Definition af_mcompand.c:54
static FILE * out
static AVFormatContext * ctx
#define T(x)
Definition vpx_arith.h:29
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition audio.c:34
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition audio.c:74
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define E
Definition avdct.c:34
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1073
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition avfilter.c:911
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition avfilter.c:1701
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition avfilter.c:1545
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition avfilter.c:851
Main libavfilter public API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define xi(width, name, var, range_min, range_max, subs,...)
Definition cbs_h264.c:115
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
#define av_clipf
Definition common.h:145
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
static __device__ float sqrtf(float a)
static __device__ float floor(float a)
static const int sample_rates[]
Definition dcaenc.h:34
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define M(chr)
Definition exr.c:177
static struct @346255127015250356166251341105367306144006377143 state
#define X
Definition f_ebur128.c:157
static SDL_Window * window
Definition ffplay.c:442
#define FRAME_SIZE
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition formats.c:1088
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition formats.c:1217
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition avfilter.h:172
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition avfilter.h:210
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
int a
static const int16_t alpha[]
Definition ilbcdata.h:55
#define r
Definition input.c:42
#define b
Definition input.c:43
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
unsigned offset
Definition libaomenc.c:763
static int mix(int c0, int c1)
Definition 4xm.c:717
#define C
static int shift(int a, int b)
Definition bonk.c:261
const char * arg
Definition jacosubdec.c:65
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition filters.h:694
#define FF_FILTER_FORWARD_STATUS(inlink, outlink)
Acknowledge the status on an input link and forward it to an output link.
Definition filters.h:666
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
Definition filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition filters.h:639
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
#define av_cold
Definition attributes.h:117
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
Definition file_open.c:160
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition float_dsp.c:135
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
#define FFSWAP(type, a, b)
Definition macros.h:52
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
#define M_PI
Definition mathematics.h:67
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
#define LOCAL_ALIGNED_32(t, v,...)
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
#define P
static const uint64_t c1
Definition murmur3.c:52
AVOptions.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
float im
Definition tx.h:28
float re
Definition tx.h:28
An instance of a filter.
Definition avfilter.h:279
Lists of formats / etc.
Definition avfilter.h:120
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
uint8_t ** extended_data
pointers to the data planes/channels.
Definition frame.h:540
AVOption.
Definition opt.h:428
RNNModel * model[2]
Definition af_arnndn.c:148
AVFloatDSPContext * fdsp
Definition af_arnndn.c:150
char * model_name
Definition af_arnndn.c:139
DenoiseState * st
Definition af_arnndn.c:143
float window[WINDOW_SIZE]
Definition af_arnndn.c:145
float dct_table[FFALIGN(NB_BANDS, 4)][FFALIGN(NB_BANDS, 4)]
Definition af_arnndn.c:146
float mem_hp_x[2]
Definition af_arnndn.c:128
float pitch_enh_buf[PITCH_BUF_SIZE]
Definition af_arnndn.c:125
float analysis_mem[FRAME_SIZE]
Definition af_arnndn.c:120
float cepstral_mem[CEPS_MEM][NB_BANDS]
Definition af_arnndn.c:121
RNNState rnn[2]
Definition af_arnndn.c:131
float synthesis_mem[FRAME_SIZE]
Definition af_arnndn.c:123
float lastg[NB_BANDS]
Definition af_arnndn.c:129
AVTXContext * txi
Definition af_arnndn.c:132
float last_gain
Definition af_arnndn.c:126
float pitch_buf[PITCH_BUF_SIZE]
Definition af_arnndn.c:124
av_tx_fn txi_fn
Definition af_arnndn.c:133
float history[FRAME_SIZE]
Definition af_arnndn.c:130
AVTXContext * tx
Definition af_arnndn.c:132
av_tx_fn tx_fn
Definition af_arnndn.c:133
int nb_inputs
Definition af_arnndn.c:78
const float * input_weights
Definition af_arnndn.c:77
int activation
Definition af_arnndn.c:80
int nb_neurons
Definition af_arnndn.c:79
const float * bias
Definition af_arnndn.c:76
const float * recurrent_weights
Definition af_arnndn.c:86
const float * input_weights
Definition af_arnndn.c:85
int nb_inputs
Definition af_arnndn.c:87
int nb_neurons
Definition af_arnndn.c:88
const float * bias
Definition af_arnndn.c:84
int activation
Definition af_arnndn.c:89
int vad_gru_size
Definition af_arnndn.c:96
const DenseLayer * denoise_output
Definition af_arnndn.c:106
const DenseLayer * input_dense
Definition af_arnndn.c:94
int denoise_gru_size
Definition af_arnndn.c:102
int vad_output_size
Definition af_arnndn.c:108
const DenseLayer * vad_output
Definition af_arnndn.c:109
int denoise_output_size
Definition af_arnndn.c:105
int input_dense_size
Definition af_arnndn.c:93
const GRULayer * vad_gru
Definition af_arnndn.c:97
const GRULayer * noise_gru
Definition af_arnndn.c:100
const GRULayer * denoise_gru
Definition af_arnndn.c:103
int noise_gru_size
Definition af_arnndn.c:99
float * denoise_gru_state
Definition af_arnndn.c:115
float * noise_gru_state
Definition af_arnndn.c:114
float * vad_gru_state
Definition af_arnndn.c:113
RNNModel * model
Definition af_arnndn.c:116
Used for passing data between threads.
Definition v210dec.c:35
AVFrame * out
#define stride
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
static void error(const char *err)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
int num
Definition error.c:23
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition tx.c:295
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition tx.c:903
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
Definition tx.h:47
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition tx.h:151
const char * g
Definition vf_curves.c:128
int len
static double c[64]