Merge pull request #57 from lwvmobile/pulse-dpmr

dPMR Smooth Sync and Playback
This commit is contained in:
lwvmobile
2022-04-08 20:49:12 -04:00
committed by GitHub
13 changed files with 248 additions and 1121 deletions

View File

@@ -241,7 +241,6 @@ typedef struct
unsigned int errs1[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4]; /* 8 x errors #1 computed when demodulate the AMBE voice bit of the frame */
unsigned int errs2[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4]; /* 8 x errors #2 computed when demodulate the AMBE voice bit of the frame */
unsigned char AmbeBit[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4][49]; /* 8 x 49 bit of AMBE voice of the frame */
//unsigned char AmbeBit[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4][36];
unsigned char CCHData[NB_OF_DPMR_VOICE_FRAME_TO_DECODE][48];
unsigned int CCHDataHammingOk[NB_OF_DPMR_VOICE_FRAME_TO_DECODE];
unsigned char CCHDataCRC[NB_OF_DPMR_VOICE_FRAME_TO_DECODE];

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2016 by Jonathan Naylor, G4KLX
*
* Modifications of original code to work with OP25
* Copyright (C) 2019 by Graham J. Norbury
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef DMRTrellis_H
#define DMRTrellis_H
class CDMRTrellis {
public:
CDMRTrellis();
~CDMRTrellis();
bool decode(const unsigned char* data, unsigned char* payload);
private:
void deinterleave(const unsigned char* in, signed char* dibits) const;
void dibitsToPoints(const signed char* dibits, unsigned char* points) const;
void pointsToDibits(const unsigned char* points, signed char* dibits) const;
void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const;
void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const;
bool fixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) const;
unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const;
};
#endif

View File

@@ -410,6 +410,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
/* Burst = RATE 3/4 DATA */
case 0b1000:
{
//disabled until a viable viterbi/trellis decoding solution is worked out
//Process34Data(opts, state, trellisdibits, (uint8_t *)syncdata, (uint8_t *)SlotType);
break;
}

View File

@@ -84,7 +84,7 @@ void ProcessDMR (dsd_opts * opts, dsd_state * state)
//
if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
{
fprintf(stderr, " BPK %d", state->K);
fprintf(stderr, " BPK %lld", state->K);
for(Frame = 0; Frame < 6; Frame++)
{
for(i = 0; i < 3; i++)

View File

@@ -60,15 +60,26 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
//CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
unsigned char tdibits_reverse[98];
unsigned char tdibits_inverted[98];
if (opts->payload == 1)
unsigned char tdibits_to_bits[196];
if (1 == 2)
{
fprintf (stderr, "\n Raw Trellis Dibits\n ");
fprintf (stderr, "\n Raw Trellis Dibits to Bits\n ");
for (i = 0; i < 98; i++)
{
fprintf (stderr, "[%X]", tdibits[i]);
tdibits_to_bits[i * 2] = (tdibits[i] >> 0) & 1;
tdibits_to_bits[(i * 2) + 1] = (tdibits[1] >> 1) & 1;
fprintf (stderr, "%d%d", tdibits_to_bits[i * 2], tdibits_to_bits[(i * 2) + 1]);
}
}
if (opts->payload == 1)
{
//fprintf (stderr, "\n Raw Trellis Dibits\n ");
for (i = 0; i < 98; i++)
{
//fprintf (stderr, "#%d [%X] ", i, tdibits[i]);
//tdibits_reverse[97-i] = tdibits[i];
tdibits_reverse[97-i] = ((tdibits[i] & 1)<<1) | ((tdibits[i] & 2)>>1);
tdibits_inverted[i] = tdibits[i] ^ 2;
//tdibits_reverse[97-i] = ((tdibits[i] & 1)<<1) | ((tdibits[i] & 2)>>1);
//tdibits_inverted[i] = tdibits[i] ^ 2;
}
}
@@ -76,10 +87,10 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
CDMRTrellisDecode(tdibits, TrellisReturn); //figure out how this works!!
if (opts->payload == 1)
{
fprintf (stderr, "\nFull 3/4 Rate Trellis Payload (reversed order)\n ");
fprintf (stderr, "\nFull 3/4 Rate Trellis Payload\n ");
for (i = 0; i < 18; i++)
{
fprintf (stderr, "[%02X]", TrellisReturn[17-i]);
fprintf (stderr, "[%02X]", TrellisReturn[i]);
}
}
/* Extract the BPTC 196,96 DMR data */
@@ -230,7 +241,7 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
}
}
//Full
if (opts->payload == 1)
if (opts->payload == 2)
{
fprintf (stderr, "\nFull 3/4 Rate Payload DmrDataByte (reverse bits)\n ");
for (i = 0; i < 18; i++)
@@ -1433,7 +1444,7 @@ void ProcessDmrPIHeader(dsd_opts * opts, dsd_state * state, uint8_t info[196], u
}
else if((IrrecoverableErrors == 0))
{
fprintf (stderr, "( PI FEC Okay)");
fprintf (stderr, " (PI FEC Okay)");
}
else fprintf (stderr, (" (PI CRC Fail, FEC Fail)"));

View File

@@ -18,15 +18,8 @@
#include "dsd.h"
#include "dpmr_const.h"
/* Uncomment this define to display the dPMR debug info */
//#define dPMR_PRINT_DEBUG_INFO
void processdPMRvoice (dsd_opts * opts, dsd_state * state)
{
for (short q = 0; q < 1; q++)
{
// extracts AMBE frames from DMR frame
uint32_t i, j, k, dibit;
uint8_t CCH[NB_OF_DPMR_VOICE_FRAME_TO_DECODE][72] = {0};
uint8_t CCHDescrambled[NB_OF_DPMR_VOICE_FRAME_TO_DECODE][72] = {0};
@@ -34,10 +27,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
uint8_t CCHDataHammingCorrected[NB_OF_DPMR_VOICE_FRAME_TO_DECODE][48] = {0};
uint8_t CCHDataCRC[NB_OF_DPMR_VOICE_FRAME_TO_DECODE] = {0};
uint8_t CCHDataCRCComputed[NB_OF_DPMR_VOICE_FRAME_TO_DECODE] = {0};
//uint8_t TCH[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4][72] = {0};
uint8_t CC[NB_OF_DPMR_VOICE_FRAME_TO_DECODE / 2][24] = {0};
char ambe_fr[NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4][4][24] = {0};
char ambe_fr2[8][4][24];
const int *w, *x, *y, *z;
uint32_t ScramblerLFSR = 0;
bool correctable = true;
@@ -65,11 +56,6 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
uint8_t CalledID[8] = {0};
uint8_t CallingID[8] = {0};
/* Remove compiler warning */
//UNUSED_VARIABLE(AmbeBitDescrambled[0]);
//UNUSED_VARIABLE(ScramblerKey);
//UNUSED_VARIABLE(PartOfSuperFrame);
if (opts->errorbars == 1)
{
//fprintf(stderr, "VOICE e:");
@@ -90,13 +76,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
CCH[0][(i * 2)] = (1 & (dibit >> 1)); // bit 1
CCH[0][(i * 2) + 1] = (1 & dibit); // bit 0
#ifdef DPMR_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
}
#ifdef DPMR_DUMP
fprintf(stderr, " ");
#endif
/* 4 TCH (Traffic CHannel) = 4 x 72 bit voice playload */
k = 0;
@@ -116,15 +97,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
dibit = (dibit ^ 2);
}
#ifdef DPMR_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
ambe_fr[j][*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr[j][*y][*z] = (1 & dibit); // bit 0
ambe_fr2[j][*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr2[j][*y][*z] = (1 & dibit); // bit 0
//TCH[j][k] = (1 & (dibit >> 1)); // bit 1
//TCH[j][k + 1] = (1 & dibit); // bit 0
state->dPMRVoiceFS2Frame.RawVoiceBit[j][k] = (1 & (dibit >> 1)); // bit 1
state->dPMRVoiceFS2Frame.RawVoiceBit[j][k + 1] = (1 & dibit); // bit 0
k = k + 2;
@@ -132,18 +106,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
x++;
y++;
z++;
}
processMbeFrame (opts, state, NULL, ambe_fr2[j], NULL); //HERE HERE
#ifdef DPMR_DUMP
fprintf(stderr, " ");
#endif
}
//processMbeFrame (opts, state, NULL, ambe_fr[0], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[1], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[2], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[3], NULL); //HERE HERE
/* First CC (Channel Code) - 24 bit */
k = 0;
@@ -159,13 +123,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
CC[0][k++] = (1 & (dibit >> 1)); // bit 1
CC[0][k++] = (1 & dibit); // bit 0
#ifdef DPMR_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
}
#ifdef DPMR_DUMP
fprintf(stderr, " ");
#endif
/* Get the color code */
state->dPMRVoiceFS2Frame.ColorCode[0] = (unsigned int)GetdPmrColorCode(CC[0]);
@@ -184,16 +143,14 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
CCH[1][k++] = (1 & (dibit >> 1)); // bit 1
CCH[1][k++] = (1 & dibit); // bit 0
#ifdef DPMR_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
}
#ifdef DPMR_DUMP
fprintf(stderr, " ");
#endif
/* 4 TCH (Traffic CHannel) = 4 x 72 bit voice playload */
//Sync issues occur when FS2 occurs immediatly after the 4th rep, so cutting of 4 early to gain constant resync
//probably can't resync fast enough when the next sync starts immediately after the 4th rep of 36 dibits
//consider writing a method that will loop this entire process based on the frame numbering found inside the CCH info, is that possible?
k = 0;
for (j = 0; j < 4; j++)
{
@@ -211,15 +168,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
dibit = (dibit ^ 2);
}
#ifdef DPMR_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
ambe_fr[j + 4][*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr[j + 4][*y][*z] = (1 & dibit); // bit 0
ambe_fr2[j+4][*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr2[j+4][*y][*z] = (1 & dibit); // bit 0
//TCH[j + 4][k] = (1 & (dibit >> 1)); // bit 1
//TCH[j + 4][k + 1] = (1 & dibit); // bit 0
state->dPMRVoiceFS2Frame.RawVoiceBit[j + 4][k] = (1 & (dibit >> 1)); // bit 1
state->dPMRVoiceFS2Frame.RawVoiceBit[j + 4][k + 1] = (1 & dibit); // bit 0
k = k + 2;
@@ -227,21 +177,12 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
x++;
y++;
z++;
if (j == 3 && i == 28) //find sweet spot to cut off early
{
i = 40; //break early so FS2 sync can resync
}
}
processMbeFrame (opts, state, NULL, ambe_fr2[j+4], NULL);
#ifdef DPMR_DUMP
fprintf(stderr, " ");
#endif
}
//processMbeFrame (opts, state, NULL, ambe_fr[4], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[5], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[6], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, ambe_fr[7], NULL); //HERE HERE
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
/* Initialize the Hamming (12,8) error code detection
* Not needed because it has already been done
@@ -270,17 +211,17 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
if(correctable)
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "CCH data corrected successfully\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "CCH data corrected successfully\n");
HammingOk[i] = 1;
}
else
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "ERROR !!! CCH data contains uncorrectable bit\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "ERROR !!! CCH data contains uncorrectable bit\n");
HammingOk[i] = 0;
}
@@ -300,19 +241,19 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
if(CCHDataCRC[i] == CCHDataCRCComputed[i])
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Good CCH CRCs ! CRC received = 0x%02X, CRC computed = 0x%02X\n",
CCHDataCRC[i], CCHDataCRCComputed[i]);
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "Good CCH CRCs ! CRC received = 0x%02X, CRC computed = 0x%02X\n",
// CCHDataCRC[i], CCHDataCRCComputed[i]);
CrcOk[i] = 1;
}
else
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "ERROR !!! CCH CRCs are different ! CRC received = 0x%02X, CRC computed = 0x%02X\n",
CCHDataCRC[i], CCHDataCRCComputed[i]);
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "ERROR !!! CCH CRCs are different ! CRC received = 0x%02X, CRC computed = 0x%02X\n",
// CCHDataCRC[i], CCHDataCRCComputed[i]);
CrcOk[i] = 0;
}
@@ -360,29 +301,29 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
strcpy((char *)CallingID, (char *)state->dPMRVoiceFS2Frame.CallingID);
CallingID[7] = '\0';
#ifdef dPMR_PRINT_DEBUG_INFO
/* Print Hamming debug info */
fprintf(stderr, " | ");
//fprintf(stderr, " | ");
for(i = 0; i < NB_OF_DPMR_VOICE_FRAME_TO_DECODE; i++)
{
fprintf(stderr, "Hamming[%u]=", i);
//fprintf(stderr, "Hamming[%u]=", i);
for(j = 0; j < 6; j++)
{
if(HammingCorrectable[i][j]) fprintf(stderr, "1");
else fprintf(stderr, "0");
//if(HammingCorrectable[i][j]) fprintf(stderr, "1");
//else fprintf(stderr, "0");
}
fprintf(stderr, " HammingOk[%u]=%u", i, HammingOk[i]);
fprintf(stderr, " CrcOk[%u]=%u", i, CrcOk[i]);
//fprintf(stderr, " HammingOk[%u]=%u", i, HammingOk[i]);
//fprintf(stderr, " CrcOk[%u]=%u", i, CrcOk[i]);
//fprintf(stderr, " Bit[%u]=", i);
//for(j = 0; j < 7; j++)
//{
// if(CCHDataHammingCorrected[i][j + 41]) fprintf(stderr, "1");
// else fprintf(stderr, "0");
//}
fprintf(stderr, " CRCrec=0x%02X CRCcomp=0x%02X", CCHDataCRC[i], CCHDataCRCComputed[i]);
if(i < (NB_OF_DPMR_VOICE_FRAME_TO_DECODE - 1)) fprintf(stderr, " - ");
//fprintf(stderr, " CRCrec=0x%02X CRCcomp=0x%02X", CCHDataCRC[i], CCHDataCRCComputed[i]);
//if(i < (NB_OF_DPMR_VOICE_FRAME_TO_DECODE - 1)) fprintf(stderr, " - ");
}
#endif /* dPMR_PRINT_DEBUG_INFO */
#if (NB_OF_DPMR_VOICE_FRAME_TO_DECODE == 2)
@@ -396,9 +337,9 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
/* First part of the super frame */
PartOfSuperFrame = 1;
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "First part of the Super Frame\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "\nFirst part of the Super Frame");
/* The next part will normally be the second part */
opts->dPMR_next_part_of_superframe = 2;
@@ -437,9 +378,9 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
/* Second part of the super frame */
PartOfSuperFrame = 2;
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Second part of the Super Frame\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "\nSecond part of the Super Frame");
/* The next part will normally be the first part */
opts->dPMR_next_part_of_superframe = 1;
@@ -482,9 +423,9 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
if(opts->dPMR_next_part_of_superframe == 1)
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Supposed first part of the Super Frame\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "Supposed first part of the Super Frame\n");
/* Set the next part as the second part */
opts->dPMR_next_part_of_superframe = 2;
@@ -492,9 +433,8 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
else if(opts->dPMR_next_part_of_superframe == 2)
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Supposed second part of the Super Frame\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "Supposed second part of the Super Frame\n");
/* Set the next part as the first part */
opts->dPMR_next_part_of_superframe = 1;
@@ -502,9 +442,9 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
else
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Unknown part of the Super Frame\n");
#endif /* dPMR_PRINT_DEBUG_INFO */
//fprintf(stderr, "Unknown part of the Super Frame\n");
/* Unknown current part, set to 0 */
opts->dPMR_next_part_of_superframe = 0;
@@ -513,6 +453,7 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
if(state->dPMRVoiceFS2Frame.ColorCode[0] != (unsigned int)(-1))
{
//only print the CC and src/tg info if CRC is good
/* Display the color code */
//fprintf(stderr, " | Color Code=%02d ", (int)state->dPMRVoiceFS2Frame.ColorCode[0]);
}
@@ -551,186 +492,56 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
//strcpy (state->dpmr_caller_id, CallingID);
state->dpmr_caller_id = CallingID;
//fprintf(stderr, " (CRC OK) ");
fprintf(stderr, " (CRC OK) \n");
}
else
{
fprintf(stderr, " (CRC ERR) ");
fprintf(stderr, " (CRC ERR) \n");
}
#endif /* (NB_OF_DPMR_VOICE_FRAME_TO_DECODE == 2) */
/* Test if the current frame is encrypted or not */
for(i = 0; i < NB_OF_DPMR_VOICE_FRAME_TO_DECODE; i++)
//Play only voice frames by first looking to see if there is a TCH voice in CommunicationMode,
//then sending it to be processed by processMbeFrame, its much cleaner this way
short start = 0;
short end = 4;
for (short o = 0; o < 2; o++)
{
//if(HammingOk[i] && CrcOk[i])
if(HammingCorrectable[i][2] && CrcOk[i])
//depending on first or second TCH, set start and end variables appropriately
if (o == 1)
{
/* Unencrypted voice frame => Version = 0 (0b00) */
if(state->dPMRVoiceFS2Frame.Version[i] == 0x00)
start = 4;
end = 8;
//add extra line break on second repitition only when dumping payload to console
if (opts->payload == 1)
{
opts->dPMR_curr_frame_is_encrypted = 0;
}
/* Encrypted voice frame => Version = 3 (0b11) */
else if(state->dPMRVoiceFS2Frame.Version[i] == 0x03)
{
opts->dPMR_curr_frame_is_encrypted = 1;
}
else
{
/* Unknown clear or encrypted voice frame status */
fprintf(stderr, "\n");
}
/* Valid encryption parameter found,
* exit the "for" loop */
break;
} /* End if(HammingCorrectable[i][2] && CrcOk[i]) */
}
if(opts->dPMR_curr_frame_is_encrypted) fprintf(stderr, "| Scrambler ");
/* Determine if the received frame is a voice frame, a voice frame + data
* or a data frame.
*
* See ETSI TS 102 658 chapter 5.0.5 "Communication Mode [BT]"
* for details
*/
VoiceFrameFlag = 0;
AttachedDataFlag = 0;
for(i = 0; i < NB_OF_DPMR_VOICE_FRAME_TO_DECODE; i++)
{
/* Search for voice frame
* Note : Due to error decoding, we parse all CCH
* Communication Mode parameters, if a voice parameter is
* found, the entire payload is considered as voice */
if((state->dPMRVoiceFS2Frame.CommunicationMode[i] == 0) ||
(state->dPMRVoiceFS2Frame.CommunicationMode[i] == 1) ||
(state->dPMRVoiceFS2Frame.CommunicationMode[i] == 5))
{
/* Voice frame detected */
VoiceFrameFlag = 1;
/* Check if the voice frame contains attached data */
if((state->dPMRVoiceFS2Frame.CommunicationMode[i] == 5) && state->dPMRVoiceFS2Frame.CCHDataCrcOk[i])
{
AttachedDataFlag = 1;
}
}
}
if(VoiceFrameFlag)
{
if(AttachedDataFlag) fprintf(stderr, "| Voice+Data ");
else fprintf(stderr, "| Voice ");
}
else
{
fprintf(stderr, "| Data ");
}
/* Demodulate and store AMBE sample only if the current superframe
* is a voice frame */
if(VoiceFrameFlag)
{
/* There is 4 AMBE voice sample per voice frame (= 8 per superframe) */
//for(i = 0; i < (NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4); i++)
for(i = 0; i < (8); i++)
{
/* Apply ECC 1 to the AMBE frames */
//state->dPMRVoiceFS2Frame.errs1[i] = (unsigned int)mbe_eccAmbe3600x2450C0(ambe_fr[i]);
//state->dPMRVoiceFS2Frame.errs1[i] = (unsigned int)mbe_eccAmbe3600x2450C0(ambe_fr[i]);
//state->dPMRVoiceFS2Frame.errs2[i] = state->dPMRVoiceFS2Frame.errs1[i];
/* Demodulate the AMBE frames */
//mbe_demodulateAmbe3600x2450Data(ambe_fr[i]);
//mbe_demodulateAmbe3600x2450Data(ambe_fr[i]);
/* Apply ECC 2 to the AMBE frames and get the 49 bit of the voice sample */
//state->dPMRVoiceFS2Frame.errs2[i] += (unsigned int)mbe_eccAmbe3600x2450Data(ambe_fr[i], (char *)state->dPMRVoiceFS2Frame.AmbeBit[i]);
//state->dPMRVoiceFS2Frame.errs2[i] += (unsigned int)mbe_eccAmbe3600x2450Data(ambe_fr[i], (char *)state->dPMRVoiceFS2Frame.AmbeBit[i]);
//processMbeFrame (opts, state, NULL, ambe_fr[i], NULL); //HERE HERE
//processMbeFrame (opts, state, NULL, state->dPMRVoiceFS2Frame.AmbeBit[i], NULL); //HERE HERE
}
} /* End if(VoiceFrameFlag && !AttachedDataFlag) */
//Check if the voice frame to play is encrypted
if(opts->dPMR_curr_frame_is_encrypted)
{
//Encryption is not supported in the public version
ScramblerKey = 0;
}
else
{
//The frame is unencrypted,
//so set the scrambler key to 0
ScramblerKey = 0;
}
//Play only voice frame
if(VoiceFrameFlag)
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Voice frame to play\n");
#endif //dPMR_PRINT_DEBUG_INFO
//There is 4 AMBE voice sample per voice frame (so 2 x 4 = 8 per superframe)
for(i = 0; i < (8); i++) //is this backwards, shouldn't we run this first, and then voice frame after?
//fprintf (stderr, "\nCommunication Mode: %d\n", state->dPMRVoiceFS2Frame.CommunicationMode[o]);
//fprintf (stderr, "Encryption Mode: %d\n", state->dPMRVoiceFS2Frame.Version[o]);
//fprintf (stderr, "Superframe Number: %d", state->dPMRVoiceFS2Frame.FrameNumbering[o]); //should be 1-4, but may be same number on TCH 1 or TCH 2
if((state->dPMRVoiceFS2Frame.CommunicationMode[o] == 0) ||
(state->dPMRVoiceFS2Frame.CommunicationMode[o] == 1) ||
(state->dPMRVoiceFS2Frame.CommunicationMode[o] == 5))
{
//errs = (uint32_t*)&(state->dPMRVoiceFS2Frame.errs1[i]);
errs2 = (uint32_t*)&(state->dPMRVoiceFS2Frame.errs2[i]);
errs = 0;
//errs2 = 0;
state->errs = state->dPMRVoiceFS2Frame.errs1[i];
state->errs2 = state->dPMRVoiceFS2Frame.errs2[i];
//sounds like choppy shit, but .amb file playback is acceptable, so investigate why this doesn't work properly
//could be related to err states not properly done or something?
//mbe_processAmbe2450Dataf (state->audio_out_temp_buf, (int *)errs, (int *)errs2, state->err_str,
// (char *)state->dPMRVoiceFS2Frame.AmbeBit[i],
// state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
if (opts->mbe_out_f != NULL)
//There are 4 AMBE voice samples per TCH
for(i = start; i < end; i++)
{
//saveAmbe2450Data (opts, state, (char *)state->dPMRVoiceFS2Frame.AmbeBit[i]);
}
if (opts->errorbars == 1)
{
//fprintf(stderr, "%s", state->err_str);
}
processMbeFrame (opts, state, NULL, ambe_fr[i], NULL);
} //End for(i = start; i < end); i++)
} //if comms and not encrypted
}//End for TCH for o loop
state->debug_audio_errors += *errs2;
//processAudio(opts, state);
if (opts->wav_out_f != NULL)
{
//writeSynthesizedVoice (opts, state);
}
if (opts->audio_out == 1)
{
//Play the AMBE Frames
//playSynthesizedVoice (opts, state);
}
} //End for(i = 0; i < (NB_OF_DPMR_VOICE_FRAME_TO_DECODE * 4); i++)
} //End if(VoiceFrameFlag)
else
{
#ifdef dPMR_PRINT_DEBUG_INFO
fprintf(stderr, "Data frame, don't play it !\n");
#endif //dPMR_PRINT_DEBUG_INFO
}
if (opts->errorbars == 1)
{
fprintf(stderr, "\n");
}
//keep code below, could be handy cheat sheet for other info
#ifdef dPMR_PRINT_DEBUG_INFO
//Display the CCH content
for(i = 0; i < NB_OF_DPMR_VOICE_FRAME_TO_DECODE; i++)
@@ -748,9 +559,6 @@ void processdPMRvoice (dsd_opts * opts, dsd_state * state)
}
#endif //dPMR_PRINT_DEBUG_INFO
//Print sPMR frame (if needed)
//dPMRVoiceFrameProcess(opts, state); //HERE HERE disabled to build
}
} //End processdPMRvoice()
@@ -940,6 +748,4 @@ void ConvertAirInterfaceID(uint32_t AI_ID, uint8_t ID[8])
} /* End convertAirInterfaceID() */
/* End of file */

View File

@@ -299,7 +299,7 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
}
else
{
dibit = 0; // +2
dibit = 0; // +1
}
}
}

View File

@@ -248,14 +248,12 @@ processFrame (dsd_opts * opts, dsd_state * state)
else if ((state->synctype == 20) || (state->synctype == 24))
{
/* dPMR Frame Sync 1 */
fprintf(stderr, "dPMR Frame sync 1 ");
fprintf(stderr, "dPMR Frame Sync 1 ");
}
else if ((state->synctype == 21) || (state->synctype == 25))
{
/* dPMR Frame Sync 2 */
//for (short o = 0; o < 2; o++)
//{
fprintf(stderr, "dPMR Frame sync 2 ");
fprintf(stderr, "dPMR Frame Sync 2 ");
//state->rf_mod = GFSK_MODE;
state->nac = 0;
@@ -277,21 +275,21 @@ processFrame (dsd_opts * opts, dsd_state * state)
}
sprintf(state->fsubtype, " VOICE ");
processdPMRvoice (opts, state);
//}
return;
}
else if ((state->synctype == 22) || (state->synctype == 26))
{
/* dPMR Frame Sync 3 */
fprintf(stderr, "dPMR Frame sync 3 ");
fprintf(stderr, "dPMR Frame Sync 3 ");
}
else if ((state->synctype == 23) || (state->synctype == 27))
{
/* dPMR Frame Sync 4 */
fprintf(stderr, "dPMR Frame sync 4 ");
fprintf(stderr, "dPMR Frame Sync 4 ");
}
//LEH dPMR
//dPMR
else
{
// Read the NAC, 12 bits

View File

@@ -83,27 +83,15 @@ char * getDate(void) {
void
printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, char *modulation)
{
//char datestr[32];
//struct tm timep;
//erase();
//attron(COLOR_PAIR(4));
//for (short int i = 0; i < 7; i++) {
//printw("%s \n", FM_banner2[i]);}
//attroff(COLOR_PAIR(4));
if (opts->verbose > 0)
{
//strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep);
//fprintf (stderr,"Sync: %s ", frametype);
//fprintf (stderr,"%s %s Sync: %s ", getDate(), getTime(), frametype);
fprintf (stderr,"%s ", getTime());
fprintf (stderr,"Sync: %s ", frametype);
//fprintf (stderr,"%s Sync: %s ", getTime(), frametype);
//printw("%s Sync: %s ", getTime(), frametype);
}
if (opts->verbose > 2)
{
fprintf (stderr,"o: %4i ", offset);
//fprintf (stderr,"o: %4i ", offset);
//printw("o: %4i ", offset);
}
if (opts->verbose > 1)
@@ -113,7 +101,7 @@ printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset,
}
if (opts->verbose > 2)
{
fprintf (stderr,"g: %f ", state->aout_gain);
//fprintf (stderr,"g: %f ", state->aout_gain);
//printw("g: %f ", state->aout_gain);
}
//refresh();
@@ -514,85 +502,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
}
}
//old style for DMR
/*
if (opts->frame_dmr == 1)
{
if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0) )//try this
//if ((strncmperr (synctest, DMR_MS_DATA_SYNC, 24, 1) == 0) || (strncmperr (synctest, DMR_MS_DATA_SYNC, 24, 1) == 0))
{
now = time(NULL);
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + (lmax)) / 2;
state->min = ((state->min) + (lmin)) / 2;
if (opts->inverted_dmr == 0)
{
// data frame
sprintf (state->ftype, "DMR");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +DMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 10;
return (10);
}
else
{
// inverted voice frame
sprintf (state->ftype, "DMR");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -DMR ", synctest_pos + 1, modulation);
}
if (state->lastsynctype != 11)
{
state->firstframe = 1;
}
state->lastsynctype = 11;
return (11);
}
}
if ((strcmp (synctest, DMR_MS_VOICE_SYNC) == 0) || (strcmp (synctest, DMR_BS_VOICE_SYNC) == 0))
//if ( strcmp (synctest, DMR_MS_VOICE_SYNC) == 0 || strcmp (synctest, DMR_BS_VOICE_SYNC) == 0 || strcmp (synctest, DMR_DIRECT_MODE_TS1_VOICE_SYNC) == 0 || strcmp (synctest, DMR_DIRECT_MODE_TS2_VOICE_SYNC) == 0 )
//if ((strncmperr (synctest, DMR_MS_VOICE_SYNC, 24, 1) == 0) || (strncmperr (synctest, DMR_BS_VOICE_SYNC, 24, 1) == 0))
{
now = time(NULL);
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (opts->inverted_dmr == 0)
{
// voice frame
sprintf (state->ftype, "DMR");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +DMR ", synctest_pos + 1, modulation);
}
if (state->lastsynctype != 12)
{
state->firstframe = 1;
}
state->lastsynctype = 12;
return (12);
}
else
{
// inverted data frame
sprintf (state->ftype, "DMR");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -DMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 13;
return (13);
}
}
}
*/
// lwvmobile dPMR sync
//dPMR sync
strncpy(synctest, (synctest_p - 23), 24);
strncpy(synctest12, (synctest_p - 11), 12);
if(opts->frame_dpmr == 1)
@@ -601,11 +512,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
if(strcmp(synctest, DPMR_FRAME_SYNC_1) == 0)
{
fprintf (stderr, "DPMR_FRAME_SYNC_1\n");
fprintf (stderr, "+dPMR FS1\n");
}
if(strcmp(synctest12, DPMR_FRAME_SYNC_2) == 0)
{
fprintf (stderr, "DPMR_FRAME_SYNC_2\n");
//fprintf (stderr, "DPMR_FRAME_SYNC_2\n");
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
@@ -616,28 +527,27 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 21;
return (21);
}
if(strcmp(synctest12, DPMR_FRAME_SYNC_3) == 0)
{
fprintf (stderr, "DPMR_FRAME_SYNC_3\n");
fprintf (stderr, "+dPMR FS3 \n");
}
if(strcmp(synctest, DPMR_FRAME_SYNC_4) == 0)
{
fprintf (stderr, "DPMR_FRAME_SYNC_4\n");
fprintf (stderr, "+dPMR FS4 \n");
}
}
if (opts->inverted_dpmr == 1)
{
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_1) == 0)
{
fprintf (stderr, "INV_DPMR_FRAME_SYNC_1\n");
fprintf (stderr, "-dPMR FS1 \n");
}
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_2) == 0)
{
fprintf (stderr, "INV_DPMR_FRAME_SYNC_2\n");
//fprintf (stderr, "INV_DPMR_FRAME_SYNC_2\n");
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
@@ -654,533 +564,16 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_3) == 0)
{
fprintf (stderr, "INV_DPMR_FRAME_SYNC_3\n");
fprintf (stderr, "-dPMR FS3 \n");
}
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_4) == 0)
{
fprintf (stderr, "INV_DPMR_FRAME_SYNC_4\n");
fprintf (stderr, "-dPMR FS4 \n");
}
}
}
//LEH dPMR
/*
if(opts->frame_dpmr == 1)
{
strncpy(synctest, (synctest_p - 23), 24);
strncpy(synctest12, (synctest_p - 11), 12);
if(strcmp(synctest, DPMR_FRAME_SYNC_1) == 0)
{
if (opts->inverted_dpmr == 0)
{
fprintf(stderr, "DPMR_FRAME_SYNC_1\n"); // TODO : To be removed
//if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
// (state->lastsynctype == 22) || (state->lastsynctype == 23))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 20;
return (20);
//}
//else
//{
// state->lastsynctype = 20;
//}
} //End if (opts->inverted_dpmr == 0)
}
if(strcmp(synctest12, DPMR_FRAME_SYNC_2) == 0)
{
if (opts->inverted_dpmr == 0)
{
fprintf(stderr, "DPMR_FRAME_SYNC_2\n"); // TODO : To be removed
// TODO : Modif 2019-01-04
//if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
// (state->lastsynctype == 22) || (state->lastsynctype == 23))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 21;
return (21);
// TODO : Modif 2019-01-04
//}
//else
//{
// state->lastsynctype = 21;
//}
}
}
else if(strcmp(synctest12, DPMR_FRAME_SYNC_3) == 0)
{
//if (opts->inverted_dpmr == 0)
//{
fprintf(stderr, "DPMR_FRAME_SYNC_3\n"); // TODO : To be removed
if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
(state->lastsynctype == 22) || (state->lastsynctype == 23))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 22;
return (22);
//}
//else
//{
// state->lastsynctype = 22;
//}
}
}
if(strcmp(synctest, DPMR_FRAME_SYNC_4) == 0)
{
if (opts->inverted_dpmr == 0)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_4\n"); // TODO : To be removed
//if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
// (state->lastsynctype == 22) || (state->lastsynctype == 23))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "+dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 23;
return (23);
//}
//else
//{
// state->lastsynctype = 23;
//}
}
}
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_1) == 0)
{
if (opts->inverted_dpmr == 1)
{
fprintf(stderr, "INV_DPMR_FRAME_SYNC_1\n"); // TODO : To be removed
//if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
// (state->lastsynctype == 26) || (state->lastsynctype == 27))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "-dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 24;
return (24);
//}
//else
//{
// state->lastsynctype = 24;
//}
}
}
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_2) == 0)
{
if (opts->inverted_dpmr == 1)
{
fprintf(stderr, "INV_DPMR_FRAME_SYNC_2\n"); // TODO : To be removed
//if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
// (state->lastsynctype == 26) || (state->lastsynctype == 27))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "-dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 25;
return (25);
//}
//else
//{
// state->lastsynctype = 25;
//}
}
}
if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_3) == 0)
{
if (opts->inverted_dpmr == 1)
{
fprintf(stderr, "INV_DPMR_FRAME_SYNC_3\n"); // TODO : To be removed
//if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
// (state->lastsynctype == 26) || (state->lastsynctype == 27))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "-dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 26;
return (26);
//}
//else
//{
// state->lastsynctype = 26;
//}
}
}
if(strcmp(synctest, INV_DPMR_FRAME_SYNC_4) == 0)
{
if (opts->inverted_dpmr == 1)
{
fprintf(stderr, "INV_DPMR_FRAME_SYNC_4\n"); // TODO : To be removed
//if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
// (state->lastsynctype == 26) || (state->lastsynctype == 27))
//{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, "dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, "-dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 27;
return (27);
}
//else
//{
// state->lastsynctype = 27;
//}
//}
}
//else
//{
// No dPMR frame sync detected
//}
} // End if(opts->frame_dpmr == 1)
*/
//
//LEH dPMR
//testing frame syncs here for better performance
/*
if(opts->frame_dpmr == 1)
{
strncpy(synctest, (synctest_p - 23), 24);
strncpy(synctest12, (synctest_p - 11), 12);
//if(strcmp(synctest, DPMR_FRAME_SYNC_1) == 0)
if (strncmperr (synctest, DPMR_FRAME_SYNC_1, 24, 1) == 0 ) //24 bits on frame 1 and 4, 12 on 2 and 3?
{
if (opts->inverted_dpmr == 0)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_1\n"); // TODO : To be removed
if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
(state->lastsynctype == 22) || (state->lastsynctype == 23))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 20;
return (20);
}
else
{
state->lastsynctype = 20;
}
} //End if (opts->inverted_dpmr == 0)
}
//else if(strcmp(synctest12, DPMR_FRAME_SYNC_2) == 0)
if (strncmperr (synctest12, DPMR_FRAME_SYNC_2, 12, 1) == 0 ) //char synctest12[13] ??
{
if (opts->inverted_dpmr == 0)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_2\n"); // TODO : To be removed
// TODO : Modif 2019-01-04
if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
(state->lastsynctype == 22) || (state->lastsynctype == 23))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 21;
return (21);
// TODO : Modif 2019-01-04
}
else
{
state->lastsynctype = 21;
}
}
}
//else if(strcmp(synctest12, DPMR_FRAME_SYNC_3) == 0)
if (strncmperr (synctest12, DPMR_FRAME_SYNC_3, 12, 1) == 0 ) //char synctest12[13] ??
{
if (opts->inverted_dpmr == 0)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_3\n"); // TODO : To be removed
if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
(state->lastsynctype == 22) || (state->lastsynctype == 23))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part//
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 22;
return (22);
}
else
{
state->lastsynctype = 22;
}
}
}
//if(strcmp(synctest, DPMR_FRAME_SYNC_4) == 0)
if (strncmperr (synctest, DPMR_FRAME_SYNC_4, 24, 1) == 0 ) //if, or else if? original is else if
{
if (opts->inverted_dpmr == 0)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_4\n"); // TODO : To be removed
if ((state->lastsynctype == 20) || (state->lastsynctype == 21) ||
(state->lastsynctype == 22) || (state->lastsynctype == 23))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " +dPMR ", synctest_pos + 1, modulation);
}
//The next part of the superframe will normally be the first part
//opts->dPMR_next_part_of_superframe = 1;
state->lastsynctype = 23;
return (23);
}
else
{
state->lastsynctype = 23;
}
}
}
//else if(strcmp(synctest, INV_DPMR_FRAME_SYNC_1) == 0)
//else if (strncmperr (synctest12, INV_DPMR_FRAME_SYNC_1, 12, 1) == 0 )
if (strncmperr (synctest, INV_DPMR_FRAME_SYNC_1, 24, 1) == 0 ) //if, or else if
{
if (opts->inverted_dpmr)
{
//fprintf(stderr, "INV_DPMR_FRAME_SYNC_1\n"); // TODO : To be removed
if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
(state->lastsynctype == 26) || (state->lastsynctype == 27))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 24;
return (24);
}
else
{
state->lastsynctype = 24;
}
}
}
//else if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_2) == 0)
if (strncmperr (synctest12, INV_DPMR_FRAME_SYNC_2, 12, 1) == 0 )
{
if (opts->inverted_dpmr)
{
//fprintf(stderr, "DPMR_FRAME_SYNC_2\n"); // TODO : To be removed
if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
(state->lastsynctype == 26) || (state->lastsynctype == 27))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 25;
return (25);
}
else
{
state->lastsynctype = 25;
}
}
}
//else if(strcmp(synctest12, INV_DPMR_FRAME_SYNC_3) == 0)
if (strncmperr (synctest12, INV_DPMR_FRAME_SYNC_3, 12, 1) == 0 )
{
if (opts->inverted_dpmr)
{
//fprintf(stderr, "INV_DPMR_FRAME_SYNC_3\n"); // TODO : To be removed
if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
(state->lastsynctype == 26) || (state->lastsynctype == 27))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 26;
return (26);
}
else
{
state->lastsynctype = 26;
}
}
}
//if(strcmp(synctest, INV_DPMR_FRAME_SYNC_4) == 0) //if, or else if
if (strncmperr (synctest, INV_DPMR_FRAME_SYNC_4, 24, 1) == 0 )
{
if (opts->inverted_dpmr)
{
//fprintf(stderr, "INV_DPMR_FRAME_SYNC_4\n"); // TODO : To be removed
if ((state->lastsynctype == 24) || (state->lastsynctype == 25) ||
(state->lastsynctype == 26) || (state->lastsynctype == 27))
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf(state->ftype, " dPMR ");
if (opts->errorbars == 1)
{
printFrameSync (opts, state, " -dPMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 27;
return (27);
}
else
{
state->lastsynctype = 27;
}
}
}
else
{
//No dPMR frame sync detected
}
} //End if(opts->frame_dpmr == 1)
*/
//LEH DMR Sync
//New DMR Sync
if (opts->frame_dmr == 1)
{
if ((strcmp (synctest, DMR_MS_DATA_SYNC) == 0) || (strcmp (synctest, DMR_BS_DATA_SYNC) == 0))
@@ -1491,14 +884,13 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
{
strncpy (synctest18, (synctest_p - 17), 18); //seems like other sync tests do this as well
strncpy (synctest18, (synctest_p - 17), 18);
//if ((strcmp (synctest18, NXDN_BS_VOICE_SYNC) == 0) || (strcmp (synctest18, NXDN_MS_VOICE_SYNC) == 0)) //or is this the double up test?
//borrowing from LEH here WOW! This works so much better, its not even a joke
if ((strncmperr (synctest18, NXDN_BS_VOICE_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_VOICE_SYNC, 18, 1) == 0))
{
now = time(NULL); //here, or after next if
if ((state->lastsynctype == 8) || (state->lastsynctype == 16)) //is this checking for multiple matches first, could be causing 'skips' in audio decode HERE HERE
//if ( (opts->frame_nxdn96 == 1) ||(opts->frame_nxdn48 == 1)) //kind of hacky, but too lazy to remove brackets and re-indent
now = time(NULL);
if ((state->lastsynctype == 8) || (state->lastsynctype == 16))
{
state->carrier = 1;
state->offset = synctest_pos;
@@ -1542,8 +934,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->lastsynctype = 8;
}
}
//else if ((strcmp (synctest18, INV_NXDN_BS_VOICE_SYNC) == 0) || (strcmp (synctest18, INV_NXDN_MS_VOICE_SYNC) == 0))
//else if ((strncmperr (synctest18, NXDN_BS_DATA_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_DATA_SYNC, 18, 1) == 0)) //supposed to be voice, not data? IT WAS THIS ONE!!
else if ((strncmperr (synctest18, INV_NXDN_BS_VOICE_SYNC, 18, 1) == 0) || (strncmperr (synctest18, INV_NXDN_MS_VOICE_SYNC, 18, 1) == 0)) //supposed to be voice, not data?
{
@@ -1586,7 +977,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->lastsynctype = 9;
}
}
//else if ((strcmp (synctest18, NXDN_BS_DATA_SYNC) == 0) || (strcmp (synctest18, NXDN_MS_DATA_SYNC) == 0))
else if ((strncmperr (synctest18, NXDN_BS_DATA_SYNC, 18, 1) == 0) || (strncmperr (synctest18, NXDN_MS_DATA_SYNC, 18, 1) == 0))
{
now = time(NULL);
@@ -1628,7 +1019,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->lastsynctype = 16;
}
}
//else if ((strcmp (synctest18, INV_NXDN_BS_DATA_SYNC) == 0) || (strcmp (synctest18, INV_NXDN_MS_DATA_SYNC) == 0))
else if ((strncmperr (synctest18, INV_NXDN_BS_DATA_SYNC, 18, 1) == 0) || (strncmperr (synctest18, INV_NXDN_MS_DATA_SYNC, 18, 1) == 0))
{
now = time(NULL);
@@ -1903,7 +1294,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
return (-1);
}
}
if ( opts->monitor_input_audio == 1 && (time(NULL) - now) > 1 ) //okay, still something going on, still doing the read part for some reason
if ( opts->monitor_input_audio == 1 && (time(NULL) - now) > 1 ) //okay, still something going on, latency issues
//if ( opts->monitor_input_audio == 1)
{
//playRawAudio(opts, state); //this is on line 21 in dsd_audio.c

View File

@@ -163,13 +163,13 @@ initOpts (dsd_opts * opts)
opts->serial_baud = 115200;
sprintf (opts->serial_dev, "/dev/ttyUSB0");
opts->resume = 0;
opts->frame_dstar = 1; //was disabled for some reason, make sure there are no false positives
opts->frame_dstar = 1;
opts->frame_x2tdma = 1;
opts->frame_p25p1 = 1;
opts->frame_nxdn48 = 0;
opts->frame_nxdn96 = 0;
opts->frame_dmr = 1;
opts->frame_dpmr = 0; //borrow from LEH
opts->frame_dpmr = 0;
opts->frame_provoice = 0;
opts->mod_c4fm = 1;
opts->mod_qpsk = 1;
@@ -658,12 +658,10 @@ main (int argc, char **argv)
for (short int i = 0; i < 7; i++) {
fprintf (stderr,"%s%s \n", FM_banner[i], KCYN);
fprintf (stderr,"%s%s \n", FM_banner[i], KCYN); //cyan/blue text
}
fprintf (stderr,"%s", KNRM); //change back to normal
fprintf (stderr, "%s \n", FM_banner[7]);
//pretty_colors();
//fprintf (stderr,"Digital Speech Decoder 1.7.0-dev (build:%s)\n", GIT_TAG);
fprintf (stderr,"Digital Speech Decoder: Florida Man Edition\n");
fprintf (stderr, "Github Build Version: %s \n", GIT_TAG);
fprintf (stderr,"mbelib version %s\n", versionstr);
@@ -835,8 +833,6 @@ main (int argc, char **argv)
}
break;
case 'n':
//opts.audio_out = 0;
//fprintf (stderr,"Disabling audio output to soundcard.\n");
opts.reset_state = 1;
fprintf (stderr,"Enabling Automatic Reset of P25 states\n");
fprintf (stderr," -Helps with multiple signal type decoding\n");
@@ -865,16 +861,11 @@ main (int argc, char **argv)
opts.frame_dstar = 1;
opts.frame_x2tdma = 1;
opts.frame_p25p1 = 1;
opts.frame_nxdn48 = 0; //turn it on, doesn't work due to symbol rate difference
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0; //causes false positives, leave on 0
opts.frame_dmr = 1;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_provoice = 0; //turn it on, doesn't work due to symbol rate difference
//adding stereo for DMR so we don't accidentally segfault
//opts.pulse_raw_rate_out = 24000; //doing tests with 2 channels at 24000 for 48000 audio default in pulse
//opts.pulse_digi_rate_out = 24000; //need to copy this to rtl type in and change rate out to 8000
//opts.pulse_raw_out_channels = 2;
//opts.pulse_digi_out_channels = 2; //2
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
sprintf (opts.output_name, "Default Channel");
}
else if (optarg[0] == 'd')
@@ -885,7 +876,7 @@ main (int argc, char **argv)
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
sprintf (opts.output_name, "D-STAR");
fprintf (stderr,"Decoding only D-STAR frames.\n");
@@ -920,8 +911,8 @@ main (int argc, char **argv)
opts.mod_gfsk = 1;
state.rf_mod = 2;
sprintf (opts.output_name, "ProVoice");
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
fprintf (stderr,"Enabling only GFSK modulation optimizations.\n");
//fprintf (stderr,"Setting symbol rate to 9600 / second\n");
//fprintf (stderr,"Enabling only GFSK modulation optimizations.\n");
fprintf (stderr,"Decoding only ProVoice frames.\n");
}
else if (optarg[0] == '1')
@@ -932,10 +923,10 @@ main (int argc, char **argv)
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
opts.mod_gfsk = 0;
opts.mod_c4fm = 1; //Phase 1 only uses C4FM, right?
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
state.rf_mod = 0; //
sprintf (opts.output_name, "P25P1");
@@ -949,19 +940,18 @@ main (int argc, char **argv)
opts.frame_nxdn48 = 1;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
//I think I've got it to decode on proper modulation now c4fm, not really sure what the difference is in DSD, seems to work either way for some reason
state.samplesPerSymbol = 20;
state.symbolCenter = 10;
opts.mod_c4fm = 1; // was 0
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //was 1 with others on zero
state.rf_mod = 0; //was 2
opts.mod_gfsk = 0;
state.rf_mod = 0;
sprintf (opts.output_name, "NXDN48");
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
fprintf (stderr,"Decoding only NXDN 4800 baud frames.\n");
}
else if (optarg[0] == 'n')
@@ -972,14 +962,14 @@ main (int argc, char **argv)
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 1;
opts.frame_dmr = 0;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
opts.mod_c4fm = 1; //was 0
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //was 1
state.rf_mod = 0; //was 2
opts.mod_gfsk = 0;
state.rf_mod = 0;
sprintf (opts.output_name, "NXDN96");
fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
fprintf (stderr,"Decoding only NXDN 9600 baud frames.\n");
}
else if (optarg[0] == 'r')
@@ -990,9 +980,9 @@ main (int argc, char **argv)
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 1;
opts.frame_dpmr = 0; //borrow from LEH
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
opts.mod_c4fm = 1; //just a test
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //
state.rf_mod = 0; //
@@ -1002,6 +992,7 @@ main (int argc, char **argv)
//opts.pulse_digi_out_channels = 2; //2
sprintf (opts.output_name, "DMR/MOTOTRBO");
//sprintf (opts.output_name, "DMR/MOTOTRBO Left");
fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
fprintf (stderr,"Decoding only DMR/MOTOTRBO frames.\n");
}
else if (optarg[0] == 'm')
@@ -1019,50 +1010,45 @@ main (int argc, char **argv)
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0;
state.rf_mod = 0; //garbage value to keep jitter in check?
state.rf_mod = 0;
sprintf (opts.output_name, "dPMR");
//opts.pulse_digi_rate_in = 48000;
//opts.pulse_digi_rate_out = 48000; //need to copy this to rtl type in and change rate out to 8000
//opts.pulse_digi_in_channels = 1;
//opts.pulse_digi_out_channels = 1;
//opts.inverted_dpmr = 1;
fprintf(stderr, "Setting symbol rate to 2400 / second\n");
//fprintf(stderr, "Enabling only GFSK modulation optimizations.\n");
fprintf(stderr, "Enabling only C4FM modulation optimizations.\n");
fprintf(stderr, "Decoding only dPMR (4800 baud frames).\n");
fprintf(stderr, "Notice: dPMR cannot autodetect polarity. \n Use -xd option if Inverted Signal expected.\n");
//fprintf(stderr, "Enabling only C4FM modulation optimizations.\n");
fprintf(stderr, "Decoding only dPMR frames.\n");
}
break;
//don't mess with the modulations, doesn't really do anything anyways
case 'm':
if (optarg[0] == 'a')
{
opts.mod_c4fm = 1;
opts.mod_qpsk = 1;
opts.mod_gfsk = 1;
state.rf_mod = 0;
//opts.mod_c4fm = 1;
//opts.mod_qpsk = 1;
//opts.mod_gfsk = 1;
//state.rf_mod = 0;
}
else if (optarg[0] == 'c')
{
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0;
state.rf_mod = 0;
fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
//opts.mod_c4fm = 1;
//opts.mod_qpsk = 0;
//opts.mod_gfsk = 0;
//state.rf_mod = 0;
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
}
else if (optarg[0] == 'g')
{
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
fprintf (stderr,"Enabling only GFSK modulation optimizations.\n");
//opts.mod_c4fm = 0;
//opts.mod_qpsk = 0;
//opts.mod_gfsk = 1;
//state.rf_mod = 2;
//fprintf (stderr,"Enabling only GFSK modulation optimizations.\n");
}
else if (optarg[0] == 'q')
{
opts.mod_c4fm = 0;
opts.mod_qpsk = 1;
opts.mod_gfsk = 0;
state.rf_mod = 1;
fprintf (stderr,"Enabling only QPSK modulation optimizations.\n");
//opts.mod_c4fm = 0;
//opts.mod_qpsk = 1;
//opts.mod_gfsk = 0;
//state.rf_mod = 1;
//fprintf (stderr,"Enabling only QPSK modulation optimizations.\n");
}
break;
case 'u':

View File

@@ -446,7 +446,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//attron(COLOR_PAIR(3));
printw ("| DCC: [%2i] FID: [%02X] SOP: [%02X] ", dcc, state->dmr_fid, state->dmr_so);
//if(state->payload_mi == 0 && state->dmr_so & 0x40)
if(state->payload_mi == 0 && state->dmr_so == 0x40)
if(state->payload_mi == 0 && (state->dmr_so & 0xCF) == 0x40) //4F or CF mask?
{
attron(COLOR_PAIR(5));
printw ("**BP** ");
@@ -455,7 +455,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3));
}
//if(state->payload_keyid > 0 && state->dmr_so & 0x40)
if(state->payload_keyid > 0 && state->dmr_so == 0x40)
if(state->payload_keyid > 0 && (state->dmr_so & 0xCF) == 0x40)
{
attron(COLOR_PAIR(5));
printw (" ALG: [0x%02X] KEY [0x%02X] MI [0x%08X]", state->payload_algid, state->payload_keyid, state->payload_mi);
@@ -464,7 +464,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3));
}
//if(state->K > 0 && state->payload_keyid == 0 && state->dmr_so & 0x40)
if(state->K > 0 && state->dmr_so == 0x40)
if(state->K > 0 && (state->dmr_so & 0xCF) == 0x40)
{
attron(COLOR_PAIR(5));
printw ("BPK [%3lld]", state->K);

View File

@@ -138,8 +138,11 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
// printf ("res: %zd\n, offset: %lld", result, sf_seek(opts->audio_in_file, 0, SEEK_CUR));
if (opts->use_cosine_filter)
{
if (state->lastsynctype >= 10 && state->lastsynctype <= 13)
sample = dmr_filter(sample);
if ( (state->lastsynctype >= 10 && state->lastsynctype <= 13) )
{
sample = dmr_filter(sample);
}
else if (state->lastsynctype == 8 || state->lastsynctype == 9 ||
state->lastsynctype == 16 || state->lastsynctype == 17)
{

View File

@@ -35,27 +35,25 @@ const unsigned char ENCODE_TABLE[] = {
2U, 10U, 6U, 14U, 0U, 8U, 4U, 12U,
6U, 14U, 0U, 8U, 4U, 12U, 2U, 10U};
const unsigned char DECODE_TABLE[] = { //flip the rows and columns, right?
0,4,1,5,3,7,2,6,
8,12,9,13,11,15,10,14,
4,2,5,3,7,1,6,0,
12,10,13,11,15,9,14,8,
2,6,3,7,1,5,0,4,
10,14,11,15,9,13,8,12,
6,0,7,1,5,3,4,2,
14,8,15,9,13,11,12,10
};
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
//unsigned char state = 0U;
//unsigned int superposition = 0;
//CDMRTrellis::CDMRTrellis()
//{
//}
unsigned char state = 0U;
//CDMRTrellis::~CDMRTrellis()
//{
//}
//void CDMRTrellis::tribitsToBits(const unsigned char* tribits, unsigned char* payload) const
//void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload) const
//bool CDMRTrellis::fixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) const
//bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) const
bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned char* payload)
{
//unsigned int bestPos = 0U;
//unsigned int bestVal = 0U;
@@ -63,12 +61,12 @@ bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned ch
for (unsigned j = 0U; j < 20U; j++) {
unsigned int bestPos = 0U;
unsigned int bestVal = 0U;
fprintf (stderr, " fail%d-", failPos);
//fprintf (stderr, " fail%d-", failPos);
for (unsigned int i = 0U; i < 16U; i++) {
points[failPos] = i;
fprintf (stderr, "i%d", i);
//fprintf (stderr, "i%d", i);
unsigned char tribits[49U];
unsigned int pos = CDMRTrellisCheckCode(points, tribits);
@@ -91,29 +89,8 @@ bool CDMRTrellisFixCode(unsigned char* points, unsigned int failPos, unsigned ch
}
void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload)
{
//g4klx version below
/*
for (unsigned int i = 0U; i < 48U; i++) {
unsigned char tribit = tribits[i];
bool b1 = (tribit & 0x04U) == 0x04U;
bool b2 = (tribit & 0x02U) == 0x02U;
bool b3 = (tribit & 0x01U) == 0x01U;
unsigned int n = 143U - i * 3U;
/*
WRITE_BIT(payload, n, b1);
n--;
WRITE_BIT(payload, n, b2);
n--;
WRITE_BIT(payload, n, b3);
}
*/
// boatbod version below...
// convert tribits to bits
unsigned char bits[144];
for (int i = 0; i < 48; i++) {
@@ -130,49 +107,19 @@ void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* paylo
}
//unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const
//unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits) const
/*
unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits)
{
//replace i with superposition; revert back if totally borked
//unsigned char state = 0U;
//for (unsigned int i = 0U; i < 49U; i++) {
//tribits[i] = 9U;
for (superposition; superposition < 49U; superposition++) {
tribits[superposition] = 9U;
for (unsigned int j = 0U; j < 8U; j++) {
if (points[superposition] == ENCODE_TABLE[state * 8U + j]) {
tribits[superposition] = j;
break;
}
}
if (tribits[superposition] == 9) {
return superposition;
//experiment placing fixcode right in here instead
//or we need to find a way to update state outside of this function
}
state = tribits[superposition];
}
//if (tribits[48U] != 0U)
//return 48U;
return 999U;
}
*/
unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tribits)
{
unsigned char state = 0U;
//unsigned char state = 0U; //move outside of function to preserve state for every iteration
//let's try reversing the points to pass through the decode table instead of flipping them here,
//it may mess up the fixcode and failpos POS
state = 0U;
for (unsigned int i = 0U; i < 49U; i++) {
tribits[i] = 9U;
for (unsigned int j = 0U; j < 8U; j++) {
if (points[i] == ENCODE_TABLE[state * 8U + j]) {
//if (points[i] == ENCODE_TABLE[state * 8U + j]) {
if (points[i] == DECODE_TABLE[state * 8U + j]) {
//if (points[48-i] == DECODE_TABLE[state * 8U + j]) {
tribits[i] = j;
break;
}
@@ -182,16 +129,19 @@ unsigned int CDMRTrellisCheckCode(const unsigned char* points, unsigned char* tr
return i;
state = tribits[i];
}
if (tribits[48U] != 0U)
//if (tribits[48U] != 0U)
if (tribits[48U] != 0U) //
{
return 48U;
}
return 999U;
}
//void CDMRTrellis::deinterleave(const unsigned char* data, signed char* dibits) const
//void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits) const
void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits)
{
int n;
@@ -215,13 +165,13 @@ void CDMRTrellisDeinterleave(const unsigned char* data, signed char* dibits)
else
dibit = -3;
n = INTERLEAVE_TABLE[i];
n = INTERLEAVE_TABLE[i]; //should this go in reverse?
dibits[n] = dibit;
//n = INTERLEAVE_TABLE[97-i]; //should this go in reverse?
//dibits[97-n] = dibit;
}
}
//void CDMRTrellis::dibitsToPoints(const signed char* dibits, unsigned char* points) const
//void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points) const
void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points)
{
for (unsigned int i = 0U; i < 49U; i++) {
@@ -260,8 +210,6 @@ void CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points)
}
}
//void CDMRTrellis::pointsToDibits(const unsigned char* points, signed char* dibits) const
//void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits) const
void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits)
{
for (unsigned int i = 0U; i < 49U; i++) {
@@ -334,8 +282,6 @@ void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits)
}
}
//void CDMRTrellis::bitsToTribits(const unsigned char* payload, unsigned char* tribits) const
//void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits) const
void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits)
{
for (unsigned int i = 0U; i < 48U; i++) {
@@ -358,17 +304,22 @@ void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribi
tribits[48U] = 0U;
}
//bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload)
bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
{
assert(data != NULL);
assert(payload != NULL);
if (1 == 1)
unsigned char tribits[49U];
for (short i = 0; i < 49; i++)
{
tribits[i] = 0; //initialize with 0 values so we know later on if these values are actually being assigned or not
}
if (1 == 2)
{
fprintf (stderr, "\n Raw Trellis Dibits inside Decoder\n ");
for (short i = 0; i < 98; i++)
{
fprintf (stderr, "[%0d]", data[i]);
fprintf (stderr, "#%d [%0d] ", i, data[i]);
}
}
signed char dibits[98U];
@@ -378,34 +329,50 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
fprintf (stderr, "\n Trellis Deinterleaved Dibits inside Decoder (converted to signed)\n ");
for (short i = 0; i < 98; i++)
{
fprintf (stderr, "[%d]", dibits[i]); //signed char, values should be -3, -1, 1, 3 only
fprintf (stderr, "#%d [%d] ", i, dibits[i]); //signed char, values should be -3, -1, 1, 3 only
}
}
unsigned char points[49U];
CDMRTrellisDibitsToPoints(dibits, points);
if (1 == 1)
{
fprintf (stderr, "\n Trellis Points inside Decoder (no higher than 15U?)\n ");
fprintf (stderr, "\n Trellis Points inside Decoder\n ");
for (short i = 0; i < 49; i++)
{
fprintf (stderr, "[%02u]", points[i]);
fprintf (stderr, "#%d [%02u] ", i, points[i]);
}
}
// Check the original code
unsigned char tribits[49U];
unsigned int failPos = CDMRTrellisCheckCode(points, tribits);
unsigned char reverse_points[49U];
fprintf (stderr, "\n Trellis Reversed Points inside Decoder\n ");
for (short i = 0; i < 49; i++)
{
reverse_points[i] = points[48-i];
fprintf (stderr, "#%d [%02u] ", i, reverse_points[i]);
}
//unsigned int failPos = CDMRTrellisCheckCode(points, tribits);
unsigned int failPos = CDMRTrellisCheckCode(reverse_points, tribits);
if (1 == 1)
{
fprintf (stderr, "\n Check Code Trellis Tribits inside Decoder\n ");
for (short i = 0; i < 49; i++)
{
fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7?
}
}
if (failPos == 999U) {
if (failPos == 999U)
{
CDMRTrellisTribitsToBits(tribits, payload);
if (1 == 1)
{
fprintf (stderr, "\nTrellis Payload Tribits to Bits failPos == 999U\n ");
for (short i = 0; i < 18; i++)
{
fprintf (stderr, "[%02u]", payload[i]);
fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7?
}
}
return true;
@@ -413,17 +380,19 @@ bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
unsigned char savePoints[49U];
for (unsigned int i = 0U; i < 49U; i++)
savePoints[i] = points[i];
//savePoints[i] = points[i];
savePoints[i] = reverse_points[i];
bool ret = CDMRTrellisFixCode(points, failPos, payload);
//bool ret = CDMRTrellisFixCode(points, failPos, payload);
bool ret = CDMRTrellisFixCode(reverse_points, failPos, payload);
if (ret){
if (1 == 1)
{
fprintf (stderr, "\n Trellis Tribits inside Decoder\n ");
fprintf (stderr, "\n if return Trellis Tribits inside Decoder\n ");
for (short i = 0; i < 49; i++)
{
fprintf (stderr, "[%0u]", tribits[i]); //shouldn't have any values greater that 0x7?
fprintf (stderr, "#%d [%0u] ", i, tribits[i]); //shouldn't have any values greater that 0x7?
}
}