mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-23 08:28:36 -05:00
DSD demod plugin: integration of DSD engine
This commit is contained in:
parent
3f92de1d53
commit
97b60ccb87
@ -15,22 +15,21 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include "dsd_cleanupexit.h"
|
#include "dsd_cleanupexit.h"
|
||||||
#include "dsd_nocarrier.h"
|
#include "dsd_nocarrier.h"
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
|
|
||||||
void
|
void cleanupAndExit(dsd_opts * opts, dsd_state * state)
|
||||||
cleanupAndExit (dsd_opts * opts, dsd_state * state)
|
|
||||||
{
|
{
|
||||||
noCarrier (opts, state);
|
noCarrier(opts, state);
|
||||||
#ifdef USE_LIBSNDFILE
|
#ifdef USE_LIBSNDFILE
|
||||||
if (opts->wav_out_f != NULL)
|
if (opts->wav_out_f != NULL)
|
||||||
{
|
{
|
||||||
closeWavOutFile (opts, state);
|
closeWavOutFile (opts, state);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
printf ("Exiting.\n");
|
printf("dsd::cleanupAndExit: Exiting.\n");
|
||||||
//exit (0); // You just can't do that within SDRangel
|
int rc = 0;
|
||||||
|
pthread_exit(&rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
609
dsd/dsd_frame.c
609
dsd/dsd_frame.c
@ -20,455 +20,464 @@
|
|||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void printFrameInfo(dsd_opts * opts, dsd_state * state)
|
||||||
printFrameInfo (dsd_opts * opts, dsd_state * state)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
if (state->nac != 0)
|
if (state->nac != 0)
|
||||||
{
|
{
|
||||||
printf ("nac: %4X ", state->nac);
|
printf("nac: %4X ", state->nac);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->verbose > 1)
|
if (opts->verbose > 1)
|
||||||
{
|
{
|
||||||
printf ("src: %8i ", state->lastsrc);
|
printf("src: %8i ", state->lastsrc);
|
||||||
}
|
}
|
||||||
printf ("tg: %5i ", state->lasttg);
|
printf("tg: %5i ", state->lasttg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void processFrame(dsd_opts * opts, dsd_state * state)
|
||||||
processFrame (dsd_opts * opts, dsd_state * state)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int i, j, dibit;
|
int i, j, dibit;
|
||||||
char duid[3];
|
char duid[3];
|
||||||
char nac[13];
|
char nac[13];
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
duid[2] = 0;
|
duid[2] = 0;
|
||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
if (state->rf_mod == 1)
|
if (state->rf_mod == 1)
|
||||||
{
|
{
|
||||||
state->maxref = (state->max * 0.80);
|
state->maxref = (state->max * 0.80);
|
||||||
state->minref = (state->min * 0.80);
|
state->minref = (state->min * 0.80);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state->maxref = state->max;
|
state->maxref = state->max;
|
||||||
state->minref = state->min;
|
state->minref = state->min;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state->synctype == 8) || (state->synctype == 9))
|
if ((state->synctype == 8) || (state->synctype == 9))
|
||||||
{
|
{
|
||||||
state->rf_mod = 2;
|
state->rf_mod = 2;
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " VOICE ");
|
sprintf(state->fsubtype, " VOICE ");
|
||||||
processNXDNVoice (opts, state);
|
processNXDNVoice(opts, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((state->synctype == 16) || (state->synctype == 17))
|
else if ((state->synctype == 16) || (state->synctype == 17))
|
||||||
{
|
{
|
||||||
state->rf_mod = 2;
|
state->rf_mod = 2;
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " DATA ");
|
sprintf(state->fsubtype, " DATA ");
|
||||||
processNXDNData (opts, state);
|
processNXDNData(opts, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((state->synctype == 6) || (state->synctype == 7))
|
else if ((state->synctype == 6) || (state->synctype == 7))
|
||||||
{
|
{
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " VOICE ");
|
sprintf(state->fsubtype, " VOICE ");
|
||||||
processDSTAR (opts, state);
|
processDSTAR(opts, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((state->synctype == 18) || (state->synctype == 19))
|
else if ((state->synctype == 18) || (state->synctype == 19))
|
||||||
{
|
{
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " DATA ");
|
sprintf(state->fsubtype, " DATA ");
|
||||||
processDSTAR_HD (opts, state);
|
processDSTAR_HD(opts, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((state->synctype >= 10) && (state->synctype <= 13))
|
else if ((state->synctype >= 10) && (state->synctype <= 13))
|
||||||
{
|
{
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((state->synctype == 11) || (state->synctype == 12))
|
if ((state->synctype == 11) || (state->synctype == 12))
|
||||||
{
|
{
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " VOICE ");
|
sprintf(state->fsubtype, " VOICE ");
|
||||||
processDMRvoice (opts, state);
|
processDMRvoice(opts, state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
closeMbeOutFile (opts, state);
|
if (opts->mbe_out_f != NULL) {
|
||||||
state->err_str[0] = 0;
|
closeMbeOutFile(opts, state);
|
||||||
processDMRdata (opts, state);
|
}
|
||||||
|
state->err_str[0] = 0;
|
||||||
|
processDMRdata(opts, state);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((state->synctype >= 2) && (state->synctype <= 5))
|
else if ((state->synctype >= 2) && (state->synctype <= 5))
|
||||||
{
|
{
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
}
|
}
|
||||||
if ((state->synctype == 3) || (state->synctype == 4))
|
if ((state->synctype == 3) || (state->synctype == 4))
|
||||||
{
|
{
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " VOICE ");
|
sprintf(state->fsubtype, " VOICE ");
|
||||||
processX2TDMAvoice (opts, state);
|
processX2TDMAvoice(opts, state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
closeMbeOutFile (opts, state);
|
if (opts->mbe_out_f != NULL) {
|
||||||
state->err_str[0] = 0;
|
closeMbeOutFile(opts, state);
|
||||||
processX2TDMAdata (opts, state);
|
}
|
||||||
|
state->err_str[0] = 0;
|
||||||
|
processX2TDMAdata(opts, state);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((state->synctype == 14) || (state->synctype == 15))
|
else if ((state->synctype == 14) || (state->synctype == 15))
|
||||||
{
|
{
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->verbose > 0)
|
if (opts->verbose > 0)
|
||||||
{
|
{
|
||||||
level = (int) state->max / 164;
|
level = (int) state->max / 164;
|
||||||
printf ("inlvl: %2i%% ", level);
|
printf("inlvl: %2i%% ", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
sprintf (state->fsubtype, " VOICE ");
|
sprintf(state->fsubtype, " VOICE ");
|
||||||
processProVoice (opts, state);
|
processProVoice(opts, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
dibit = getDibit (opts, state);
|
dibit = getDibit(opts, state);
|
||||||
nac[j] = (1 & (dibit >> 1)) + 48; // bit 1
|
nac[j] = (1 & (dibit >> 1)) + 48; // bit 1
|
||||||
j++;
|
j++;
|
||||||
nac[j] = (1 & dibit) + 48; // bit 0
|
nac[j] = (1 & dibit) + 48; // bit 0
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
nac[12] = 0;
|
nac[12] = 0;
|
||||||
state->nac = strtol (nac, NULL, 2);
|
state->nac = strtol(nac, NULL, 2);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
duid[i] = getDibit (opts, state) + 48;
|
duid[i] = getDibit(opts, state) + 48;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (duid, "00") == 0)
|
if (strcmp(duid, "00") == 0)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" HDU\n");
|
printf(" HDU\n");
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
{
|
{
|
||||||
closeMbeOutFile (opts, state);
|
if (opts->mbe_out_f != NULL) {
|
||||||
openMbeOutFile (opts, state);
|
closeMbeOutFile(opts, state);
|
||||||
|
}
|
||||||
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
mbe_initMbeParms(state->cur_mp, state->prev_mp,
|
||||||
state->lastp25type = 2;
|
state->prev_mp_enhanced);
|
||||||
sprintf (state->fsubtype, " HDU ");
|
state->lastp25type = 2;
|
||||||
processHDU (opts, state);
|
sprintf(state->fsubtype, " HDU ");
|
||||||
|
processHDU(opts, state);
|
||||||
}
|
}
|
||||||
else if (strcmp (duid, "11") == 0)
|
else if (strcmp(duid, "11") == 0)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" LDU1 ");
|
printf(" LDU1 ");
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
{
|
{
|
||||||
if (opts->mbe_out_f == NULL)
|
if (opts->mbe_out_f == NULL)
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 1;
|
state->lastp25type = 1;
|
||||||
sprintf (state->fsubtype, " LDU1 ");
|
sprintf(state->fsubtype, " LDU1 ");
|
||||||
state->numtdulc = 0;
|
state->numtdulc = 0;
|
||||||
processLDU1 (opts, state);
|
processLDU1(opts, state);
|
||||||
}
|
}
|
||||||
else if (strcmp (duid, "22") == 0)
|
else if (strcmp(duid, "22") == 0)
|
||||||
{
|
{
|
||||||
if (state->lastp25type != 1)
|
if (state->lastp25type != 1)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" Ignoring LDU2 not preceeded by LDU1\n");
|
printf(" Ignoring LDU2 not preceeded by LDU1\n");
|
||||||
}
|
}
|
||||||
state->lastp25type = 0;
|
state->lastp25type = 0;
|
||||||
sprintf (state->fsubtype, " ");
|
sprintf(state->fsubtype, " ");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" LDU2 ");
|
printf(" LDU2 ");
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
{
|
{
|
||||||
if (opts->mbe_out_f == NULL)
|
if (opts->mbe_out_f == NULL)
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 2;
|
state->lastp25type = 2;
|
||||||
sprintf (state->fsubtype, " LDU2 ");
|
sprintf(state->fsubtype, " LDU2 ");
|
||||||
state->numtdulc = 0;
|
state->numtdulc = 0;
|
||||||
processLDU2 (opts, state);
|
processLDU2(opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp (duid, "33") == 0)
|
else if (strcmp(duid, "33") == 0)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" TDULC\n");
|
printf(" TDULC\n");
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
{
|
{
|
||||||
closeMbeOutFile (opts, state);
|
if (opts->mbe_out_f != NULL) {
|
||||||
}
|
closeMbeOutFile(opts, state);
|
||||||
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
||||||
state->lasttg = 0;
|
|
||||||
state->lastsrc = 0;
|
|
||||||
state->lastp25type = 0;
|
|
||||||
state->err_str[0] = 0;
|
|
||||||
sprintf (state->fsubtype, " TDULC ");
|
|
||||||
state->numtdulc++;
|
|
||||||
if ((opts->resume > 0) && (state->numtdulc > opts->resume))
|
|
||||||
{
|
|
||||||
resumeScan (opts, state);
|
|
||||||
}
|
|
||||||
processTDULC (opts, state);
|
|
||||||
state->err_str[0] = 0;
|
|
||||||
}
|
|
||||||
else if (strcmp (duid, "03") == 0)
|
|
||||||
{
|
|
||||||
if (opts->errorbars == 1)
|
|
||||||
{
|
|
||||||
printFrameInfo (opts, state);
|
|
||||||
printf (" TDU\n");
|
|
||||||
}
|
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
|
||||||
{
|
|
||||||
closeMbeOutFile (opts, state);
|
|
||||||
}
|
|
||||||
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
||||||
state->lasttg = 0;
|
|
||||||
state->lastsrc = 0;
|
|
||||||
state->lastp25type = 0;
|
|
||||||
state->err_str[0] = 0;
|
|
||||||
sprintf (state->fsubtype, " TDU ");
|
|
||||||
skipDibit (opts, state, 40);
|
|
||||||
}
|
|
||||||
else if (strcmp (duid, "13") == 0)
|
|
||||||
{
|
|
||||||
if (opts->errorbars == 1)
|
|
||||||
{
|
|
||||||
printFrameInfo (opts, state);
|
|
||||||
printf (" TSDU\n");
|
|
||||||
}
|
|
||||||
if (opts->resume > 0)
|
|
||||||
{
|
|
||||||
resumeScan (opts, state);
|
|
||||||
}
|
|
||||||
state->lasttg = 0;
|
|
||||||
state->lastsrc = 0;
|
|
||||||
state->lastp25type = 3;
|
|
||||||
sprintf (state->fsubtype, " TSDU ");
|
|
||||||
skipDibit (opts, state, 328);
|
|
||||||
}
|
|
||||||
else if (strcmp (duid, "30") == 0)
|
|
||||||
{
|
|
||||||
if (opts->errorbars == 1)
|
|
||||||
{
|
|
||||||
printFrameInfo (opts, state);
|
|
||||||
printf (" PDU\n");
|
|
||||||
}
|
|
||||||
if (opts->resume > 0)
|
|
||||||
{
|
|
||||||
resumeScan (opts, state);
|
|
||||||
}
|
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
|
||||||
{
|
|
||||||
if (opts->mbe_out_f == NULL)
|
|
||||||
{
|
|
||||||
openMbeOutFile (opts, state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 4;
|
mbe_initMbeParms(state->cur_mp, state->prev_mp,
|
||||||
sprintf (state->fsubtype, " PDU ");
|
state->prev_mp_enhanced);
|
||||||
}
|
state->lasttg = 0;
|
||||||
// try to guess based on previous frame if unknown type
|
state->lastsrc = 0;
|
||||||
else if (state->lastp25type == 1)
|
state->lastp25type = 0;
|
||||||
{
|
state->err_str[0] = 0;
|
||||||
if (opts->errorbars == 1)
|
sprintf(state->fsubtype, " TDULC ");
|
||||||
|
state->numtdulc++;
|
||||||
|
if ((opts->resume > 0) && (state->numtdulc > opts->resume))
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
resumeScan(opts, state);
|
||||||
printf ("(LDU2) ");
|
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
processTDULC(opts, state);
|
||||||
|
state->err_str[0] = 0;
|
||||||
|
}
|
||||||
|
else if (strcmp(duid, "03") == 0)
|
||||||
|
{
|
||||||
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
if (opts->mbe_out_f == NULL)
|
printFrameInfo(opts, state);
|
||||||
|
printf(" TDU\n");
|
||||||
|
}
|
||||||
|
if (opts->mbe_out_f != NULL)
|
||||||
|
{
|
||||||
|
closeMbeOutFile(opts, state);
|
||||||
|
}
|
||||||
|
mbe_initMbeParms(state->cur_mp, state->prev_mp,
|
||||||
|
state->prev_mp_enhanced);
|
||||||
|
state->lasttg = 0;
|
||||||
|
state->lastsrc = 0;
|
||||||
|
state->lastp25type = 0;
|
||||||
|
state->err_str[0] = 0;
|
||||||
|
sprintf(state->fsubtype, " TDU ");
|
||||||
|
skipDibit(opts, state, 40);
|
||||||
|
}
|
||||||
|
else if (strcmp(duid, "13") == 0)
|
||||||
|
{
|
||||||
|
if (opts->errorbars == 1)
|
||||||
|
{
|
||||||
|
printFrameInfo(opts, state);
|
||||||
|
printf(" TSDU\n");
|
||||||
|
}
|
||||||
|
if (opts->resume > 0)
|
||||||
|
{
|
||||||
|
resumeScan(opts, state);
|
||||||
|
}
|
||||||
|
state->lasttg = 0;
|
||||||
|
state->lastsrc = 0;
|
||||||
|
state->lastp25type = 3;
|
||||||
|
sprintf(state->fsubtype, " TSDU ");
|
||||||
|
skipDibit(opts, state, 328);
|
||||||
|
}
|
||||||
|
else if (strcmp(duid, "30") == 0)
|
||||||
|
{
|
||||||
|
if (opts->errorbars == 1)
|
||||||
|
{
|
||||||
|
printFrameInfo(opts, state);
|
||||||
|
printf(" PDU\n");
|
||||||
|
}
|
||||||
|
if (opts->resume > 0)
|
||||||
|
{
|
||||||
|
resumeScan(opts, state);
|
||||||
|
}
|
||||||
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
|
{
|
||||||
|
if (opts->mbe_out_f == NULL)
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 0;
|
state->lastp25type = 4;
|
||||||
sprintf (state->fsubtype, "(LDU2) ");
|
sprintf(state->fsubtype, " PDU ");
|
||||||
state->numtdulc = 0;
|
|
||||||
processLDU2 (opts, state);
|
|
||||||
}
|
}
|
||||||
else if (state->lastp25type == 2)
|
// try to guess based on previous frame if unknown type
|
||||||
|
else if (state->lastp25type == 1)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf ("(LDU1) ");
|
printf("(LDU2) ");
|
||||||
}
|
}
|
||||||
if (opts->mbe_out_dir[0] != 0)
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
{
|
{
|
||||||
if (opts->mbe_out_f == NULL)
|
if (opts->mbe_out_f == NULL)
|
||||||
{
|
{
|
||||||
openMbeOutFile (opts, state);
|
openMbeOutFile(opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 0;
|
state->lastp25type = 0;
|
||||||
sprintf (state->fsubtype, "(LDU1) ");
|
sprintf(state->fsubtype, "(LDU2) ");
|
||||||
state->numtdulc = 0;
|
state->numtdulc = 0;
|
||||||
processLDU1 (opts, state);
|
processLDU2(opts, state);
|
||||||
}
|
}
|
||||||
else if (state->lastp25type == 3)
|
else if (state->lastp25type == 2)
|
||||||
{
|
{
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" (TSDU)\n");
|
printf("(LDU1) ");
|
||||||
}
|
}
|
||||||
state->lastp25type = 0;
|
if (opts->mbe_out_dir[0] != 0)
|
||||||
sprintf (state->fsubtype, "(TSDU) ");
|
|
||||||
skipDibit (opts, state, 328);
|
|
||||||
}
|
|
||||||
else if (state->lastp25type == 4)
|
|
||||||
{
|
|
||||||
if (opts->errorbars == 1)
|
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
if (opts->mbe_out_f == NULL)
|
||||||
printf (" (PDU)\n");
|
{
|
||||||
|
openMbeOutFile(opts, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
state->lastp25type = 0;
|
state->lastp25type = 0;
|
||||||
|
sprintf(state->fsubtype, "(LDU1) ");
|
||||||
|
state->numtdulc = 0;
|
||||||
|
processLDU1(opts, state);
|
||||||
}
|
}
|
||||||
else
|
else if (state->lastp25type == 3)
|
||||||
{
|
{
|
||||||
state->lastp25type = 0;
|
if (opts->errorbars == 1)
|
||||||
sprintf (state->fsubtype, " ");
|
|
||||||
if (opts->errorbars == 1)
|
|
||||||
{
|
{
|
||||||
printFrameInfo (opts, state);
|
printFrameInfo(opts, state);
|
||||||
printf (" duid:%s *Unknown DUID*\n", duid);
|
printf(" (TSDU)\n");
|
||||||
|
}
|
||||||
|
state->lastp25type = 0;
|
||||||
|
sprintf(state->fsubtype, "(TSDU) ");
|
||||||
|
skipDibit(opts, state, 328);
|
||||||
|
}
|
||||||
|
else if (state->lastp25type == 4)
|
||||||
|
{
|
||||||
|
if (opts->errorbars == 1)
|
||||||
|
{
|
||||||
|
printFrameInfo(opts, state);
|
||||||
|
printf(" (PDU)\n");
|
||||||
|
}
|
||||||
|
state->lastp25type = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->lastp25type = 0;
|
||||||
|
sprintf(state->fsubtype, " ");
|
||||||
|
if (opts->errorbars == 1)
|
||||||
|
{
|
||||||
|
printFrameInfo(opts, state);
|
||||||
|
printf(" duid:%s *Unknown DUID*\n", duid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ int
|
|||||||
getFrameSync (dsd_opts * opts, dsd_state * state)
|
getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
/* detects frame sync and returns frame type
|
/* detects frame sync and returns frame type
|
||||||
|
* -1 -> thread has to terminate
|
||||||
* 0 = +P25p1
|
* 0 = +P25p1
|
||||||
* 1 = -P25p1
|
* 1 = -P25p1
|
||||||
* 2 = +X2-TDMA (non inverted signal data frame)
|
* 2 = +X2-TDMA (non inverted signal data frame)
|
||||||
@ -107,6 +108,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
{
|
{
|
||||||
t++;
|
t++;
|
||||||
symbol = getSymbol (opts, state, 0);
|
symbol = getSymbol (opts, state, 0);
|
||||||
|
|
||||||
|
if (!state->dsd_running) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
lbuf[lidx] = symbol;
|
lbuf[lidx] = symbol;
|
||||||
state->sbuf[state->sidx] = symbol;
|
state->sbuf[state->sidx] = symbol;
|
||||||
if (lidx == 23)
|
if (lidx == 23)
|
||||||
|
@ -21,8 +21,13 @@
|
|||||||
|
|
||||||
void liveScanner(dsd_opts * opts, dsd_state * state)
|
void liveScanner(dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
while (1) // FIXME: loop while input available
|
while (state->dsd_running) // FIXME: loop while input available
|
||||||
{
|
{
|
||||||
|
// if (pthread_cond_wait(&state->input_ready, &state->input_mutex)) {
|
||||||
|
// fprintf(stderr, "dsd::liveScanner: Error waiting for input ready condition\n");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fprintf (stderr, "dsd::liveScanner: input is ready\n");
|
||||||
noCarrier(opts, state);
|
noCarrier(opts, state);
|
||||||
state->synctype = getFrameSync(opts, state);
|
state->synctype = getFrameSync(opts, state);
|
||||||
|
|
||||||
@ -31,7 +36,7 @@ void liveScanner(dsd_opts * opts, dsd_state * state)
|
|||||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||||
|
|
||||||
while (state->synctype != -1) // TODO: make sure it ends
|
while (state->synctype != -1) // -1 -> exit thread
|
||||||
{
|
{
|
||||||
processFrame(opts, state);
|
processFrame(opts, state);
|
||||||
state->synctype = getFrameSync(opts, state);
|
state->synctype = getFrameSync(opts, state);
|
||||||
@ -42,4 +47,6 @@ void liveScanner(dsd_opts * opts, dsd_state * state)
|
|||||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf (stderr, "dsd::liveScanner: end loop\n");
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,14 @@
|
|||||||
#include "dsd_opts.h"
|
#include "dsd_opts.h"
|
||||||
#include "dsd_state.h"
|
#include "dsd_state.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void liveScanner (dsd_opts * opts, dsd_state * state);
|
void liveScanner (dsd_opts * opts, dsd_state * state);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* INCLUDE_DSD_LIVESCANNER_H_ */
|
#endif /* INCLUDE_DSD_LIVESCANNER_H_ */
|
||||||
|
@ -121,5 +121,16 @@ void initState(dsd_state * state)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
initialize_p25_heuristics(&state->p25_heuristics);
|
initialize_p25_heuristics(&state->p25_heuristics);
|
||||||
|
|
||||||
|
// Initialize the mutexes
|
||||||
|
if (pthread_mutex_init(&state->input_mutex, NULL)) {
|
||||||
|
fprintf(stderr, "dsd::initState: Unable to initialize input mutex\n");
|
||||||
|
}
|
||||||
|
// Initialize the conditions
|
||||||
|
if (pthread_cond_init(&state->input_ready, NULL)) {
|
||||||
|
fprintf(stderr, "dsd::initState: Unable to initialize input condition\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
state->dsd_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#ifndef INCLUDE_DSD_STATE_H_
|
#ifndef INCLUDE_DSD_STATE_H_
|
||||||
#define INCLUDE_DSD_STATE_H_
|
#define INCLUDE_DSD_STATE_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <mbelib.h>
|
#include <mbelib.h>
|
||||||
#include "p25p1_heuristics.h"
|
#include "p25p1_heuristics.h"
|
||||||
|
|
||||||
@ -113,6 +114,11 @@ typedef struct
|
|||||||
int output_num_samples; //!< Number of L+R samples available in the above buffer
|
int output_num_samples; //!< Number of L+R samples available in the above buffer
|
||||||
int output_length; //!< L+R buffer size (fixed)
|
int output_length; //!< L+R buffer size (fixed)
|
||||||
int output_finished; //!< 0: not ready, 1: ready
|
int output_finished; //!< 0: not ready, 1: ready
|
||||||
|
|
||||||
|
pthread_mutex_t input_mutex;
|
||||||
|
pthread_cond_t input_ready;
|
||||||
|
pthread_t dsd_thread;
|
||||||
|
int dsd_running;
|
||||||
} dsd_state;
|
} dsd_state;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -86,40 +86,25 @@ int getSymbol(dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
{
|
{
|
||||||
if (opts->audio_in_fd == -1)
|
if (opts->audio_in_fd == -1)
|
||||||
{
|
{
|
||||||
// Get the next sample from the buffer
|
if (state->input_length == 0) // no input available
|
||||||
sample = state->input_samples[state->input_offset++]; // FIXME: get sample only if available
|
{
|
||||||
|
// wait for input
|
||||||
|
if (pthread_cond_wait(&state->input_ready, &state->input_mutex)) {
|
||||||
|
fprintf(stderr, "dsd::getSymbol: Error waiting for input ready condition\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state->input_offset == state->input_length) // all available samples have been read
|
if (!state->dsd_running) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->input_offset == state->input_length) // finished
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
state->input_length = 0; // states all samples have been consumed
|
||||||
// We've reached the end of the buffer. Wait for more next time.
|
|
||||||
state->input_length = 0;
|
|
||||||
|
|
||||||
state->output_num_samples = state->output_offset;
|
state->output_num_samples = state->output_offset;
|
||||||
|
|
||||||
// GNUradio drivel
|
//fprintf(stderr, "dsd::getSymbol: input processing has finished\n");
|
||||||
// if (state->output_num_samples > state->output_length)
|
|
||||||
// {
|
|
||||||
// state->output_num_samples = state->output_length;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (i = 0; i < state->output_length - state->output_num_samples; i++)
|
|
||||||
// {
|
|
||||||
// state->output_samples[i] = 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (; i < state->output_length; i++)
|
|
||||||
// {
|
|
||||||
// state->output_samples[i] = state->output_buffer[i - (state->output_length - state->output_num_samples)] / 32768.0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// state->output_offset -= state->output_num_samples;
|
|
||||||
//
|
|
||||||
// for (i = 0; i < state->output_offset; i++)
|
|
||||||
// {
|
|
||||||
// state->output_buffer[i] = state->output_buffer[i + state->output_num_samples];
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (state->output_num_samples > state->output_length)
|
if (state->output_num_samples > state->output_length)
|
||||||
{
|
{
|
||||||
@ -135,6 +120,10 @@ int getSymbol(dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
|
|
||||||
state->output_finished = 1;
|
state->output_finished = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = state->input_samples[state->input_offset++]; // get sample and move pointer to next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -83,6 +83,59 @@ void DSDDecoder::setInBuffer(const short *inBuffer)
|
|||||||
|
|
||||||
void DSDDecoder::pushSamples(int nbSamples)
|
void DSDDecoder::pushSamples(int nbSamples)
|
||||||
{
|
{
|
||||||
m_dsdParams.state.input_length = nbSamples;
|
|
||||||
m_dsdParams.state.input_offset = 0;
|
m_dsdParams.state.input_offset = 0;
|
||||||
|
m_dsdParams.state.input_length = nbSamples;
|
||||||
|
|
||||||
|
if (pthread_cond_signal(&m_dsdParams.state.input_ready)) {
|
||||||
|
printf("DSDDecoder::pushSamples: Unable to signal input ready");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSDDecoder::start()
|
||||||
|
{
|
||||||
|
qDebug("DSDDecoder::start: starting");
|
||||||
|
m_dsdParams.state.dsd_running = 1;
|
||||||
|
|
||||||
|
if (pthread_create(&m_dsdParams.state.dsd_thread, NULL, &run_dsd, &m_dsdParams))
|
||||||
|
{
|
||||||
|
qCritical("DSDDecoder::start: Unable to spawn thread");
|
||||||
|
m_dsdParams.state.dsd_running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("DSDDecoder::start: started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSDDecoder::stop()
|
||||||
|
{
|
||||||
|
if (m_dsdParams.state.dsd_running)
|
||||||
|
{
|
||||||
|
qDebug("DSDDecoder::stop: stopping");
|
||||||
|
m_dsdParams.state.dsd_running = 0;
|
||||||
|
char *b;
|
||||||
|
|
||||||
|
if (pthread_cond_signal(&m_dsdParams.state.input_ready)) {
|
||||||
|
printf("DSDDecoder::pushSamples: Unable to signal input ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (pthread_join(m_dsdParams.state.dsd_thread, (void**) &b)) {
|
||||||
|
// qCritical("DSDDecoder::stop: cannot join dsd thread");
|
||||||
|
// }
|
||||||
|
|
||||||
|
qDebug("DSDDecoder::stop: stopped");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("DSDDecoder::stop: not running");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* DSDDecoder::run_dsd(void *arg)
|
||||||
|
{
|
||||||
|
dsd_params *params = (dsd_params *) arg;
|
||||||
|
liveScanner (¶ms->opts, ¶ms->state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@ public:
|
|||||||
void setInBuffer(const short *inBuffer);
|
void setInBuffer(const short *inBuffer);
|
||||||
void pushSamples(int nbSamples); // Push this amount of samples to the DSD decoder thread
|
void pushSamples(int nbSamples); // Push this amount of samples to the DSD decoder thread
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -36,6 +39,8 @@ private:
|
|||||||
dsd_state state;
|
dsd_state state;
|
||||||
} dsd_params;
|
} dsd_params;
|
||||||
|
|
||||||
|
static void* run_dsd(void *arg);
|
||||||
|
|
||||||
dsd_params m_dsdParams;
|
dsd_params m_dsdParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -209,10 +209,12 @@ void DSDDemod::start()
|
|||||||
{
|
{
|
||||||
m_audioFifo.clear();
|
m_audioFifo.clear();
|
||||||
m_phaseDiscri.reset();
|
m_phaseDiscri.reset();
|
||||||
|
m_dsdDecoder.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSDDemod::stop()
|
void DSDDemod::stop()
|
||||||
{
|
{
|
||||||
|
m_dsdDecoder.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSDDemod::handleMessage(const Message& cmd)
|
bool DSDDemod::handleMessage(const Message& cmd)
|
||||||
|
Loading…
Reference in New Issue
Block a user