1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-10-01 17:26:40 -04:00

DSDplus library: interim state #1

This commit is contained in:
f4exb 2016-04-10 14:53:40 +02:00
parent 0b58a50ee8
commit dd39afdc64
10 changed files with 749 additions and 37 deletions

View File

@ -17,11 +17,55 @@
#include "dmr_voice.h"
#include "dsd_decoder.h"
namespace DSDPlus
namespace DSDplus
{
/*
* DMR AMBE interleave schedule
*/
const int DSDDMRVoice::rW[36] = {
0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 2,
0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2
};
const int DSDDMRVoice::rX[36] = {
23, 10, 22, 9, 21, 8,
20, 7, 19, 6, 18, 5,
17, 4, 16, 3, 15, 2,
14, 1, 13, 0, 12, 10,
11, 9, 10, 8, 9, 7,
8, 6, 7, 5, 6, 4
};
const int DSDDMRVoice::rY[36] = {
0, 2, 0, 2, 0, 2,
0, 2, 0, 3, 0, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3
};
const int DSDDMRVoice::rZ[36] = {
5, 3, 4, 2, 3, 1,
2, 0, 1, 13, 0, 12,
22, 11, 21, 10, 20, 9,
19, 8, 18, 7, 17, 6,
16, 5, 15, 4, 14, 3,
13, 2, 12, 1, 11, 0
};
DSDDMRVoice::DSDDMRVoice(DSDDecoder *dsdDecoder) :
m_dsdDecoder(dsdDecoder)
m_dsdDecoder(dsdDecoder),
m_symbolIndex(0),
m_dibitIndex(0),
mutecurrentslot(0),
m_slotIndex(-1)
{
}
@ -34,13 +78,307 @@ void DSDDMRVoice::init()
mutecurrentslot = 0;
msMode = 0;
dibit_p = m_dsdDecoder->m_state.dibit_buf_p - 144;
m_slotIndex = 0;
m_majorBlock = 0;
m_symbolIndex = 0;
preProcess();
m_symbolIndex = 144; // reposition symbol index in frame
}
void DSDDMRVoice::process()
{
m_majorBlock = m_symbolIndex / 288; // frame (major block) index
m_dibitIndex = m_symbolIndex % 288; // index of symbol in frame
int symbolIndex = getSlotIndex(m_dibitIndex); // returns symbol index in current slot. Updates m_slotIndex.
switch(m_slotIndex)
{
case 0:
processSlot0(symbolIndex);
break;
case 1:
processSlot1(symbolIndex);
break;
case 2:
processSlot2(symbolIndex);
break;
case 3:
processSlot3(symbolIndex);
break;
case 4:
processSlot4(symbolIndex);
break;
case 5:
processSlot5(symbolIndex);
break;
case 6:
processSlot6(symbolIndex);
break;
case 7:
processSlot7(symbolIndex);
break;
case 8:
processSlot8(symbolIndex);
break;
case 9:
processSlot9(symbolIndex);
break;
default:
break;
}
m_symbolIndex++;
}
void DSDDMRVoice::preProcess()
{
// copy in memory to dibit cache
memcpy((void *) m_dibitCache, (const void *) dibit_p, 144 * sizeof(int));
m_dibitIndex = 54-1; // set cache pointer - skip slot 0
m_dibitIndex += 12; // advance cache pointer
processSlot1(12-1);
m_dibitIndex += 36; // advance cache pointer
processSlot2(36-1);
m_dibitIndex += 18; // advance cache pointer
processSlot3(18-1);
m_dibitIndex += 24; // advance cache pointer
processSlot4(24-1);
m_dibitIndex += 18; // advance cache pointer
processSlot5(18-1);
m_dibitIndex += 36; // advance cache pointer
processSlot6(36-1);
m_dibitIndex += 12; // advance cache pointer
processSlot7(12-1);
m_dibitIndex += 54; // advance cache pointer - skip slot 8
processSlot9(24-1);
m_dibitIndex += 24; // advance cache pointer
processSlot9(24-1);
m_symbolIndex = 144; // advance the main symbol index
}
void DSDDMRVoice::processSlot0(int symbolIndex) // Slot0 is a 54 symbol slot
{
m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it
}
void DSDDMRVoice::processSlot8(int symbolIndex) // Slot8 is a 54 symbol slot
{
m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it
}
void DSDDMRVoice::processSlot1(int symbolIndex) // Slot1 is a 12 symbol slot
{
if (m_majorBlock > 0) // 0:1 reads from 144 in memory dibits. Handled by upper layer.
{
int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
m_dibitCache[m_dibitIndex] = dibit;
}
if (symbolIndex == 12-1) // last symbol -> launch process
{
int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section
// CACH
for (int i = 0; i < 12; i++)
{
int dibit = dibitCache[i];
cachdata[i] = dibit;
if (i == 2)
{
m_dsdDecoder->m_state.currentslot = (1 & (dibit >> 1)); // bit 1
if (m_dsdDecoder->m_state.currentslot == 0)
{
m_dsdDecoder->m_state.slot0light[0] = '[';
m_dsdDecoder->m_state.slot0light[6] = ']';
m_dsdDecoder->m_state.slot1light[0] = ' ';
m_dsdDecoder->m_state.slot1light[6] = ' ';
}
else
{
m_dsdDecoder->m_state.slot1light[0] = '[';
m_dsdDecoder->m_state.slot1light[6] = ']';
m_dsdDecoder->m_state.slot0light[0] = ' ';
m_dsdDecoder->m_state.slot0light[6] = ' ';
}
}
}
cachdata[12] = 0;
m_dibitIndex = 0; // done with the cache -> reset index
}
}
void DSDDMRVoice::processSlot2(int symbolIndex) // Slot2 is a 36 symbol slot
{
if (m_majorBlock > 0) // 0:2 reads from 144 in memory dibits. Handled by upper layer.
{
int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
m_dibitCache[m_dibitIndex] = dibit;
}
if (symbolIndex == 36-1) // last symbol -> launch process
{
int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section
w = rW;
x = rX;
y = rY;
z = rZ;
for (int i = 0; i < 36; i++)
{
int dibit = dibitCache[i];
ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr[*y][*z] = (1 & dibit); // bit 0
w++;
x++;
y++;
z++;
}
}
}
void DSDDMRVoice::processSlot3(int symbolIndex) // Slot3 is a 18 symbol slot
{
if (m_majorBlock > 0) // 0:3 reads from 144 in memory dibits. Handled by upper layer.
{
int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
m_dibitCache[m_dibitIndex] = dibit;
}
if (symbolIndex == 18-1) // last symbol -> launch process
{
int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section
w = rW;
x = rX;
y = rY;
z = rZ;
for (int i = 0; i < 18; i++)
{
int dibit = dibitCache[i];
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
w++;
x++;
y++;
z++;
}
}
}
void DSDDMRVoice::processSlot4(int symbolIndex) // Slot4 is a 24 symbol slot
{
if (m_majorBlock > 0) // 0:3 reads from 144 in memory dibits. Handled by upper layer.
{
int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
m_dibitCache[m_dibitIndex] = dibit;
}
if (symbolIndex == 24-1) // last symbol -> launch process
{
int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section
for (int i = 0; i < 18; i++)
{
int dibit = dibitCache[i];
syncdata[i] = dibit;
sync[i] = (dibit | 1) + 48;
}
sync[24] = 0;
syncdata[24] = 0;
if ((strcmp(sync, DMR_BS_DATA_SYNC) == 0)
|| (strcmp(sync, DMR_MS_DATA_SYNC) == 0))
{
mutecurrentslot = 1;
if (m_dsdDecoder->m_state.currentslot == 0)
{
sprintf(m_dsdDecoder->m_state.slot0light, "[slot0]");
}
else
{
sprintf(m_dsdDecoder->m_state.slot1light, "[slot1]");
}
}
else if ((strcmp(sync, DMR_BS_VOICE_SYNC) == 0)
|| (strcmp(sync, DMR_MS_VOICE_SYNC) == 0))
{
mutecurrentslot = 0;
if (m_dsdDecoder->m_state.currentslot == 0)
{
sprintf(m_dsdDecoder->m_state.slot0light, "[SLOT0]");
}
else
{
sprintf(m_dsdDecoder->m_state.slot1light, "[SLOT1]");
}
}
if ((strcmp(sync, DMR_MS_VOICE_SYNC) == 0)
|| (strcmp(sync, DMR_MS_DATA_SYNC) == 0))
{
msMode = 1;
}
if ((m_majorBlock == 0) && (m_dsdDecoder->m_opts.errorbars == 1))
{
fprintf(stderr, "%s %s VOICE e:", m_dsdDecoder->m_state.slot0light, m_dsdDecoder->m_state.slot1light);
}
}
}
void DSDDMRVoice::processSlot5(int symbolIndex) // Slot5 is a 18 symbol slot
{
int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
m_dibitCache[m_dibitIndex] = dibit;
if (symbolIndex == 18-1) // last symbol -> launch process
{
int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section
for (int i = 0; i < 18; i++)
{
int dibit = dibitCache[i];
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
w++;
x++;
y++;
z++;
}
if (mutecurrentslot == 0)
{
if (m_dsdDecoder->m_state.firstframe == 1)
{ // we don't know if anything received before the first sync after no carrier is valid
m_dsdDecoder->m_state.firstframe = 0;
}
else
{
m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr, 0);
m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr2, 0);
}
}
}
}
} // namespace dsdplus

View File

@ -42,7 +42,7 @@
#ifndef DSDPLUS_DMR_VOICE_H_
#define DSDPLUS_DMR_VOICE_H_
namespace DSDPlus
namespace DSDplus
{
class DSDDecoder;
@ -57,12 +57,82 @@ public:
void process();
private:
int getSlotIndex(int symbolInMajorBlockIndex) //!< calculates current slot index and returns symbol index in the slot
{
if (symbolInMajorBlockIndex < 54)
{
m_slotIndex = 0;
return symbolInMajorBlockIndex;
}
else if (symbolInMajorBlockIndex < 54+12)
{
m_slotIndex = 1;
return symbolInMajorBlockIndex - 54;
}
else if (symbolInMajorBlockIndex < 54+12+36)
{
m_slotIndex = 2;
return symbolInMajorBlockIndex - 54+12;
}
else if (symbolInMajorBlockIndex < 54+12+36+18)
{
m_slotIndex = 3;
return symbolInMajorBlockIndex - 54+12+36;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24)
{
m_slotIndex = 4;
return symbolInMajorBlockIndex - 54+12+36+18;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24+18)
{
m_slotIndex = 5;
return symbolInMajorBlockIndex - 54+12+36+18+24;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36)
{
m_slotIndex = 6;
return symbolInMajorBlockIndex - 54+12+36+18+24+18;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12)
{
m_slotIndex = 7;
return symbolInMajorBlockIndex - 54+12+36+18+24+18+36;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12+54)
{
m_slotIndex = 8;
return symbolInMajorBlockIndex - 54+12+36+18+24+18+36+12;
}
else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12+54+24)
{
m_slotIndex = 9;
return symbolInMajorBlockIndex - 54+12+36+18+24+18+36+12+54;
}
else // cannot go there if using this function in its valid context (input is a remainder of division by 288)
{
m_slotIndex = -1; // invalid slot
return 0;
}
}
void preProcess(); //!< process the 144 in memory dibits in initial phase
void processSlot0(int symbolIndex);
void processSlot1(int symbolIndex);
void processSlot2(int symbolIndex);
void processSlot3(int symbolIndex);
void processSlot4(int symbolIndex);
void processSlot5(int symbolIndex);
void processSlot6(int symbolIndex);
void processSlot7(int symbolIndex);
void processSlot8(int symbolIndex);
void processSlot9(int symbolIndex);
DSDDecoder *m_dsdDecoder;
// extracts AMBE frames from DMR frame
int m_slotIndex; //!< Slot index in major block 0..9 //i;
int m_majorBlock; //!< Major block index 0..5 //j;
int dibit;
int m_symbolIndex; //!< Current absolute symbol index
int m_slotIndex; //!< Slot index in major block 0..9 //i;
int m_majorBlock; //!< Major block index 0..5 //j;
int *dibit_p;
char ambe_fr[4][24];
char ambe_fr2[4][24];
@ -73,8 +143,14 @@ private:
char cachdata[13];
int mutecurrentslot;
int msMode;
int m_dibitCache[54]; // biggest slot is 54 dibits
int m_dibitIndex; // index in dibit cache
int m_dibitCache[288]; // has to handle a complete frame (288 dibits)
int m_dibitIndex; // index in dibit cache
static const int rW[36];
static const int rX[36];
static const int rY[36];
static const int rZ[36];
};
}

View File

@ -17,12 +17,14 @@
#include <stdlib.h>
#include "dsd_decoder.h"
namespace DSDPlus
namespace DSDplus
{
DSDDecoder::DSDDecoder() :
m_symbol(0),
m_fsmState(DSDLookForSync),
m_hasSync(0),
m_mbeDecoder(this),
m_dsdDMRVoice(this)
{
resetSymbol();
@ -36,27 +38,32 @@ DSDDecoder::~DSDDecoder()
void DSDDecoder::run(short sample)
{
if (pushSample(sample, 0))
if (pushSample(sample, 0)) // a symbol is retrieved
{
switch (m_fsmState)
{
case DSDLookForSync:
m_state.synctype = getFrameSync();
m_hasSync = 0;
m_state.synctype = getFrameSync(); // -> -2: still looking, -1 not found, 0 and above: sync found
if (m_state.synctype > -2)
if (m_state.synctype > -2) // -1 and above means syncing has been processed (sync found or not but not searching)
{
// TODO: deal with the noCarrier() call
// recalibrate center/umid/lmid
m_state.center = ((m_state.max) + (m_state.min)) / 2;
m_state.umid = (((m_state.max) - m_state.center) * 5 / 8) + m_state.center;
m_state.lmid = (((m_state.min) - m_state.center) * 5 / 8) + m_state.center;
if (m_state.synctype > -1)
if (m_state.synctype > -1) // 0 and above means a sync has been found
{
processFrame();
m_hasSync = 1;
processFrame(); // process the frame which sync has been found. This will change FSM state
}
else // no sync has been found after searching -> call noCarrier() and go back searching (same FSM state)
{
noCarrier();
}
}
// still searching -> no change in FSM state
break;
case DSDprocessDMRvoice:
m_dsdDMRVoice.process();
@ -111,7 +118,7 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
m_sampleIndex--;
}
else if ((m_state.jitter >= m_state.symbolCenter + 1)
&& (m_state.jitter <= m_state.symbolCenter + 2))
&& (m_state.jitter <= m_state.symbolCenter + 2))
{
m_sampleIndex++;
}
@ -124,7 +131,7 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
m_sampleIndex--; // catch up
}
else if ((m_state.jitter > m_state.symbolCenter)
&& (m_state.jitter < m_state.samplesPerSymbol))
&& (m_state.jitter < m_state.samplesPerSymbol))
{
m_sampleIndex++; // fall back
}
@ -140,8 +147,8 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
{
sample = m_dsdFilters.dmr_filter(sample);
}
else if (m_state.lastsynctype == 8 || m_state.lastsynctype == 9
|| m_state.lastsynctype == 16 || m_state.lastsynctype == 17)
else if (m_state.lastsynctype == 8 || m_state.lastsynctype == 9
|| m_state.lastsynctype == 16 || m_state.lastsynctype == 17)
{
sample = m_dsdFilters.nxdn_filter(sample);
}
@ -174,7 +181,7 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
m_state.jitter = m_sampleIndex;
}
if ((m_opts.symboltiming == 1) && (have_sync == 0)
&& (m_state.lastsynctype != -1))
&& (m_state.lastsynctype != -1))
{
fprintf(stderr, "O");
}
@ -182,13 +189,13 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
else
{
if ((m_opts.symboltiming == 1) && (have_sync == 0)
&& (m_state.lastsynctype != -1))
&& (m_state.lastsynctype != -1))
{
fprintf(stderr, "+");
}
if ((m_state.jitter < 0)
&& (m_state.lastsample < m_state.center)
&& (m_state.rf_mod != 1))
&& (m_state.lastsample < m_state.center)
&& (m_state.rf_mod != 1))
{ // first transition edge
m_state.jitter = m_sampleIndex;
}
@ -211,7 +218,7 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
m_state.jitter = m_sampleIndex;
}
if ((m_opts.symboltiming == 1) && (have_sync == 0)
&& (m_state.lastsynctype != -1))
&& (m_state.lastsynctype != -1))
{
fprintf(stderr, "X");
}
@ -219,13 +226,13 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
else
{
if ((m_opts.symboltiming == 1) && (have_sync == 0)
&& (m_state.lastsynctype != -1))
&& (m_state.lastsynctype != -1))
{
fprintf(stderr, "-");
}
if ((m_state.jitter < 0)
&& (m_state.lastsample > m_state.center)
&& (m_state.rf_mod != 1))
&& (m_state.lastsample > m_state.center)
&& (m_state.rf_mod != 1))
{ // first transition edge
m_state.jitter = m_sampleIndex;
}
@ -290,6 +297,292 @@ bool DSDDecoder::pushSample(short sample, int have_sync)
}
}
int DSDDecoder::getDibit()
{
// returns one dibit value
int i, j, o, symbol;
int sbuf2[128];
int spectrum[64];
char modulation[8];
int lmin, lmax, lsum;
m_state.numflips = 0;
symbol = m_symbol;
m_state.sbuf[m_state.sidx] = m_symbol;
for (i = 0; i < m_opts.ssize; i++)
{
sbuf2[i] = m_state.sbuf[i];
}
qsort(sbuf2, m_opts.ssize, sizeof(int), comp);
// continuous update of min/max in rf_mod=1 (QPSK) mode
// in c4fm min/max must only be updated during sync
if (m_state.rf_mod == 1)
{
lmin = (sbuf2[0] + sbuf2[1]) / 2;
lmax = (sbuf2[(m_opts.ssize - 1)] + sbuf2[(m_opts.ssize - 2)]) / 2;
m_state.minbuf[m_state.midx] = lmin;
m_state.maxbuf[m_state.midx] = lmax;
if (m_state.midx == (m_opts.msize - 1))
{
m_state.midx = 0;
}
else
{
m_state.midx++;
}
lsum = 0;
for (i = 0; i < m_opts.msize; i++)
{
lsum += m_state.minbuf[i];
}
m_state.min = lsum / m_opts.msize;
lsum = 0;
for (i = 0; i < m_opts.msize; i++)
{
lsum += m_state.maxbuf[i];
}
m_state.max = lsum / m_opts.msize;
m_state.center = ((m_state.max) + (m_state.min)) / 2;
m_state.umid = (((m_state.max) - m_state.center) * 5 / 8) + m_state.center;
m_state.lmid = (((m_state.min) - m_state.center) * 5 / 8) + m_state.center;
m_state.maxref = ((m_state.max) * 0.80);
m_state.minref = ((m_state.min) * 0.80);
}
else
{
m_state.maxref = m_state.max;
m_state.minref = m_state.min;
}
if (m_state.sidx == (m_opts.ssize - 1))
{
m_state.sidx = 0;
if (m_opts.datascope == 1)
{
if (m_state.rf_mod == 0)
{
sprintf(modulation, "C4FM");
}
else if (m_state.rf_mod == 1)
{
sprintf(modulation, "QPSK");
}
else if (m_state.rf_mod == 2)
{
sprintf(modulation, "GFSK");
}
for (i = 0; i < 64; i++)
{
spectrum[i] = 0;
}
for (i = 0; i < m_opts.ssize; i++)
{
o = (sbuf2[i] + 32768) / 1024;
spectrum[o]++;
}
if (m_state.symbolcnt > (4800 / m_opts.scoperate))
{
m_state.symbolcnt = 0;
fprintf(stderr, "\n");
fprintf(stderr,
"Demod mode: %s Nac: %4X\n",
modulation, m_state.nac);
fprintf(stderr,
"Frame Type: %s Talkgroup: %7i\n",
m_state.ftype, m_state.lasttg);
fprintf(stderr,
"Frame Subtype: %s Source: %12i\n",
m_state.fsubtype, m_state.lastsrc);
fprintf(stderr,
"TDMA activity: %s %s Voice errors: %s\n",
m_state.slot0light, m_state.slot1light, m_state.err_str);
fprintf(stderr,
"+----------------------------------------------------------------+\n");
for (i = 0; i < 10; i++)
{
fprintf(stderr, "|");
for (j = 0; j < 64; j++)
{
if (i == 0)
{
if ((j == ((m_state.min) + 32768) / 1024)
|| (j == ((m_state.max) + 32768) / 1024))
{
fprintf(stderr, "#");
}
else if ((j == ((m_state.lmid) + 32768) / 1024)
|| (j == ((m_state.umid) + 32768) / 1024))
{
fprintf(stderr, "^");
}
else if (j == (m_state.center + 32768) / 1024)
{
fprintf(stderr, "!");
}
else
{
if (j == 32)
{
fprintf(stderr, "|");
}
else
{
fprintf(stderr, " ");
}
}
}
else
{
if (spectrum[j] > 9 - i)
{
fprintf(stderr, "*");
}
else
{
if (j == 32)
{
fprintf(stderr, "|");
}
else
{
fprintf(stderr, " ");
}
}
}
}
fprintf(stderr, "|\n");
}
fprintf(stderr,
"+----------------------------------------------------------------+\n");
}
}
}
else
{
m_state.sidx++;
}
if (m_state.dibit_buf_p > m_state.dibit_buf + 900000)
{
m_state.dibit_buf_p = m_state.dibit_buf + 200;
}
// determine dibit state
if ((m_state.synctype == 6) || (m_state.synctype == 14)
|| (m_state.synctype == 18))
{
if (m_symbol > m_state.center)
{
*m_state.dibit_buf_p = 1;
m_state.dibit_buf_p++;
return (0);
}
else
{
*m_state.dibit_buf_p = 3;
m_state.dibit_buf_p++;
return (1);
}
}
else if ((m_state.synctype == 7) || (m_state.synctype == 15)
|| (m_state.synctype == 19))
{
if (m_symbol > m_state.center)
{
*m_state.dibit_buf_p = 1;
m_state.dibit_buf_p++;
return (1);
}
else
{
*m_state.dibit_buf_p = 3;
m_state.dibit_buf_p++;
return (0);
}
}
else if ((m_state.synctype == 1) || (m_state.synctype == 3)
|| (m_state.synctype == 5) || (m_state.synctype == 9)
|| (m_state.synctype == 11) || (m_state.synctype == 13))
{
if (m_symbol > m_state.center)
{
if (m_symbol > m_state.umid)
{
*m_state.dibit_buf_p = 1; // store non-inverted values in dibit_buf
m_state.dibit_buf_p++;
return (3);
}
else
{
*m_state.dibit_buf_p = 0;
m_state.dibit_buf_p++;
return (2);
}
}
else
{
if (m_symbol < m_state.lmid)
{
*m_state.dibit_buf_p = 3;
m_state.dibit_buf_p++;
return (1);
}
else
{
*m_state.dibit_buf_p = 2;
m_state.dibit_buf_p++;
return (0);
}
}
}
else
{
if (m_symbol > m_state.center)
{
if (m_symbol > m_state.umid)
{
*m_state.dibit_buf_p = 1;
m_state.dibit_buf_p++;
return (1);
}
else
{
*m_state.dibit_buf_p = 0;
m_state.dibit_buf_p++;
return (0);
}
}
else
{
if (m_symbol < m_state.lmid)
{
*m_state.dibit_buf_p = 3;
m_state.dibit_buf_p++;
return (3);
}
else
{
*m_state.dibit_buf_p = 2;
m_state.dibit_buf_p++;
return (2);
}
}
}
}
void DSDDecoder::resetFrameSync()
{
for (int i = 18; i < 24; i++)

View File

@ -20,6 +20,7 @@
#include "dsd_opts.h"
#include "dsd_state.h"
#include "dsd_filters.h"
#include "dsd_mbe.h"
#include "dmr_voice.h"
/*
@ -57,7 +58,7 @@
#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311"
#define PROVOICE_EA_SYNC "31131311331331111133131311311133"
namespace DSDPlus
namespace DSDplus
{
class DSDDecoder
@ -88,6 +89,7 @@ public:
private:
bool pushSample(short sample, int have_sync); //!< push a new sample into the decoder. Returns true if a new symbol is available
int getDibit(); //!< get dibit from the last retrieved symbol. Returns the dibit as its dibit value: 0,1,2,3
int getFrameSync();
void resetSymbol();
void resetFrameSync();
@ -119,8 +121,11 @@ private:
int m_lsum;
char m_spectrum[64];
int m_t;
int m_hasSync; //!< tells whether we are in synced phase
// Other
DSDFilters m_dsdFilters;
// MBE decoder
DSDMBEDecoder m_mbeDecoder;
// Frame decoders
DSDDMRVoice m_dsdDMRVoice;
};

View File

@ -16,7 +16,7 @@
#include "dsd_filters.h"
namespace DSDPlus
namespace DSDplus
{
// DMR filter

View File

@ -21,7 +21,7 @@
#define NXZEROS 134
namespace DSDPlus
namespace DSDplus
{
class DSDFilters

View File

@ -16,7 +16,7 @@
#include "dsd_opts.h"
namespace DSDPlus
namespace DSDplus
{
DSDOpts::DSDOpts()

View File

@ -17,7 +17,7 @@
#ifndef DSDPLUS_DSD_OPTS_H_
#define DSDPLUS_DSD_OPTS_H_
namespace DSDPlus
namespace DSDplus
{
class DSDOpts

View File

@ -16,7 +16,7 @@
#include "dsd_state.h"
namespace DSDPlus
namespace DSDplus
{
DSDState::DSDState()

View File

@ -22,7 +22,7 @@
#include <string.h>
#include <mbelib.h>
namespace DSDPlus
namespace DSDplus
{
class DSDState