diff --git a/dsdplus/dmr_voice.cpp b/dsdplus/dmr_voice.cpp index ec064d72d..2e659c220 100644 --- a/dsdplus/dmr_voice.cpp +++ b/dsdplus/dmr_voice.cpp @@ -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 diff --git a/dsdplus/dmr_voice.h b/dsdplus/dmr_voice.h index a154e63d5..b2ed201da 100644 --- a/dsdplus/dmr_voice.h +++ b/dsdplus/dmr_voice.h @@ -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]; + }; } diff --git a/dsdplus/dsd_decoder.cpp b/dsdplus/dsd_decoder.cpp index 6d7669acc..931ff63cd 100644 --- a/dsdplus/dsd_decoder.cpp +++ b/dsdplus/dsd_decoder.cpp @@ -17,12 +17,14 @@ #include #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++) diff --git a/dsdplus/dsd_decoder.h b/dsdplus/dsd_decoder.h index 8dfe74590..aba6814ca 100644 --- a/dsdplus/dsd_decoder.h +++ b/dsdplus/dsd_decoder.h @@ -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; }; diff --git a/dsdplus/dsd_filters.cpp b/dsdplus/dsd_filters.cpp index 5c1aeffc6..db87ff2b0 100644 --- a/dsdplus/dsd_filters.cpp +++ b/dsdplus/dsd_filters.cpp @@ -16,7 +16,7 @@ #include "dsd_filters.h" -namespace DSDPlus +namespace DSDplus { // DMR filter diff --git a/dsdplus/dsd_filters.h b/dsdplus/dsd_filters.h index 77f83d491..e30ff491f 100644 --- a/dsdplus/dsd_filters.h +++ b/dsdplus/dsd_filters.h @@ -21,7 +21,7 @@ #define NXZEROS 134 -namespace DSDPlus +namespace DSDplus { class DSDFilters diff --git a/dsdplus/dsd_opts.cpp b/dsdplus/dsd_opts.cpp index cecdf45fb..0423d939a 100644 --- a/dsdplus/dsd_opts.cpp +++ b/dsdplus/dsd_opts.cpp @@ -16,7 +16,7 @@ #include "dsd_opts.h" -namespace DSDPlus +namespace DSDplus { DSDOpts::DSDOpts() diff --git a/dsdplus/dsd_opts.h b/dsdplus/dsd_opts.h index 4cea3c200..5e4220479 100644 --- a/dsdplus/dsd_opts.h +++ b/dsdplus/dsd_opts.h @@ -17,7 +17,7 @@ #ifndef DSDPLUS_DSD_OPTS_H_ #define DSDPLUS_DSD_OPTS_H_ -namespace DSDPlus +namespace DSDplus { class DSDOpts diff --git a/dsdplus/dsd_state.cpp b/dsdplus/dsd_state.cpp index e6195b4a3..4348710e2 100644 --- a/dsdplus/dsd_state.cpp +++ b/dsdplus/dsd_state.cpp @@ -16,7 +16,7 @@ #include "dsd_state.h" -namespace DSDPlus +namespace DSDplus { DSDState::DSDState() diff --git a/dsdplus/dsd_state.h b/dsdplus/dsd_state.h index 81b573de8..1436d165a 100644 --- a/dsdplus/dsd_state.h +++ b/dsdplus/dsd_state.h @@ -22,7 +22,7 @@ #include #include -namespace DSDPlus +namespace DSDplus { class DSDState