Make sure downsampler always buffers 22 samples at a time

This commit is contained in:
Geoffrey Merck 2020-05-12 14:15:04 +02:00
parent 0fad84b46d
commit a0a3080da2
4 changed files with 77 additions and 44 deletions

102
FM.cpp
View File

@ -20,8 +20,8 @@
#include "Globals.h"
#include "FM.h"
const uint16_t FM_TX_BLOCK_SIZE = 127U;
const uint16_t FM_SERIAL_BLOCK_SIZE = 127U;
const uint16_t FM_TX_BLOCK_SIZE = 400U;
const uint16_t FM_SERIAL_BLOCK_SIZE = 126U;
CFM::CFM() :
m_callsign(),
@ -50,7 +50,7 @@ m_useCOS(true),
m_cosInvert(false),
m_rfAudioBoost(1U),
m_extAudioBoost(1U),
m_downsampler(1200U),// 100 ms of audio
m_downsampler(400U),// 100 ms of audio
m_extEnabled(false),
m_rxLevel(1),
m_inputRFRB(4800U), // 200ms of audio
@ -117,10 +117,6 @@ void CFM::samples(bool cos, q15_t* samples, uint8_t length)
// Only let RF audio through when relaying RF audio
if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF || m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) {
currentSample = m_blanking.process(currentSample);
if (m_extEnabled && (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF))
m_downsampler.addSample(currentSample);
currentSample *= currentBoost;
} else {
currentSample = 0;
@ -153,44 +149,75 @@ void CFM::samples(bool cos, q15_t* samples, uint8_t length)
void CFM::process()
{
uint16_t space = io.getSpace() - 2U;
uint16_t length = m_outputRFRB.getData();
if (space > 2 && length >= FM_TX_BLOCK_SIZE ) {
if(length > FM_TX_BLOCK_SIZE)
length = FM_TX_BLOCK_SIZE;
uint16_t txLength = m_outputRFRB.getData();
if (space > 2 && txLength >= FM_TX_BLOCK_SIZE ) {
if(txLength > FM_TX_BLOCK_SIZE)
txLength = FM_TX_BLOCK_SIZE;
if(space > FM_TX_BLOCK_SIZE)
space = FM_TX_BLOCK_SIZE;
if(length > space)
length = space;
if(txLength > space)
txLength = space;
q15_t samples[FM_TX_BLOCK_SIZE];
for(uint16_t i = 0U; i < length; i++) {
for (uint16_t i = 0U; i < txLength; i++) {
q15_t sample = 0;
m_outputRFRB.get(sample);
samples[i] = sample;
}
io.write(STATE_FM, samples, length);
}
if (m_extEnabled) {
length = m_downsampler.getData();
//Write audio to serial
if (length >= FM_SERIAL_BLOCK_SIZE) {
if(length > FM_SERIAL_BLOCK_SIZE)
length = FM_SERIAL_BLOCK_SIZE;
uint8_t serialSamples[FM_SERIAL_BLOCK_SIZE];
for(uint16_t i = 0U; i < length; i++) {
uint8_t serialSample = 0U;
m_downsampler.getPackedData(serialSample);
serialSamples[i] = serialSample;
if(m_extEnabled && (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF)) {
m_downsampler.addSample(sample);
uint16_t downSamplerLength = m_downsampler.getData();
if(downSamplerLength >= FM_SERIAL_BLOCK_SIZE) {
TSamplePairPack serialSamples[FM_SERIAL_BLOCK_SIZE];
for(uint16_t j = 0U; j < downSamplerLength; j++) {
m_downsampler.getPackedData(serialSamples[j]);
}
serial.writeFMData((uint8_t*)serialSamples, txLength * sizeof(TSamplePairPack));
}
}
serial.writeFMData(serialSamples, length);
}
io.write(STATE_FM, samples, txLength);
}
// if (space > 2 && length >= FM_TX_BLOCK_SIZE ) {
// if(length > FM_TX_BLOCK_SIZE)
// length = FM_TX_BLOCK_SIZE;
// if(space > FM_TX_BLOCK_SIZE)
// space = FM_TX_BLOCK_SIZE;
// if(length > space)
// length = space;
// q15_t samples[FM_TX_BLOCK_SIZE];
// for(uint16_t i = 0U; i < length; i++) {
// q15_t sample = 0;
// m_outputRFRB.get(sample);
// samples[i] = sample;
// }
// io.write(STATE_FM, samples, length);
// }
// if (m_extEnabled) {
// length = m_downsampler.getData();
// //Write audio to serial
// if (length >= FM_SERIAL_BLOCK_SIZE) {
// if(length > FM_SERIAL_BLOCK_SIZE)
// length = FM_SERIAL_BLOCK_SIZE;
// TSamplePairPack serialSamples[FM_SERIAL_BLOCK_SIZE];
// for(uint16_t i = 0U; i < length; i++) {
// TSamplePairPack samplePair = {0U, 0U, 0U};
// m_downsampler.getPackedData(samplePair);
// serialSamples[i] = samplePair;
// }
// serial.writeFMData((uint8_t*)&serialSamples, length * sizeof(TSamplePairPack));
// }
// }
}
void CFM::reset()
@ -338,7 +365,7 @@ void CFM::clock(uint8_t length)
m_statusTimer.clock(length);
if (m_statusTimer.isRunning() && m_statusTimer.hasExpired()) {
serial.writeFMStatus();
serial.writeFMStatus(false);
m_statusTimer.start();
}
}
@ -364,7 +391,7 @@ void CFM::listeningState(bool validRFSignal, bool validExtSignal)
m_callsignTimer.start();
m_statusTimer.start();
serial.writeFMStatus();
serial.writeFMStatus(true);
} else if (validExtSignal) {
if (m_kerchunkTimer.getTimeout() > 0U) {
DEBUG1("State to KERCHUNK_EXT");
@ -384,7 +411,7 @@ void CFM::listeningState(bool validRFSignal, bool validExtSignal)
m_callsignTimer.start();
m_statusTimer.start();
serial.writeFMStatus();
serial.writeFMStatus(false);
}
}
@ -729,3 +756,4 @@ void CFM::insertDelay(uint16_t ms)
for (uint32_t i = 0U; i < nSamples; i++)
m_inputRFRB.put(0);
}

1
FM.h
View File

@ -120,7 +120,6 @@ private:
void beginRelaying();
void insertDelay(uint16_t ms);
void insertSilence(uint16_t ms);
};
#endif

View File

@ -43,9 +43,9 @@ void CFMDownsampler::addSample(q15_t sample)
m_samplePack |= uint32_t(sample);
//we did not use MSB; skip it
m_ringBuffer.put(m_samplePackPointer[1U]);
m_ringBuffer.put(m_samplePackPointer[2U]);
m_ringBuffer.put(m_samplePackPointer[3U]);
TSamplePairPack pair{m_samplePackPointer[1U], m_samplePackPointer[2U], m_samplePackPointer[3U]};
m_ringBuffer.put(pair);
m_samplePack = 0;//reset the sample pack
}
@ -64,7 +64,7 @@ void CFMDownsampler::addSample(q15_t sample)
m_downSampleIndex = 0U;
}
bool CFMDownsampler::getPackedData(uint8_t& data)
bool CFMDownsampler::getPackedData(TSamplePairPack& data)
{
return m_ringBuffer.get(data);
}

View File

@ -23,16 +23,22 @@
#include "Config.h"
#include "RingBuffer.h"
struct TSamplePairPack {
uint8_t byte0;
uint8_t byte1;
uint8_t byte2;
};
class CFMDownsampler {
public:
CFMDownsampler(uint16_t length);
void addSample(q15_t sample);
bool getPackedData(uint8_t& data);
bool getPackedData(TSamplePairPack& data);
uint16_t getData();
void reset();
private:
CRingBuffer<uint8_t> m_ringBuffer;
CRingBuffer<TSamplePairPack> m_ringBuffer;
uint32_t m_samplePack;
uint32_t *m_samplePackPointer;