From e04d76584e08d5d806c8daf9f6d912171e6ac920 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 6 Sep 2016 19:42:15 +0100 Subject: [PATCH] Configurable DMR jitter buffer. --- Conf.cpp | 8 ++++++++ Conf.h | 2 ++ DMRControl.cpp | 4 ++-- DMRControl.h | 2 +- DMRSlot.cpp | 39 ++++++++++++++++++--------------------- DMRSlot.h | 5 ++++- MMDVM.ini | 1 + MMDVMHost.cpp | 5 ++++- 8 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 43f11e8..4c099bc 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -118,6 +118,7 @@ m_dmrNetworkPort(0U), m_dmrNetworkLocal(0U), m_dmrNetworkPassword(), m_dmrNetworkDebug(false), +m_dmrNetworkJitter(300U), m_dmrNetworkSlot1(true), m_dmrNetworkSlot2(true), m_dmrNetworkRSSI(false), @@ -442,6 +443,8 @@ bool CConf::read() m_dmrNetworkPassword = value; else if (::strcmp(key, "Debug") == 0) m_dmrNetworkDebug = ::atoi(value) == 1; + else if (::strcmp(key, "Jitter") == 0) + m_dmrNetworkJitter = (unsigned int)::atoi(value); else if (::strcmp(key, "Slot1") == 0) m_dmrNetworkSlot1 = ::atoi(value) == 1; else if (::strcmp(key, "Slot2") == 0) @@ -859,6 +862,11 @@ bool CConf::getDMRNetworkDebug() const return m_dmrNetworkDebug; } +unsigned int CConf::getDMRNetworkJitter() const +{ + return m_dmrNetworkJitter; +} + bool CConf::getDMRNetworkSlot1() const { return m_dmrNetworkSlot1; diff --git a/Conf.h b/Conf.h index 14f411d..7c203a2 100644 --- a/Conf.h +++ b/Conf.h @@ -119,6 +119,7 @@ public: unsigned int getDMRNetworkLocal() const; std::string getDMRNetworkPassword() const; bool getDMRNetworkDebug() const; + unsigned int getDMRNetworkJitter() const; bool getDMRNetworkSlot1() const; bool getDMRNetworkSlot2() const; bool getDMRNetworkRSSI() const; @@ -240,6 +241,7 @@ private: unsigned int m_dmrNetworkLocal; std::string m_dmrNetworkPassword; bool m_dmrNetworkDebug; + unsigned int m_dmrNetworkJitter; bool m_dmrNetworkSlot1; bool m_dmrNetworkSlot2; bool m_dmrNetworkRSSI; diff --git a/DMRControl.cpp b/DMRControl.cpp index 32bbf7d..3ba58ee 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -20,7 +20,7 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), @@ -38,7 +38,7 @@ m_lookup(NULL) m_lookup = new CDMRLookup(lookupFile); m_lookup->read(); - CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset); + CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter); } CDMRControl::~CDMRControl() diff --git a/DMRControl.h b/DMRControl.h index 4cf6836..3187828 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -30,7 +30,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF,const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset); + CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF,const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter); ~CDMRControl(); bool processWakeup(const unsigned char* data); diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 2115198..9cea73a 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -44,6 +44,9 @@ unsigned int CDMRSlot::m_hangCount = 3U * 17U; int CDMRSlot::m_rssiMultiplier = 0; int CDMRSlot::m_rssiOffset = 0; +unsigned int CDMRSlot::m_jitterTime = 300U; +unsigned int CDMRSlot::m_jitterSlots = 5U; + unsigned char* CDMRSlot::m_idle = NULL; FLCO CDMRSlot::m_flco1; @@ -73,7 +76,7 @@ m_netN(0U), m_networkWatchdog(1000U, 0U, 1500U), m_rfTimeoutTimer(1000U, timeout), m_netTimeoutTimer(1000U, timeout), -m_packetTimer(1000U, 0U, 300U), +m_packetTimer(1000U, 0U, 50U), m_interval(), m_elapsed(), m_rfFrames(0U), @@ -793,10 +796,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_modem->writeDMRAbort(m_slotNo); } - writeQueueNet(m_idle); - writeQueueNet(m_idle); - writeQueueNet(m_idle); - writeQueueNet(m_idle); + for (unsigned int i = 0U; i < m_jitterSlots; i++) + writeQueueNet(m_idle); writeQueueNet(data); writeQueueNet(data); @@ -963,10 +964,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_modem->writeDMRAbort(m_slotNo); } - writeQueueNet(m_idle); - writeQueueNet(m_idle); - writeQueueNet(m_idle); - writeQueueNet(m_idle); + for (unsigned int i = 0U; i < m_jitterSlots; i++) + writeQueueNet(m_idle); // Create a dummy start frame unsigned char start[DMR_FRAME_LENGTH_BYTES + 2U]; @@ -1026,7 +1025,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_lastFrameValid = true; m_netSeqNo = dmrData.getSeqNo(); m_netN = dmrData.getN(); - m_elapsed.start(); m_netLost = 0U; } else { insertSilence(data, dmrData.getSeqNo()); @@ -1035,6 +1033,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) writeQueueNet(data); m_packetTimer.start(); + m_elapsed.start(); m_netFrames++; @@ -1078,7 +1077,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_lastFrameValid = true; m_netSeqNo = dmrData.getSeqNo(); m_netN = dmrData.getN(); - m_elapsed.start(); m_netLost = 0U; } else { insertSilence(data, dmrData.getSeqNo()); @@ -1087,6 +1085,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) writeQueueNet(data); m_packetTimer.start(); + m_elapsed.start(); m_netFrames++; @@ -1238,14 +1237,10 @@ void CDMRSlot::clock() if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) { unsigned int elapsed = m_elapsed.elapsed(); - unsigned int frames = elapsed / DMR_SLOT_TIME; - - if (frames > m_netFrames) { - unsigned int count = frames - m_netFrames; - if (count > 3U) { - LogDebug("DMR Slot %u, lost audio for 300ms filling in, elapsed: %ums, expected: %u, received: %u", m_slotNo, elapsed, frames, m_netFrames); - insertSilence(count - 1U); - } + if (elapsed >= m_jitterTime) { + LogDebug("DMR Slot %u, lost audio for %ums filling in", m_slotNo, elapsed); + insertSilence(m_jitterSlots); + m_elapsed.start(); } m_packetTimer.start(); @@ -1338,7 +1333,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlacklist, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlacklist, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) { assert(id != 0U); assert(modem != NULL); @@ -1360,8 +1355,10 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHa m_rssiMultiplier = rssiMultiplier; m_rssiOffset = rssiOffset; - m_idle = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U]; + m_jitterTime = jitter; + m_jitterSlots = jitter / DMR_SLOT_TIME; + m_idle = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U]; ::memcpy(m_idle, DMR_IDLE_DATA, DMR_FRAME_LENGTH_BYTES + 2U); // Generate the Slot Type for the Idle frame diff --git a/DMRSlot.h b/DMRSlot.h index ab4b74a..d678a42 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -50,7 +50,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset); + static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); private: unsigned int m_slotNo; @@ -103,6 +103,9 @@ private: static int m_rssiMultiplier; static int m_rssiOffset; + static unsigned int m_jitterTime; + static unsigned int m_jitterSlots; + static unsigned char* m_idle; static FLCO m_flco1; diff --git a/MMDVM.ini b/MMDVM.ini index d4b937f..addf531 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -87,6 +87,7 @@ Debug=0 Enable=1 Address=44.131.4.1 Port=62031 +Jitter=300 # Local=3350 Password=PASSWORD RSSI=0 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 7a3d335..b3bef3b 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -311,6 +311,7 @@ int CMMDVMHost::run() unsigned int txHang = m_conf.getDMRTXHang(); int rssiMultiplier = m_conf.getModemRSSIMultiplier(); int rssiOffset = m_conf.getModemRSSIOffset(); + unsigned int jitter = m_conf.getDMRNetworkJitter(); if (txHang > m_rfModeHang) txHang = m_rfModeHang; @@ -354,7 +355,7 @@ int CMMDVMHost::run() LogInfo(" RSSI Offset: %d", rssiOffset); } - dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookupFile, rssiMultiplier, rssiOffset); + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookupFile, rssiMultiplier, rssiOffset, jitter); m_dmrTXTimer.setTimeout(txHang); } @@ -756,6 +757,7 @@ bool CMMDVMHost::createDMRNetwork() unsigned int id = m_conf.getDMRId(); std::string password = m_conf.getDMRNetworkPassword(); bool debug = m_conf.getDMRNetworkDebug(); + unsigned int jitter = m_conf.getDMRNetworkJitter(); bool slot1 = m_conf.getDMRNetworkSlot1(); bool slot2 = m_conf.getDMRNetworkSlot2(); bool rssi = m_conf.getDMRNetworkRSSI(); @@ -768,6 +770,7 @@ bool CMMDVMHost::createDMRNetwork() LogInfo(" Local: %u", local); else LogInfo(" Local: random"); + LogInfo(" Jitter: %ums", jitter); LogInfo(" Slot 1: %s", slot1 ? "enabled" : "disabled"); LogInfo(" Slot 2: %s", slot2 ? "enabled" : "disabled"); LogInfo(" RSSI: %s", rssi ? "enabled" : "disabled");