From 676c5f0f093e226e79c43d5e2eb198b90c06628e Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Wed, 27 Dec 2023 18:08:52 -0500 Subject: [PATCH] Patch - Cleanup Old/Obsolete Patches; --- patch/g_dmr_per_call_wav_file_fixes.patch | 489 ----------- ...call_wav_file_fixes_w_custom_wav_dir.patch | 461 ----------- patch/p25p2_superframe_18V_tests2.patch | 769 ------------------ ...f_dmr_mono_stereo_interleaving_tests.patch | 105 --- ...dmr__mono_stereo_interleaving_tests2.patch | 228 ------ 5 files changed, 2052 deletions(-) delete mode 100644 patch/g_dmr_per_call_wav_file_fixes.patch delete mode 100644 patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir.patch delete mode 100644 patch/p25p2_superframe_18V_tests2.patch delete mode 100644 patch/wolf_dmr_mono_stereo_interleaving_tests.patch delete mode 100644 patch/wolf_p25p2_and_dmr__mono_stereo_interleaving_tests2.patch diff --git a/patch/g_dmr_per_call_wav_file_fixes.patch b/patch/g_dmr_per_call_wav_file_fixes.patch deleted file mode 100644 index 9eb4aa1..0000000 --- a/patch/g_dmr_per_call_wav_file_fixes.patch +++ /dev/null @@ -1,489 +0,0 @@ -diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c -index 0780788..7e8a3bc 100644 ---- a/src/dmr_csbk.c -+++ b/src/dmr_csbk.c -@@ -518,6 +518,25 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - //rigctl - if (opts->use_rigctl == 1) - { -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away - //reset some strings - sprintf (state->call_string[state->currentslot], "%s", " "); //21 spaces -@@ -534,6 +553,26 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - else if (opts->audio_in_type == 3) - { - #ifdef USE_RTLSDR -+ -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away - //reset some strings - sprintf (state->call_string[state->currentslot], "%s", " "); //21 spaces -diff --git a/src/dmr_flco.c b/src/dmr_flco.c -index 2c54880..44977f6 100644 ---- a/src/dmr_flco.c -+++ b/src/dmr_flco.c -@@ -10,6 +10,38 @@ - *-----------------------------------------------------------------------------*/ - - #include "dsd.h" -+//I really just need to make ONE consolidated date and time function that works correctly -+char * getDateFLC(void) { -+ #ifdef AERO_BUILD -+ char datename[80]; -+ #else -+ char datename[99]; -+ #endif -+ char * curr2; -+ struct tm * to; -+ time_t t; -+ t = time(NULL); -+ to = localtime( & t); -+ strftime(datename, sizeof(datename), "%Y%m%d", to); -+ curr2 = strtok(datename, " "); -+ return curr2; -+} -+ -+//fix from YorgosTheodorakis fork -- https://github.com/YorgosTheodorakis/dsd-fme/commit/7884ee555521a887d388152b3b1f11f20433a94b -+char * getTimeFLC(void) //get pretty hhmmss timestamp -+{ -+ char * curr = (char *) malloc(9); -+ time_t t = time(NULL); -+ struct tm * ptm = localtime(& t); -+ sprintf( -+ curr, -+ "%02d%02d%02d", -+ ptm->tm_hour, -+ ptm->tm_min, -+ ptm->tm_sec -+ ); -+ return curr; -+} - - //combined flco handler (vlc, tlc, emb), minus the superfluous structs and strings - void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t CRCCorrect, uint32_t IrrecoverableErrors, uint8_t type) -@@ -304,6 +336,14 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - state->dmr_so = so; - state->lasttg = target; - state->lastsrc = source; -+ char * timestr; -+ timestr = getTimeFLC(); -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f == NULL) -+ { -+ sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateFLC(), timestr, state->dmr_color_code, target, source); -+ openWavOutFileL (opts, state); -+ } - } - if (state->currentslot == 1) - { -@@ -311,6 +351,14 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - state->dmr_soR = so; - state->lasttgR = target; - state->lastsrcR = source; -+ char * timestr; -+ timestr = getTimeFLC(); -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR == NULL) -+ { -+ sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateFLC(), timestr, state->dmr_color_code, target, source); -+ openWavOutFileR (opts, state); -+ } - } - - //update cc amd vc sync time for trunking purposes (particularly Con+) -@@ -337,6 +385,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gain = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } - } - if (state->currentslot == 1) - { -@@ -350,6 +404,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gainR = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } - } - - } -diff --git a/src/dsd_file.c b/src/dsd_file.c -index 8e9094c..4ccec6a 100644 ---- a/src/dsd_file.c -+++ b/src/dsd_file.c -@@ -366,7 +366,7 @@ void closeMbeOutFile (dsd_opts * opts, dsd_state * state) - fclose (opts->mbe_out_f); - opts->mbe_out_f = NULL; - opts->mbe_out = 0; -- fprintf (stderr, "\nClosing MBE out file 1.\n"); -+ // fprintf (stderr, "\nClosing MBE out file 1.\n"); - } - - } -@@ -385,7 +385,7 @@ void closeMbeOutFileR (dsd_opts * opts, dsd_state * state) - fclose (opts->mbe_out_fR); - opts->mbe_out_fR = NULL; - opts->mbe_outR = 0; -- fprintf (stderr, "\nClosing MBE out file 2.\n"); -+ // fprintf (stderr, "\nClosing MBE out file 2.\n"); - } - - } -@@ -420,7 +420,7 @@ void openMbeOutFile (dsd_opts * opts, dsd_state * state) - } - - state->tgcount = 0; -- -+ //TODO: Change the date/time functions here to operate without using colons - sprintf (opts->mbe_out_file, "%s %s S1%s", getDateF(), getTimeF(), ext); - - sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_file); -@@ -467,7 +467,7 @@ void openMbeOutFileR (dsd_opts * opts, dsd_state * state) - } - - state->tgcount = 0; -- -+ //TODO: Change the date/time functions here to operate without using colons - sprintf (opts->mbe_out_fileR, "%s %s S2%s", getDateF(), getTimeF(), ext); - - sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_fileR); -@@ -557,6 +557,43 @@ void closeWavOutFile (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ -+ //TODO: Remove .wav extension in the wav file itself when opening them, and then concantenate .wav and run the system command to 'mv' it and rename it that way -+ char shell[2065], newfilename[1032], tempa[1024], tempb[1032]; //make these larger if needed -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+ //of course, the cygwin build doesn't seem to support the system() command properly, wasted way too much time on this, should have just went with -+ //the rename() function immediately instead, damned piece of sH*t -+ //If I pursue this fix later on, just using rename will be a better option, unsure if we would need to -+ //change the / to a \ for windows or not though -+#ifdef AERO_BUILD -+ // opts->wav_out_file[1] = '\b'; -+ // newfilename[1] = '\b'; -+ -+ opts->wav_out_file[5] = '\\'; -+ newfilename[5] = '\\'; -+ memcpy (tempa, opts->wav_out_file+2, 1022); -+ memcpy (tempb, newfilename+2, 1030); -+ UNUSED(shell); -+ -+ // sprintf (shell, "move \"%s\" \"%s\" ", opts->wav_out_file, newfilename); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", opts->wav_out_file, newfilename); //debug -+ // sprintf (shell, "move \"%s\" \"%s\" ", tempa, tempb); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", tempa, tempb); //debug -+ // fprintf (stderr, "%s", shell); //debug -+ -+ result = rename (tempa, tempb); -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_file, newfilename); -+ result = system (shell); -+ UNUSED2(tempa, tempb); -+#endif -+ // result = system (shell); -+ -+ //TODO: Check output of result for failure -+ // fprintf (stderr, "\n Close WAV FileF %s; Result: %d \n", newfilename, result); -+ UNUSED(result); -+ - } - - void closeWavOutFileL (dsd_opts * opts, dsd_state * state) -@@ -564,6 +601,40 @@ void closeWavOutFileL (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ -+ //TODO: Remove .wav extension in the wav file itself when opening them, and then concantenate .wav and run the system command to 'mv' it and rename it that way -+ char shell[2065], newfilename[1032], tempa[1024], tempb[1032]; //make these larger if needed -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+#ifdef AERO_BUILD -+ // opts->wav_out_file[1] = '\b'; -+ // newfilename[1] = '\b'; -+ -+ opts->wav_out_file[5] = '\\'; -+ newfilename[5] = '\\'; -+ memcpy (tempa, opts->wav_out_file+2, 1022); -+ memcpy (tempb, newfilename+2, 1030); -+ UNUSED(shell); -+ -+ // sprintf (shell, "move \"%s\" \"%s\" ", opts->wav_out_file, newfilename); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", opts->wav_out_file, newfilename); //debug -+ // sprintf (shell, "move \"%s\" \"%s\" ", tempa, tempb); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", tempa, tempb); //debug -+ // fprintf (stderr, "%s", shell); //debug -+ -+ result = rename (tempa, tempb); -+ -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_file, newfilename); -+ result = system (shell); -+ UNUSED2(tempa, tempb); -+#endif -+ // result = system (shell); -+ -+ //TODO: Check output of result for failure -+ // fprintf (stderr, "\n Close WAV FileL %s; Result: %d \n", newfilename, result); -+ UNUSED(result); -+ - } - - void closeWavOutFileR (dsd_opts * opts, dsd_state * state) -@@ -571,6 +642,40 @@ void closeWavOutFileR (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_fR); -+ -+ //TODO: Remove .wav extension in the wav file itself when opening them, and then concantenate .wav and run the system command to 'mv' it and rename it that way -+ char shell[2065], newfilename[1032], tempa[1024], tempb[1032]; //make these larger if needed -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_fileR); -+#ifdef AERO_BUILD -+ -+ // opts->wav_out_fileR[1] = '\b'; -+ // newfilename[1] = '\b'; -+ -+ UNUSED(shell); -+ opts->wav_out_fileR[5] = '\\'; -+ newfilename[5] = '\\'; -+ memcpy (tempa, opts->wav_out_fileR+2, 1022); -+ memcpy (tempb, newfilename+2, 1030); -+ -+ // sprintf (shell, "move \"%s\" \"%s\" ", opts->wav_out_fileR, newfilename); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", opts->wav_out_fileR, newfilename); //debug -+ // sprintf (shell, "move \"%s\" \"%s\" ", tempa, tempb); -+ // fprintf (stderr, " move \"%s\" \"%s\" ", tempa, tempb); //debug -+ // fprintf (stderr, "%s", shell); //debug -+ -+ result = rename (tempa, tempb); -+ -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_fileR, newfilename); -+ result = system (shell); -+ UNUSED2(tempa, tempb); -+#endif -+ // result = system (shell); -+ -+ //TODO: Check output of result for failure -+ // fprintf (stderr, "\n Close WAV FileR %s; Result: %d \n", newfilename, result); -+ UNUSED(result); - } - - void closeWavOutFileRaw (dsd_opts * opts, dsd_state * state) -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 58174be..64ec180 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -107,6 +107,19 @@ void - noCarrier (dsd_opts * opts, dsd_state * state) - { - -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ //end perCall wav file close -+ - #ifdef AERO_BUILD - //TODO: Investigate why getSymbol needs to be run first in this context...truly confused here - if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 -diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c -index 9f609ca..f23209c 100644 ---- a/src/dsd_mbe.c -+++ b/src/dsd_mbe.c -@@ -1191,7 +1191,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0) - { - //write wav to per call on left channel Slot 1 -- writeSynthesizedVoice (opts, state); -+ if (opts->wav_out_f != NULL) -+ writeSynthesizedVoice (opts, state); - } - } - -@@ -1201,7 +1202,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0) - { - //write wav to per call on right channel Slot 2 -- writeSynthesizedVoiceR (opts, state); -+ if (opts->wav_out_fR != NULL) -+ writeSynthesizedVoiceR (opts, state); - } - } - -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..4e29344 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -999,7 +999,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) - if (choicec == 12) - { - //flesh out all closewavs and sprint "" wav filenames -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - //closeWavOutFileRaw (opts, state); -@@ -2063,6 +2063,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->dmr_stereo_wav == 1 && src != 0 ) //&& tgn != 0, some TG can be 0 on NXDN - { - //close old first, assign name based on time and radio, open wav file -+ if (opts->wav_out_f != NULL) - closeWavOutFileL (opts, state); - sprintf (opts->wav_out_file, "./%s/%s %s NXDN - RAN %d - TGT %d - SRC %d.wav", opts->wav_out_dir, getDateN(), timestr, rn, tgn, src); - openWavOutFileL (opts, state); //testing for now, will want to move to per call later -@@ -2105,13 +2106,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- sprintf (opts->wav_out_file, "./%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2126,7 +2128,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - - //DMR BS Slot 1 - matrix 0-4 -- if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 || lls == 35 || lls == 36) ) -+ if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 ) ) //|| lls == 35 || lls == 36 - { - - for (short int k = 0; k < 4; k++) -@@ -2147,14 +2149,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[4][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- -- sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2190,20 +2192,21 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rdR and tgR are not 0 -- if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileR (opts, state); -- sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tgR, rdR); -- openWavOutFileR (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_fR != NULL) -+ // closeWavOutFileR (opts, state); -+ // sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tgR, rdR); -+ // openWavOutFileR (opts, state); //testing for now, will want to move to per call later -+ // } - -- if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -- { -- //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -- beeper (opts, state, 1); -- state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -- } -+ // if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -+ // beeper (opts, state, 1); -+ // state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -+ // } - - memset(state->dmr_alias_block_segment[1], 0, sizeof(state->dmr_alias_block_segment[1])); - sprintf (state->dmr_embedded_gps[1], "%s", ""); -@@ -3913,7 +3916,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (c == 112) //'p' key - stop all per call wav files - { - //hope this one doesn't cause random crashing or garbage writing -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - sprintf (opts->wav_out_file, "%s", ""); diff --git a/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir.patch b/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir.patch deleted file mode 100644 index e0167c1..0000000 --- a/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir.patch +++ /dev/null @@ -1,461 +0,0 @@ -diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c -index a315421..441a4b8 100644 ---- a/src/dmr_csbk.c -+++ b/src/dmr_csbk.c -@@ -518,6 +518,25 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - //rigctl - if (opts->use_rigctl == 1) - { -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away - //reset some strings - sprintf (state->call_string[state->currentslot], "%s", " "); //21 spaces -@@ -534,6 +553,26 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - else if (opts->audio_in_type == 3) - { - #ifdef USE_RTLSDR -+ -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away - //reset some strings - sprintf (state->call_string[state->currentslot], "%s", " "); //21 spaces -diff --git a/src/dmr_flco.c b/src/dmr_flco.c -index 2c54880..44977f6 100644 ---- a/src/dmr_flco.c -+++ b/src/dmr_flco.c -@@ -10,6 +10,38 @@ - *-----------------------------------------------------------------------------*/ - - #include "dsd.h" -+//I really just need to make ONE consolidated date and time function that works correctly -+char * getDateFLC(void) { -+ #ifdef AERO_BUILD -+ char datename[80]; -+ #else -+ char datename[99]; -+ #endif -+ char * curr2; -+ struct tm * to; -+ time_t t; -+ t = time(NULL); -+ to = localtime( & t); -+ strftime(datename, sizeof(datename), "%Y%m%d", to); -+ curr2 = strtok(datename, " "); -+ return curr2; -+} -+ -+//fix from YorgosTheodorakis fork -- https://github.com/YorgosTheodorakis/dsd-fme/commit/7884ee555521a887d388152b3b1f11f20433a94b -+char * getTimeFLC(void) //get pretty hhmmss timestamp -+{ -+ char * curr = (char *) malloc(9); -+ time_t t = time(NULL); -+ struct tm * ptm = localtime(& t); -+ sprintf( -+ curr, -+ "%02d%02d%02d", -+ ptm->tm_hour, -+ ptm->tm_min, -+ ptm->tm_sec -+ ); -+ return curr; -+} - - //combined flco handler (vlc, tlc, emb), minus the superfluous structs and strings - void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t CRCCorrect, uint32_t IrrecoverableErrors, uint8_t type) -@@ -304,6 +336,14 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - state->dmr_so = so; - state->lasttg = target; - state->lastsrc = source; -+ char * timestr; -+ timestr = getTimeFLC(); -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f == NULL) -+ { -+ sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateFLC(), timestr, state->dmr_color_code, target, source); -+ openWavOutFileL (opts, state); -+ } - } - if (state->currentslot == 1) - { -@@ -311,6 +351,14 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - state->dmr_soR = so; - state->lasttgR = target; - state->lastsrcR = source; -+ char * timestr; -+ timestr = getTimeFLC(); -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR == NULL) -+ { -+ sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateFLC(), timestr, state->dmr_color_code, target, source); -+ openWavOutFileR (opts, state); -+ } - } - - //update cc amd vc sync time for trunking purposes (particularly Con+) -@@ -337,6 +385,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gain = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } - } - if (state->currentslot == 1) - { -@@ -350,6 +404,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gainR = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } - } - - } -diff --git a/src/dsd_file.c b/src/dsd_file.c -index 8e9094c..e8441ec 100644 ---- a/src/dsd_file.c -+++ b/src/dsd_file.c -@@ -366,7 +366,7 @@ void closeMbeOutFile (dsd_opts * opts, dsd_state * state) - fclose (opts->mbe_out_f); - opts->mbe_out_f = NULL; - opts->mbe_out = 0; -- fprintf (stderr, "\nClosing MBE out file 1.\n"); -+ // fprintf (stderr, "\nClosing MBE out file 1.\n"); - } - - } -@@ -385,7 +385,7 @@ void closeMbeOutFileR (dsd_opts * opts, dsd_state * state) - fclose (opts->mbe_out_fR); - opts->mbe_out_fR = NULL; - opts->mbe_outR = 0; -- fprintf (stderr, "\nClosing MBE out file 2.\n"); -+ // fprintf (stderr, "\nClosing MBE out file 2.\n"); - } - - } -@@ -420,7 +420,7 @@ void openMbeOutFile (dsd_opts * opts, dsd_state * state) - } - - state->tgcount = 0; -- -+ //TODO: Change the date/time functions here to operate without using colons - sprintf (opts->mbe_out_file, "%s %s S1%s", getDateF(), getTimeF(), ext); - - sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_file); -@@ -467,7 +467,7 @@ void openMbeOutFileR (dsd_opts * opts, dsd_state * state) - } - - state->tgcount = 0; -- -+ //TODO: Change the date/time functions here to operate without using colons - sprintf (opts->mbe_out_fileR, "%s %s S2%s", getDateF(), getTimeF(), ext); - - sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_fileR); -@@ -557,6 +557,19 @@ void closeWavOutFile (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ char shell[2065], newfilename[1032]; -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+#ifdef AERO_BUILD -+ result = rename (opts->wav_out_file, newfilename); -+ UNUSED(shell); -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_file, newfilename); -+ result = system (shell); -+#endif -+ // fprintf (stderr, "\n Close WAV FileF %s; Result: %d \n", newfilename, result); -+ UNUSED(result); -+ - } - - void closeWavOutFileL (dsd_opts * opts, dsd_state * state) -@@ -564,6 +577,19 @@ void closeWavOutFileL (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ char shell[2065], newfilename[1032]; -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+#ifdef AERO_BUILD -+ result = rename (opts->wav_out_file, newfilename); -+ UNUSED(shell); -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_file, newfilename); -+ result = system (shell); -+#endif -+ // fprintf (stderr, "\n Close WAV FileL %s; Result: %d \n", newfilename, result); -+ UNUSED(result); -+ - } - - void closeWavOutFileR (dsd_opts * opts, dsd_state * state) -@@ -571,6 +597,18 @@ void closeWavOutFileR (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_fR); -+ char shell[2065], newfilename[1032]; -+ int result; -+ sprintf (newfilename, "%s.wav", opts->wav_out_fileR); -+#ifdef AERO_BUILD -+ result = rename (opts->wav_out_fileR, newfilename); -+ UNUSED(shell); -+#else -+ sprintf (shell, "mv '%s' '%s'", opts->wav_out_fileR, newfilename); -+ result = system (shell); -+#endif -+ // fprintf (stderr, "\n Close WAV FileR %s; Result: %d \n", newfilename, result); -+ UNUSED(result); - } - - void closeWavOutFileRaw (dsd_opts * opts, dsd_state * state) -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 1d2616b..c3a216d 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -107,6 +107,19 @@ void - noCarrier (dsd_opts * opts, dsd_state * state) - { - -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ //end perCall wav file close -+ - #ifdef AERO_BUILD - //TODO: Investigate why getSymbol needs to be run first in this context...truly confused here - if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 -@@ -1568,9 +1581,9 @@ main (int argc, char **argv) - } - - #ifdef AERO_BUILD -- fprintf (stderr, "Build Version: AW (20231015) \n"); -+ fprintf (stderr, "Build Version: AW (20231214) G Build\n"); - #else -- fprintf (stderr, "Build Version: AW %s \n", GIT_TAG); -+ fprintf (stderr, "Build Version: AW %s G Build\n", GIT_TAG); - #endif - fprintf (stderr,"MBElib Version: %s\n", versionstr); - -diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c -index 9f609ca..f23209c 100644 ---- a/src/dsd_mbe.c -+++ b/src/dsd_mbe.c -@@ -1191,7 +1191,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0) - { - //write wav to per call on left channel Slot 1 -- writeSynthesizedVoice (opts, state); -+ if (opts->wav_out_f != NULL) -+ writeSynthesizedVoice (opts, state); - } - } - -@@ -1201,7 +1202,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0) - { - //write wav to per call on right channel Slot 2 -- writeSynthesizedVoiceR (opts, state); -+ if (opts->wav_out_fR != NULL) -+ writeSynthesizedVoiceR (opts, state); - } - } - -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..ab5497e 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -999,7 +999,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) - if (choicec == 12) - { - //flesh out all closewavs and sprint "" wav filenames -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - //closeWavOutFileRaw (opts, state); -@@ -2063,6 +2063,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->dmr_stereo_wav == 1 && src != 0 ) //&& tgn != 0, some TG can be 0 on NXDN - { - //close old first, assign name based on time and radio, open wav file -+ if (opts->wav_out_f != NULL) - closeWavOutFileL (opts, state); - sprintf (opts->wav_out_file, "./%s/%s %s NXDN - RAN %d - TGT %d - SRC %d.wav", opts->wav_out_dir, getDateN(), timestr, rn, tgn, src); - openWavOutFileL (opts, state); //testing for now, will want to move to per call later -@@ -2105,13 +2106,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- sprintf (opts->wav_out_file, "./%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2126,7 +2128,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - - //DMR BS Slot 1 - matrix 0-4 -- if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 || lls == 35 || lls == 36) ) -+ if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 ) ) //|| lls == 35 || lls == 36 - { - - for (short int k = 0; k < 4; k++) -@@ -2147,14 +2149,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[4][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- -- sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2190,20 +2192,21 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rdR and tgR are not 0 -- if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -- { -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileR (opts, state); -- sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tgR, rdR); -- openWavOutFileR (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_fR != NULL) -+ // closeWavOutFileR (opts, state); -+ // sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tgR, rdR); -+ // openWavOutFileR (opts, state); //testing for now, will want to move to per call later -+ // } - -- if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -- { -- //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -- beeper (opts, state, 1); -- state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -- } -+ // if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -+ // beeper (opts, state, 1); -+ // state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -+ // } - - memset(state->dmr_alias_block_segment[1], 0, sizeof(state->dmr_alias_block_segment[1])); - sprintf (state->dmr_embedded_gps[1], "%s", ""); -@@ -2275,7 +2278,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->ncurses_compact == 1) - { - printw ("------------------------------------------------------------------------------\n"); -- printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)"); -+ printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231214)"); - printw ("------------------------------------------------------------------------------\n"); - } - #elif LIMAZULUTWEAKS -@@ -2313,13 +2316,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (i == 4 && opts->frame_m17 == 1) printw (" CODEC2"); - #endif - #ifdef AERO_BUILD -- if (i == 5) printw (" %s ", "Aero Build"); -- if (i == 6) printw (" AW (20231015) \n"); -+ if (i == 5) printw (" %s ", "G Build"); -+ if (i == 6) printw (" AW (20231214) \n"); - #elif ZDEV_BUILD -- if (i == 5) printw (" %s ", "AW "); -+ if (i == 5) printw (" %s ", "AW G Build"); - if (i == 6) printw (" %s \n", GIT_TAG); - #else -- if (i == 5) printw (" %s ", "AW "); -+ if (i == 5) printw (" %s ", "AW G Build"); - if (i == 6) printw (" %s \n", GIT_TAG); - #endif - else printw ("\n"); -@@ -3913,7 +3916,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (c == 112) //'p' key - stop all per call wav files - { - //hope this one doesn't cause random crashing or garbage writing -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - sprintf (opts->wav_out_file, "%s", ""); diff --git a/patch/p25p2_superframe_18V_tests2.patch b/patch/p25p2_superframe_18V_tests2.patch deleted file mode 100644 index 9fb5f78..0000000 --- a/patch/p25p2_superframe_18V_tests2.patch +++ /dev/null @@ -1,769 +0,0 @@ -diff --git a/include/dsd.h b/include/dsd.h -index 0b47dee..f459528 100644 ---- a/include/dsd.h -+++ b/include/dsd.h -@@ -437,8 +437,8 @@ typedef struct - //new stereo short sample storage - short s_l[160]; //single sample left - short s_r[160]; //single sample right -- short s_l4[4][160]; //quad sample for up to a P25p2 4V -- short s_r4[4][160]; //quad sample for up to a P25p2 4V -+ short s_l4[36][160]; //quad sample for up to a P25p2 4V -+ short s_r4[36][160]; //quad sample for up to a P25p2 4V - //new stereo short sample storage tapped from 48_k internal upsampling - short s_lu[160*6]; //single sample left - short s_ru[160*6]; //single sample right -@@ -654,6 +654,7 @@ typedef struct - int p2_vch_chan_num; //vch channel number (0 or 1, not the 0-11 TS) - int ess_b[2][96]; //external storage for ESS_B fragments - int fourv_counter[2]; //external reference counter for ESS_B fragment collection -+ int voice_counter[2]; //external reference counter for 18V x 2 P25p2 Superframe - int p2_is_lcch; //flag to tell us when a frame is lcch and not sacch - - //iden freq storage for frequency calculations -@@ -926,6 +927,7 @@ void agf (dsd_opts * opts, dsd_state * state, float samp[160], int slot); //floa - void playSynthesizedVoiceSS (dsd_opts * opts, dsd_state * state); //short stereo mix - void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state); //short stereo mix 3v2 DMR - void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state); //short stereo mix 4v2 P25p2 -+void playSynthesizedVoiceSS18 (dsd_opts * opts, dsd_state * state); //short stereo mix 18V Superframe - void upsampleS (short invalue, short prev, short outbuf[6]); //upsample 8k to 48k short - // - void openAudioOutDevice (dsd_opts * opts, int speed); -diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c -index a836afc..4ab705f 100644 ---- a/src/dsd_audio2.c -+++ b/src/dsd_audio2.c -@@ -906,8 +906,31 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - //CHEAT: Using the slot on/off, use that to set encL or encR back on - //as a simple way to turn off voice synthesis in a particular slot - //its not really 'disabled', we just aren't playing it -- if (opts->slot1_on == 0) encL = 1; -- if (opts->slot2_on == 0) encR = 1; -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 16) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 16) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 16 && state->dmrburstR != 16) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 16 && state->dmrburstL != 16) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } - - //WIP: Mute if on B list (or not W list) - char modeL[8]; -@@ -944,12 +967,37 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - if (strcmp(modeL, "B") == 0) encL = 1; - if (strcmp(modeR, "B") == 0) encR = 1; - -+ //check to see if we need to enable slot and toggle slot preference here -+ //this method will always favor slot 2 (this is a patch anyways, so....meh) -+ if (strcmp(modeL, "A") == 0) -+ { -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (strcmp(modeR, "A") == 0) -+ { -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } -+ - //if TG Hold in place, mute anything but that TG #132 -- if (state->tg_hold != 0 && state->tg_hold != TGL) encL = 1; -- if (state->tg_hold != 0 && state->tg_hold != TGR) encR = 1; -- //likewise, override and unmute if TG hold matches TG -- if (state->tg_hold != 0 && state->tg_hold == TGL) encL = 0; -- if (state->tg_hold != 0 && state->tg_hold == TGR) encR = 0; -+ if (state->tg_hold != 0 && state->tg_hold != TGL) -+ encL = 1; -+ if (state->tg_hold != 0 && state->tg_hold != TGR) -+ encR = 1; -+ //likewise, override and unmute if TG hold matches TG (and turn on slot and set preference) -+ if (state->tg_hold != 0 && state->tg_hold == TGL) -+ { -+ encL = 0; -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (state->tg_hold != 0 && state->tg_hold == TGR) -+ { -+ encR = 0; -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } - - //interleave left and right channels from the short storage area - for (i = 0; i < 160; i++) -@@ -1092,8 +1140,31 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state) - //CHEAT: Using the slot on/off, use that to set encL or encR back on - //as a simple way to turn off voice synthesis in a particular slot - //its not really 'disabled', we just aren't playing it -- if (opts->slot1_on == 0) encL = 1; -- if (opts->slot2_on == 0) encR = 1; -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 21) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 21) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 21 && state->dmrburstR != 21) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 21 && state->dmrburstL != 21) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } - - //WIP: Mute if on B list (or not W list) - char modeL[8]; -@@ -1130,12 +1201,37 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state) - if (strcmp(modeL, "B") == 0) encL = 1; - if (strcmp(modeR, "B") == 0) encR = 1; - -+ //check to see if we need to enable slot and toggle slot preference here -+ //this method will always favor slot 2 (this is a patch anyways, so....meh) -+ if (strcmp(modeL, "A") == 0) -+ { -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (strcmp(modeR, "A") == 0) -+ { -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } -+ - //if TG Hold in place, mute anything but that TG #132 -- if (state->tg_hold != 0 && state->tg_hold != TGL) encL = 1; -- if (state->tg_hold != 0 && state->tg_hold != TGR) encR = 1; -- //likewise, override and unmute if TG hold matches TG -- if (state->tg_hold != 0 && state->tg_hold == TGL) encL = 0; -- if (state->tg_hold != 0 && state->tg_hold == TGR) encR = 0; -+ if (state->tg_hold != 0 && state->tg_hold != TGL) -+ encL = 1; -+ if (state->tg_hold != 0 && state->tg_hold != TGR) -+ encR = 1; -+ //likewise, override and unmute if TG hold matches TG (and turn on slot and set preference) -+ if (state->tg_hold != 0 && state->tg_hold == TGL) -+ { -+ encL = 0; -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (state->tg_hold != 0 && state->tg_hold == TGR) -+ { -+ encR = 0; -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } - - //interleave left and right channels from the short storage area - for (i = 0; i < 160; i++) -@@ -1238,6 +1334,226 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state) - - } - -+//short stereo mix 18v superframe -+void playSynthesizedVoiceSS18 (dsd_opts * opts, dsd_state * state) -+{ -+ -+ //NOTE: This will run once every superframe during a sacch field -+ //exact implementation to be determined -+ -+ int i, j; -+ uint8_t encL, encR; -+ -+ short stereo_sf[18][320]; //8k 2-channel stereo interleave mix for full superframe -+ // memset (stereo_sf, 1, 18*sizeof(short)); //I don't think 18*sizeof(short) was large enough, should probably be 18*320*sizeof(short) -+ memset (stereo_sf, 1, sizeof(stereo_sf)); -+ -+ short empty[320]; -+ memset (empty, 1, sizeof(empty)); -+ -+ //p25p2 enc checkdown for whether or not to fill the stereo sample or not for playback or writing -+ encL = encR = 1; -+ if (state->payload_algid == 0 || state->payload_algid == 0x80) -+ encL = 0; -+ if (state->payload_algidR == 0 || state->payload_algidR == 0x80) -+ encR = 0; -+ -+ //checkdown to see if we can lift the 'mute' if a key is available -+ if (encL) -+ { -+ if (state->payload_algid == 0xAA) -+ { -+ if (state->R != 0) -+ { -+ encL = 0; -+ } -+ } -+ } -+ -+ if (encR) -+ { -+ if (state->payload_algidR == 0xAA) -+ { -+ if (state->RR != 0) -+ { -+ encR = 0; -+ } -+ } -+ } -+ -+ -+ //TODO: add option to bypass enc with a toggle as well -+ -+ //CHEAT: Using the slot on/off, use that to set encL or encR back on -+ //as a simple way to turn off voice synthesis in a particular slot -+ //its not really 'disabled', we just aren't playing it -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 21) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 21) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 21 && state->dmrburstR != 21) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 21 && state->dmrburstL != 21) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } -+ -+ //WIP: Mute if on B list (or not W list) -+ char modeL[8]; -+ sprintf (modeL, "%s", ""); -+ char modeR[8]; -+ sprintf (modeR, "%s", ""); -+ -+ int TGL = state->lasttg; -+ int TGR = state->lasttgR; -+ -+ //if we are using allow/whitelist mode, then write 'B' to mode for block -+ //comparison below will look for an 'A' to write to mode if it is allowed -+ if (opts->trunk_use_allow_list == 1) -+ { -+ sprintf (modeL, "%s", "B"); -+ sprintf (modeR, "%s", "B"); -+ } -+ -+ for (i = 0; i < state->group_tally; i++) -+ { -+ if (state->group_array[i].groupNumber == TGL) -+ { -+ strcpy (modeL, state->group_array[i].groupMode); -+ // break; //need to keep going to check other potential slot group -+ } -+ if (state->group_array[i].groupNumber == TGR) -+ { -+ strcpy (modeR, state->group_array[i].groupMode); -+ // break; //need to keep going to check other potential slot group -+ } -+ } -+ -+ //flag either left or right as 'enc' to mute if B -+ if (strcmp(modeL, "B") == 0) encL = 1; -+ if (strcmp(modeR, "B") == 0) encR = 1; -+ -+ //check to see if we need to enable slot and toggle slot preference here -+ //this method will always favor slot 2 (this is a patch anyways, so....meh) -+ if (strcmp(modeL, "A") == 0) -+ { -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (strcmp(modeR, "A") == 0) -+ { -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } -+ -+ //if TG Hold in place, mute anything but that TG #132 -+ if (state->tg_hold != 0 && state->tg_hold != TGL) -+ encL = 1; -+ if (state->tg_hold != 0 && state->tg_hold != TGR) -+ encR = 1; -+ //likewise, override and unmute if TG hold matches TG (and turn on slot and set preference) -+ if (state->tg_hold != 0 && state->tg_hold == TGL) -+ { -+ encL = 0; -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (state->tg_hold != 0 && state->tg_hold == TGR) -+ { -+ encR = 0; -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } -+ -+ //at this point, if both channels are still flagged as enc, then we can skip all playback/writing functions -+ if (encL && encR) -+ goto SS18_END; -+ -+ //interleave left and right channels from the short storage area -+ for (j = 0; j < 18; j++) -+ { -+ for (i = 0; i < 160; i++) -+ { -+ if (!encL) -+ stereo_sf[j][i*2+0] = state->s_l4[j][i]; -+ if (!encR) -+ stereo_sf[j][i*2+1] = state->s_r4[j][i]; -+ } -+ } -+ -+ if (opts->audio_out_type == 0) //Pulse Audio -+ { -+ for (j = 0; j < 18; j++) -+ { -+ if (memcmp(empty, stereo_sf[j], sizeof(empty)) != 0) //may not work as intended because its stereo and one will have something in it most likely -+ pa_simple_write(opts->pulse_digi_dev_out, stereo_sf[j], 320*2, NULL); -+ } -+ } -+ -+ if (opts->audio_out_type == 8) //UDP Audio -+ { -+ for (j = 0; j < 18; j++) -+ { -+ if (memcmp(empty, stereo_sf[j], sizeof(empty)) != 0) //may not work as intended because its stereo and one will have something in it most likely -+ udp_socket_blaster (opts, state, 320*2, stereo_sf[j]); -+ } -+ } -+ -+ -+ if (opts->audio_out_type == 1 || opts->audio_out_type == 2) //STDOUT or OSS 8k/2channel -+ { -+ for (j = 0; j < 18; j++) -+ { -+ if (memcmp(empty, stereo_sf[j], sizeof(empty)) != 0) //may not work as intended because its stereo and one will have something in it most likely -+ write (opts->audio_out_fd, stereo_sf[j], 320*2); -+ } -+ } -+ -+ SS18_END: -+ -+ //run cleanup since we pulled stuff from processAudio -+ state->audio_out_idx = 0; -+ state->audio_out_idxR = 0; -+ -+ //set float temp buffer to baseline -+ memset (state->s_l4, 1, sizeof(state->s_l4)); -+ memset (state->s_r4, 1, sizeof(state->s_r4)); -+ -+ if (state->audio_out_idx2 >= 800000) -+ { -+ state->audio_out_float_buf_p = state->audio_out_float_buf + 100; -+ state->audio_out_buf_p = state->audio_out_buf + 100; -+ memset (state->audio_out_float_buf, 0, 100 * sizeof (float)); -+ memset (state->audio_out_buf, 0, 100 * sizeof (short)); -+ state->audio_out_idx2 = 0; -+ } -+ -+ if (state->audio_out_idx2R >= 800000) -+ { -+ state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100; -+ state->audio_out_buf_pR = state->audio_out_bufR + 100; -+ memset (state->audio_out_float_bufR, 0, 100 * sizeof (float)); -+ memset (state->audio_out_bufR, 0, 100 * sizeof (short)); -+ state->audio_out_idx2R = 0; -+ } -+ -+} -+ - //largely borrowed from Boatbod OP25 (simplified single tone ID version) - void soft_tonef (float samp[160], int n, int ID, int AD) - { -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 1d2616b..02590a6 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -382,6 +382,8 @@ if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 - } - state->fourv_counter[0] = 0; - state->fourv_counter[1] = 0; -+ state->voice_counter[0] = 0; -+ state->voice_counter[1] = 0; - - //values displayed in ncurses terminal - // state->p25_vc_freq[0] = 0; -@@ -745,7 +747,7 @@ initOpts (dsd_opts * opts) - //slot preference is used during OSS audio playback to - //prefer one tdma voice slot over another when both are playing back - //this is a fix to OSS 48k/1 output -- opts->slot_preference = 0; //default prefer slot 1 -- state->currentslot = 0; -+ opts->slot_preference = 2; //default prefer slot 1 -- state->currentslot = 0; - - //hardset slots to synthesize - opts->slot1_on = 1; -@@ -941,6 +943,8 @@ initState (dsd_state * state) - } - state->fourv_counter[0] = 0; - state->fourv_counter[1] = 0; -+ state->voice_counter[0] = 0; -+ state->voice_counter[1] = 0; - - state->K = 0; - state->R = 0; -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..fc3f28b 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -2568,11 +2568,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - { - printw ("| Voice Error: [%i][%i] Slot 1 (1)", state->errs, state->errs2); - if (opts->slot1_on == 0) printw (" OFF"); -- if (opts->slot1_on == 1) printw (" ON"); -+ if (opts->slot1_on == 1) printw (" ON"); if (opts->slot_preference == 0) printw (" *Preferred"); - printw ("\n"); - printw ("| Voice Error: [%i][%i] Slot 2 (2)", state->errsR, state->errs2R); - if (opts->slot2_on == 0) printw (" OFF"); -- if (opts->slot2_on == 1) printw (" ON"); -+ if (opts->slot2_on == 1) printw (" ON"); if (opts->slot_preference == 1) printw (" *Preferred"); - printw ("\n"); - } - printw ("------------------------------------------------------------------------------\n"); -@@ -3654,8 +3654,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot1_on == 1) - { -- opts->slot1_on = 0; -- opts->slot_preference = 1; //slot 2 -+ opts->slot1_on = 0; if (opts->slot_preference == 0) opts->slot_preference = 2; -+ // opts->slot_preference = 1; //slot 2 - //clear any previously buffered audio - state->audio_out_float_buf_p = state->audio_out_float_buf + 100; - state->audio_out_buf_p = state->audio_out_buf + 100; -@@ -3680,8 +3680,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot2_on == 1) - { -- opts->slot2_on = 0; -- opts->slot_preference = 0; //slot 1 -+ opts->slot2_on = 0; if (opts->slot_preference == 1) opts->slot_preference = 2; -+ // opts->slot_preference = 0; //slot 1 - //clear any previously buffered audio - state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100; - state->audio_out_buf_pR = state->audio_out_bufR + 100; -@@ -3701,6 +3701,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - } - -+ if (c == 51) //'3' key, cycle slot preferences -+ { -+ if (opts->slot_preference < 2) -+ opts->slot_preference++; -+ else opts->slot_preference = 0; -+ } -+ - if (c == 43) //+ key, increment audio_gain - { - -diff --git a/src/p25p2_frame.c b/src/p25p2_frame.c -index c391eba..99a4840 100644 ---- a/src/p25p2_frame.c -+++ b/src/p25p2_frame.c -@@ -490,18 +490,27 @@ void process_4V (dsd_opts * opts, dsd_state * state) - // else state->dmrburstR = 21; - // } - // #endif -+ -+ //unsure of the best location for these counter resets -+ if (state->voice_counter[0] >= 18) -+ state->voice_counter[0] = 0; -+ -+ if (state->voice_counter[1] >= 18) -+ state->voice_counter[1] = 0; - - processMbeFrame (opts, state, NULL, ambe_fr1, NULL); - if(state->currentslot == 0) - { - memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu)); - } - else - { - memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[0], state->s_ru, sizeof(state->s_ru)); - } - -@@ -509,13 +518,15 @@ void process_4V (dsd_opts * opts, dsd_state * state) - if(state->currentslot == 0) - { - memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu)); - } - else - { - memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[1], state->s_ru, sizeof(state->s_ru)); - } - -@@ -523,13 +534,15 @@ void process_4V (dsd_opts * opts, dsd_state * state) - if(state->currentslot == 0) - { - memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu)); - } - else - { - memcpy(state->f_r4[2], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[2], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[2], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[2], state->s_ru, sizeof(state->s_ru)); - } - -@@ -537,13 +550,15 @@ void process_4V (dsd_opts * opts, dsd_state * state) - if(state->currentslot == 0) - { - memcpy(state->f_l4[3], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[3], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[3], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[3], state->s_lu, sizeof(state->s_lu)); - } - else - { - memcpy(state->f_r4[3], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[3], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[3], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[3], state->s_ru, sizeof(state->s_ru)); - } - -@@ -709,17 +724,26 @@ void process_2V (dsd_opts * opts, dsd_state * state) - // } - // #endif - -+ //unsure of the best location for these counter resets -+ if (state->voice_counter[0] >= 18) -+ state->voice_counter[0] = 0; -+ -+ if (state->voice_counter[1] >= 18) -+ state->voice_counter[1] = 0; -+ - processMbeFrame (opts, state, NULL, ambe_fr1, NULL); - if(state->currentslot == 0) - { - memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu)); - } - else - { - memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[0], state->s_ru, sizeof(state->s_ru)); - } - -@@ -727,17 +751,19 @@ void process_2V (dsd_opts * opts, dsd_state * state) - if(state->currentslot == 0) - { - memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf)); -- memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l)); -+ // memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l)); -+ memcpy(state->s_l4[(state->voice_counter[0]++)%18], state->s_l, sizeof(state->s_l)); - memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu)); - - } - else - { - memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR)); -- memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r)); -+ // memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r)); -+ memcpy(state->s_r4[(state->voice_counter[1]++)%18], state->s_r, sizeof(state->s_r)); - memcpy(state->s_r4u[1], state->s_ru, sizeof(state->s_ru)); - } -- -+ // if (state->currentslot == 0) state->voice_counter[0] = 0; if (state->currentslot == 1) state->voice_counter[1] = 0; - process_ESS(opts, state); - - //reset drop bytes after a 2V -@@ -930,6 +956,8 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state) - state->p2_is_lcch = 0; - state->fourv_counter[0] = 0; - state->fourv_counter[1] = 0; -+ state->voice_counter[0] = 0; -+ state->voice_counter[1] = 0; - - goto END; - } -@@ -949,8 +977,32 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state) - if (sacch == 0 && ts_counter & 1 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 8000) - playSynthesizedVoiceFS4 (opts, state); - -- if (sacch == 0 && ts_counter & 1 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) -- playSynthesizedVoiceSS4 (opts, state); -+ // if (sacch == 0 && ts_counter & 1 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) -+ // playSynthesizedVoiceSS4 (opts, state); -+ -+ // fprintf (stderr, " VCH0: %d;", state->voice_counter[0]); //debug -+ // fprintf (stderr, " VCH1: %d;", state->voice_counter[1]); //debug -+ -+ //this works, but may still have an element of 'dual voice stutter' which was my initial complaint, but shouldn't 'lag' during trunking operations (hopefully) -+ if ( (state->voice_counter[0] >= 18 || state->voice_counter[1] >= 18 ) && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) //&& ts_counter & 1 -+ { -+ playSynthesizedVoiceSS18 (opts, state); -+ state->voice_counter[0] = 0; //reset -+ state->voice_counter[1] = 0; //reset -+ } -+ -+ //these two will work, but NOT at the same time on dual voice -+ // if (state->voice_counter[0] >= 18 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) //&& ts_counter & 1 -+ // { -+ // playSynthesizedVoiceSS18 (opts, state); -+ // state->voice_counter[0] = 0; //reset -+ // } -+ -+ // if (state->voice_counter[1] >= 18 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) //&& ts_counter & 1 -+ // { -+ // playSynthesizedVoiceSS18 (opts, state); -+ // state->voice_counter[1] = 0; //reset -+ // } - - //debug: fix burst indicator for ncurses if marginal signal - // if (voice) -diff --git a/src/p25p2_xcch.c b/src/p25p2_xcch.c -index 101d1e4..847fe71 100644 ---- a/src/p25p2_xcch.c -+++ b/src/p25p2_xcch.c -@@ -122,6 +122,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] - { - //reset fourv_counter and dropbyte on PTT - state->fourv_counter[0] = 0; -+ state->voice_counter[0] = 0; - state->dropL = 256; - - state->dmrburstL = 20; -@@ -171,6 +172,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] - { - //reset fourv_counter and dropbyte on PTT - state->fourv_counter[1] = 0; -+ state->voice_counter[1] = 0; - state->dropR = 256; - state->payload_algidR = 0; //zero this out as well - -@@ -230,6 +232,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] - { - - state->fourv_counter[0] = 0; -+ state->voice_counter[0] = 0; - state->dropL = 256; - state->dmrburstL = 23; - state->payload_algid = 0; -@@ -258,6 +261,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] - { - - state->fourv_counter[1] = 0; -+ state->voice_counter[1] = 0; - state->dropR = 256; - state->dmrburstR = 23; - state->payload_algidR = 0; -@@ -498,6 +502,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - { - //reset fourv_counter and dropbyte on PTT - state->fourv_counter[0] = 0; -+ state->voice_counter[0] = 0; - state->dropL = 256; - - state->dmrburstL = 20; -@@ -538,6 +543,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - { - //reset fourv_counter and dropbyte on PTT - state->fourv_counter[1] = 0; -+ state->voice_counter[1] = 0; - state->dropR = 256; - - state->dmrburstR = 20; -@@ -594,6 +600,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - { - - state->fourv_counter[0] = 0; -+ state->voice_counter[0] = 0; - state->dropL = 256; - state->dmrburstL = 23; - state->payload_algid = 0; //zero this out as well -@@ -622,6 +629,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - { - - state->fourv_counter[1] = 0; -+ state->voice_counter[1] = 0; - state->dropR = 256; - state->dmrburstR = 23; - state->payload_algidR = 0; //zero this out as well -@@ -723,6 +731,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - state->payload_keyid = 0; - state->dmrburstL = 24; - state->fourv_counter[0] = 0; -+ state->voice_counter[0] = 0; - state->lastsrc = 0; - state->lasttg = 0; - -@@ -733,6 +742,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156] - state->payload_keyidR = 0; - state->dmrburstR = 24; - state->fourv_counter[1] = 0; -+ state->voice_counter[1] = 0; - state->lastsrcR = 0; - state->lasttgR = 0; - diff --git a/patch/wolf_dmr_mono_stereo_interleaving_tests.patch b/patch/wolf_dmr_mono_stereo_interleaving_tests.patch deleted file mode 100644 index 91dfc33..0000000 --- a/patch/wolf_dmr_mono_stereo_interleaving_tests.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c -index a836afc..7b830c3 100644 ---- a/src/dsd_audio2.c -+++ b/src/dsd_audio2.c -@@ -906,8 +906,31 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - //CHEAT: Using the slot on/off, use that to set encL or encR back on - //as a simple way to turn off voice synthesis in a particular slot - //its not really 'disabled', we just aren't playing it -- if (opts->slot1_on == 0) encL = 1; -- if (opts->slot2_on == 0) encR = 1; -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 16) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 16) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 16 && state->dmrburstR != 16) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 16 && state->dmrburstL != 16) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } - - //WIP: Mute if on B list (or not W list) - char modeL[8]; -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 1d2616b..924bf00 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -745,7 +745,7 @@ initOpts (dsd_opts * opts) - //slot preference is used during OSS audio playback to - //prefer one tdma voice slot over another when both are playing back - //this is a fix to OSS 48k/1 output -- opts->slot_preference = 0; //default prefer slot 1 -- state->currentslot = 0; -+ opts->slot_preference = 2; //default prefer slot 1 -- state->currentslot = 0; - - //hardset slots to synthesize - opts->slot1_on = 1; -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..fc3f28b 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -2568,11 +2568,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - { - printw ("| Voice Error: [%i][%i] Slot 1 (1)", state->errs, state->errs2); - if (opts->slot1_on == 0) printw (" OFF"); -- if (opts->slot1_on == 1) printw (" ON"); -+ if (opts->slot1_on == 1) printw (" ON"); if (opts->slot_preference == 0) printw (" *Preferred"); - printw ("\n"); - printw ("| Voice Error: [%i][%i] Slot 2 (2)", state->errsR, state->errs2R); - if (opts->slot2_on == 0) printw (" OFF"); -- if (opts->slot2_on == 1) printw (" ON"); -+ if (opts->slot2_on == 1) printw (" ON"); if (opts->slot_preference == 1) printw (" *Preferred"); - printw ("\n"); - } - printw ("------------------------------------------------------------------------------\n"); -@@ -3654,8 +3654,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot1_on == 1) - { -- opts->slot1_on = 0; -- opts->slot_preference = 1; //slot 2 -+ opts->slot1_on = 0; if (opts->slot_preference == 0) opts->slot_preference = 2; -+ // opts->slot_preference = 1; //slot 2 - //clear any previously buffered audio - state->audio_out_float_buf_p = state->audio_out_float_buf + 100; - state->audio_out_buf_p = state->audio_out_buf + 100; -@@ -3680,8 +3680,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot2_on == 1) - { -- opts->slot2_on = 0; -- opts->slot_preference = 0; //slot 1 -+ opts->slot2_on = 0; if (opts->slot_preference == 1) opts->slot_preference = 2; -+ // opts->slot_preference = 0; //slot 1 - //clear any previously buffered audio - state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100; - state->audio_out_buf_pR = state->audio_out_bufR + 100; -@@ -3701,6 +3701,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - } - -+ if (c == 51) //'3' key, cycle slot preferences -+ { -+ if (opts->slot_preference < 2) -+ opts->slot_preference++; -+ else opts->slot_preference = 0; -+ } -+ - if (c == 43) //+ key, increment audio_gain - { - diff --git a/patch/wolf_p25p2_and_dmr__mono_stereo_interleaving_tests2.patch b/patch/wolf_p25p2_and_dmr__mono_stereo_interleaving_tests2.patch deleted file mode 100644 index 9dc97b0..0000000 --- a/patch/wolf_p25p2_and_dmr__mono_stereo_interleaving_tests2.patch +++ /dev/null @@ -1,228 +0,0 @@ -diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c -index a836afc..91e5869 100644 ---- a/src/dsd_audio2.c -+++ b/src/dsd_audio2.c -@@ -906,8 +906,31 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - //CHEAT: Using the slot on/off, use that to set encL or encR back on - //as a simple way to turn off voice synthesis in a particular slot - //its not really 'disabled', we just aren't playing it -- if (opts->slot1_on == 0) encL = 1; -- if (opts->slot2_on == 0) encR = 1; -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 16) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 16) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 16 && state->dmrburstR != 16) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 16 && state->dmrburstL != 16) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } - - //WIP: Mute if on B list (or not W list) - char modeL[8]; -@@ -944,12 +967,37 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - if (strcmp(modeL, "B") == 0) encL = 1; - if (strcmp(modeR, "B") == 0) encR = 1; - -+ //check to see if we need to enable slot and toggle slot preference here -+ //this method will always favor slot 2 (this is a patch anyways, so....meh) -+ if (strcmp(modeL, "A") == 0) -+ { -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (strcmp(modeR, "A") == 0) -+ { -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } -+ - //if TG Hold in place, mute anything but that TG #132 -- if (state->tg_hold != 0 && state->tg_hold != TGL) encL = 1; -- if (state->tg_hold != 0 && state->tg_hold != TGR) encR = 1; -- //likewise, override and unmute if TG hold matches TG -- if (state->tg_hold != 0 && state->tg_hold == TGL) encL = 0; -- if (state->tg_hold != 0 && state->tg_hold == TGR) encR = 0; -+ if (state->tg_hold != 0 && state->tg_hold != TGL) -+ encL = 1; -+ if (state->tg_hold != 0 && state->tg_hold != TGR) -+ encR = 1; -+ //likewise, override and unmute if TG hold matches TG (and turn on slot and set preference) -+ if (state->tg_hold != 0 && state->tg_hold == TGL) -+ { -+ encL = 0; -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (state->tg_hold != 0 && state->tg_hold == TGR) -+ { -+ encR = 0; -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } - - //interleave left and right channels from the short storage area - for (i = 0; i < 160; i++) -@@ -1092,8 +1140,31 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state) - //CHEAT: Using the slot on/off, use that to set encL or encR back on - //as a simple way to turn off voice synthesis in a particular slot - //its not really 'disabled', we just aren't playing it -- if (opts->slot1_on == 0) encL = 1; -- if (opts->slot2_on == 0) encR = 1; -+ // if (opts->slot1_on == 0) encL = 1; -+ // if (opts->slot2_on == 0) encR = 1; -+ -+ //this may have some unintended side effects that I haven't tested/explored yet, that's why its a patch only -+ //particularly in regards to 'Aero' Builds with their OSS Jank and slot_preference = 3 by default -+ //if rounds of testing in various scenaries looks good, I may expand this to P25p2 and the Float Variants as well -+ if (opts->slot1_on == 0 && opts->slot2_on == 1) //slot 1 is hard off and slot 2 is on -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (opts->slot1_on == 1 && opts->slot2_on == 0) //slot 2 is hard off and slot 1 is on -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 0 && state->dmrburstL == 21) //slot 1 is preferred, and voice in slot 1 -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (opts->slot_preference == 1 && state->dmrburstR == 21) //slot 2 is preferred, and voice in slot 2 -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ else if (state->dmrburstL == 21 && state->dmrburstR != 21) //voice in left, no voice in right -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); //copy left to right -+ else if (state->dmrburstR == 21 && state->dmrburstL != 21) //voice in right, no voice in left -+ memcpy (state->s_l4, state->s_r4, sizeof(state->s_l4)); //copy right to left -+ //else if voice in both, and both slots on, and no preference on slot, then regular stereo interleave (left and right channels) -+ -+ if (opts->slot1_on == 0 && opts->slot2_on == 0) //both slots are hard off, disable playback -+ { -+ encL = 1; -+ encR = 1; -+ } - - //WIP: Mute if on B list (or not W list) - char modeL[8]; -@@ -1126,16 +1197,37 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state) - } - } - -- //flag either left or right as 'enc' to mute if B -- if (strcmp(modeL, "B") == 0) encL = 1; -- if (strcmp(modeR, "B") == 0) encR = 1; -+ //check to see if we need to enable slot and toggle slot preference here -+ //this method will always favor slot 2 (this is a patch anyways, so....meh) -+ if (strcmp(modeL, "A") == 0) -+ { -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (strcmp(modeR, "A") == 0) -+ { -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } - - //if TG Hold in place, mute anything but that TG #132 -- if (state->tg_hold != 0 && state->tg_hold != TGL) encL = 1; -- if (state->tg_hold != 0 && state->tg_hold != TGR) encR = 1; -- //likewise, override and unmute if TG hold matches TG -- if (state->tg_hold != 0 && state->tg_hold == TGL) encL = 0; -- if (state->tg_hold != 0 && state->tg_hold == TGR) encR = 0; -+ if (state->tg_hold != 0 && state->tg_hold != TGL) -+ encL = 1; -+ if (state->tg_hold != 0 && state->tg_hold != TGR) -+ encR = 1; -+ //likewise, override and unmute if TG hold matches TG (and turn on slot and set preference) -+ if (state->tg_hold != 0 && state->tg_hold == TGL) -+ { -+ encL = 0; -+ opts->slot1_on = 1; -+ opts->slot_preference = 0; -+ } -+ if (state->tg_hold != 0 && state->tg_hold == TGR) -+ { -+ encR = 0; -+ opts->slot2_on = 1; -+ opts->slot_preference = 1; -+ } - - //interleave left and right channels from the short storage area - for (i = 0; i < 160; i++) -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 1d2616b..924bf00 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -745,7 +745,7 @@ initOpts (dsd_opts * opts) - //slot preference is used during OSS audio playback to - //prefer one tdma voice slot over another when both are playing back - //this is a fix to OSS 48k/1 output -- opts->slot_preference = 0; //default prefer slot 1 -- state->currentslot = 0; -+ opts->slot_preference = 2; //default prefer slot 1 -- state->currentslot = 0; - - //hardset slots to synthesize - opts->slot1_on = 1; -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..fc3f28b 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -2568,11 +2568,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - { - printw ("| Voice Error: [%i][%i] Slot 1 (1)", state->errs, state->errs2); - if (opts->slot1_on == 0) printw (" OFF"); -- if (opts->slot1_on == 1) printw (" ON"); -+ if (opts->slot1_on == 1) printw (" ON"); if (opts->slot_preference == 0) printw (" *Preferred"); - printw ("\n"); - printw ("| Voice Error: [%i][%i] Slot 2 (2)", state->errsR, state->errs2R); - if (opts->slot2_on == 0) printw (" OFF"); -- if (opts->slot2_on == 1) printw (" ON"); -+ if (opts->slot2_on == 1) printw (" ON"); if (opts->slot_preference == 1) printw (" *Preferred"); - printw ("\n"); - } - printw ("------------------------------------------------------------------------------\n"); -@@ -3654,8 +3654,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot1_on == 1) - { -- opts->slot1_on = 0; -- opts->slot_preference = 1; //slot 2 -+ opts->slot1_on = 0; if (opts->slot_preference == 0) opts->slot_preference = 2; -+ // opts->slot_preference = 1; //slot 2 - //clear any previously buffered audio - state->audio_out_float_buf_p = state->audio_out_float_buf + 100; - state->audio_out_buf_p = state->audio_out_buf + 100; -@@ -3680,8 +3680,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - //switching, but want to control each seperately plz - if (opts->slot2_on == 1) - { -- opts->slot2_on = 0; -- opts->slot_preference = 0; //slot 1 -+ opts->slot2_on = 0; if (opts->slot_preference == 1) opts->slot_preference = 2; -+ // opts->slot_preference = 0; //slot 1 - //clear any previously buffered audio - state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100; - state->audio_out_buf_pR = state->audio_out_bufR + 100; -@@ -3701,6 +3701,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - } - -+ if (c == 51) //'3' key, cycle slot preferences -+ { -+ if (opts->slot_preference < 2) -+ opts->slot_preference++; -+ else opts->slot_preference = 0; -+ } -+ - if (c == 43) //+ key, increment audio_gain - { -