ref: bd2e9a34fba837386082e5e16f1b878a16f2274e
parent: caca188b5a0275b1c04baf8fcc9798b900692a2c
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Thu Dec 21 18:36:16 EST 2023
Add simulated loss to opus_demo
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,6 +138,9 @@
if ENABLE_OSCE
LPCNET_HEAD += $(OSCE_HEAD)
endif
+if ENABLE_LOSSGEN
+LPCNET_HEAD += $(LOSSGEN_HEAD)
+endif
libopus_la_SOURCES = $(CELT_SOURCES) $(SILK_SOURCES) $(LPCNET_SOURCES) $(OPUS_SOURCES)
libopus_la_LDFLAGS = -no-undefined -version-info @OPUS_LT_CURRENT@:@OPUS_LT_REVISION@:@OPUS_LT_AGE@
@@ -189,6 +192,9 @@
tests/test_opus_projection
opus_demo_SOURCES = src/opus_demo.c
+if ENABLE_LOSSGEN
+opus_demo_SOURCES += $(LOSSGEN_SOURCES)
+endif
opus_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,7 +9,7 @@
srcdir=`dirname $0`
test -n "$srcdir" && cd "$srcdir"
-dnn/download_model.sh 591c8ba
+dnn/download_model.sh caca188
echo "Updating build configuration files, please wait...."
--- a/configure.ac
+++ b/configure.ac
@@ -180,6 +180,15 @@
])
AM_CONDITIONAL([ENABLE_DEEP_PLC], [test "$enable_deep_plc" = "yes" || test "$enable_dred" = "yes" || test "$enable_osce" = "yes" || test "$enable_osce_training_data" = "yes"])
+AC_ARG_ENABLE([lossgen],
+ [AS_HELP_STRING([--enable-lossgen], [Build opus_demo with packet loss simulator])],,
+ [enable_lossgen=no])
+
+AS_IF([test "$enable_lossgen" = "yes"],[
+ AC_DEFINE([ENABLE_LOSSGEN], [1], [LOSSGEN])
+])
+AM_CONDITIONAL([ENABLE_LOSSGEN], [test "$enable_lossgen" = "yes"])
+
has_float_approx=no
case "$host_cpu" in
i[[3456]]86 | x86_64 | arm* | aarch64* | powerpc64 | powerpc32 | ia64)
--- a/dnn/lossgen.c
+++ b/dnn/lossgen.c
@@ -56,9 +56,7 @@
int sample_loss(
LossGenState *st,
- float percent_loss,
- int arch
- )
+ float percent_loss)
{
float input[2];
float tmp[LOSSGEN_DENSE_IN_OUT_SIZE];
@@ -67,10 +65,10 @@
LossGen *model = &st->model;
input[0] = st->last_loss;
input[1] = percent_loss;
- compute_generic_dense_lossgen(&model->lossgen_dense_in, tmp, input, ACTIVATION_TANH, arch);
- compute_generic_gru_lossgen(&model->lossgen_gru1_input, &model->lossgen_gru1_recurrent, st->gru1_state, tmp, arch);
- compute_generic_gru_lossgen(&model->lossgen_gru2_input, &model->lossgen_gru2_recurrent, st->gru2_state, st->gru1_state, arch);
- compute_generic_dense_lossgen(&model->lossgen_dense_out, &out, st->gru2_state, ACTIVATION_SIGMOID, arch);
+ compute_generic_dense_lossgen(&model->lossgen_dense_in, tmp, input, ACTIVATION_TANH, 0);
+ compute_generic_gru_lossgen(&model->lossgen_gru1_input, &model->lossgen_gru1_recurrent, st->gru1_state, tmp, 0);
+ compute_generic_gru_lossgen(&model->lossgen_gru2_input, &model->lossgen_gru2_recurrent, st->gru2_state, st->gru1_state, 0);
+ compute_generic_dense_lossgen(&model->lossgen_dense_out, &out, st->gru2_state, ACTIVATION_SIGMOID, 0);
loss = (float)rand()/RAND_MAX < out;
st->last_loss = loss;
return loss;
@@ -114,7 +112,7 @@
p = atof(argv[1]);
N = atoi(argv[2]);
for (i=0;i<N;i++) {
- printf("%d\n", sample_loss(&st, p, 0));
+ printf("%d\n", sample_loss(&st, p));
}
}
#endif
--- a/dnn/lossgen.h
+++ b/dnn/lossgen.h
@@ -23,8 +23,6 @@
int sample_loss(
LossGenState *st,
- float percent_loss,
- int arch
- );
+ float percent_loss);
#endif
--- a/dnn/torch/lossgen/train_lossgen.py
+++ b/dnn/torch/lossgen/train_lossgen.py
@@ -48,7 +48,7 @@
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
checkpoint['model_args'] = ()
-checkpoint['model_kwargs'] = {'gru1_size': 16, 'gru2_size': 48}
+checkpoint['model_kwargs'] = {'gru1_size': 16, 'gru2_size': 32}
model = lossgen.LossGen(*checkpoint['model_args'], **checkpoint['model_kwargs'])
dataset = LossDataset('loss_sorted.txt')
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True, drop_last=True, num_workers=4)
--- a/lpcnet_headers.mk
+++ b/lpcnet_headers.mk
@@ -38,3 +38,7 @@
dnn/nndsp.h \
dnn/lace_data.h \
dnn/nolace_data.h
+
+LOSSGEN_HEAD = \
+dnn/lossgen.h \
+dnn/lossgen_data.h
--- a/lpcnet_sources.mk
+++ b/lpcnet_sources.mk
@@ -30,6 +30,10 @@
dnn/lace_data.c \
dnn/nolace_data.c
+LOSSGEN_SOURCES = \
+dnn/lossgen.c \
+dnn/lossgen_data.c
+
DNN_SOURCES_X86_RTCD = dnn/x86/x86_dnn_map.c
DNN_SOURCES_AVX2 = dnn/x86/nnet_avx2.c
DNN_SOURCES_SSE4_1 = dnn/x86/nnet_sse4_1.c
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -39,6 +39,9 @@
#include "opus_types.h"
#include "opus_private.h"
#include "opus_multistream.h"
+#ifdef ENABLE_LOSSGEN
+#include "lossgen.h"
+#endif
#define MAX_PACKET 1500
@@ -111,6 +114,9 @@
fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" );
fprintf(stderr, "-dtx : enable SILK DTX\n" );
fprintf(stderr, "-loss <perc> : optimize for loss percentage and simulate packet loss, in percent (0-100); default: 0\n" );
+#ifdef ENABLE_LOSSGEN
+ fprintf(stderr, "-sim_loss <perc> : simulate realistic (bursty) packet loss from percentage, using generative model\n" );
+#endif
fprintf(stderr, "-lossfile <file> : simulate packet loss, reading loss from file\n" );
fprintf(stderr, "-dred <frames> : add Deep REDundancy (in units of 10-ms frames)\n" );
}
@@ -346,6 +352,10 @@
int forcechannels;
int cvbr = 0;
int packet_loss_perc;
+#ifdef ENABLE_LOSSGEN
+ float lossgen_perc = -1.f;
+ LossGenState lossgen;
+#endif
opus_int32 count=0, count_act=0;
int k;
opus_int32 skip=0;
@@ -555,6 +565,12 @@
} else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
packet_loss_perc = atoi( argv[ args + 1 ] );
args += 2;
+#ifdef ENABLE_LOSSGEN
+ } else if( strcmp( argv[ args ], "-sim_loss" ) == 0 ) {
+ lossgen_perc = atof( argv[ args + 1 ] );
+ lossgen_init(&lossgen);
+ args += 2;
+#endif
} else if( strcmp( argv[ args ], "-lossfile" ) == 0 ) {
packet_loss_file = fopen( argv[ args + 1 ], "r" );
if (packet_loss_file == NULL) {
@@ -933,6 +949,10 @@
if ( fscanf(packet_loss_file, "%d", &lost) != 1) {
lost = 0;
}
+#ifdef ENABLE_LOSSGEN
+ } else if (lossgen_perc >= 0) {
+ lost = sample_loss(&lossgen, lossgen_perc*.01f);
+#endif
} else {
lost = (packet_loss_perc>0) && (rand()%100 < packet_loss_perc);
}
--
⑨