DMR Stereo Inversion Handling

DMR Stereo Inversion Handling
--Fix frame sync not forwarding inverted signal to DMR Stereo methods
--Other Misc Bug Fixes
This commit is contained in:
lwvmobile
2022-05-12 11:25:41 -04:00
committed by GitHub
parent 2263ddae63
commit 7d6c3dc67c
5 changed files with 131 additions and 143 deletions

View File

@@ -185,6 +185,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
sync[24] = 0;
EmbeddedSignallingOk = -1;
if(QR_16_7_6_decode(EmbeddedSignalling))
{
@@ -192,9 +193,10 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
internalcolorcode = 69; //set so we know if this value is being set properly
if(EmbeddedSignallingOk == 1)
//state->color_code = 69;
if( EmbeddedSignallingOk == 1 ) //don't set on 1?
{
state->color_code = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
//state->color_code = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
internalcolorcode = (unsigned int)((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
state->color_code_ok = EmbeddedSignallingOk;
@@ -255,7 +257,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
//reset vc counters to 1 if new voice sync frame on each slot
if ( (strcmp (sync, DMR_BS_VOICE_SYNC) == 0) )
//fixed to compensate for inverted signal
if ( ((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) && opts->inverted_dmr == 0) || ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) && opts->inverted_dmr == 1) )
{
if (internalslot == 0)
{
@@ -268,7 +271,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
//check for sync pattern here after collected the rest of the payload, decide what to do with it
if ( (strcmp (sync, DMR_BS_DATA_SYNC) == 0) )
//fixed to compensate for inverted signal
if ( ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) && opts->inverted_dmr == 0) || ((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) && opts->inverted_dmr == 1) )
{
fprintf (stderr,"%s ", getTime());
if (internalslot == 0)
@@ -293,8 +297,10 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
skipcount++; //after 6 data frames, drop back to getFrameSync and process subsequent data with processDMRdata
goto SKIP;
}
if( (strcmp (sync, DMR_BS_DATA_SYNC) != 0) ) //only play voice no data sync // || (strcmp (sync, DMR_MS_DATA_SYNC) != 0)
//only play voice on no data sync
//fixed to compensate for inverted signal
//(strcmp (sync, DMR_BS_DATA_SYNC) != 0)
if( ((strcmp (sync, DMR_BS_DATA_SYNC) != 0) && opts->inverted_dmr == 0) || ((strcmp (sync, DMR_BS_VOICE_SYNC) != 0) && opts->inverted_dmr == 1))
{
if (EmbeddedSignallingOk == 0)
{
@@ -305,13 +311,15 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
if (internalslot == 0)
{
state->dmrburstL = 16; //use 16 for Voice?
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->dmr_color_code, vc1);
fprintf (stderr,"Sync: +DMR [slot1] slot2 | | DMRSTEREO | VC%d \n",vc1);
}
if (internalslot == 1)
{
state->dmrburstR = 16; //use 16 for Voice?
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | VC%d \n", state->dmr_color_code, vc2);
fprintf (stderr,"Sync: +DMR [slot1] slot2 | | DMRSTEREO | VC%d \n",vc2);
}
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
{

View File

@@ -51,11 +51,13 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
dibit_p = state->dibit_buf_p - 90;
//using the estimate_symbol method for the dmr_payload_p buffer causes sync
//issues with P25, so only do it when frame_p25p1 == 0, or -fr option
if (opts->frame_p25p1 == 0) //opts->frame_p25p1 == 0
//temp fix to only use dmr_payload_p buffer when no inversion expected, otherwise use dibit_buf
if (opts->frame_p25p1 == 0 && opts->inverted_dmr == 0) //opts->frame_p25p1 == 0
{
dibit_p = state->dmr_payload_p - 90;
}
// CACH
for (i = 0; i < 12; i++)
{
@@ -312,7 +314,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
//fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
/* Reconstitute the burst type */
//consider assigning thsi only when slottypeok or similar check passes, eliminate bad burst types from decoding randomly
//consider assigning this only when slottypeok or similar check passes, eliminate bad burst types from decoding randomly
burst = (unsigned int)((SlotType[4] << 3) + (SlotType[5] << 2) + (SlotType[6] << 1) + SlotType[7]);
if (state->currentslot == 0)
{
@@ -323,7 +325,6 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
state->dmrburstR = burst;
}
/* Reconstitute the burst type */
bursttype[0] = SlotType[4] + '0';
bursttype[1] = SlotType[5] + '0';
@@ -331,48 +332,6 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
bursttype[3] = SlotType[7] + '0';
bursttype[4] = '\0';
/* //delete this chunk later
if (state->dmr_stereo == 3) //may not need this any longer
{
burst = (state->dmr_stereo_payload[63] << 2) | (state->dmr_stereo_payload[64]);
//this whole split for getting burst and burst type is makes no sense
//why not just use burst
bursttype[0] = (((state->dmr_stereo_payload[63] >> 1) & 1) + '0');
bursttype[1] = (((state->dmr_stereo_payload[63] >> 0) & 1) + '0');
bursttype[2] = (((state->dmr_stereo_payload[64] >> 1) & 1) + '0');
bursttype[3] = (((state->dmr_stereo_payload[64] >> 0) & 1) + '0');
bursttype[4] = '\0';
//fprintf(stderr, "BURST1 = %04b ", burst);
}
//figure out why the sync is wrong when dumping the payload to processDMRdata for MS Data
//I think its a conversion issue with the payload(chat) from the dibit buffer (int *)
//actually, its the dibit buffer storing as 1 and 3 only (GFSK) when sync drops
//made a seperate dmr buffer, but still, when sync loss and regain, takes a few syncs to calibrate center/umid/lmid properly
//getting accurate MS data AND leading BS data may be impossible without saving the symbols, calibrating, then going back
//and running the buffer payload, but I honestly don't know right now, probably easier to start from stratch than fix this
if (state->dmr_ms_mode == 7)
{
burst = (unsigned int)((SlotType[4] << 3) | (SlotType[5] << 2) | (SlotType[6] << 1) | SlotType[7]);
bursttype[0] = SlotType[4] + '0';
bursttype[1] = SlotType[5] + '0';
bursttype[2] = SlotType[6] + '0';
bursttype[3] = SlotType[7] + '0';
bursttype[4] = '\0';
//fprintf(stderr, "BURST1 = %04b ", burst);
}
if (state->dmr_stereo == 3)
{
fprintf(stderr, "BURST2 = %b%b%b%b Slot Dump ", SlotType[4], SlotType[5], SlotType[6], SlotType[7] );
fprintf(stderr, " Slot Dump = ");
for (i = 0; i < 20; i++)
{
fprintf(stderr, "%b", SlotType[i]);
}
fprintf(stderr, "\n ");
}
*/
if (strcmp (bursttype, "0000") == 0)
{
sprintf(state->fsubtype, " PI Header ");
@@ -554,7 +513,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
/* Burst = Slot idle */
case 0b1001:
{
if(state->color_code_ok) state->dmr_color_code = state->color_code; //try setting this on idle if crc ok
if(state->color_code_ok && state->dmr_stereo == 0) state->dmr_color_code = state->color_code; //try setting this on idle if crc ok
break;
}

View File

@@ -586,7 +586,7 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "MS MODE ");
fprintf (stderr,"%s ", getTime());
fprintf (stderr,"Sync: +DMR | Color Code=XX | DMRSTEREO | VC1 FS \n");
fprintf (stderr,"Sync: +DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);

View File

@@ -687,7 +687,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->min = ((state->min) + lmin) / 2;
//state->directmode = 0;
//fprintf (stderr, "DMR MS Data");
if (0 == 0) //opts->inverted_dmr
if (opts->inverted_dmr == 0) //opts->inverted_dmr
{
// data frame
sprintf(state->ftype, "DMR MS");
@@ -706,6 +706,16 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
return (33); //33
}
else //inverted MS voice frame
{
sprintf(state->ftype, "DMR MS");
state->lastsynctype = 32;
if ( opts->monitor_input_audio == 1)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
return (32);
}
}
//not sure if this should be here, RC data should only be present in vc6?
if(strcmp (synctest, DMR_RC_DATA_SYNC) == 0)
@@ -746,7 +756,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->min = ((state->min) + lmin) / 2;
//state->directmode = 0;
//fprintf (stderr, "DMR MS VOICE\n");
if (0 == 0) //opts->inverted_dmr
if (opts->inverted_dmr == 0) //opts->inverted_dmr
{
// voice frame
sprintf(state->ftype, "DMR MS");
@@ -765,6 +775,17 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
return (32);
}
else //inverted MS data frame
{
sprintf(state->ftype, "DMR MS");
state->lastsynctype = 33;
if ( opts->monitor_input_audio == 1)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
return (33);
}
}
//if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0))
@@ -794,7 +815,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
// inverted voice frame
sprintf(state->ftype, "DMR ");
if (opts->errorbars == 1)
if (opts->errorbars == 1 && opts->dmr_stereo == 0)
{
printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
}
@@ -928,7 +949,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
// inverted data frame
sprintf(state->ftype, "DMR ");
if (opts->errorbars == 1 && opts->dmr_stereo == 0)
if (opts->errorbars == 1) //&& opts->dmr_stereo == 0
{
printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
}

View File

@@ -410,90 +410,90 @@ initState (dsd_state * state)
void
usage ()
{
fprintf (stderr, "Github Build Version: %s \n", GIT_TAG);
fprintf (stderr,"\n");
fprintf (stderr,"Usage: dsd [options] Live scanner mode\n");
fprintf (stderr," or: dsd [options] -r <files> Read/Play saved mbe data from file(s)\n");
fprintf (stderr," or: dsd -h Show help\n");
fprintf (stderr,"\n");
fprintf (stderr,"Display Options:\n");
fprintf (stderr," -e Show Frame Info and errorbars (default)\n");
fprintf (stderr," -pe Show P25 encryption sync bits\n");
fprintf (stderr," -pl Show P25 link control bits\n");
fprintf (stderr," -ps Show P25 status bits and low speed data\n");
fprintf (stderr," -pt Show P25 talkgroup info\n");
fprintf (stderr," -q Don't show Frame Info/errorbars\n");
fprintf (stderr," -s Datascope (disables other display options)\n");
fprintf (stderr," -t Show symbol timing during sync\n");
fprintf (stderr," -v <num> Frame information Verbosity\n");
fprintf (stderr," -z <num> Frame rate for datascope\n");
fprintf (stderr,"\n");
fprintf (stderr,"Input/Output options:\n");
fprintf (stderr," -i <device> Audio input device (default is pulse audio, \n - for piped stdin, rtl for rtl device)\n");
fprintf (stderr," -o <device> Audio output device (default is pulse audio)\n");
fprintf (stderr," -d <dir> Create mbe data files, use this directory\n");
fprintf (stderr," -r <files> Read/Play saved mbe data from file(s)\n");
fprintf (stderr," -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
fprintf (stderr," -w <file> Output synthesized speech to a .wav file\n");
//fprintf (stderr," -a Display port audio devices\n");
fprintf (stderr," -W Monitor Source Audio When No Sync Detected (WIP!)\n");
fprintf (stderr,"\n");
fprintf (stderr,"RTL-SDR options:\n");
fprintf (stderr," -c <hertz> RTL-SDR Frequency\n");
fprintf (stderr," -P <num> RTL-SDR PPM Error (default = 0)\n");
fprintf (stderr," -D <num> RTL-SDR Device Index Number\n");
fprintf (stderr," -G <num> RTL-SDR Device Gain (0-49) (default = 0 Auto Gain)\n");
fprintf (stderr," -L <num> RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)\n (Just have to guess really...)\n");
fprintf (stderr," -V <num> RTL-SDR Sample Gain Multiplier (default = 1)\n");
fprintf (stderr," -Y <num> RTL-SDR VFO Bandwidth kHz (default = 48)(6, 8, 12, 16, 24, 48) \n");
fprintf (stderr," -U <num> RTL-SDR UDP Remote Port (default = 6020)\n");
fprintf (stderr,"\n");
fprintf (stderr,"Scanner control options:\n");
fprintf (stderr," -B <num> Serial port baud rate (default=115200)\n");
fprintf (stderr," -C <device> Serial port for scanner control (default=/dev/ttyUSB0)\n");
fprintf (stderr," -R <num> Resume scan after <num> TDULC frames or any PDU or TSDU\n");
fprintf (stderr,"\n");
fprintf (stderr,"Decoder options:\n");
fprintf (stderr," -fa Auto-detect frame type (default)\n");
fprintf (stderr," -f1 Decode only P25 Phase 1\n");
fprintf (stderr," -fd Decode only D-STAR\n");
fprintf (stderr," -fr Decode only DMR/MOTOTRBO\n");
fprintf (stderr," -fx Decode only X2-TDMA\n");
fprintf (stderr," -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
fprintf (stderr," -fn Decode only NXDN96* (12.5 kHz)\n");
fprintf (stderr," -fp Decode only ProVoice*\n");
fprintf (stderr," -fm Decode only dPMR*\n");
fprintf (stderr," -l Disable DMR/MOTOTRBO and NXDN input filtering\n");
fprintf (stderr," -ma Auto-select modulation optimizations (default)\n");
fprintf (stderr," -mc Use only C4FM modulation optimizations\n");
fprintf (stderr," -mg Use only GFSK modulation optimizations\n");
fprintf (stderr," -mq Use only QPSK modulation optimizations\n");
fprintf (stderr," -pu Unmute Encrypted P25\n");
fprintf (stderr," -u <num> Unvoiced speech quality (default=3)\n");
fprintf (stderr," -xx Expect non-inverted X2-TDMA signal\n");
fprintf (stderr," -xr Expect inverted DMR/MOTOTRBO signal\n");
fprintf (stderr," -xd Expect inverted ICOM dPMR signal\n"); //still need to do this
fprintf (stderr,"\n");
fprintf (stderr," * denotes frame types that cannot be auto-detected.\n");
fprintf (stderr,"\n");
fprintf (stderr,"Advanced decoder options:\n");
fprintf (stderr," -A <num> QPSK modulation auto detection threshold (default=26)\n");
fprintf (stderr," -S <num> Symbol buffer size for QPSK decision point tracking\n");
fprintf (stderr," (default=36)\n");
fprintf (stderr," -M <num> Min/Max buffer size for QPSK decision point tracking\n");
fprintf (stderr," (default=15)\n");
fprintf (stderr," -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
fprintf (stderr," Helps when decoding mixed signal types (P25P1) at same time\n");
fprintf (stderr," (WiP! May Cause Slow Memory Leak or System Hang - Experimental)\n");
fprintf (stderr," -T Enable DMR TDMA Stereo Voice (Two Slot Dual Voices)\n");
fprintf (stderr," This feature will open two streams for slot 1 voice and slot 2 voice\n");
fprintf (stderr," May Cause Skipping or sync issues if bad signal/errors\n");
fprintf (stderr," -F Enable DMR TDMA Stereo Passive Frame Sync\n");
fprintf (stderr," This feature will attempt to resync less often due to excessive voice errors\n");
fprintf (stderr," Use if skipping occurs, but may cause wonky audio due to loss of good sync\n");
fprintf (stderr," -Z Log MBE Payload to console\n");
fprintf (stderr,"\n");
fprintf (stderr,"Report bugs to: https://github.com/lwvmobile/dsd-fme/issues \n");
printf ( "Github Build Version: %s \n", GIT_TAG);
printf ("\n");
printf ("Usage: dsd [options] Live scanner mode\n");
printf (" or: dsd [options] -r <files> Read/Play saved mbe data from file(s)\n");
printf (" or: dsd -h Show help\n");
printf ("\n");
printf ("Display Options:\n");
printf (" -e Show Frame Info and errorbars (default)\n");
printf (" -pe Show P25 encryption sync bits\n");
printf (" -pl Show P25 link control bits\n");
printf (" -ps Show P25 status bits and low speed data\n");
printf (" -pt Show P25 talkgroup info\n");
printf (" -q Don't show Frame Info/errorbars\n");
printf (" -s Datascope (disables other display options)\n");
printf (" -t Show symbol timing during sync\n");
printf (" -v <num> Frame information Verbosity\n");
printf (" -z <num> Frame rate for datascope\n");
printf ("\n");
printf ("Input/Output options:\n");
printf (" -i <device> Audio input device (default is pulse audio, \n - for piped stdin, rtl for rtl device)\n");
printf (" -o <device> Audio output device (default is pulse audio)\n");
printf (" -d <dir> Create mbe data files, use this directory\n");
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
printf (" -w <file> Output synthesized speech to a .wav file\n");
//printf (" -a Display port audio devices\n");
printf (" -W Monitor Source Audio When No Sync Detected (WIP!)\n");
printf ("\n");
printf ("RTL-SDR options:\n");
printf (" -c <hertz> RTL-SDR Frequency\n");
printf (" -P <num> RTL-SDR PPM Error (default = 0)\n");
printf (" -D <num> RTL-SDR Device Index Number\n");
printf (" -G <num> RTL-SDR Device Gain (0-49) (default = 0 Auto Gain)\n");
printf (" -L <num> RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)\n (Just have to guess really...)\n");
printf (" -V <num> RTL-SDR Sample Gain Multiplier (default = 1)\n");
printf (" -Y <num> RTL-SDR VFO Bandwidth kHz (default = 48)(6, 8, 12, 16, 24, 48) \n");
printf (" -U <num> RTL-SDR UDP Remote Port (default = 6020)\n");
printf ("\n");
printf ("Scanner control options:\n");
printf (" -B <num> Serial port baud rate (default=115200)\n");
printf (" -C <device> Serial port for scanner control (default=/dev/ttyUSB0)\n");
printf (" -R <num> Resume scan after <num> TDULC frames or any PDU or TSDU\n");
printf ("\n");
printf ("Decoder options:\n");
printf (" -fa Auto-detect frame type (default)\n");
printf (" -f1 Decode only P25 Phase 1\n");
printf (" -fd Decode only D-STAR\n");
printf (" -fr Decode only DMR/MOTOTRBO\n");
printf (" -fx Decode only X2-TDMA\n");
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
printf (" -fp Decode only ProVoice*\n");
printf (" -fm Decode only dPMR*\n");
printf (" -l Disable DMR/MOTOTRBO and NXDN input filtering\n");
printf (" -ma Auto-select modulation optimizations (default)\n");
printf (" -mc Use only C4FM modulation optimizations\n");
printf (" -mg Use only GFSK modulation optimizations\n");
printf (" -mq Use only QPSK modulation optimizations\n");
printf (" -pu Unmute Encrypted P25\n");
printf (" -u <num> Unvoiced speech quality (default=3)\n");
printf (" -xx Expect non-inverted X2-TDMA signal\n");
printf (" -xr Expect inverted DMR/MOTOTRBO signal\n");
printf (" -xd Expect inverted ICOM dPMR signal\n"); //still need to do this
printf ("\n");
printf (" * denotes frame types that cannot be auto-detected.\n");
printf ("\n");
printf ("Advanced decoder options:\n");
printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
printf (" -S <num> Symbol buffer size for QPSK decision point tracking\n");
printf (" (default=36)\n");
printf (" -M <num> Min/Max buffer size for QPSK decision point tracking\n");
printf (" (default=15)\n");
printf (" -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
printf (" Helps when decoding mixed signal types (P25P1) at same time\n");
printf (" (WiP! May Cause Slow Memory Leak or System Hang - Experimental)\n");
printf (" -T Enable DMR TDMA Stereo Voice (Two Slot Dual Voices)\n");
printf (" This feature will open two streams for slot 1 voice and slot 2 voice\n");
printf (" May Cause Skipping or sync issues if bad signal/errors\n");
printf (" -F Enable DMR TDMA Stereo Passive Frame Sync\n");
printf (" This feature will attempt to resync less often due to excessive voice errors\n");
printf (" Use if skipping occurs, but may cause wonky audio due to loss of good sync\n");
printf (" -Z Log MBE Payload to console\n");
printf ("\n");
printf ("Report bugs to: https://github.com/lwvmobile/dsd-fme/issues \n");
exit (0);
}