mirror of https://github.com/g4klx/MMDVM.git
Implement an efficient FIR filter.
This commit is contained in:
parent
f936bc6fe8
commit
57730d7f81
36
FM.cpp
36
FM.cpp
|
@ -30,8 +30,8 @@ const uint16_t FILTER_COEFFS_LEN = 51U;
|
||||||
|
|
||||||
|
|
||||||
CFM::CFM() :
|
CFM::CFM() :
|
||||||
m_filter(),
|
m_filterBuffer(NULL),
|
||||||
m_filterState(),
|
m_filterPosition(0U),
|
||||||
m_callsign(),
|
m_callsign(),
|
||||||
m_rfAck(),
|
m_rfAck(),
|
||||||
m_ctcssRX(),
|
m_ctcssRX(),
|
||||||
|
@ -48,11 +48,7 @@ m_ackMinTimer(),
|
||||||
m_ackDelayTimer(),
|
m_ackDelayTimer(),
|
||||||
m_hangTimer()
|
m_hangTimer()
|
||||||
{
|
{
|
||||||
::memset(m_filterState, 0x00U, 230U * sizeof(q15_t));
|
m_filterBuffer = new q15_t[FILTER_COEFFS_LEN];
|
||||||
|
|
||||||
m_filter.numTaps = FILTER_COEFFS_LEN;
|
|
||||||
m_filter.pState = m_filterState;
|
|
||||||
m_filter.pCoeffs = FILTER_COEFFS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFM::samples(q15_t* samples, uint8_t length)
|
void CFM::samples(q15_t* samples, uint8_t length)
|
||||||
|
@ -98,8 +94,7 @@ void CFM::samples(q15_t* samples, uint8_t length)
|
||||||
if (!m_callsign.isRunning() && !m_rfAck.isRunning())
|
if (!m_callsign.isRunning() && !m_rfAck.isRunning())
|
||||||
currentSample += m_timeoutTone.getAudio();
|
currentSample += m_timeoutTone.getAudio();
|
||||||
|
|
||||||
//ToDo Filtering
|
currentSample = filter(currentSample);
|
||||||
//::arm_fir_fast_q15(&m_filter, samples + i, ¤tSample, 1);
|
|
||||||
|
|
||||||
currentSample += m_ctcssTX.getAudio();
|
currentSample += m_ctcssTX.getAudio();
|
||||||
|
|
||||||
|
@ -395,3 +390,26 @@ void CFM::beginRelaying()
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_ackMinTimer.start();
|
m_ackMinTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q15_t CFM::filter(q15_t sample)
|
||||||
|
{
|
||||||
|
q15_t output = 0;
|
||||||
|
|
||||||
|
m_filterBuffer[m_filterPosition] = sample;
|
||||||
|
|
||||||
|
uint8_t iTaps = 0U;
|
||||||
|
|
||||||
|
for (int8_t i = m_filterPosition; i >= 0; i--) {
|
||||||
|
q31_t temp = FILTER_COEFFS[iTaps++] * m_filterBuffer[i];
|
||||||
|
output += q15_t(__SSAT((temp >> 15), 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int8_t i = FILTER_COEFFS_LEN - 1; i >= m_filterPosition; i--) {
|
||||||
|
q31_t temp = FILTER_COEFFS[iTaps++] * m_filterBuffer[i];
|
||||||
|
output += q15_t(__SSAT((temp >> 15), 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_filterPosition = (m_filterPosition + 1U) % FILTER_COEFFS_LEN;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
6
FM.h
6
FM.h
|
@ -52,8 +52,8 @@ public:
|
||||||
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime);
|
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
arm_fir_instance_q15 m_filter;
|
q15_t* m_filterBuffer;
|
||||||
q15_t m_filterState[130U]; // NoTaps + BlockSize - 1, 101 + 20 - 1 plus some spare
|
uint8_t m_filterPosition;
|
||||||
CFMKeyer m_callsign;
|
CFMKeyer m_callsign;
|
||||||
CFMKeyer m_rfAck;
|
CFMKeyer m_rfAck;
|
||||||
CFMCTCSSRX m_ctcssRX;
|
CFMCTCSSRX m_ctcssRX;
|
||||||
|
@ -81,6 +81,8 @@ private:
|
||||||
|
|
||||||
void sendCallsign();
|
void sendCallsign();
|
||||||
void beginRelaying();
|
void beginRelaying();
|
||||||
|
|
||||||
|
q15_t filter(q15_t sample);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue