DMR Stereo TDMA

DMR Stereo TDMA
--play voice in both TDMA slots with the -T option (dsd -fr -T)
--Improved MS voice (mostly working) and data handling (hit or miss)
--pretty pretty colors on the console log output
--rate 3/4 data decoding partially working
This commit is contained in:
lwvmobile
2022-04-30 04:43:03 -04:00
committed by GitHub
parent 8b48328431
commit 3cd1eefad8
29 changed files with 3291 additions and 1003 deletions

View File

@@ -26,17 +26,6 @@
#include "provoice_const.h"
#include "git_ver.h"
//pretty pretty colors
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
int pretty_colors()
{
fprintf (stderr,"%sred\n", KRED);
@@ -84,6 +73,10 @@ noCarrier (dsd_opts * opts, dsd_state * state)
{
state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200);
//dmr buffer
state->dmr_payload_p = state->dibit_buf + 200;
memset (state->dmr_payload_buf, 0, sizeof (int) * 200);
//dmr buffer end
if (opts->mbe_out_f != NULL)
{
closeMbeOutFile (opts, state);
@@ -93,7 +86,7 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->carrier = 0;
state->max = 15000;
state->min = -15000;
state->center = 0;
state->center = 0; //quick disable for dmr testing with buffer
state->err_str[0] = 0;
state->err_strR[0] = 0;
sprintf (state->fsubtype, " ");
@@ -110,15 +103,26 @@ noCarrier (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, " slot1 ");
state->firstframe = 0;
if (opts->audio_gain == (float) 0)
{
state->aout_gain = 25;
}
{
state->aout_gain = 25;
}
if (opts->audio_gainR == (float) 0)
{
state->aout_gainR = 25;
}
memset (state->aout_max_buf, 0, sizeof (float) * 200);
state->aout_max_buf_p = state->aout_max_buf;
state->aout_max_buf_idx = 0;
memset (state->aout_max_bufR, 0, sizeof (float) * 200);
state->aout_max_buf_pR = state->aout_max_bufR;
state->aout_max_buf_idxR = 0;
sprintf (state->algid, "________");
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);
}
void
@@ -151,11 +155,13 @@ initOpts (dsd_opts * opts)
#endif
opts->split = 0;
opts->playoffset = 0;
opts->playoffsetR = 0;
opts->mbe_out_dir[0] = 0;
opts->mbe_out_file[0] = 0;
opts->mbe_out_path[0] = 0;
opts->mbe_out_f = NULL;
opts->audio_gain = 0;
opts->audio_gainR = 0;
opts->audio_out = 1;
opts->wav_out_file[0] = 0;
opts->wav_out_f = NULL;
@@ -163,7 +169,7 @@ initOpts (dsd_opts * opts)
opts->serial_baud = 115200;
sprintf (opts->serial_dev, "/dev/ttyUSB0");
opts->resume = 0;
opts->frame_dstar = 1;
opts->frame_dstar = 1;
opts->frame_x2tdma = 1;
opts->frame_p25p1 = 1;
opts->frame_nxdn48 = 0;
@@ -200,13 +206,14 @@ initOpts (dsd_opts * opts)
opts->pulse_digi_in_channels = 1; //2
opts->pulse_digi_out_channels = 1; //2
sprintf (opts->output_name, "Default Channel");
sprintf (opts->output_name, "Auto Detect");
opts->pulse_flush = 1; //set 0 to flush, 1 for flushed
opts->use_ncurses_terminal = 0;
opts->payload = 0;
opts->EncryptionMode = MODE_UNENCRYPTED;
opts->inverted_dpmr = 0;
opts->dmr_stereo = 0; //change currently only in dsd_frame.c
}
void
@@ -218,13 +225,18 @@ initState (dsd_state * state)
state->dibit_buf = malloc (sizeof (int) * 1000000);
state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200);
//dmr buffer -- double check this set up
state->dmr_payload_buf = malloc (sizeof (int) * 1000000);
state->dmr_payload_p = state->dmr_payload_buf + 200;
memset (state->dmr_payload_buf, 0, sizeof (int) * 200);
//dmr buffer end
state->repeat = 0;
state->audio_out_buf = malloc (sizeof (short) * 1000000);
state->audio_out_bufR = malloc (sizeof (short) * 1000000);
memset (state->audio_out_buf, 0, 100 * sizeof (short));
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
state->audio_out_buf_p = state->audio_out_buf + 100;
state->audio_out_buf_pR = state->audio_out_buf + 100;
state->audio_out_buf_pR = state->audio_out_bufR + 100;
state->audio_out_float_buf = malloc (sizeof (float) * 1000000);
state->audio_out_float_bufR = malloc (sizeof (float) * 1000000);
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
@@ -296,6 +308,11 @@ initState (dsd_state * state)
memset (state->aout_max_buf, 0, sizeof (float) * 200);
state->aout_max_buf_p = state->aout_max_buf;
state->aout_max_buf_idx = 0;
memset (state->aout_max_bufR, 0, sizeof (float) * 200);
state->aout_max_buf_pR = state->aout_max_bufR;
state->aout_max_buf_idxR = 0;
state->samplesPerSymbol = 10;
state->symbolCenter = 4;
sprintf (state->algid, "________");
@@ -304,10 +321,17 @@ initState (dsd_state * state)
state->cur_mp = malloc (sizeof (mbe_parms));
state->prev_mp = malloc (sizeof (mbe_parms));
state->prev_mp_enhanced = malloc (sizeof (mbe_parms));
state->cur_mp2 = malloc (sizeof (mbe_parms));
state->prev_mp2 = malloc (sizeof (mbe_parms));
state->prev_mp_enhanced2 = malloc (sizeof (mbe_parms));
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->p25kid = 0;
state->debug_audio_errors = 0;
state->debug_audio_errorsR = 0;
state->debug_header_errors = 0;
state->debug_header_critical_errors = 0;
@@ -340,6 +364,7 @@ initState (dsd_state * state)
sprintf (state->dmr_lrrp[5], "");
state->K = 0;
state->dmr_stereo = 0;
#ifdef TRACE_DSD
state->debug_sample_index = 0;
@@ -380,7 +405,7 @@ usage ()
fprintf (stderr," -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
fprintf (stderr," -w <file> Output synthesized speech to a .wav file\n");
//fprintf (stderr," -a Display port audio devices\n");
//fprintf (stderr," -W Monitor Source Audio When No Sync Detected (WIP!)\n");
fprintf (stderr," -W Monitor Source Audio When No Sync Detected (WIP!)\n");
fprintf (stderr,"\n");
fprintf (stderr,"RTL-SDR options:\n");
fprintf (stderr," -c <hertz> RTL-SDR Frequency\n");
@@ -429,6 +454,9 @@ usage ()
fprintf (stderr," -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
fprintf (stderr," Helps when decoding mixed signal types at same time\n");
fprintf (stderr," (WiP! May Cause Slow Memory Leak - 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," (WiP! May Cause DMR sync break resync issues)\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");
@@ -674,7 +702,7 @@ main (int argc, char **argv)
exitflag = 0;
signal (SIGINT, sigfun);
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NWrlZ")) != -1)
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NWrlZT")) != -1)
{
opterr = 0;
switch (c)
@@ -771,8 +799,10 @@ main (int argc, char **argv)
case 'W': //monitor_input_audio if no sync
opts.monitor_input_audio = 1;
fprintf (stderr, "%s", KRED);
fprintf (stderr,"Monitoring Source Audio when carrier present and No Sync Detected.\n");
fprintf (stderr," - May cause Pulse Audio Server to crash on some systems.\n");
fprintf (stderr, "%s", KNRM);
break;
case 'N':
@@ -786,6 +816,17 @@ main (int argc, char **argv)
fprintf (stderr,"Logging MBE Payload to console\n");
break;
case 'T':
opts.dmr_stereo = 1; //just the end user option
state.dmr_stereo = 1; //this values toggles on and off depending on voice or data handling
opts.pulse_digi_rate_out = 24000;
opts.pulse_digi_out_channels = 2;
fprintf (stderr, "%s", KRED);
fprintf (stderr,"Experimental DMR Stereo Sync and Functionality. WIP!\n");
fprintf (stderr,"DMR Stereo will disable WAV and MBE file saving!\n");
fprintf (stderr, "%s", KNRM);
break;
case 'z':
sscanf (optarg, "%d", &opts.scoperate);
opts.errorbars = 0;
@@ -830,13 +871,16 @@ main (int argc, char **argv)
{
fprintf (stderr,"Setting audio out gain to %f\n", opts.audio_gain);
state.aout_gain = opts.audio_gain;
state.aout_gainR = opts.audio_gain;
}
break;
case 'n':
opts.reset_state = 1;
fprintf (stderr, "%s", KRED);
fprintf (stderr,"Enabling Automatic Reset of P25 states\n");
fprintf (stderr," -Helps with multiple signal type decoding\n");
fprintf (stderr," -(WiP! May cause slow memory leak)\n");
fprintf (stderr, "%s", KNRM);
break;
case 'w':
strncpy(opts.wav_out_file, optarg, 1023);
@@ -866,7 +910,7 @@ main (int argc, char **argv)
opts.frame_dmr = 1;
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
sprintf (opts.output_name, "Default Channel");
sprintf (opts.output_name, "Auto Detect");
}
else if (optarg[0] == 'd')
{
@@ -889,7 +933,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, "X2-TDMA");
fprintf (stderr,"Decoding only X2-TDMA frames.\n");
@@ -902,7 +946,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 = 1;
state.samplesPerSymbol = 5;
state.symbolCenter = 2;
@@ -911,8 +955,7 @@ 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,"Decoding only ProVoice frames.\n");
}
else if (optarg[0] == '1')
@@ -942,6 +985,7 @@ main (int argc, char **argv)
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
opts.frame_ysf = 0;
state.samplesPerSymbol = 20;
state.symbolCenter = 10;
opts.mod_c4fm = 1;
@@ -951,9 +995,30 @@ main (int argc, char **argv)
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,"Decoding only NXDN 4800 baud frames.\n");
}
else if (optarg[0] == 'y')
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 0;
opts.frame_ysf = 1;
state.samplesPerSymbol = 10;
//state.symbolCenter = 10;
opts.mod_c4fm = 1;
opts.mod_qpsk = 0;
opts.mod_gfsk = 0;
state.rf_mod = 0;
sprintf (opts.output_name, "YSF");
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
fprintf (stderr,"Decoding only YSF frames.\nNot working yet!\n");
}
else if (optarg[0] == 'n')
{
opts.frame_dstar = 0;
@@ -969,7 +1034,6 @@ main (int argc, char **argv)
opts.mod_gfsk = 0;
state.rf_mod = 0;
sprintf (opts.output_name, "NXDN96");
//fprintf (stderr,"Enabling only C4FM modulation optimizations.\n");
fprintf (stderr,"Decoding only NXDN 9600 baud frames.\n");
}
else if (optarg[0] == 'r')
@@ -986,13 +1050,8 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //
state.rf_mod = 0; //
//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
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, "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')
@@ -1005,6 +1064,7 @@ main (int argc, char **argv)
opts.frame_dmr = 0;
opts.frame_provoice = 0;
opts.frame_dpmr = 1;
opts.frame_ysf = 0; //testing with NXDN48 parameters
state.samplesPerSymbol = 20; //same as NXDN48 - 20
state.symbolCenter = 10; //same as NXDN48 - 10
opts.mod_c4fm = 1;
@@ -1013,11 +1073,10 @@ main (int argc, char **argv)
state.rf_mod = 0;
sprintf (opts.output_name, "dPMR");
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
//don't mess with the modulations, doesn't really do anything meaningful anyways
case 'm':
if (optarg[0] == 'a')
{
@@ -1127,7 +1186,6 @@ main (int argc, char **argv)
if (opts.use_ncurses_terminal == 1)
{
ncursesOpen();
//ncursesPrinter(&opts, &state);
}
if (opts.resume > 0)
@@ -1165,6 +1223,7 @@ main (int argc, char **argv)
{
opts.split = 1;
opts.playoffset = 0;
opts.playoffsetR = 0;
opts.delay = 0;
if (strlen(opts.wav_out_file) > 0)
{
@@ -1179,6 +1238,7 @@ main (int argc, char **argv)
{
opts.split = 1;
opts.playoffset = 0;
opts.playoffsetR = 0;
opts.delay = 0;
if (strlen(opts.wav_out_file) > 0)
{
@@ -1197,7 +1257,8 @@ main (int argc, char **argv)
else
{
opts.split = 0;
opts.playoffset = 25; // 38
opts.playoffset = 25; // 38
opts.playoffsetR = 25; // 38
opts.delay = 0;
openAudioInDevice (&opts); //disabled all four instances of openAudio devices, in and out for now
opts.audio_out_fd = opts.audio_in_fd;
@@ -1214,8 +1275,8 @@ main (int argc, char **argv)
else
{
liveScanner (&opts, &state);
}
if (opts.use_ncurses_terminal == 1){
//ncursesClose ();
}