diff --git a/src/common/compandor.c b/src/common/compandor.c index d7c7bce..aea20cd 100644 --- a/src/common/compandor.c +++ b/src/common/compandor.c @@ -1,4 +1,4 @@ -/* Compandor to use various networks like C-Netz / NMT / AMPS +/* Compandor to use various networks like C-Netz / NMT / AMPS / TACS * * (C) 2016 by Andreas Eversberg * All Rights Reserved @@ -46,7 +46,7 @@ static double sqrt_tab[10000]; * Hopefully this is correct * */ -void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, double unaffected_level) +void init_compandor(compandor_t *state, double samplerate, double attack_ms, double recovery_ms, double unaffected_level) { int i; @@ -56,10 +56,10 @@ void init_compandor(compandor_t *state, int samplerate, double attack_ms, double state->c.envelope = 1.0; state->e.peak = 1.0; state->e.envelope = 1.0; - state->c.step_up = pow(COMPRESS_ATTACK_FACTOR, 1000.0 / attack_ms / (double)samplerate); - state->c.step_down = pow(COMPRESS_RECOVERY_FACTOR, 1000.0 / recovery_ms / (double)samplerate); - state->e.step_up = pow(EXPAND_ATTACK_FACTOR, 1000.0 / attack_ms / (double)samplerate); - state->e.step_down = pow(EXPAND_RECOVERY_FACTOR, 1000.0 / recovery_ms / (double)samplerate); + state->c.step_up = pow(COMPRESS_ATTACK_FACTOR, 1000.0 / attack_ms / samplerate); + state->c.step_down = pow(COMPRESS_RECOVERY_FACTOR, 1000.0 / recovery_ms / samplerate); + state->e.step_up = pow(EXPAND_ATTACK_FACTOR, 1000.0 / attack_ms / samplerate); + state->e.step_down = pow(EXPAND_RECOVERY_FACTOR, 1000.0 / recovery_ms / samplerate); state->c.unaffected = unaffected_level; state->e.unaffected = unaffected_level; diff --git a/src/common/compandor.h b/src/common/compandor.h index 2151baa..cc53ad8 100644 --- a/src/common/compandor.h +++ b/src/common/compandor.h @@ -15,7 +15,7 @@ typedef struct compandor { } e; } compandor_t; -void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, double unaffected_level); +void init_compandor(compandor_t *state, double samplerate, double attack_ms, double recovery_ms, double unaffected_level); void compress_audio(compandor_t *state, sample_t *samples, int num); void expand_audio(compandor_t *state, sample_t *samples, int num); diff --git a/src/test/Makefile.am b/src/test/Makefile.am index 393a0b5..852c235 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -19,11 +19,16 @@ test_filter_LDADD = \ $(SOAPY_LIBS) \ -lm -test_compandor_SOURCES = test_compandor.c +test_compandor_SOURCES = \ + test_compandor.c \ + dummy.c test_compandor_LDADD = \ $(COMMON_LA) \ $(top_builddir)/src/common/libcommon.a \ + $(ALSA_LIBS) \ + $(UHD_LIBS) \ + $(SOAPY_LIBS) \ -lm test_emphasis_SOURCES = test_emphasis.c dummy.c diff --git a/src/test/test_compandor.c b/src/test/test_compandor.c index 6b7d4cb..4b0ff7b 100644 --- a/src/test/test_compandor.c +++ b/src/test/test_compandor.c @@ -11,7 +11,6 @@ #define SAMPLERATE 48000 #define ATTACK_MS 15.0 #define RECOVERY_MS 15.0 -#define UNAFFECTED 10000.0 static double test_frequency[3] = { 2000.0, 4000.0, 1000.0 }; @@ -29,24 +28,26 @@ static void generate_test_sample(double test_frequency) for (i = 0; i < SAMPLERATE; i++) { value = cos(2.0 * M_PI * test_frequency / (double)SAMPLERATE * i); - samples_4db[i] = (int)(UNAFFECTED * value * db2level(-4)); - samples_16db[i] = (int)(UNAFFECTED * value * db2level(-16)); - samples_2db[i] = (int)(UNAFFECTED * value * db2level(-2)); - samples_8db[i] = (int)(UNAFFECTED * value * db2level(-8)); - samples_0db[i] = (int)(UNAFFECTED * value); + samples_4db[i] = value * db2level(-4); + samples_16db[i] = value * db2level(-16); + samples_2db[i] = value * db2level(-2); + samples_8db[i] = value * db2level(-8); + samples_0db[i] = value; } } static void check_level(sample_t *samples, double duration, const char *desc, double target_db) { int i; - int last = 0, envelop = 0; + double last = 0.0, envelop = 0.0; int up = 0; double factor; int when = (int)((double)SAMPLERATE + (double)SAMPLERATE * duration / 1000.0 + 0.5); +//printf("%d %d\n", SAMPLERATE, when); for (i = 0; i < when; i++) { +//puts(debug_amplitude(samples[i])); if (last < samples[i]) { up = 1; } else if (last > samples[i]) { @@ -57,12 +58,12 @@ static void check_level(sample_t *samples, double duration, const char *desc, do } #if 0 if (i >= (SAMPLERATE-(SAMPLERATE/100)) && (i % (SAMPLERATE/(SAMPLERATE/10))) == 0) - printf("%s: envelop = %.4f (when=%d)\n", desc, level2db((double)envelop / UNAFFECTED), i); + printf("%s: envelop = %.4f (val=%.4f) (when=%d)\n", desc, level2db(envelop), envelop, i); #endif last = samples[i]; } - factor = (envelop / UNAFFECTED) / db2level(target_db); - printf("%s: envelop after the instance of %.1f ms is %.4f db factor =%.4f\n", desc, duration, level2db((double)envelop / UNAFFECTED), factor); + factor = envelop / db2level(target_db); + printf("%s: envelop after the instance of %.1f ms is %.4f db factor =%.4f\n", desc, duration, level2db(envelop), factor); } int main(void) @@ -71,47 +72,56 @@ int main(void) sample_t samples[SAMPLERATE * 2]; int f; - init_compandor(&cstate, SAMPLERATE, ATTACK_MS, RECOVERY_MS, UNAFFECTED); + init_compandor(&cstate, SAMPLERATE, ATTACK_MS, RECOVERY_MS, 1.0); for (f = 0; f < 3; f++) { /* -16 and -4 dB */ + printf("Testing frequency %.0f Hz:\n", test_frequency[f]); generate_test_sample(test_frequency[f]); +#if 0 + check_level(samples_0db, -100.0, "generate sample with 0db", 0.0); + check_level(samples_2db, -100.0, "generate sample with -2db", -2.0); + check_level(samples_4db, -100.0, "generate sample with -4db", -4.0); + check_level(samples_8db, -100.0, "generate sample with -8db", -8.0); + check_level(samples_16db, -100.0, "generate sample with -16db", -16.0); +#endif + /* low to high transition */ - memcpy(samples, samples_16db, SAMPLERATE * 2); - memcpy(samples + SAMPLERATE, samples_4db, SAMPLERATE * 2); + memcpy(samples, samples_16db, SAMPLERATE * sizeof(sample_t)); + memcpy(samples + SAMPLERATE, samples_4db, SAMPLERATE * sizeof(sample_t)); compress_audio(&cstate, samples, SAMPLERATE * 2); check_level(samples, ATTACK_MS, "compressor attack", -2.0); /* high to low transition */ - memcpy(samples, samples_4db, SAMPLERATE * 2); - memcpy(samples + SAMPLERATE, samples_16db, SAMPLERATE * 2); + memcpy(samples, samples_4db, SAMPLERATE * sizeof(sample_t)); + memcpy(samples + SAMPLERATE, samples_16db, SAMPLERATE * sizeof(sample_t)); compress_audio(&cstate, samples, SAMPLERATE * 2); check_level(samples, RECOVERY_MS, "compressor recovery", -8.0); /* low to high transition */ - memcpy(samples, samples_8db, SAMPLERATE * 2); - memcpy(samples + SAMPLERATE, samples_2db, SAMPLERATE * 2); + memcpy(samples, samples_8db, SAMPLERATE * sizeof(sample_t)); + memcpy(samples + SAMPLERATE, samples_2db, SAMPLERATE * sizeof(sample_t)); expand_audio(&cstate, samples, SAMPLERATE * 2); check_level(samples, ATTACK_MS, "expander attack", -4.0); /* high to low transition */ - memcpy(samples, samples_2db, SAMPLERATE * 2); - memcpy(samples + SAMPLERATE, samples_8db, SAMPLERATE * 2); + memcpy(samples, samples_2db, SAMPLERATE * sizeof(sample_t)); + memcpy(samples + SAMPLERATE, samples_8db, SAMPLERATE * sizeof(sample_t)); expand_audio(&cstate, samples, SAMPLERATE * 2); check_level(samples, RECOVERY_MS, "expander recovery", -16.0); /* 0 DB */ - memcpy(samples, samples_0db, SAMPLERATE * 2); - memcpy(samples + SAMPLERATE, samples_0db, SAMPLERATE * 2); + memcpy(samples, samples_0db, SAMPLERATE * sizeof(sample_t)); + memcpy(samples + SAMPLERATE, samples_0db, SAMPLERATE * sizeof(sample_t)); check_level(samples, RECOVERY_MS, "unaffected level", 0.0);