mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-14 17:57:28 -05:00
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:
137
src/dsd_main.c
137
src/dsd_main.c
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user