diff --git a/dsdplus/CMakeLists.txt b/dsdplus/CMakeLists.txt
index 9c2eb7f5d..8d6e1b2ce 100644
--- a/dsdplus/CMakeLists.txt
+++ b/dsdplus/CMakeLists.txt
@@ -7,6 +7,7 @@ set(dsdplus_SOURCES
dsd_mbe.cpp
dsd_opts.cpp
dsd_state.cpp
+ dstar.cpp
)
set(dsdplus_HEADERS
@@ -16,6 +17,7 @@ set(dsdplus_HEADERS
dsd_mbe.h
dsd_opts.h
dsd_state.h
+ dstar.h
)
include_directories(
diff --git a/dsdplus/dmr_data.cpp b/dsdplus/dmr_data.cpp
index 170e83ba9..3045b71c5 100644
--- a/dsdplus/dmr_data.cpp
+++ b/dsdplus/dmr_data.cpp
@@ -212,7 +212,7 @@ void DSDDMRData::preProcess()
if (m_dsdDecoder->m_opts.errorbars == 1)
{
- printf("%s %s ", m_dsdDecoder->m_state.slot0light, m_dsdDecoder->m_state.slot1light);
+ fprintf(m_dsdDecoder->m_state.logfile, "%s %s ", m_dsdDecoder->m_state.slot0light, m_dsdDecoder->m_state.slot1light);
}
}
diff --git a/dsdplus/dsd_decoder.cpp b/dsdplus/dsd_decoder.cpp
index 03d7cdd99..666403bdf 100644
--- a/dsdplus/dsd_decoder.cpp
+++ b/dsdplus/dsd_decoder.cpp
@@ -26,7 +26,8 @@ DSDDecoder::DSDDecoder() :
m_hasSync(0),
m_mbeDecoder(this),
m_dsdDMRVoice(this),
- m_dsdDMRData(this)
+ m_dsdDMRData(this),
+ m_dsdDstar(this)
{
resetSymbol();
resetFrameSync();
@@ -71,6 +72,15 @@ void DSDDecoder::run(short sample)
case DSDprocessDMRvoice:
m_dsdDMRVoice.process();
break;
+ case DSDprocessDMRdata:
+ m_dsdDMRData.process();
+ break;
+ case DSDprocessDSTAR:
+ m_dsdDstar.process();
+ break;
+ case DSDprocessDSTAR_HD:
+ m_dsdDstar.processHD();
+ break;
default:
break;
}
@@ -1646,6 +1656,7 @@ void DSDDecoder::processFrame()
m_state.nac = 0;
sprintf(m_state.fsubtype, " VOICE ");
+ m_dsdDstar.init();
m_fsmState = DSDprocessDSTAR;
}
else if ((m_state.synctype == 18) || (m_state.synctype == 19))
@@ -1665,6 +1676,7 @@ void DSDDecoder::processFrame()
m_state.nac = 0;
sprintf(m_state.fsubtype, " DATA ");
+ m_dsdDstar.init();
m_fsmState = DSDprocessDSTAR_HD;
}
else
diff --git a/dsdplus/dsd_decoder.h b/dsdplus/dsd_decoder.h
index e3728b663..9684d2492 100644
--- a/dsdplus/dsd_decoder.h
+++ b/dsdplus/dsd_decoder.h
@@ -23,6 +23,7 @@
#include "dsd_mbe.h"
#include "dmr_voice.h"
#include "dmr_data.h"
+#include "dstar.h"
/*
* Frame sync patterns
@@ -67,6 +68,7 @@ class DSDDecoder
friend class DSDMBEDecoder;
friend class DSDDMRVoice;
friend class DSDDMRData;
+ friend class DSDDstar;
public:
typedef enum
{
@@ -132,6 +134,7 @@ private:
// Frame decoders
DSDDMRVoice m_dsdDMRVoice;
DSDDMRData m_dsdDMRData;
+ DSDDstar m_dsdDstar;
};
} // namespace dsdplus
diff --git a/dsdplus/dstar.cpp b/dsdplus/dstar.cpp
new file mode 100644
index 000000000..a638e2ace
--- /dev/null
+++ b/dsdplus/dstar.cpp
@@ -0,0 +1,229 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2016 Edouard Griffiths, F4EXB. //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include "dstar.h"
+#include "dsd_decoder.h"
+
+namespace DSDplus
+{
+
+const int DSDDstar::dW[72] = {
+
+ // 0-11
+ 0, 0,
+ 3, 2,
+ 1, 1,
+ 0, 0,
+ 1, 1,
+ 0, 0,
+
+ // 12-23
+ 3, 2,
+ 1, 1,
+ 3, 2,
+ 1, 1,
+ 0, 0,
+ 3, 2,
+
+ // 24-35
+ 0, 0,
+ 3, 2,
+ 1, 1,
+ 0, 0,
+ 1, 1,
+ 0, 0,
+
+ // 36-47
+ 3, 2,
+ 1, 1,
+ 3, 2,
+ 1, 1,
+ 0, 0,
+ 3, 2,
+
+ // 48-59
+ 0, 0,
+ 3, 2,
+ 1, 1,
+ 0, 0,
+ 1, 1,
+ 0, 0,
+
+ // 60-71
+ 3, 2,
+ 1, 1,
+ 3, 3,
+ 2, 1,
+ 0, 0,
+ 3, 3,
+};
+
+const int DSDDstar::dX[72] = {
+
+ // 0-11
+ 10, 22,
+ 11, 9,
+ 10, 22,
+ 11, 23,
+ 8, 20,
+ 9, 21,
+
+ // 12-23
+ 10, 8,
+ 9, 21,
+ 8, 6,
+ 7, 19,
+ 8, 20,
+ 9, 7,
+
+ // 24-35
+ 6, 18,
+ 7, 5,
+ 6, 18,
+ 7, 19,
+ 4, 16,
+ 5, 17,
+
+ // 36-47
+ 6, 4,
+ 5, 17,
+ 4, 2,
+ 3, 15,
+ 4, 16,
+ 5, 3,
+
+ // 48-59
+ 2, 14,
+ 3, 1,
+ 2, 14,
+ 3, 15,
+ 0, 12,
+ 1, 13,
+
+ // 60-71
+ 2, 0,
+ 1, 13,
+ 0, 12,
+ 10, 11,
+ 0, 12,
+ 1, 13,
+};
+
+DSDDstar::DSDDstar(DSDDecoder *dsdDecoder) :
+ m_dsdDecoder(dsdDecoder)
+{
+}
+
+DSDDstar::~DSDDstar()
+{
+}
+
+void DSDDstar::init()
+{
+ if (m_dsdDecoder->m_opts.errorbars == 1) {
+ fprintf(m_dsdDecoder->m_state.logfile, "e:");
+ }
+
+ if (m_dsdDecoder->m_state.synctype == 18) {
+ framecount = 0;
+ m_dsdDecoder->m_state.synctype = 6;
+ } else if (m_dsdDecoder->m_state.synctype == 19) {
+ framecount = 0;
+ m_dsdDecoder->m_state.synctype = 7;
+ } else {
+ framecount = 1; //just saw a sync frame; there should be 20 not 21 till the next
+ }
+
+ sync_missed = 0;
+ bitbuffer = 0;
+ m_symbolIndex = 0;
+}
+
+void DSDDstar::initVoiceFrame()
+{
+ memset(ambe_fr, 0, 96);
+ // voice frame
+ w = dW;
+ x = dX;
+}
+
+void DSDDstar::process()
+{
+ if (m_symbolIndex < 72) // voice frame
+ {
+ if (m_symbolIndex == 0) {
+ initVoiceFrame();
+ }
+
+ processVoice();
+ }
+ else if (m_symbolIndex < 97) // data frame
+ {
+
+ }
+
+ m_symbolIndex++;
+}
+
+void DSDDstar::processHD()
+{
+}
+
+void DSDDstar::processVoice()
+{
+ int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache
+ m_dibitCache[m_symbolIndex] = dibit;
+
+ if (m_symbolIndex == 72-1) // last dibit in voice frame
+ {
+ for (int i = 0; i < 72; i++)
+ {
+ int dibit = m_dibitCache[i];
+
+ bitbuffer <<= 1;
+
+ if (dibit == 1) {
+ bitbuffer |= 0x01;
+ }
+
+ if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468)
+ {
+ // we're slipping bits
+ fprintf(m_dsdDecoder->m_state.logfile, "sync in voice after i=%d, restarting\n", i);
+ //ugh just start over
+ i = 0;
+ w = dW;
+ x = dX;
+ framecount = 1;
+ continue;
+ }
+
+ ambe_fr[*w][*x] = (1 & dibit);
+ w++;
+ x++;
+ }
+
+ m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr, 0);
+ }
+}
+
+void DSDDstar::processData()
+{
+
+}
+
+} // namespace DSDplus
diff --git a/dsdplus/dstar.h b/dsdplus/dstar.h
new file mode 100644
index 000000000..b5f50143e
--- /dev/null
+++ b/dsdplus/dstar.h
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2016 Edouard Griffiths, F4EXB. //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef DSDPLUS_DSTAR_H_
+#define DSDPLUS_DSTAR_H_
+
+namespace DSDplus
+{
+
+class DSDDecoder;
+
+class DSDDstar
+{
+public:
+ DSDDstar(DSDDecoder *dsdDecoder);
+ ~DSDDstar();
+
+ void init();
+ void process();
+ void processHD();
+
+private:
+ void initVoiceFrame();
+ void processVoice();
+ void processData();
+
+ DSDDecoder *m_dsdDecoder;
+ int m_symbolIndex; //!< Current symbol index
+ int m_dibitCache[97]; // has to handle a voice + data frame (97 dibits)
+ int m_dibitIndex; // index in dibit cache
+
+ // DSTAR
+ char ambe_fr[4][24];
+ unsigned char data[9];
+ unsigned int bits[4];
+ int framecount;
+ int sync_missed;
+ unsigned char slowdata[4];
+ unsigned int bitbuffer;
+ const int *w, *x;
+
+ // DSTAR-HD
+ int radioheaderbuffer[660];
+
+ // constants
+ static const int dW[72];
+ static const int dX[72];
+};
+
+} // namespace DSDplus
+
+#endif /* DSDPLUS_DSTAR_H_ */