Add AMBE data bypass processing for Fast Data.

This commit is contained in:
Jonathan Naylor 2018-11-14 10:50:08 +00:00
parent 2a3611e87c
commit 3f179985d1
4 changed files with 50 additions and 28 deletions

View file

@ -1486,4 +1486,5 @@ Support the GPS data from the Kenwood TH-D74.
-------- --------
Add support for external GPS input for mobile systems. Add support for external GPS input for mobile systems.
Add audio bypass processing for fast data mode.

View file

@ -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 * 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 * 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, true, false, true, true, false, true, false, false,
false, true, true, false, true, false, false, false}; false, true, true, false, true, false, false, false};
const unsigned char END_PATTERN_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, const unsigned char END_PATTERN_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const bool END_PATTERN_BITS[] = {true, false, true, false, true, false, true, false, 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,
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, false, true, false, true, false, false,
true, false, true, false, true, true, true, true}; 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_BITS = 72U;
const unsigned int VOICE_FRAME_LENGTH_BYTES = VOICE_FRAME_LENGTH_BITS / 8U; const unsigned int VOICE_FRAME_LENGTH_BYTES = VOICE_FRAME_LENGTH_BITS / 8U;

View file

@ -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 * 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 * it under the terms of the GNU General Public License as published by
@ -95,6 +95,7 @@ m_flag1(0x00U),
m_flag2(0x00U), m_flag2(0x00U),
m_flag3(0x00U), m_flag3(0x00U),
m_restricted(false), m_restricted(false),
m_fastData(false),
m_frames(0U), m_frames(0U),
m_silence(0U), m_silence(0U),
m_errors(0U), m_errors(0U),
@ -582,6 +583,9 @@ void CRepeaterHandler::processRepeater(CHeaderData& header)
m_silence = 0U; m_silence = 0U;
m_errors = 0U; m_errors = 0U;
// Assume voice mode
m_fastData = false;
// An RF header resets the reconnect timer // An RF header resets the reconnect timer
m_linkReconnectTimer.start(); m_linkReconnectTimer.start();
@ -736,32 +740,45 @@ void CRepeaterHandler::processRepeater(CAMBEData& data)
unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES]; unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES];
data.getData(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) // Data signatures only appear at the beginning of the frame
m_silence++; 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 // Don't do AMBE processing when in Fast Data mode
if (m_dtmfEnabled && m_g2Status != G2_XBAND) { if (!m_fastData) {
bool pressed = m_dtmf.decode(buffer, data.isEnd()); if (::memcmp(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES) == 0)
if (pressed) { m_silence++;
// Replace the DTMF with silence
::memcpy(buffer, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);
data.setData(buffer, DV_FRAME_LENGTH_BYTES);
}
bool dtmfDone = m_dtmf.hasCommand(); // Don't do DTMF decoding or blanking if off and not on crossband either
if (dtmfDone) { if (m_dtmfEnabled && m_g2Status != G2_XBAND) {
wxString command = m_dtmf.translate(); 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 bool dtmfDone = m_dtmf.hasCommand();
if (!m_restricted && m_yourCall.Left(4U).IsSameAs(wxT("CQCQ"))) { if (dtmfDone) {
if (command.IsEmpty()) { wxString command = m_dtmf.translate();
// Do nothing
} else if (isCCSCommand(command)) { // Only process the DTMF command if the your call is CQCQCQ and not a restricted user
ccsCommandHandler(command, m_myCall1, wxT("DTMF")); if (!m_restricted && m_yourCall.Left(4U).IsSameAs(wxT("CQCQ"))) {
} else if (command.IsSameAs(wxT(" I"))) { if (command.IsEmpty()) {
m_infoNeeded = true; // Do nothing
} else { } else if (isCCSCommand(command)) {
reflectorCommandHandler(command, m_myCall1, wxT("DTMF")); ccsCommandHandler(command, m_myCall1, wxT("DTMF"));
} else if (command.IsSameAs(wxT(" I"))) {
m_infoNeeded = true;
} else {
reflectorCommandHandler(command, m_myCall1, wxT("DTMF"));
}
} }
} }
} }

View file

@ -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 * 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 * 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_flag2;
unsigned char m_flag3; unsigned char m_flag3;
bool m_restricted; bool m_restricted;
bool m_fastData;
// Statistics // Statistics
unsigned int m_frames; unsigned int m_frames;