mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 17:27:21 -05:00
M17 - Simple BRT Encoder; Setup for PKT Encoder;
This commit is contained in:
@@ -271,6 +271,8 @@ typedef struct
|
||||
int msize;
|
||||
int playfiles;
|
||||
int m17encoder;
|
||||
int m17encoderbrt;
|
||||
int m17encoderpkt;
|
||||
int delay;
|
||||
int use_cosine_filter;
|
||||
int unmute_encrypted_p25;
|
||||
@@ -1016,6 +1018,8 @@ void processYSF(dsd_opts * opts, dsd_state * state); //YSF
|
||||
void processM17STR(dsd_opts * opts, dsd_state * state); //M17 (STR)
|
||||
void processM17LSF(dsd_opts * opts, dsd_state * state); //M17 (LSF)
|
||||
void encodeM17STR(dsd_opts * opts, dsd_state * state); //M17 (STR) encoder
|
||||
void encodeM17BRT(dsd_opts * opts, dsd_state * state); //M17 (BRT) encoder
|
||||
void encodeM17PKT(dsd_opts * opts, dsd_state * state); //M17 (PKT) encoder
|
||||
void processP2(dsd_opts * opts, dsd_state * state); //P2
|
||||
void processTSBK(dsd_opts * opts, dsd_state * state); //P25 Trunking Single Block
|
||||
void processMPDU(dsd_opts * opts, dsd_state * state); //P25 Multi Block PDU (SAP 0x61 FMT 0x15 or 0x17 for Trunking Blocks)
|
||||
|
||||
@@ -626,6 +626,8 @@ initOpts (dsd_opts * opts)
|
||||
opts->msize = 1024; //15 default, max is 1024, much cleaner data decodes on Phase 2 cqpsk at max
|
||||
opts->playfiles = 0;
|
||||
opts->m17encoder = 0;
|
||||
opts->m17encoderbrt = 0;
|
||||
opts->m17encoderpkt = 0;
|
||||
opts->delay = 0;
|
||||
opts->use_cosine_filter = 1;
|
||||
opts->unmute_encrypted_p25 = 0;
|
||||
@@ -1288,6 +1290,11 @@ usage ()
|
||||
printf (" Example: dsd-fme -fZ -i tcp -8 -o pulse -N 2> m17encoderlog.ans\n");
|
||||
printf (" Run M17 Encoding, listening to default tcp input, without internal decode/playback and output to 48k/1 analog output device\n");
|
||||
printf ("\n");
|
||||
printf (" -fB M17 BERT Encoder\n");
|
||||
printf (" Example: dsd-fme -fB -6 m17bert.wav\n");
|
||||
printf (" -fP M17 Packet Encoder\n");
|
||||
printf (" Example: dsd-fme -fP -6 m17pkt.wav (NOTE: WIP)\n");
|
||||
printf ("\n");
|
||||
printf ("Decoder options:\n");
|
||||
printf (" -fa Auto Detection\n");
|
||||
printf (" -ft TDMA Trunking P25p1 Control and Voice, P25p2 Trunked Channels, and DMR\n");
|
||||
@@ -2387,13 +2394,27 @@ main (int argc, char **argv)
|
||||
fprintf(stderr, "Notice: M17 cannot autodetect polarity. \n Use -xz option if Inverted Signal expected.\n");
|
||||
fprintf(stderr, "Decoding only M17 frames.\n");
|
||||
}
|
||||
else if (optarg[0] == 'Z') //Captial Z to Run the M17 encoder
|
||||
else if (optarg[0] == 'Z') //Captial Z to Run the M17 STR encoder
|
||||
{
|
||||
opts.m17encoder = 1;
|
||||
opts.pulse_digi_rate_out = 48000;
|
||||
opts.pulse_digi_out_channels = 1;
|
||||
sprintf (opts.output_name, "M17 Encoder");
|
||||
}
|
||||
else if (optarg[0] == 'B') //Captial B to Run the M17 BRT encoder
|
||||
{
|
||||
opts.m17encoderbrt = 1;
|
||||
opts.pulse_digi_rate_out = 48000;
|
||||
opts.pulse_digi_out_channels = 1;
|
||||
sprintf (opts.output_name, "M17 BERT");
|
||||
}
|
||||
else if (optarg[0] == 'P') //Captial P to Run the M17 PKT encoder
|
||||
{
|
||||
opts.m17encoderpkt = 1;
|
||||
opts.pulse_digi_rate_out = 48000;
|
||||
opts.pulse_digi_out_channels = 1;
|
||||
sprintf (opts.output_name, "M17 Packet");
|
||||
}
|
||||
break;
|
||||
//don't mess with the modulations unless you really need to
|
||||
case 'm':
|
||||
@@ -2951,6 +2972,22 @@ main (int argc, char **argv)
|
||||
encodeM17STR(&opts, &state);
|
||||
}
|
||||
|
||||
else if (opts.m17encoderbrt == 1)
|
||||
{
|
||||
opts.pulse_digi_rate_out = 8000;
|
||||
//open any outputs, if not already opened
|
||||
if (opts.audio_out_type == 0) openPulseOutput(&opts);
|
||||
encodeM17BRT(&opts, &state);
|
||||
}
|
||||
|
||||
else if (opts.m17encoderpkt == 1)
|
||||
{
|
||||
opts.pulse_digi_rate_out = 8000;
|
||||
//open any outputs, if not already opened
|
||||
if (opts.audio_out_type == 0) openPulseOutput(&opts);
|
||||
encodeM17PKT(&opts, &state);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
156
src/m17.c
156
src/m17.c
@@ -1118,7 +1118,7 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type)
|
||||
}
|
||||
|
||||
//Preamble (just repeat the preamble 12 times to make 192 symbols)
|
||||
if (type == 33) //B Pattern prepends ??? (last symbol opposite of first symbol to prevent zero-crossing)
|
||||
if (type == 33) //B Pattern prepends BRT (last symbol opposite of first symbol to prevent zero-crossing)
|
||||
{
|
||||
for (i = 0; i < 192; i++)
|
||||
output_dibits[i] = (m17_preamble_b[ (i*2+0)%16 ] << 1) + (m17_preamble_b[ (i*2+1)%16 ] << 0);
|
||||
@@ -1144,18 +1144,18 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type)
|
||||
output_dibits[i] = (m17_str_fs[i*2+0] << 1) + (m17_str_fs[i*2+1] << 0);
|
||||
}
|
||||
|
||||
if (type == 3) //PKT
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
output_dibits[i] = (m17_pkt_fs[i*2+0] << 1) + (m17_pkt_fs[i*2+1] << 0);
|
||||
}
|
||||
|
||||
if (type == 4) //BRT
|
||||
if (type == 3) //BRT
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
output_dibits[i] = (m17_brt_fs[i*2+0] << 1) + (m17_brt_fs[i*2+1] << 0);
|
||||
}
|
||||
|
||||
if (type == 4) //PKT
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
output_dibits[i] = (m17_pkt_fs[i*2+0] << 1) + (m17_pkt_fs[i*2+1] << 0);
|
||||
}
|
||||
|
||||
//load rest of frame (if not preamble, EOT marker, or dead air)
|
||||
if (type < 5)
|
||||
{
|
||||
@@ -1210,6 +1210,10 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type)
|
||||
// fprintf (stderr, " %d", baseband[i]);
|
||||
// }
|
||||
|
||||
//debug insert random 'noise' into the baseband audio
|
||||
// for (i = 0; i < 40; i++)
|
||||
// baseband[i] -= rand()& 0x7FFF;
|
||||
|
||||
//dead air type, output to all enabled formats zero sample to simulate dead air
|
||||
//NOTE: 25 rounds is approximately 1 second even, seems optimal
|
||||
if (type == 99)
|
||||
@@ -2084,3 +2088,139 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state)
|
||||
free(samp2);
|
||||
|
||||
}
|
||||
|
||||
//encode and create audio of a Project M17 BERT signal
|
||||
void encodeM17BRT(dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
//NOTE: BERT will not use the nucrses terminal,
|
||||
//just strictly for making a BERT test signal
|
||||
|
||||
uint8_t nil[368]; //empty array
|
||||
memset (nil, 0, sizeof(nil));
|
||||
|
||||
int i, j, k, x; //basic utility counters
|
||||
|
||||
//send dead air with type 99
|
||||
for (i = 0; i < 25; i++)
|
||||
encodeM17RF (opts, state, nil, 99);
|
||||
|
||||
//send preamble_b for the BERT frame
|
||||
encodeM17RF (opts, state, nil, 33);
|
||||
|
||||
//BERT - 197 bits generated from a PRBS9 Generator
|
||||
uint8_t m17_b1[201]; memset (m17_b1, 0, sizeof(m17_b1));
|
||||
|
||||
uint16_t lfsr = 1; //starting value of the LFSR
|
||||
uint16_t bit = 1; //result bit of taps XOR
|
||||
m17_b1[0] = 1;
|
||||
|
||||
while (!exitflag)
|
||||
{
|
||||
|
||||
//Generate sequence (if doing 197 at a time)
|
||||
// for (j = 0; j < 197; j++)
|
||||
// {
|
||||
// bit = ( (lfsr >> 8) ^ (lfsr ^ 4) ) & 1;
|
||||
// lfsr = (lfsr << 1) | bit;
|
||||
// m17_b1[j] = bit;
|
||||
// }
|
||||
|
||||
//BERT (reversed sequence for output)
|
||||
uint8_t m17_b1r[208]; memset (m17_b1r, 0, sizeof(m17_b1r));
|
||||
|
||||
//BERT (after Convolutional Encode)
|
||||
uint8_t m17_b1c[402]; memset (m17_b1c, 0, sizeof(m17_b1c));
|
||||
|
||||
//BERT (after P2 Puncturing)
|
||||
uint8_t m17_b2p[368]; memset (m17_b2p, 0, sizeof(m17_b2p));
|
||||
|
||||
//BERT (Interleaved Bits)
|
||||
uint8_t m17_b3i[368]; memset (m17_b3i, 0, sizeof(m17_b3i));
|
||||
|
||||
//BERT (Scrambling Applied)
|
||||
uint8_t m17_b4s[368]; memset (m17_b4s, 0, sizeof(m17_b4s));
|
||||
|
||||
simple_conv_encoder (m17_b1, m17_b1c, 201); //197+4
|
||||
|
||||
//use the P2 puncture to...puncture and collapse the BERT Frame
|
||||
k = 0; x = 0;
|
||||
for (i = 0; i < 34; i++)
|
||||
{
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
//quit early on last set of i when 368 k bits reached
|
||||
//index from 0 to 367,so 368 is breakpoint with k++
|
||||
if (k == 368) break;
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
m17_b2p[k++] = m17_b1c[x++];
|
||||
x++;
|
||||
}
|
||||
|
||||
//debug K and X bit positions
|
||||
fprintf (stderr, " K: %d; X: %d", k, x);
|
||||
|
||||
//interleave the bit array using Quadratic Permutation Polynomial
|
||||
//function π(x) = (45x + 92x^2 ) mod 368
|
||||
for (i = 0; i < 368; i++)
|
||||
{
|
||||
x = ((45*i)+(92*i*i)) % 368;
|
||||
m17_b3i[x] = m17_b2p[i];
|
||||
}
|
||||
|
||||
//scramble/randomize the frame
|
||||
for (i = 0; i < 368; i++)
|
||||
m17_b4s[i] = (m17_b3i[i] ^ m17_scramble[i]) & 1;
|
||||
|
||||
//debug insert 3 random bit flip in the finished BERT frame
|
||||
// int rnd1 = rand()%368;
|
||||
// int rnd2 = rand()%368;
|
||||
// int rnd3 = rand()%368;
|
||||
// m17_b4s[rnd1] ^= 1;
|
||||
// m17_b4s[rnd2] ^= 1;
|
||||
// m17_b4s[rnd3] ^= 1;
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
fprintf (stderr, "\n M17 BERT (ENCODER): ");
|
||||
|
||||
//reverse the sequence and shift so it appears correct on display
|
||||
for (i = 0; i < 197; i++)
|
||||
m17_b1r[i+3] = m17_b1[196-i];
|
||||
|
||||
//Dump Output of the BERT array (reversed and shifted sequence)
|
||||
for (i = 0; i < 25; i++)
|
||||
fprintf (stderr, "%02X", (uint8_t)ConvertBitIntoBytes(&m17_b1r[i*8], 8));
|
||||
|
||||
//convert bit array into symbols and RF/Audio
|
||||
encodeM17RF (opts, state, m17_b4s, 3);
|
||||
|
||||
//advance sequence if doing 1 bit each BERT frame
|
||||
bit = ( (lfsr >> 8) ^ (lfsr ^ 4) ) & 1;
|
||||
lfsr = (lfsr << 1) | bit;
|
||||
|
||||
//shift the array once and put the result bit into the zero position
|
||||
//NOTE: The endian-ness of this may be opposite of what is expected
|
||||
for (j = 1; j < 197; j++)
|
||||
m17_b1[197-j] = m17_b1[197-j-1];
|
||||
m17_b1[0] = bit;
|
||||
|
||||
//end sequence advancement
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//encode and create audio of a Project M17 PKT signal
|
||||
void encodeM17PKT(dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
UNUSED(opts); UNUSED(state);
|
||||
//TODO: This whole thing
|
||||
fprintf (stderr, "\n M17 Packet (ENCODER): ");
|
||||
}
|
||||
Reference in New Issue
Block a user