diff --git a/CHANGES.txt b/CHANGES.txt index d5b4c0e..edb04a7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1486,4 +1486,5 @@ Support the GPS data from the Kenwood TH-D74. -------- Add support for external GPS input for mobile systems. +Add audio bypass processing for fast data mode. diff --git a/Common/DStarDefines.h b/Common/DStarDefines.h index 8ea9ae6..6fbae59 100644 --- a/Common/DStarDefines.h +++ b/Common/DStarDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 by Jonathan Naylor, G4KLX + * Copyright (C) 2009-2015,2018 by Jonathan Naylor, G4KLX * * 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 @@ -31,8 +31,7 @@ const bool DATA_SYNC_BITS[] = {true, false, true, false, true, false, true, true, false, true, true, false, true, false, false, false, true, true, false, true, false, false, false}; -const unsigned char END_PATTERN_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const unsigned char END_PATTERN_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const bool END_PATTERN_BITS[] = {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, @@ -59,6 +58,10 @@ const bool NULL_SLOW_DATA_BITS[] = {false, true, true, false, true, false, fa true, false, false, true, false, true, false, false, true, false, true, false, true, true, true, true}; +const unsigned char KENWOOD_DATA_MODE_BYTES[] = {0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U}; +const unsigned char ICOM_DATA_MODE_BYTES1[] = {0xB2U, 0x4DU, 0x22U, 0x48U, 0xC0U, 0x16U, 0x28U, 0x26U, 0xC8U}; +const unsigned char ICOM_DATA_MODE_BYTES2[] = {0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU}; + const unsigned int VOICE_FRAME_LENGTH_BITS = 72U; const unsigned int VOICE_FRAME_LENGTH_BYTES = VOICE_FRAME_LENGTH_BITS / 8U; diff --git a/Common/RepeaterHandler.cpp b/Common/RepeaterHandler.cpp index 215e0dd..ddfc764 100644 --- a/Common/RepeaterHandler.cpp +++ b/Common/RepeaterHandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2010-2015,2018 by Jonathan Naylor G4KLX * * 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 @@ -95,6 +95,7 @@ m_flag1(0x00U), m_flag2(0x00U), m_flag3(0x00U), m_restricted(false), +m_fastData(false), m_frames(0U), m_silence(0U), m_errors(0U), @@ -582,6 +583,9 @@ void CRepeaterHandler::processRepeater(CHeaderData& header) m_silence = 0U; m_errors = 0U; + // Assume voice mode + m_fastData = false; + // An RF header resets the reconnect timer m_linkReconnectTimer.start(); @@ -736,32 +740,45 @@ void CRepeaterHandler::processRepeater(CAMBEData& data) unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES]; data.getData(buffer, DV_FRAME_MAX_LENGTH_BYTES); - if (::memcmp(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES) == 0) - m_silence++; + // Data signatures only appear at the beginning of the frame + if (!m_fastData && m_frames < 21U) { + if (::memcmp(buffer, KENWOOD_DATA_MODE_BYTES, VOICE_FRAME_LENGTH_BYTES) == 0) + m_fastData = true; + else if (::memcmp(buffer, ICOM_DATA_MODE_BYTES1, VOICE_FRAME_LENGTH_BYTES) == 0) + m_fastData = true; + else if (::memcmp(buffer, ICOM_DATA_MODE_BYTES2, VOICE_FRAME_LENGTH_BYTES) == 0) { + m_fastData = true; + } - // Don't do DTMF decoding or blanking if off and not on crossband either - if (m_dtmfEnabled && m_g2Status != G2_XBAND) { - bool pressed = m_dtmf.decode(buffer, data.isEnd()); - if (pressed) { - // Replace the DTMF with silence - ::memcpy(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES); - data.setData(buffer, DV_FRAME_LENGTH_BYTES); - } + // Don't do AMBE processing when in Fast Data mode + if (!m_fastData) { + if (::memcmp(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES) == 0) + m_silence++; - bool dtmfDone = m_dtmf.hasCommand(); - if (dtmfDone) { - wxString command = m_dtmf.translate(); + // Don't do DTMF decoding or blanking if off and not on crossband either + if (m_dtmfEnabled && m_g2Status != G2_XBAND) { + bool pressed = m_dtmf.decode(buffer, data.isEnd()); + if (pressed) { + // Replace the DTMF with silence + ::memcpy(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES); + data.setData(buffer, DV_FRAME_LENGTH_BYTES); + } - // Only process the DTMF command if the your call is CQCQCQ and not a restricted user - if (!m_restricted && m_yourCall.Left(4U).IsSameAs(wxT("CQCQ"))) { - if (command.IsEmpty()) { - // Do nothing - } else if (isCCSCommand(command)) { - ccsCommandHandler(command, m_myCall1, wxT("DTMF")); - } else if (command.IsSameAs(wxT(" I"))) { - m_infoNeeded = true; - } else { - reflectorCommandHandler(command, m_myCall1, wxT("DTMF")); + bool dtmfDone = m_dtmf.hasCommand(); + if (dtmfDone) { + wxString command = m_dtmf.translate(); + + // Only process the DTMF command if the your call is CQCQCQ and not a restricted user + if (!m_restricted && m_yourCall.Left(4U).IsSameAs(wxT("CQCQ"))) { + if (command.IsEmpty()) { + // Do nothing + } else if (isCCSCommand(command)) { + ccsCommandHandler(command, m_myCall1, wxT("DTMF")); + } else if (command.IsSameAs(wxT(" I"))) { + m_infoNeeded = true; + } else { + reflectorCommandHandler(command, m_myCall1, wxT("DTMF")); + } } } } diff --git a/Common/RepeaterHandler.h b/Common/RepeaterHandler.h index 5871775..05baca2 100644 --- a/Common/RepeaterHandler.h +++ b/Common/RepeaterHandler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2010-2015,2018 by Jonathan Naylor G4KLX * * 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 @@ -208,6 +208,7 @@ private: unsigned char m_flag2; unsigned char m_flag3; bool m_restricted; + bool m_fastData; // Statistics unsigned int m_frames;