Skip to content

Commit df246fd

Browse files
committed
Added parameterizable maximum attenuation.
1 parent a2f4659 commit df246fd

File tree

4 files changed

+90
-19
lines changed

4 files changed

+90
-19
lines changed

Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ noinst_PROGRAMS = examples/rnnoise_demo
3636
endif
3737

3838
examples_rnnoise_demo_SOURCES = examples/rnnoise_demo.c
39-
examples_rnnoise_demo_LDADD = librnnoise.la
39+
examples_rnnoise_demo_LDADD = librnnoise.la $(LIBM)
4040

4141
pkgconfigdir = $(libdir)/pkgconfig
4242
pkgconfig_DATA = rnnoise.pc

examples/rnnoise_demo.c

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,36 +24,65 @@
2424
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2525
*/
2626

27+
#include <math.h>
2728
#include <stdio.h>
2829
#include "rnnoise.h"
30+
#include <stdlib.h>
31+
#include <sys/types.h>
32+
#include "rnnoise.h"
2933

3034
#define FRAME_SIZE 480
3135

3236
int main(int argc, char **argv) {
33-
int i;
37+
int i, ci;
3438
int first = 1;
39+
int channels;
3540
float x[FRAME_SIZE];
36-
FILE *f1, *fout;
37-
DenoiseState *st;
38-
st = rnnoise_create(NULL);
39-
if (argc!=3) {
40-
fprintf(stderr, "usage: %s <noisy speech> <output denoised>\n", argv[0]);
41+
short *tmp;
42+
RNNModel *model = NULL;
43+
DenoiseState **sts;
44+
float max_attenuation;
45+
if (argc < 3) {
46+
fprintf(stderr, "usage: %s <channels> <max attenuation dB>\n", argv[0]);
47+
return 1;
48+
}
49+
50+
channels = atoi(argv[1]);
51+
if (channels < 1) channels = 1;
52+
max_attenuation = pow(10, -atof(argv[2])/10);
53+
54+
sts = malloc(channels * sizeof(DenoiseState *));
55+
if (!sts) {
56+
perror("malloc");
4157
return 1;
4258
}
43-
f1 = fopen(argv[1], "r");
44-
fout = fopen(argv[2], "w");
59+
tmp = malloc(channels * FRAME_SIZE * sizeof(short));
60+
if (!tmp) {
61+
perror("malloc");
62+
return 1;
63+
}
64+
for (i = 0; i < channels; i++) {
65+
sts[i] = rnnoise_create(model);
66+
rnnoise_set_param(sts[i], RNNOISE_PARAM_MAX_ATTENUATION, max_attenuation);
67+
}
68+
4569
while (1) {
46-
short tmp[FRAME_SIZE];
47-
fread(tmp, sizeof(short), FRAME_SIZE, f1);
48-
if (feof(f1)) break;
49-
for (i=0;i<FRAME_SIZE;i++) x[i] = tmp[i];
50-
rnnoise_process_frame(st, x, x);
51-
for (i=0;i<FRAME_SIZE;i++) tmp[i] = x[i];
52-
if (!first) fwrite(tmp, sizeof(short), FRAME_SIZE, fout);
70+
fread(tmp, sizeof(short), channels * FRAME_SIZE, stdin);
71+
if (feof(stdin)) break;
72+
73+
for (ci = 0; ci < channels; ci++) {
74+
for (i=0;i<FRAME_SIZE;i++) x[i] = tmp[i*channels+ci];
75+
rnnoise_process_frame(sts[ci], x, x);
76+
for (i=0;i<FRAME_SIZE;i++) tmp[i*channels+ci] = x[i];
77+
}
78+
79+
if (!first) fwrite(tmp, sizeof(short), channels * FRAME_SIZE, stdout);
5380
first = 0;
5481
}
55-
rnnoise_destroy(st);
56-
fclose(f1);
57-
fclose(fout);
82+
83+
for (i = 0; i < channels; i++)
84+
rnnoise_destroy(sts[i]);
85+
free(tmp);
86+
free(sts);
5887
return 0;
5988
}

include/rnnoise.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,9 @@ RNNOISE_EXPORT RNNModel *rnnoise_model_from_file(FILE *f);
6161

6262
RNNOISE_EXPORT void rnnoise_model_free(RNNModel *model);
6363

64+
/* Parameters to a denoise state */
65+
#define RNNOISE_PARAM_MAX_ATTENUATION 1
66+
67+
RNNOISE_EXPORT void rnnoise_set_param(DenoiseState *st, int param, float value);
68+
6469
#endif

src/denoise.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@
6565

6666
#define NB_FEATURES (NB_BANDS+3*NB_DELTA_CEPS+2)
6767

68+
/* We don't allow max attenuation to be more than 60dB */
69+
#define MIN_MAX_ATTENUATION 0.000001f
70+
6871

6972
#ifndef TRAINING
7073
#define TRAINING 0
@@ -100,6 +103,8 @@ struct DenoiseState {
100103
float mem_hp_x[2];
101104
float lastg[NB_BANDS];
102105
RNNState rnn;
106+
107+
float max_attenuation;
103108
};
104109

105110
#if SMOOTH_BANDS
@@ -508,6 +513,26 @@ float rnnoise_process_frame(DenoiseState *st, float *out, const float *in) {
508513
g[i] = MAX16(g[i], alpha*st->lastg[i]);
509514
st->lastg[i] = g[i];
510515
}
516+
517+
/* Apply maximum attenuation (minimum value) */
518+
if (st->max_attenuation) {
519+
float min = 1, mult;
520+
for (i=0;i<NB_BANDS;i++) {
521+
if (g[i] < min) min = g[i];
522+
}
523+
if (min < st->max_attenuation) {
524+
if (min < MIN_MAX_ATTENUATION)
525+
min = MIN_MAX_ATTENUATION;
526+
mult = st->max_attenuation / min;
527+
for (i=0;i<NB_BANDS;i++) {
528+
if (g[i] < MIN_MAX_ATTENUATION) g[i] = MIN_MAX_ATTENUATION;
529+
g[i] *= mult;
530+
if (g[i] > 1) g[i] = 1;
531+
st->lastg[i] = g[i];
532+
}
533+
}
534+
}
535+
511536
interp_band_gain(gf, g);
512537
#if 1
513538
for (i=0;i<FREQ_SIZE;i++) {
@@ -521,6 +546,18 @@ float rnnoise_process_frame(DenoiseState *st, float *out, const float *in) {
521546
return vad_prob;
522547
}
523548

549+
void rnnoise_set_param(DenoiseState *st, int param, float value)
550+
{
551+
switch (param) {
552+
case RNNOISE_PARAM_MAX_ATTENUATION:
553+
if ((value > MIN_MAX_ATTENUATION && value <= 1) || value == 0)
554+
st->max_attenuation = value;
555+
else
556+
st->max_attenuation = MIN_MAX_ATTENUATION;
557+
break;
558+
}
559+
}
560+
524561
#if TRAINING
525562

526563
static float uni_rand() {

0 commit comments

Comments
 (0)