From 324191d79f97f7f57b0891df73579c3584324a8c Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 23 Dec 2022 18:27:13 -0500 Subject: [PATCH] Disable Audio Smoothing TCP/RTL; Make User Toggle; --- README.md | 3 + include/dsd.h | 3 + src/dsd_audio.c | 12 +--- src/dsd_main.c | 36 +++++++++--- src/dsd_ncurses.c | 11 +++- src/dsd_upsample.c | 140 +++++++++++++++++++++++---------------------- 6 files changed, 119 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 5202b07..c95b1cf 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ sudo make install -t Set Trunking VC/sync loss hangtime in seconds. (default = 1 second) -q Reverse Mute - Mute Unencrypted Voice and Unmute Encrypted Voice -D Manually Set TIII DMR Location Area n bit len (0-10)(10 max) + -V Disable Audio Smoothing on Upsampled Audio (XDMA and DMR Stereo 24k/2 output) (Capital V) + (Audio Smoothing is now disabled on rtl, tcp, bin, and wav inputs by default -- fix crackle/buzz bug) ``` @@ -208,6 +210,7 @@ P - start per call decoded wav files p - stop per call decoded wav files 1 - Lockout Tuning/Playback of TG in Slot 1 or Conventional (Current Session Only) 2 - Lockout Tuning/Playback of TG in Slot 2 (Current Session Only) +0 - Toggle Audio Smoothing on Upsampled Audio (XDMA and DMR Stereo 24k/2 output) ``` diff --git a/include/dsd.h b/include/dsd.h index cb7fbe2..faafd34 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -640,6 +640,9 @@ typedef struct //Remus DMR End Call Alert Beep int dmr_end_alert[2]; //dmr TLC end call alert beep has already played once flag + //Upsampled Audio Smoothing + uint8_t audio_smoothing; + } dsd_state; /* diff --git a/src/dsd_audio.c b/src/dsd_audio.c index 98b8523..c24d533 100644 --- a/src/dsd_audio.c +++ b/src/dsd_audio.c @@ -92,11 +92,7 @@ processAudio (dsd_opts * opts, dsd_state * state) { // detect max level max = 0; - //attempt to reduce crackle by overriding the max value when not using pulse input - if (opts->audio_in_type != 0) - { - max = 3000; - } + state->audio_out_temp_buf_p = state->audio_out_temp_buf; for (n = 0; n < 160; n++) { @@ -238,11 +234,7 @@ processAudioR (dsd_opts * opts, dsd_state * state) { // detect max level max = 0; - //attempt to reduce crackle by overriding the max value when not using pulse input - if (opts->audio_in_type != 0) - { - max = 3000; - } + state->audio_out_temp_buf_pR = state->audio_out_temp_bufR; for (n = 0; n < 160; n++) { diff --git a/src/dsd_main.c b/src/dsd_main.c index 55117ea..736372d 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -196,12 +196,14 @@ noCarrier (dsd_opts * opts, dsd_state * state) state->firstframe = 0; if (opts->audio_gain == (float) 0) { - state->aout_gain = 25; + if (state->audio_smoothing == 0) state->aout_gain = 15; //15 + else state->aout_gain = 25; //25 } if (opts->audio_gainR == (float) 0) { - state->aout_gainR = 25; + if (state->audio_smoothing == 0) state->aout_gainR = 15; //15 + else state->aout_gainR = 25; //25 } memset (state->aout_max_buf, 0, sizeof (float) * 200); state->aout_max_buf_p = state->aout_max_buf; @@ -361,8 +363,8 @@ initOpts (dsd_opts * opts) opts->mbe_out_file[0] = 0; opts->mbe_out_path[0] = 0; opts->mbe_out_f = NULL; - opts->audio_gain = 0; - opts->audio_gainR = 0; + opts->audio_gain = 0; //0 + opts->audio_gainR = 0; //0 opts->audio_out = 1; opts->wav_out_file[0] = 0; opts->wav_out_fileR[0] = 0; @@ -514,6 +516,10 @@ initState (dsd_state * state) memset (state->dmr_payload_buf, 0, sizeof (int) * 200); //dmr buffer end state->repeat = 0; + + //Upsampled Audio Smoothing + state->audio_smoothing = 1; + state->audio_out_buf = malloc (sizeof (short) * 1000000); state->audio_out_bufR = malloc (sizeof (short) * 1000000); memset (state->audio_out_buf, 0, 100 * sizeof (short)); @@ -590,7 +596,8 @@ initState (dsd_state * state) state->firstframe = 0; sprintf (state->slot1light, "%s", ""); sprintf (state->slot2light, "%s", ""); - state->aout_gain = 25; + state->aout_gain = 0; + state->aout_gainR = 0; memset (state->aout_max_buf, 0, sizeof (float) * 200); state->aout_max_buf_p = state->aout_max_buf; state->aout_max_buf_idx = 0; @@ -898,7 +905,7 @@ usage () printf (" -fp Decode only EDACS/ProVoice*\n"); printf (" -fm Decode only dPMR*\n"); printf (" -l Disable DMR and NXDN input filtering\n"); - printf (" -pu Unmute Encrypted P25\n"); + // printf (" -pu Unmute Encrypted P25\n"); printf (" -u Unvoiced speech quality (default=3)\n"); printf (" -xx Expect non-inverted X2-TDMA signal\n"); printf (" -xr Expect inverted DMR signal\n"); @@ -957,6 +964,8 @@ usage () printf (" P25 - 7000; NXDN48 - 4000; DMR - 7000; EDACS/PV - 12500; May vary based on system stregnth, etc.\n"); printf (" -t Set Trunking VC/sync loss hangtime in seconds. (default = 1 second)\n"); printf (" -q Reverse Mute - Mute Unencrypted Voice and Unmute Encrypted Voice\n"); + printf (" -V Disable Audio Smoothing on Upsampled Audio (XDMA and DMR Stereo 24k/2 output) (Capital V)\n"); + printf (" (Audio Smoothing is now disabled on rtl, tcp, bin, and wav inputs by default -- fix crackle/buzz bug)\n"); printf ("\n"); exit (0); } @@ -1168,7 +1177,7 @@ main (int argc, char **argv) exitflag = 0; // signal (SIGINT, sigfun); - while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:H:X:NQWrlZTF1:2:345:6:7:89:")) != -1) + while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:Y:K:H:X:NQWrlZTF01:2:345:6:7:89:")) != -1) { opterr = 0; switch (c) @@ -1180,12 +1189,18 @@ main (int argc, char **argv) opts.call_alert = 1; break; - //Free'd up switches include v,Q,V,Y,z + //Free'd up switches include Q,Y,z //make sure to put a colon : after each if they need an argument //or remove colon if no argument required //Disabled the Serial Port Dev and Baud Rate, etc, If somebody uses that function, sorry... + //Disable Audio Smoothing for Upsampled Audio + case '0': + case 'V': + state.audio_smoothing = 0; + break; + //Trunking - Use Group List as Allow List case 'W': opts.trunk_use_allow_list = 1; @@ -1499,15 +1514,18 @@ main (int argc, char **argv) if (opts.audio_gain < (float) 0 ) { fprintf (stderr,"Disabling audio out gain setting\n"); + opts.audio_gainR = opts.audio_gain; } else if (opts.audio_gain == (float) 0) { opts.audio_gain = (float) 0; + opts.audio_gainR = opts.audio_gain; fprintf (stderr,"Enabling audio out auto-gain\n"); } else { fprintf (stderr,"Setting audio out gain to %f\n", opts.audio_gain); + opts.audio_gainR = opts.audio_gain; state.aout_gain = opts.audio_gain; state.aout_gainR = opts.audio_gain; } @@ -2037,6 +2055,7 @@ main (int argc, char **argv) fprintf (stderr, "%d \n", opts.tcp_portno); opts.tcp_sockfd = Connect(opts.tcp_hostname, opts.tcp_portno); opts.audio_in_type = 8; + state.audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing } //need error handling on opening rigctl so we don't exit or crash on disconnect @@ -2104,6 +2123,7 @@ main (int argc, char **argv) fprintf (stderr, "SQ %d ", opts.rtl_squelch_level); fprintf (stderr, "UDP %d \n", opts.rtl_udp_port); opts.audio_in_type = 3; + state.audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing rtl_ok = 1; #endif diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 71938a1..a2c939a 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -2032,7 +2032,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } if (opts->audio_out_type == 0) { - printw ("| Pulse Audio Output: [%2i] kHz [%i] Channel\n", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels); + printw ("| Pulse Audio Output: [%2i] kHz [%i] Channel", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels); + if (state->audio_smoothing == 1 && opts->pulse_digi_rate_out != 8000) printw (" Smoothing On"); + if (state->audio_smoothing == 0 && opts->pulse_digi_rate_out != 8000) printw (" Smoothing Off"); + printw (" \n"); } if (opts->monitor_input_audio == 1) { @@ -3096,6 +3099,12 @@ if (opts->frame_provoice != 1 && c == 50) //'2' key, lockout slot 2 tdma tgR fro } +if (c == 48) //'0' key, toggle upsampled audio smoothing +{ + if (state->audio_smoothing == 1) state->audio_smoothing = 0; + else state->audio_smoothing = 1; +} + //anything with an entry box will need the inputs and outputs stopped first //so probably just write a function to handle c input, and when c = certain values //needing an entry box, then stop all of those diff --git a/src/dsd_upsample.c b/src/dsd_upsample.c index a700acd..5d869bd 100644 --- a/src/dsd_upsample.c +++ b/src/dsd_upsample.c @@ -54,79 +54,85 @@ upsample (dsd_state * state, float invalue) *outbuf1 = d; outbuf1++; - if (state->currentslot == 1 && state->dmr_stereo == 1) + //only if enabled, produces crackling/buzzing sounds when input type is not pulse audio (reason still unknown) + //also, could be improved to provide better audio in the future + if (state->audio_smoothing == 1) { - if (state->audio_out_idx2R > 24) + if (state->currentslot == 1 && state->dmr_stereo == 1) { - // smoothing - outbuf1 -= 16; - for (j = 0; j < 4; j++) + if (state->audio_out_idx2R > 24) { - for (i = 0; i < 6; i++) + // smoothing + outbuf1 -= 16; + for (j = 0; j < 4; j++) + { + for (i = 0; i < 6; i++) + { + sum = 0; + outbuf1 -= 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 -= 2; + *outbuf1 = (sum / (float) 3); + outbuf1++; + } + outbuf1 -= 8; + } + } + } + if (state->currentslot == 0 && state->dmr_stereo == 1) + { + if (state->audio_out_idx2 > 24) + { + // smoothing + outbuf1 -= 16; + for (j = 0; j < 4; j++) { - sum = 0; - outbuf1 -= 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 -= 2; - *outbuf1 = (sum / (float) 3); - outbuf1++; + for (i = 0; i < 6; i++) + { + sum = 0; + outbuf1 -= 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 -= 2; + *outbuf1 = (sum / (float) 3); + outbuf1++; + } + outbuf1 -= 8; + } + } + } + if (state->dmr_stereo == 0) + { + if (state->audio_out_idx2 > 24) + { + // smoothing + outbuf1 -= 16; + for (j = 0; j < 4; j++) + { + for (i = 0; i < 6; i++) + { + sum = 0; + outbuf1 -= 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 += 2; + sum += (int)*outbuf1; + outbuf1 -= 2; + *outbuf1 = (sum / (float) 3); + outbuf1++; + } + outbuf1 -= 8; } - outbuf1 -= 8; } } } - if (state->currentslot == 0 && state->dmr_stereo == 1) - { - if (state->audio_out_idx2 > 24) - { - // smoothing - outbuf1 -= 16; - for (j = 0; j < 4; j++) - { - for (i = 0; i < 6; i++) - { - sum = 0; - outbuf1 -= 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 -= 2; - *outbuf1 = (sum / (float) 3); - outbuf1++; - } - outbuf1 -= 8; - } - } - } - if (state->dmr_stereo == 0) - { - if (state->audio_out_idx2 > 24) - { - // smoothing - outbuf1 -= 16; - for (j = 0; j < 4; j++) - { - for (i = 0; i < 6; i++) - { - sum = 0; - outbuf1 -= 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 += 2; - sum += (int)*outbuf1; - outbuf1 -= 2; - *outbuf1 = (sum / (float) 3); - outbuf1++; - } - outbuf1 -= 8; - } - } - } + }