Files
dsd-fme/src/nxdn_voice.c
lwvmobile 357f59b290 Minor Code Tweaks
Minor Code Tweaks
2022-06-09 16:58:45 -04:00

167 lines
5.2 KiB
C

#include "dsd.h"
#include "nxdn_const.h"
//don't know why this doesn't work right in LEH, need to figure that out for him
//works just fien when ripped from his and into mine
//must be some random thing, I'll look at his when I have a chance
void processNXDNVoice (dsd_opts * opts, dsd_state * state)
{
int i, j, dibit;
char ambe_fr[4][24];
unsigned char sacch_raw[72] = {0};
unsigned char sacch_decoded[32] = {0}; /* 26 bit + 6 bit CRC */
const int *w, *x, *y, *z;
unsigned char *pr;
uint8_t CrcIsGood = 0;
uint8_t StructureField = 0;
uint8_t RAN = 0;
uint8_t PartOfFrame = 0;
char ambe7bytesArray[7] = {0};
int PartOfEncryptedSuperFrame = 0;
if (opts->errorbars == 1)
{
fprintf(stderr, "VOICE - ");
}
/* Start pseudo-random NXDN sequence after
* LICH = 16 bit = 8 dibit
* ==> Index 8 */
pr = (unsigned char *)(&nxdnpr2[8]);
for (i = 0; i < 30; i++)
{
dibit = getDibit (opts, state);
/* Store and de-interleave directly SACCH bits */
sacch_raw[(2*i)] = ((*pr) & 1) ^ (1 & (dibit >> 1)); // bit 1
sacch_raw[(2*i)+1] = (1 & dibit); // bit 0
// TODO : Deinterleave is done in the "NXDN_SACCH_decode" function
// /* Store and de-interleave directly SACCH bits */
// sacch_raw[nsW[2*i]] = *pr ^ (1 & (dibit >> 1)); // bit 1
// sacch_raw[nsW[2*i+1]] = (1 & dibit); // bit 0
pr++;
#ifdef NXDN_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
}
#ifdef NXDN_DUMP
fprintf(stderr, " ");
#endif
// TODO : Unpuncture is done in the "NXDN_SACCH_decode" function
// /* For the sake of simplicity, handle the re-insertion of punctured bits here.
// * This makes the actual Viterbi decoder code a LOT simpler. */
// for (i = 30; i < 36; i++)
// {
// sacch_raw[nsW[2*i]] = 0;
// sacch_raw[nsW[2*i+1]] = 0;
// }
/* Decode the SACCH fields */
CrcIsGood = NXDN_SACCH_raw_part_decode(sacch_raw, sacch_decoded);
StructureField = (sacch_decoded[0]<<1 | sacch_decoded[1]<<0) & 0x03; /* Compute the Structure Field (remove 2 first bits of the SR Information in the SACCH) */
RAN = (sacch_decoded[2]<<5 | sacch_decoded[3]<<4 | sacch_decoded[4]<<3 | sacch_decoded[5]<<2 | sacch_decoded[6]<<1 | sacch_decoded[7]<<0) & 0x3F; /* Compute the RAN (6 last bits of the SR Information in the SACCH) */
/* Compute the Part of Frame according to the structure field */
if (StructureField == 3) PartOfFrame = 0;
else if(StructureField == 2) PartOfFrame = 1;
else if(StructureField == 1) PartOfFrame = 2;
else if(StructureField == 0) PartOfFrame = 3;
else PartOfFrame = 0; /* Normally we should never go here */
/* Fill the SACCH structure */
state->NxdnSacchRawPart[PartOfFrame].CrcIsGood = CrcIsGood;
state->NxdnSacchRawPart[PartOfFrame].StructureField = StructureField;
state->NxdnSacchRawPart[PartOfFrame].RAN = RAN;
memcpy(state->NxdnSacchRawPart[PartOfFrame].Data, &sacch_decoded[8], 18); /* Copy the 18 bits of SACCH content */
//fprintf(stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
//if(CrcIsGood) fprintf(stderr, " (OK) - ");
if(CrcIsGood)
{
fprintf (stderr, "%s", KCYN);
fprintf (stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
fprintf (stderr, "%s", KNRM);
//fprintf (stderr, "(CRC OK) ");
state->nxdn_last_ran = RAN; //disable, try to grab this in voice instead
}
else
{
fprintf (stderr, "%s", KRED);
fprintf(stderr, "(CRC ERR) ");
fprintf (stderr, "%s", KNRM);
}
/* Determine the current part of superframe
* (in an AES or DES encrypted frame, two superframes
* are used with the same IV, so to decipher the sound
* correctly we must know the current superframe part) */
if(state->NxdnElementsContent.PartOfNextEncryptedFrame == 1) PartOfEncryptedSuperFrame = 0;
else if(state->NxdnElementsContent.PartOfNextEncryptedFrame == 2) PartOfEncryptedSuperFrame = 1;
else PartOfEncryptedSuperFrame = 0;
/* Decode the SACCH only when all 4 voice frame
* SACCH spare parts have been received */
if(PartOfFrame == 3)
{
/* Decode the entire SACCH content */
NXDN_SACCH_Full_decode(opts, state);
}
if (opts->errorbars == 1)
{
//fprintf(stderr, "e:");
}
/* Start pseudo-random NXDN sequence after
* LICH = 16 bit = 8 dibit +
* SACCH = 60 bit = 30 dibit
* = 76 bit = 38 dibit
* ==> Index 38 */
pr = (unsigned char *)(&nxdnpr2[38]);
for (j = 0; j < 4; j++)
{
w = nW;
x = nX;
y = nY;
z = nZ;
for (i = 0; i < 36; i++)
{
dibit = getDibit (opts, state);
#ifdef NXDN_DUMP
fprintf(stderr, "%c", dibit + 48);
#endif
ambe_fr[*w][*x] = *pr ^ (1 & (dibit >> 1)); // bit 1
pr++;
ambe_fr[*y][*z] = (1 & dibit); // bit 0
w++;
x++;
y++;
z++;
}
if (opts->payload == 1 && opts->dmr_stereo == 1)
{
fprintf(stderr, "\n");
}
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
} /* End for (j = 0; j < 4; j++) */
if (opts->errorbars == 1)
{
fprintf(stderr, "\n");
}
/* Reset the SACCH CRCs when all 4 voice frame
* SACCH spare parts have been received */
if(PartOfFrame == 3)
{
/* Reset all CRCs of the SACCH */
for(i = 0; i < 4; i++) state->NxdnSacchRawPart[i].CrcIsGood = 0;
}
} /* End processNXDNVoice() */