From 98e10b262791b5f402062e63bd118ce3299f1495 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Thu, 21 Mar 2024 00:02:21 -0400 Subject: [PATCH] Automatic Gain On Analog WIP; Manual Gain Control; --- include/dsd.h | 2 ++ src/3.c | 4 +-- src/dsd_audio2.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++- src/dsd_symbol.c | 8 +++-- src/edacs-fme.c | 16 +++++---- 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index 043c4d4..386a9a4 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -983,6 +983,8 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state); //float stere void playSynthesizedVoiceFS4 (dsd_opts * opts, dsd_state * state); //float stereo mix 4v2 P25p2 void playSynthesizedVoiceFM (dsd_opts * opts, dsd_state * state); //float mono void agf (dsd_opts * opts, dsd_state * state, float samp[160], int slot); //float gain control +void agsm (dsd_opts * opts, dsd_state * state, short * input, int len); //short gain control for analog things +void analog_gain (dsd_opts * opts, dsd_state * state, short * input, int len); //manual gain handling for analong things //new short stuff void playSynthesizedVoiceSS (dsd_opts * opts, dsd_state * state); //short stereo mix void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state); //short stereo mix 3v2 DMR diff --git a/src/3.c b/src/3.c index ca974cf..ebbdbd7 100644 --- a/src/3.c +++ b/src/3.c @@ -526,9 +526,7 @@ void pbf(dsd_state * state, short * input, int len) for (i = 0; i < len; i++) { // fprintf (stderr, "\n in: %05d", input[i]); - // input[i] = PBFilter_Update(&state->PBF, input[i]); //filter only - input[i] = PBFilter_Update(&state->PBF, input[i]) * 1.5f; //add a little extra gain back - // fprintf (stderr, "\n out: %05d", input[i]); + input[i] = PBFilter_Update(&state->PBF, input[i]); } } diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c index e149850..0f4bdc5 100644 --- a/src/dsd_audio2.c +++ b/src/dsd_audio2.c @@ -1409,4 +1409,87 @@ void agf (dsd_opts * opts, dsd_state * state, float samp[160], int slot) // AGF_END: ; //do nothing -// } \ No newline at end of file +// } + +//automatic gain short mono for analog audio and some digital mono (WIP) +void agsm (dsd_opts * opts, dsd_state * state, short * input, int len) +{ + int i, j; + + UNUSED(state); + + float avg = 0.0f; //will float be suffient? + float coeff = 0.0f; //gain coeffiecient + float max = 0.0f; //the highest sample value he wave + float den = 1500.0f; //denominator value + float gain = (25.0f / opts->audio_gain); UNUSED(gain); + float samp[960]; memset (samp, 0.0f, 960*sizeof(float)); + + //assign internal float from short input + for (i = 0; i < len; i++) + samp[i] = (float)input[i]; + + // gain = 2.5f; + // for (i = 0; i < len; i++) + // samp[i] *= gain; + + for (j = 0; j < len/20; j++) + { + + for (i = 0; i < 20; i++) + { + if ( fabsf (samp[(j*20)+i]) > max) + { + max = fabsf (samp[(j*20)+i]); + } + } + + for (i = 0; i < 20; i++) + avg += (float)samp[(j*20)+i]; + + avg /= 20; + + coeff = fabsf (den / max); + + + //apply the coefficient to bring the max value to our desired maximum value + for (i = 0; i < 20; i++) + { + if ( fabsf (samp[(j*20)+i]) > 110.0f) //try not to apply to near zero values + samp[(j*20)+i] *= coeff; + } + + //debug + // fprintf (stderr, "\n M: %f; C: %f; A: %f; ", max, coeff, avg); + + max = 0; //reset + avg = 0; //reset + + } //end j loop + + // debug + // for (i = 0; i < len; i++) + // { + // fprintf (stderr, " in: %d", input[i]); + // fprintf (stderr, " out: %f", samp[i]); + // } + + //return new smaple values post agc + for (i = 0; i < len; i++) + input[i] = (short)samp[i]; + +} + +//until analog agc is fixed, going to use a manual gain control on this +//that scales a bit differently on the 1-50 index values +void analog_gain (dsd_opts * opts, dsd_state * state, short * input, int len) +{ + + int i; + UNUSED(state); + + float gain = 1.0f + (opts->audio_gain / 25.0f); //range is 1 - 3? + + for (i = 0; i < len; i++) + input[i] *= gain; +} \ No newline at end of file diff --git a/src/dsd_symbol.c b/src/dsd_symbol.c index 3e7523d..a22190c 100644 --- a/src/dsd_symbol.c +++ b/src/dsd_symbol.c @@ -278,13 +278,15 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync) sf_write_sync (opts->wav_out_raw); } + //manual gain control -- seems to work better if applied before filtering + analog_gain (opts, state, state->analog_out, 960); + // analog audio filtering // lpf(state, state->analog_out, 960); hpf (state, state->analog_out, 960); - //analog sounds really good now, still a tad bit quiet though - if (opts->audio_in_type == 3) //passband filter if using rtl_fm - pbf(state, state->analog_out, 960); + //analog sounds really good now + pbf(state, state->analog_out, 960); //unsure if this one helps anymore or not, probably not be setup correctly // if (opts->audio_in_type == 3) //notch filter if using rtl_fm diff --git a/src/edacs-fme.c b/src/edacs-fme.c index ae3364a..362f944 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -202,6 +202,11 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn sr += digitize (opts, state, (int)analog1[i]); } + //manual gain control + analog_gain (opts, state, analog1, 960); + analog_gain (opts, state, analog2, 960); + analog_gain (opts, state, analog3, 960); + // analog audio filtering // lpf (state, analog1, 960); // lpf (state, analog2, 960); @@ -211,13 +216,10 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn hpf (state, analog2, 960); hpf (state, analog3, 960); - //TODO: Test this somehow, the EDACS analog remote only ATM (Should be alright though) - if (opts->audio_in_type == 3) - { - pbf (state, analog1, 960); - pbf (state, analog2, 960); - pbf (state, analog3, 960); - } + pbf (state, analog1, 960); + pbf (state, analog2, 960); + pbf (state, analog3, 960); + //reconfigured to use seperate audio out stream that is always 48k short if (opts->audio_out_type == 0 && opts->slot1_on == 1)