Merge pull request #61 from lwvmobile/lwvmobile-dmrstereo-patch

DMR Stereo Inversion Handling
This commit is contained in:
lwvmobile 2022-05-14 09:14:53 -04:00 committed by GitHub
commit 2fd250b357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 277 additions and 188 deletions

View File

@ -50,6 +50,10 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
//memset(&state->TS1SuperFrame, 0, sizeof(TimeSlotVoiceSuperFrame_t));
//memset(&state->TS2SuperFrame, 0, sizeof(TimeSlotVoiceSuperFrame_t));
//Init slot lights
sprintf (state->slot1light, " slot1 ");
sprintf (state->slot2light, " slot2 ");
//Init the color code status
state->color_code_ok = 0;
@ -69,7 +73,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
cachdata[i] = dibit;
state->dmr_stereo_payload[i] = dibit;
@ -93,7 +97,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+12] = dibit;
redundancyA[i] = dibit;
@ -135,7 +139,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+48] = dibit;
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
@ -155,7 +159,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+66] = dibit;
syncdata[(2*i)] = (1 & (dibit >> 1)); // bit 1
@ -185,6 +189,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
sync[24] = 0;
EmbeddedSignallingOk = -1;
if(QR_16_7_6_decode(EmbeddedSignalling))
{
@ -192,9 +197,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;
@ -215,7 +221,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+90] = dibit;
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
@ -241,7 +247,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+108] = dibit;
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
@ -255,7 +261,10 @@ 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)
//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 +277,10 @@ 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 )
//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)
@ -276,7 +288,12 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
sprintf(state->slot1light, "[slot1]");
sprintf(state->slot2light, " slot2 ");
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
fprintf (stderr,"Sync: +DMR ");
//fprintf (stderr,"Sync: +DMR ");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR ");
}
else fprintf (stderr,"Sync: -DMR ");
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
vc1 = 1;
}
@ -285,7 +302,12 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
sprintf(state->slot2light, "[slot2]");
sprintf(state->slot1light, " slot1 ");
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
fprintf (stderr,"Sync: +DMR ");
//fprintf (stderr,"Sync: +DMR ");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR ");
}
else fprintf (stderr,"Sync: -DMR ");
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
vc2 = 1;
}
@ -293,8 +315,11 @@ 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
if (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 +330,23 @@ 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);
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR [SLOT1] slot2 | | DMRSTEREO | VC%d \n",vc1);
}
else 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);
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR slot1 [SLOT2] | | DMRSTEREO | VC%d \n",vc2);
}
else fprintf (stderr,"Sync: -DMR slot1 [SLOT2] | | DMRSTEREO | VC%d \n",vc2);
}
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
{
@ -444,7 +479,7 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
@ -458,7 +493,12 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
//fprintf (stderr,"\n%s ", getTime());
fprintf (stderr,"%s ", getTime());
fprintf (stderr,"Sync: +DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
}
else fprintf (stderr,"Sync: -DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
//fprintf (stderr,"Sync: +DMR | Frame Sync | DMRSTEREO | VC1 FS \n");
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
dmrBS (opts, state); //bootstrap into full TDMA frame for BS mode

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 && opts->inverted_dmr == 0
{
dibit_p = state->dmr_payload_p - 90;
}
// CACH
for (i = 0; i < 12; i++)
{
@ -76,14 +78,15 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
/* Change the current slot only if we are in relayed mode (not in direct mode) */
if(state->directmode == 0) state->currentslot = (1 & (dibit >> 1)); // bit 1
if (state->currentslot == 0)
if (state->currentslot == 0 && state->dmr_ms_mode == 0)
{
state->slot1light[0] = '[';
state->slot1light[6] = ']';
state->slot2light[0] = ' ';
state->slot2light[6] = ' ';
}
else
//else
if (state->currentslot == 1 && state->dmr_ms_mode == 0)
{
state->slot2light[0] = '[';
state->slot2light[6] = ']';
@ -95,8 +98,8 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
if(state->hardslot != 9 && state->hardslot != state->currentslot)
//if(1==1)
{
fprintf (stderr, " Current Slot = %d", state->currentslot + 1);
fprintf (stderr, "\n"); //line break after breaking out of jail
//fprintf (stderr, " Current Slot = %d", state->currentslot + 1);
//fprintf (stderr, "\n"); //line break after breaking out of jail
//goto JUMP;
}
}
@ -253,7 +256,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
fprintf(stderr, "%s ", syncbits);
#endif
if((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
if((strcmp (sync, DMR_BS_DATA_SYNC) == 0) )//|| (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
{
if (state->currentslot == 0)
{
@ -277,7 +280,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
sprintf(state->slot2light, "[sLoT2]");
}
if (opts->errorbars == 1)
if (opts->errorbars == 1 && state->dmr_ms_mode == 0)
{
fprintf(stderr, "%s %s ", state->slot1light, state->slot2light);
}
@ -291,7 +294,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
}
if (opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
if (state->dmr_stereo == 1)
{
@ -312,7 +315,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 +326,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 +333,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 ");
@ -432,7 +392,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
}
if (opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
//dibit = (dibit ^ 2);
}
if (state->dmr_stereo == 1)
{
@ -554,7 +514,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

@ -267,7 +267,10 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
}
if ( (strcmp (sync, DMR_MS_VOICE_SYNC) == 0) ) //
//if ( (strcmp (sync, DMR_MS_VOICE_SYNC) == 0) )
//fixed to compensate for inverted signal
if ( ((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) && opts->inverted_dmr == 0) || ((strcmp (sync, DMR_MS_DATA_SYNC) == 0) && opts->inverted_dmr == 1) )
{
if (internalslot == 0)
{
@ -291,7 +294,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
if (state->dmr_ms_mode == 1 ) //&& vc1 < 7
{
//do something
fprintf (stderr, "MS MODE ");
//fprintf (stderr, "MS MODE ");
}
//don't know if we will catch an RC sync in here or not, should be on VC6 if it occurs
@ -302,7 +305,8 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
{
sprintf(state->slot1light, "[slot1]");
sprintf(state->slot2light, " slot2 ");
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
fprintf (stderr,"Sync: +DMR MS MODE | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
//test with vc1 reset disabled, if all is well, leave disabled
//vc1 = 1;
}
@ -310,7 +314,8 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
{
sprintf(state->slot2light, "[slot2]");
sprintf(state->slot1light, " slot1 ");
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
fprintf (stderr,"Sync: +DMR MS MODE | Color Code=%02d | DMRSTEREO | RC ", state->color_code);
//test with vc1 reset disabled, if all is well, leave disabled
//vc2 = 1;
}
@ -321,7 +326,10 @@ void dmrMS (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_MS_DATA_SYNC) == 0) )
//if ( (strcmp (sync, DMR_MS_DATA_SYNC) == 0) )
//fixed to compensate for inverted signal
if ( ((strcmp (sync, DMR_MS_DATA_SYNC) == 0) && opts->inverted_dmr == 0) ||
((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) && opts->inverted_dmr == 1) )
{
fprintf (stderr,"%s ", getTime());
if (internalslot == 0)
@ -329,7 +337,11 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
sprintf(state->slot1light, "[slot1]");
sprintf(state->slot2light, " slot2 ");
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | MS Data ", state->color_code);
fprintf (stderr,"Sync: +DMR ");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR ");
}
else fprintf (stderr,"Sync: -DMR ");
//test with vc1 reset disabled, if all is well, leave disabled
//vc1 = 1;
}
@ -338,7 +350,11 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
sprintf(state->slot2light, "[slot2]");
sprintf(state->slot1light, " slot1 ");
//fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | Data ", state->color_code);
fprintf (stderr,"Sync: +DMR ");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR MS MODE ");
}
else fprintf (stderr,"Sync: -DMR MS MODE ");
//test with vc1 reset disabled, if all is well, leave disabled
//vc2 = 1;
}
@ -351,19 +367,34 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
goto END;
}
if( (strcmp (sync, DMR_MS_DATA_SYNC) != 0) && internalslot == activeslot && vc1 < 7) //only play voice no MS Data Sync and vc1 below 6 (no voice resync)
//if( (strcmp (sync, DMR_MS_DATA_SYNC) != 0) && internalslot == activeslot && vc1 < 7)
//only play voice no MS Data Sync and vc1 below 6 (no voice resync)
//fixed to compensate for inverted signal
if( ( ( ((strcmp (sync, DMR_MS_DATA_SYNC) != 0) && opts->inverted_dmr == 0) ||
((strcmp (sync, DMR_MS_VOICE_SYNC) != 0) && opts->inverted_dmr == 1) ) )
&& internalslot == activeslot && vc1 < 7)
{
skipcount = 0; //reset skip count if processing voice frames
fprintf (stderr,"%s ", getTime());
if (internalslot == 0)
if (internalslot == 0 && opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
fprintf (stderr,"Sync: +DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
}
if (internalslot == 1)
if (internalslot == 0 && opts->inverted_dmr == 1)
{
fprintf (stderr,"Sync: +DMR slot1 [slot2] | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
fprintf (stderr,"Sync: -DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc1);
}
if (internalslot == 1 && opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
}
if (internalslot == 1 && opts->inverted_dmr == 1)
{
fprintf (stderr,"Sync: -DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d \n", state->color_code, vc2);
}
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
{
@ -584,9 +615,14 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
}
fprintf (stderr, "MS MODE ");
//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");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR MS MODE | Frame Sync | DMRSTEREO | VC1 FS \n");
}
else fprintf (stderr,"Sync: -DMR MS MODE | 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);
@ -638,15 +674,21 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
}
//fprintf(stderr, "\n");
//print nice pretty lines
fprintf (stderr, "MS MODE ");
//fprintf (stderr, "MS MODE ");
fprintf (stderr, "%s ", getTime());
//fprintf (stderr, "Sync: +MS DATA | Color Code=XX | DMRSTEREO | Data ");
fprintf (stderr, "Sync: +DMR ");
if (opts->inverted_dmr == 0)
{
fprintf (stderr,"Sync: +DMR MS MODE ");
}
else fprintf (stderr,"Sync: -DMR MS MODE ");
//fprintf (stderr, "\n ");
//sprintf for slot 1, doesn't matter, just makes print out of data look uniform setting ahead of time
sprintf(state->slot1light, "[slot1]");
sprintf(state->slot2light, " slot2 ");
//sprintf(state->slot1light, "[slot1]");
//sprintf(state->slot2light, " slot2 ");
sprintf(state->slot1light, "");
sprintf(state->slot2light, "");
//process data
state->dmr_stereo = 1;

View File

@ -1716,7 +1716,7 @@ void ProcessDmrPIHeader(dsd_opts * opts, dsd_state * state, uint8_t info[196], u
}
else {
fprintf (stderr, "%s ", KRED);
fprintf (stderr, (" (PI CRC Fail, FEC Fail)"));
fprintf (stderr, ("\n (PI CRC Fail, FEC Fail)"));
fprintf (stderr, "%s ", KNRM);
}
@ -2085,6 +2085,10 @@ void ProcessDmrTerminaisonLC(dsd_opts * opts, dsd_state * state, uint8_t info[19
state->payload_keyid = 0;
//state->payload_mfid = 0;
state->payload_mi = 0;
state->payload_algidR = 0;
state->payload_keyidR = 0;
//state->payload_mfid = 0;
state->payload_miR = 0;
//tlc
if((IrrecoverableErrors == 0) && CRCCorrect) //amateur DMR seems to only set radio ID up here I think, figure out best way to set without messing up other DMR types

View File

@ -361,7 +361,7 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
state->directmode = 1; /* Direct mode */
sprintf(state->slot1light, "[sLoT2]");
}
else if((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_VOICE_SYNC) == 0))
else if((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) ) //|| (strcmp (sync, DMR_MS_VOICE_SYNC) == 0))
{
mutecurrentslot = 0;
state->directmode = 0;

View File

@ -200,6 +200,8 @@ processFrame (dsd_opts * opts, dsd_state * state)
sprintf (state->fsubtype, " VOICE ");
if (opts->dmr_stereo == 0 && state->synctype < 32) // -T option for DMR (TDMA) stereo
{
sprintf (state->slot1light, " slot1 ");
sprintf (state->slot2light, " slot2 ");
processDMRvoice (opts, state);
}
if (opts->dmr_stereo == 0 && state->synctype == 32)
@ -239,12 +241,16 @@ processFrame (dsd_opts * opts, dsd_state * state)
{
closeMbeOutFile (opts, state);
state->err_str[0] = 0;
sprintf (state->slot1light, " slot1 ");
sprintf (state->slot2light, " slot2 ");
processDMRdata (opts, state);
}
//switch dmr_stereo to 0 when handling BS data frame syncs with processDMRdata
if (opts->dmr_stereo == 1)
{
state->dmr_stereo = 0; //set the state to zero for handling pure data frames
sprintf (state->slot1light, " slot1 ");
sprintf (state->slot2light, " slot2 ");
processDMRdata (opts, state);
}
}

View File

@ -390,7 +390,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
fprintf (stderr,"Demod mode: %s Nac: %4X\n", modulation, state->nac);
fprintf (stderr,"Frame Type: %s Talkgroup: %7i\n", state->ftype, state->lasttg);
fprintf (stderr,"Frame Subtype: %s Source: %12i\n", state->fsubtype, state->lastsrc);
fprintf (stderr,"TDMA activity: %s %s Voice errors: %s\n", state->slot0light, state->slot1light, state->err_str);
fprintf (stderr,"TDMA activity: %s %s Voice errors: %s\n", state->slot1light, state->slot2light, state->err_str);
fprintf (stderr,"+----------------------------------------------------------------+\n");
for (i = 0; i < 10; i++)
{
@ -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);
}
@ -807,7 +828,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
return (11);
return (11); //11
}
}
if(strcmp (synctest, DMR_DIRECT_MODE_TS1_DATA_SYNC) == 0)
@ -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

@ -68,6 +68,9 @@ comp (const void *a, const void *b)
return 1;
}
//struct for checking existence of directory to write to
struct stat st = {0};
void
noCarrier (dsd_opts * opts, dsd_state * state)
{
@ -102,8 +105,10 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->repeat = 0;
state->nac = 0;
state->numtdulc = 0;
sprintf (state->slot0light, " slot0 ");
sprintf (state->slot1light, " slot1 ");
//sprintf (state->slot0light, " slot0 ");
//sprintf (state->slot0light, " slot0 ");
sprintf (state->slot1light, "");
sprintf (state->slot2light, "");
state->firstframe = 0;
if (opts->audio_gain == (float) 0)
{
@ -126,6 +131,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
sprintf (state->keyid, "________________");
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
mbe_initMbeParms (state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2);
state->dmr_ms_mode = 0;
}
void
@ -307,8 +314,10 @@ initState (dsd_state * state)
state->optind = 0;
state->numtdulc = 0;
state->firstframe = 0;
sprintf (state->slot0light, " slot0 ");
sprintf (state->slot1light, " slot1 ");
//sprintf (state->slot0light, " slot0 ");
//sprintf (state->slot1light, " slot1 ");
sprintf (state->slot1light, "");
sprintf (state->slot2light, "");
state->aout_gain = 25;
memset (state->aout_max_buf, 0, sizeof (float) * 200);
state->aout_max_buf_p = state->aout_max_buf;
@ -394,6 +403,7 @@ initState (dsd_state * state)
state->dmr_soR = 0;
state->dmr_fid = 0;
state->dmr_fidR = 0;
state->dmr_ms_mode = 0;
memset(state->dstarradioheader, 0, 41);
@ -410,90 +420,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);
}
@ -505,7 +515,7 @@ liveScanner (dsd_opts * opts, dsd_state * state)
//probably need to dig a little deeper, maybe inlvl releated?
if (opts->audio_in_type == 1)
{
opts->pulse_digi_rate_out = 48000; //change to 48K/1 for STDIN input
opts->pulse_digi_rate_out = 8000; //revert to 8K/1 for STDIN input, sometimes crackles when upsampling
opts->pulse_digi_out_channels = 1;
if (opts->dmr_stereo == 1)
{
@ -909,7 +919,13 @@ main (int argc, char **argv)
case 'd':
strncpy(opts.mbe_out_dir, optarg, 1023);
opts.mbe_out_dir[1023] = '\0';
fprintf (stderr,"Writing mbe data files to directory %s\n", opts.mbe_out_dir);
if (stat(opts.mbe_out_dir, &st) == -1)
{
fprintf (stderr, "-d %s directory does not exist\n", opts.mbe_out_dir);
fprintf (stderr, "Creating directory %s to save MBE files\n", opts.mbe_out_dir);
mkdir(opts.mbe_out_dir, 0700); //user read write execute, needs execute for some reason or segfault
}
else fprintf (stderr,"Writing mbe data files to directory %s\n", opts.mbe_out_dir);
break;
case 'c':
opts.rtlsdr_center_freq = (uint32_t)atofs(optarg);