Allow for two levels of the callsign.

This commit is contained in:
Jonathan Naylor 2020-04-22 22:10:34 +01:00
parent 526a53cd8c
commit f19009b132
9 changed files with 63 additions and 89 deletions

16
FM.cpp
View File

@ -86,10 +86,14 @@ void CFM::samples(q15_t* samples, uint8_t length)
currentSample = 0U;
if (!m_callsign.isRunning())
currentSample += m_rfAck.getAudio();
currentSample += m_rfAck.getHighAudio();
if (!m_rfAck.isRunning())
currentSample += m_callsign.getAudio();
if (!m_rfAck.isRunning()) {
if (m_state == FS_LISTENING)
currentSample += m_callsign.getHighAudio();
else
currentSample += m_callsign.getLowAudio();
}
if (!m_callsign.isRunning() && !m_rfAck.isRunning())
currentSample += m_timeoutTone.getAudio();
@ -114,7 +118,7 @@ void CFM::reset()
m_ctcssRX.reset();
}
uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t level, bool callsignAtStart, bool callsignAtEnd)
uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd)
{
m_callsignAtStart = callsignAtStart;
m_callsignAtEnd = callsignAtEnd;
@ -127,7 +131,7 @@ uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency
m_holdoffTimer.setTimeout(holdoffTime, 0U);
m_callsignTimer.setTimeout(callsignTime, 0U);
return m_callsign.setParams(callsign, speed, frequency, level);
return m_callsign.setParams(callsign, speed, frequency, highLevel, lowLevel);
}
uint8_t CFM::setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_t minTime, uint16_t delay, uint8_t level)
@ -135,7 +139,7 @@ uint8_t CFM::setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_
m_ackDelayTimer.setTimeout(0U, delay);
m_ackMinTimer.setTimeout(minTime, 0U);
return m_rfAck.setParams(rfAck, speed, frequency, level);
return m_rfAck.setParams(rfAck, speed, frequency, level, level);
}
uint8_t CFM::setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime)

2
FM.h
View File

@ -47,7 +47,7 @@ public:
void reset();
uint8_t setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t level, bool callsignAtStart, bool callsignAtEnd);
uint8_t setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd);
uint8_t setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_t minTime, uint16_t delay, uint8_t level);
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime);

View File

@ -115,17 +115,6 @@ uint8_t CFMCTCSSTX::setParams(uint8_t frequency, uint8_t level)
return 0U;
}
void CFMCTCSSTX::getAudio(q15_t* samples, uint8_t length)
{
for (uint8_t i = 0U; i < length; i++) {
samples[i] += m_values[m_n];
m_n++;
if (m_n >= m_length)
m_n = 0U;
}
}
q15_t CFMCTCSSTX::getAudio()
{
q15_t sample = m_values[m_n++];

View File

@ -27,7 +27,6 @@ public:
uint8_t setParams(uint8_t frequency, uint8_t level);
void getAudio(q15_t* samples, uint8_t length);
q15_t getAudio();
private:

View File

@ -84,11 +84,13 @@ m_dotLen(0U),
m_dotPos(0U),
m_audio(NULL),
m_audioLen(0U),
m_audioPos(0U)
m_audioPos(0U),
m_highLevel(0U),
m_lowLevel(0)
{
}
uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t level)
uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t highLevel, uint8_t lowLevel)
{
for (uint8_t i = 0U; text[i] != '\0'; i++) {
for (uint8_t j = 0U; SYMBOL_LIST[j].c != 0U; j++) {
@ -109,58 +111,60 @@ uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency,
}
}
q15_t value = q15_t(level * 128);
m_highLevel = q15_t(highLevel * 128);
m_lowLevel = q15_t(lowLevel * 128);
m_dotLen = 24000U / speed; // In samples
m_audioLen = 24000U / frequency; // In samples
m_audio = new q15_t[m_audioLen];
m_audio = new bool[m_audioLen];
for (uint16_t i = 0U; i < m_audioLen; i++) {
if (i < (m_audioLen / 2U))
m_audio[i] = value;
m_audio[i] = true;
else
m_audio[i] = -value;
m_audio[i] = false;
}
return 0U;
}
void CFMKeyer::getAudio(q15_t* samples, uint8_t length)
{
if (!m_wanted)
return;
for (uint8_t i = 0U; i < length; i++) {
bool b = READ_BIT(m_poBuffer, m_poPos);
if (b)
samples[i] += m_audio[m_audioPos];
m_audioPos++;
if (m_audioPos >= m_audioLen)
m_audioPos = 0U;
m_dotPos++;
if (m_dotPos >= m_dotLen) {
m_dotPos = 0U;
m_poPos++;
if (m_poPos >= m_poLen) {
stop();
return;
}
}
}
}
q15_t CFMKeyer::getAudio()
q15_t CFMKeyer::getHighAudio()
{
q15_t output = 0U;
if (!m_wanted)
return 0U;
return 0U;
bool b = READ_BIT(m_poBuffer, m_poPos);
if (b)
output = m_audio[m_audioPos];
output = m_audio[m_audioPos] ? m_highLevel : -m_highLevel;
m_audioPos++;
if (m_audioPos >= m_audioLen)
m_audioPos = 0U;
m_dotPos++;
if (m_dotPos >= m_dotLen) {
m_dotPos = 0U;
m_poPos++;
if (m_poPos >= m_poLen) {
stop();
return output;
}
}
return output;
}
q15_t CFMKeyer::getLowAudio()
{
q15_t output = 0U;
if (!m_wanted)
return 0U;
bool b = READ_BIT(m_poBuffer, m_poPos);
if (b)
output = m_audio[m_audioPos] ? m_lowLevel : -m_lowLevel;
m_audioPos++;
if (m_audioPos >= m_audioLen)

View File

@ -25,10 +25,10 @@ class CFMKeyer {
public:
CFMKeyer();
uint8_t setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t level);
uint8_t setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t highLevel, uint8_t lowLevel);
void getAudio(q15_t* samples, uint8_t length);
q15_t getAudio();
q15_t getHighAudio();
q15_t getLowAudio();
void start();
void stop();
@ -42,9 +42,11 @@ private:
uint16_t m_poPos;
uint16_t m_dotLen;
uint16_t m_dotPos;
q15_t* m_audio;
bool* m_audio;
uint16_t m_audioLen;
uint16_t m_audioPos;
q15_t m_highLevel;
q15_t m_lowLevel;
};
#endif

View File

@ -39,29 +39,6 @@ void CFMTimeout::setParams(uint8_t level)
m_level = q15_t(level * 128);
}
void CFMTimeout::getAudio(q15_t* samples, uint8_t length)
{
if (!m_running)
return;
for (uint8_t i = 0U; i < length; i++) {
if (m_pos > 12000U) {
q31_t sample = BUSY_AUDIO[m_n] * m_level;
samples[i] = q15_t(__SSAT((sample >> 15), 16));
m_n++;
if (m_n >= BUSY_AUDIO_LEN)
m_n = 0U;
} else {
samples[i] = 0;
}
m_pos++;
if (m_pos >= 24000U)
m_pos = 0U;
}
}
q15_t CFMTimeout::getAudio()
{
q15_t sample = 0U;

View File

@ -30,8 +30,6 @@ public:
void start();
void stop();
void getAudio(q15_t* samples, uint8_t length);
q15_t getAudio();
private:

View File

@ -365,25 +365,26 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
uint8_t CSerialPort::setFMParams1(const uint8_t* data, uint8_t length)
{
if (length < 7U)
if (length < 8U)
return 4U;
uint8_t speed = data[0U];;
uint16_t frequency = data[1U] * 10U;
uint8_t time = data[2U];
uint8_t holdoff = data[3U];
uint8_t level = data[4U];
uint8_t highLevel = data[4U];
uint8_t lowLevel = data[5U];
bool callAtStart = (data[5U] & 0x01U) == 0x01U;
bool callAtEnd = (data[5U] & 0x02U) == 0x02U;
bool callAtStart = (data[6U] & 0x01U) == 0x01U;
bool callAtEnd = (data[6U] & 0x02U) == 0x02U;
char callsign[50U];
uint8_t n = 0U;
for (uint8_t i = 6U; i < length; i++, n++)
for (uint8_t i = 7U; i < length; i++, n++)
callsign[n] = data[i];
callsign[n] = '\0';
return fm.setCallsign(callsign, speed, frequency, time, holdoff, level, callAtStart, callAtEnd);
return fm.setCallsign(callsign, speed, frequency, time, holdoff, highLevel, lowLevel, callAtStart, callAtEnd);
}
uint8_t CSerialPort::setFMParams2(const uint8_t* data, uint8_t length)