diff --git a/src/dmr_bs.c b/src/dmr_bs.c index fff2fae..e05d8e5 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -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 diff --git a/src/dmr_data.c b/src/dmr_data.c index ccb31f2..7decf4b 100644 --- a/src/dmr_data.c +++ b/src/dmr_data.c @@ -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; } diff --git a/src/dmr_ms.c b/src/dmr_ms.c index 5e5aafc..bb67bcd 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -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; diff --git a/src/dmr_sync.c b/src/dmr_sync.c index 0429358..d8d6d50 100644 --- a/src/dmr_sync.c +++ b/src/dmr_sync.c @@ -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 diff --git a/src/dmr_voice.c b/src/dmr_voice.c index e7322c3..c44598d 100644 --- a/src/dmr_voice.c +++ b/src/dmr_voice.c @@ -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; diff --git a/src/dsd_frame.c b/src/dsd_frame.c index 38dc782..d48dd63 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -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); } } diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index 546580b..c8fceb8 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -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); } diff --git a/src/dsd_main.c b/src/dsd_main.c index e183c86..df02d8d 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -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 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 Frame information Verbosity\n"); - fprintf (stderr," -z Frame rate for datascope\n"); - fprintf (stderr,"\n"); - fprintf (stderr,"Input/Output options:\n"); - fprintf (stderr," -i Audio input device (default is pulse audio, \n - for piped stdin, rtl for rtl device)\n"); - fprintf (stderr," -o Audio output device (default is pulse audio)\n"); - fprintf (stderr," -d Create mbe data files, use this directory\n"); - fprintf (stderr," -r Read/Play saved mbe data from file(s)\n"); - fprintf (stderr," -g Audio output gain (default = 0 = auto, disable = -1)\n"); - fprintf (stderr," -w 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 RTL-SDR Frequency\n"); - fprintf (stderr," -P RTL-SDR PPM Error (default = 0)\n"); - fprintf (stderr," -D RTL-SDR Device Index Number\n"); - fprintf (stderr," -G RTL-SDR Device Gain (0-49) (default = 0 Auto Gain)\n"); - fprintf (stderr," -L RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)\n (Just have to guess really...)\n"); - fprintf (stderr," -V RTL-SDR Sample Gain Multiplier (default = 1)\n"); - fprintf (stderr," -Y RTL-SDR VFO Bandwidth kHz (default = 48)(6, 8, 12, 16, 24, 48) \n"); - fprintf (stderr," -U RTL-SDR UDP Remote Port (default = 6020)\n"); - fprintf (stderr,"\n"); - fprintf (stderr,"Scanner control options:\n"); - fprintf (stderr," -B Serial port baud rate (default=115200)\n"); - fprintf (stderr," -C Serial port for scanner control (default=/dev/ttyUSB0)\n"); - fprintf (stderr," -R Resume scan after 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 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 QPSK modulation auto detection threshold (default=26)\n"); - fprintf (stderr," -S Symbol buffer size for QPSK decision point tracking\n"); - fprintf (stderr," (default=36)\n"); - fprintf (stderr," -M 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 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 Frame information Verbosity\n"); + printf (" -z Frame rate for datascope\n"); + printf ("\n"); + printf ("Input/Output options:\n"); + printf (" -i Audio input device (default is pulse audio, \n - for piped stdin, rtl for rtl device)\n"); + printf (" -o Audio output device (default is pulse audio)\n"); + printf (" -d Create mbe data files, use this directory\n"); + printf (" -r Read/Play saved mbe data from file(s)\n"); + printf (" -g Audio output gain (default = 0 = auto, disable = -1)\n"); + printf (" -w 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 RTL-SDR Frequency\n"); + printf (" -P RTL-SDR PPM Error (default = 0)\n"); + printf (" -D RTL-SDR Device Index Number\n"); + printf (" -G RTL-SDR Device Gain (0-49) (default = 0 Auto Gain)\n"); + printf (" -L RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)\n (Just have to guess really...)\n"); + printf (" -V RTL-SDR Sample Gain Multiplier (default = 1)\n"); + printf (" -Y RTL-SDR VFO Bandwidth kHz (default = 48)(6, 8, 12, 16, 24, 48) \n"); + printf (" -U RTL-SDR UDP Remote Port (default = 6020)\n"); + printf ("\n"); + printf ("Scanner control options:\n"); + printf (" -B Serial port baud rate (default=115200)\n"); + printf (" -C Serial port for scanner control (default=/dev/ttyUSB0)\n"); + printf (" -R Resume scan after 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 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 QPSK modulation auto detection threshold (default=26)\n"); + printf (" -S Symbol buffer size for QPSK decision point tracking\n"); + printf (" (default=36)\n"); + printf (" -M 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);