From 4c91588af60dde76db207571dfb05fbd16898028 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Sun, 21 May 2023 09:14:02 -0400 Subject: [PATCH] Re-enable P1 Heuristics On TCH and Non CS modes; --- include/dsd.h | 3 + src/dsd_dibit.c | 24 ++++---- src/dsd_main.c | 14 ++++- src/dsd_ncurses.c | 45 ++++++++------ src/dsd_reset.c | 152 +++++++++++++++++++++++++--------------------- src/p25_lcw.c | 13 +++- src/p25p1_mdpu.c | 37 ++++++++--- 7 files changed, 179 insertions(+), 109 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index a104283..c6a2a7a 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -380,6 +380,9 @@ typedef struct uint8_t use_dsp_output; char dsp_out_file[2048]; + //Use P25p1 heuristics + uint8_t use_heuristics; + } dsd_opts; typedef struct diff --git a/src/dsd_dibit.c b/src/dsd_dibit.c index 491a89c..3fbff10 100644 --- a/src/dsd_dibit.c +++ b/src/dsd_dibit.c @@ -283,12 +283,12 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; - //disabling again, causing issues with trunking P25 - if (state->synctype == 1 && opts->p25_trunk == 1) - { - // Use the P25 heuristics if available - // valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); - } + //testing again, either on Voice channels only (when tuned) or with trunk disabled + if (state->synctype == 1 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + { + // Use the P25p1 heuristics if available + valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); + } if (valid == 0) { @@ -347,12 +347,12 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; - //disabling again, causing issues with trunking P25 - if (state->synctype == 0 && opts->p25_trunk == 1) - { - // Use the P25 heuristics if available - // valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); - } + //testing again, either on Voice channels only (when tuned) or with trunk disabled + if (state->synctype == 0 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + { + // Use the P25p1 heuristics if available + valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); + } if (valid == 0) { diff --git a/src/dsd_main.c b/src/dsd_main.c index d53f058..a2acfd8 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -90,6 +90,13 @@ void noCarrier (dsd_opts * opts, dsd_state * state) { + //clear heuristics from last carrier signal + if (opts->frame_p25p1 == 1 && opts->use_heuristics == 1) + { + initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); + } + //only do it here on the tweaks #ifdef LIMAZULUTWEAKS state->nxdn_last_ran = -1; @@ -645,6 +652,9 @@ initOpts (dsd_opts * opts) opts->dsp_out_file[0] = 0; opts->use_dsp_output = 0; + //Use P25p1 heuristics + opts->use_heuristics = 0; + } //initopts void @@ -985,6 +995,7 @@ initState (dsd_state * state) memset (state->late_entry_mi_fragment, 0, sizeof (state->late_entry_mi_fragment)); initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); state->dPMRVoiceFS2Frame.CalledIDOk = 0; state->dPMRVoiceFS2Frame.CallingIDOk = 0; @@ -1346,7 +1357,7 @@ main (int argc, char **argv) } #ifdef AERO_BUILD - fprintf (stderr, "Build Version: v2.0.1-11 Win32 \n"); + fprintf (stderr, "Build Version: v2.0.1-12 Win32 \n"); #else fprintf (stderr, "Build Version: %s \n", GIT_TAG); #endif @@ -1793,6 +1804,7 @@ main (int argc, char **argv) // opts.setmod_bw = 12000; opts.ssize = 36; //128 current default, fall back to old default on P1 only systems opts.msize = 15; //1024 current default, fall back to old default on P1 only systems + opts.use_heuristics = 1; //enable for Phase 1 only sprintf (opts.output_name, "P25p1"); fprintf (stderr,"Decoding only P25 Phase 1 frames.\n"); } diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index e3832a7..ef50993 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -1153,7 +1153,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 2) { //setup Auto parameters--default ones - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 10; state->symbolCenter = 4; sprintf (opts->output_name, "Legacy Auto"); @@ -1183,7 +1183,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 6) { //ProVoice Specifics - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 5; state->symbolCenter = 2; sprintf (opts->output_name, "EDACS/PV"); @@ -1211,7 +1211,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 4) { //DSTAR - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 10; state->symbolCenter = 4; sprintf (opts->output_name, "D-STAR"); @@ -1241,7 +1241,13 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 5) { //P25 P1 - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak + opts->use_heuristics = 1; + if (opts->use_heuristics == 1) + { + initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); + } opts->frame_p25p1 = 1; opts->frame_p25p2 = 0; state->samplesPerSymbol = 10; @@ -1273,7 +1279,13 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 3) { //XDMA Stereo P25 1, 2, and DMR - resetState (state); //use sparingly, seems to cause issue when switching back to other formats + // resetState (state); //use sparingly, seems to cause issue when switching back to other formats + if (opts->use_heuristics == 1) + { + initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); + } + opts->use_heuristics = 0; opts->frame_dmr = 1; state->samplesPerSymbol = 10; state->symbolCenter = 4; @@ -1302,7 +1314,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 7) { //set legacy DMR settings - resetState (state); //use sparingly, seems to cause issue when switching back to other formats + // resetState (state); //use sparingly, seems to cause issue when switching back to other formats opts->frame_dmr = 1; state->samplesPerSymbol = 10; state->symbolCenter = 4; @@ -1331,7 +1343,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 8) { //dPMR - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 20; state->symbolCenter = 10; sprintf (opts->output_name, "dPMR"); @@ -1359,7 +1371,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 9) { //NXDN48 - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak opts->frame_nxdn48 = 1; state->samplesPerSymbol = 20; state->symbolCenter = 10; @@ -1388,7 +1400,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 10) { //NXDN96 - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 10; state->symbolCenter = 4; sprintf (opts->output_name, "NXDN96"); @@ -1415,7 +1427,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choice == 11) { //Decode DMR Stereo (was X2-TDMA) - resetState (state); //use sparingly, may cause memory leak + // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 10; state->symbolCenter = 4; // sprintf (opts->output_name, "X2-TDMA"); @@ -2058,7 +2070,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->ncurses_compact == 1) { printw ("------------------------------------------------------------------------------\n"); - printw ("| Digital Speech Decoder: Florida Man Edition - Aero \n", "v2.0.1-11 Win32"); + printw ("| Digital Speech Decoder: Florida Man Edition - Aero \n", "v2.0.1-12 Win32"); printw ("------------------------------------------------------------------------------\n"); } #elif LIMAZULUTWEAKS @@ -2087,7 +2099,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (i == 4) printw (" MBElib %s", versionstr); #ifdef AERO_BUILD if (i == 5) printw (" %s ", "Aero Win32"); - if (i == 6) printw (" v2.0.1-11 Win32 \n"); + if (i == 6) printw (" v2.0.1-12 Win32 \n"); #else if (i == 5) printw (" %s ", "zDEV BUILD"); if (i == 6) printw (" %s \n", GIT_TAG); @@ -2252,11 +2264,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->mod_qpsk == 1) level = (int) state->max / 328; //test values here reset = 1; } - if (state->carrier == 0 && opts->reset_state == 1 && reset == 1) - { - resetState (state); - reset = 0; - } printw ("--Audio Decode----------------------------------------------------------------\n"); printw ("| Demod/Rate: "); @@ -3273,8 +3280,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) opts->mod_qpsk = 0; opts->mod_gfsk = 0; state->rf_mod = 0; - state->samplesPerSymbol = 10; - state->symbolCenter = 4; + state->samplesPerSymbol = 8; + state->symbolCenter = 3; } } diff --git a/src/dsd_reset.c b/src/dsd_reset.c index c34f4a2..34bb13d 100644 --- a/src/dsd_reset.c +++ b/src/dsd_reset.c @@ -2,26 +2,58 @@ #include "dsd.h" #include "p25p1_heuristics.h" -void -resetState (dsd_state * state) +//fixed the memory leak, but now random segfaults occur -- double free or corruption (out) or (!prev) +void resetState (dsd_state * state) { int i, j; - // state->dibit_buf = malloc (sizeof (int) * 1000000); - // state->dibit_buf_p = state->dibit_buf + 200; - // memset (state->dibit_buf, 0, sizeof (int) * 200); - state->repeat = 0; //not sure yet - //state->audio_out_buf = malloc (sizeof (short) * 1000000); - //memset (state->audio_out_buf, 0, 100 * sizeof (short)); - //state->audio_out_buf_p = state->audio_out_buf + 100; - //state->audio_out_float_buf = malloc (sizeof (float) * 1000000); - //memset (state->audio_out_float_buf, 0, 100 * sizeof (float)); - //state->audio_out_float_buf_p = state->audio_out_float_buf + 100; - //state->audio_out_idx = 0; - //state->audio_out_idx2 = 0; - //state->audio_out_temp_buf_p = state->audio_out_temp_buf; - //state->wav_out_bytes = 0; + //Dibit Buffer -- Free Allocated Memory + free (state->dibit_buf); + + //Dibit Buffer -- Memset/Init/Allocate Memory + state->dibit_buf = malloc (sizeof (int) * 1000000); + state->dibit_buf_p = state->dibit_buf + 200; + memset (state->dibit_buf, 0, sizeof (int) * 200); + state->repeat = 0; //repeat frame? + + //Audio Buffer -- Free Allocated Memory + free (state->audio_out_buf); + free (state->audio_out_float_buf); + free (state->audio_out_bufR); + free (state->audio_out_float_bufR); + + //Audio Buffer -- Memset/Init/Allocate Memory per slot + + //slot 1 + state->audio_out_float_buf = malloc (sizeof (float) * 1000000); + state->audio_out_buf = malloc (sizeof (short) * 1000000); + + memset (state->audio_out_buf, 0, 100 * sizeof (short)); + state->audio_out_buf_p = state->audio_out_buf + 100; + + memset (state->audio_out_float_buf, 0, 100 * sizeof (float)); + state->audio_out_float_buf_p = state->audio_out_float_buf + 100; + + state->audio_out_idx = 0; + state->audio_out_idx2 = 0; + state->audio_out_temp_buf_p = state->audio_out_temp_buf; + + //slot 2 + state->audio_out_bufR = malloc (sizeof (short) * 1000000); + state->audio_out_float_bufR = malloc (sizeof (float) * 1000000); + + memset (state->audio_out_bufR, 0, 100 * sizeof (short)); + state->audio_out_buf_pR = state->audio_out_bufR + 100; + + memset (state->audio_out_float_bufR, 0, 100 * sizeof (float)); + state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100; + + state->audio_out_idxR = 0; + state->audio_out_idx2R = 0; + state->audio_out_temp_buf_pR = state->audio_out_temp_bufR; + + //Sync state->center = 0; state->jitter = -1; state->synctype = -1; @@ -31,76 +63,60 @@ resetState (dsd_state * state) state->umid = 0; state->minref = -12000; state->maxref = 12000; + state->lastsample = 0; for (i = 0; i < 128; i++) - { - state->sbuf[i] = 0; - } + { + state->sbuf[i] = 0; + } state->sidx = 0; for (i = 0; i < 1024; i++) - { - state->maxbuf[i] = 15000; - } + { + state->maxbuf[i] = 15000; + } for (i = 0; i < 1024; i++) - { - state->minbuf[i] = -15000; - } + { + state->minbuf[i] = -15000; + } + state->midx = 0; - state->err_str[0] = 0; - sprintf (state->fsubtype, " "); - sprintf (state->ftype, " "); state->symbolcnt = 0; - state->rf_mod = 0; + state->numflips = 0; state->lastsynctype = -1; state->lastp25type = 0; state->offset = 0; state->carrier = 0; - for (i = 0; i < 25; i++) - { - for (j = 0; j < 16; j++) - { - state->tg[i][j] = 48; - } - } - state->tgcount = 0; - state->lasttg = 0; - state->lastsrc = 0; - state->nac = 0; + + //Reset Voice Errors in C0 and C1 (or remaining Codewords in IMBE) state->errs = 0; state->errs2 = 0; - state->mbe_file_type = -1; + state->errsR = 0; + state->errs2R = 0; + + //Misc -- may not be needed state->optind = 0; state->numtdulc = 0; state->firstframe = 0; - sprintf (state->slot0light, " slot0 "); - sprintf (state->slot1light, " slot1 "); - state->aout_gain = 25; - memset (state->aout_max_buf, 0, sizeof (float) * 200); - state->aout_max_buf_p = state->aout_max_buf; - state->aout_max_buf_idx = 0; - state->samplesPerSymbol = 10; - state->symbolCenter = 4; - sprintf (state->algid, "________"); - sprintf (state->keyid, "________________"); - state->currentslot = 0; - state->cur_mp = malloc (sizeof (mbe_parms)); - state->prev_mp = malloc (sizeof (mbe_parms)); - state->prev_mp_enhanced = malloc (sizeof (mbe_parms)); - mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); - state->p25kid = 0; - state->debug_audio_errors = 0; - state->debug_header_errors = 0; - state->debug_header_critical_errors = 0; + //unsure if these are still used or ever were used, + // memset (state->aout_max_buf, 0, sizeof (float) * 200); + // state->aout_max_buf_p = state->aout_max_buf; + // state->aout_max_buf_idx = 0; - state->nxdn_last_ran = 0; - // state->payload_algid = 0; - // state->payload_algidR = 0; - state->dmr_encL = 0; - state->dmr_encR = 0; + // //MBE Specific + // //free the memory before allocating it again -- may not use this + // free (state->cur_mp); + // free (state->prev_mp); + // free (state->prev_mp_enhanced); - //each time you run this, it increses memory use by 4MB, massive memory leak - //need to revisit this sometime and look into only resetting only the necesary items to let P25 switch between signals (C4FM or Wide) without needing a restart - initialize_p25_heuristics(&state->p25_heuristics); //see if we want to re-init this or not, currently seems to cause memory leak when running over and over, mitigated with a reset flag + // //memory allocation and init on mbe -- may not use this + // state->cur_mp = malloc (sizeof (mbe_parms)); + // state->prev_mp = malloc (sizeof (mbe_parms)); + // state->prev_mp_enhanced = malloc (sizeof (mbe_parms)); + // mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); + + //rest the heurestics, we want to do this on each tune, each RF frequency can deviate quite a bit in strength + initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); } diff --git a/src/p25_lcw.c b/src/p25_lcw.c index 6b97936..8324fac 100644 --- a/src/p25_lcw.c +++ b/src/p25_lcw.c @@ -295,9 +295,20 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir //tune back to CC here - save about 1-2 seconds else if (lc_format == 0x4F) //# Call Termination/Cancellation { - fprintf (stderr, " Call Termination/Cancellation"); + fprintf (stderr, " Call Termination"); if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1) { + + //Will we need to check for a symbolrate change here, can a P25p2 TDMA-CC system + //revert back to a phase 1 traffic channel or carry a phase 1 traffic channel? + + //clear heuristics from current traffic channel + if (opts->frame_p25p1 == 1 && opts->use_heuristics == 1) + { + initialize_p25_heuristics(&state->p25_heuristics); + initialize_p25_heuristics(&state->inv_p25_heuristics); + } + //rigctl if (opts->use_rigctl == 1) { diff --git a/src/p25p1_mdpu.c b/src/p25p1_mdpu.c index f7dace0..6ae80d7 100644 --- a/src/p25p1_mdpu.c +++ b/src/p25p1_mdpu.c @@ -337,14 +337,24 @@ void processMPDU(dsd_opts * opts, dsd_state * state) if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency { //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel - if (opts->mod_qpsk == 1) + // if (opts->mod_qpsk == 1) + // { + // int spacing = state->p25_chan_spac[channelt >> 12]; + // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + // { + // state->samplesPerSymbol = 8; + // state->symbolCenter = 3; + // } + // } + + //changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK + if (1 == 1) { - int spacing = state->p25_chan_spac[channelt >> 12]; - if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + if (state->p25_chan_tdma[channelt >> 12] == 1) { state->samplesPerSymbol = 8; state->symbolCenter = 3; - } + } } //rigctl if (opts->use_rigctl == 1) @@ -423,15 +433,26 @@ void processMPDU(dsd_opts * opts, dsd_state * state) //reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency { + //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel - if (opts->mod_qpsk == 1) + // if (opts->mod_qpsk == 1) + // { + // int spacing = state->p25_chan_spac[channelt >> 12]; + // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + // { + // state->samplesPerSymbol = 8; + // state->symbolCenter = 3; + // } + // } + + //changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK + if (1 == 1) { - int spacing = state->p25_chan_spac[channelt >> 12]; - if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + if (state->p25_chan_tdma[channelt >> 12] == 1) { state->samplesPerSymbol = 8; state->symbolCenter = 3; - } + } } //rigctl if (opts->use_rigctl == 1)