You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
OpenAudio_ArduinoLibrary/radioNoiseBlanker_F32.cpp

135 lines
4.8 KiB

/*
* radioNoiseBlanker_F32.cpp
*
* 22 March 2020
* Bob Larkin, in support of the library:
* Chip Audette, OpenAudio, Apr 2017
* -------------------
*
* MIT License, Use at your own risk.
*/
#include "radioNoiseBlanker_F32.h"
void radioNoiseBlanker_F32::update(void) {
audio_block_f32_t *blockIn0=NULL;
audio_block_f32_t *blockOut0=NULL;
audio_block_f32_t *blockIn1=NULL;
audio_block_f32_t *blockOut1=NULL;
uint16_t i;
float32_t absSignal;
// Get input block // <<Writable??
blockIn0 = AudioStream_F32::receiveWritable_f32(0);
if (!blockIn0) {
if(errorPrint) Serial.println("NB-ERR: No input memory");
return;
}
if(twoChannel) {
blockIn1 = AudioStream_F32::receiveWritable_f32(1);
if (!blockIn1) {
AudioStream_F32::release(blockIn0);
if(errorPrint) Serial.println("NB-ERR: No 1 input memory");
return;
}
}
// Are we not noise blanking?
if(! runNB) {
AudioStream_F32::transmit(blockIn0, 0); // send the unchanged data
AudioStream_F32::release (blockIn0);
if(twoChannel) {
AudioStream_F32::transmit(blockIn1, 1);
AudioStream_F32::release (blockIn1);
}
return;
}
// Get a block for the output
blockOut0 = AudioStream_F32::allocate_f32();
if (!blockOut0) { // Didn't have any
if(errorPrint) Serial.println("NB-ERR: No output memory");
AudioStream_F32::release(blockIn0);
if(twoChannel)
AudioStream_F32::release(blockIn1);
return;
}
if(twoChannel) {
blockOut1 = AudioStream_F32::allocate_f32();
if (!blockOut1) { // Didn't have any
if(errorPrint) Serial.println("NB-ERR: No output 1 memory");
AudioStream_F32::release(blockOut0);
AudioStream_F32::release(blockIn0);
AudioStream_F32::release(blockIn1);
return;
}
}
// delayData0[], and 1, always represents 256 points of I-F data. It is pre-gate and includes noise pulses.
// Go through new data, point i at a time, entering to delay line, looking
// for noise pulses. Then in same loop, move data to output buffer blockOut0->data
// based on whether gate is open or not.
for(i=0; i<block_size; i++) {
float32_t datai0 = blockIn0->data[i]; // ith data
delayData0[(i+in_index) & delayBufferMask] = datai0; // Put ith data to circular delay buffer
if(twoChannel) {
float32_t datai1 = blockIn1->data[i];
delayData1[(i+in_index) & delayBufferMask] = datai1;
}
// All control comes from the 0 input (not the 1 input)
absSignal = fabsf(datai0); // Rectified I-F
runningSum += absSignal; // Update by adding one rectified point
runningSum -= delayData0[(i + in_index - RUNNING_SUM_SIZE) & delayBufferMask]; // & subtract one
pulseTime++; // This keeps track of leading and trailing delays of the gate pulse
if (absSignal > (threshold * runningSum)) { // A noise pulse event
if (gateOn == true) { // Signals are flowing, this is beginning of noise pulse event
gateOn = false;
pulseTime = -nAnticipation;
}
else { // gateOn==false, we are already in a noise pulse event
if (pulseTime > 0) { // Waiting for pulse event to end
pulseTime = 0; // Keep waiting
}
}
}
else { // Noise pulse is below threshold
if (gateOn == true) { // Signals are flowing normally
pulseTime = -9999;
}
else { // gateOn==false, we are already in a noise pulse event
if(pulseTime >= nDecay) { // End of a pulse event, turn gate on
gateOn = true;
pulseTime = -9999;
}
}
}
// Ready to enter I-F data to output, offset in time by "nAnticipation"
if (pulseTime == -9999) {
blockOut0->data[i] = delayData0[(256 + i - nAnticipation) & delayBufferMask];
if(twoChannel)
blockOut1->data[i] = delayData1[(256 + i - nAnticipation) & delayBufferMask];
}
else { // -nAnticipation < pulseTime < nDecay i.e., blanked out
blockOut0->data[i] = 0.0f;
if(twoChannel)
blockOut1->data[i] = 0.0f;
}
} // End of loop point by point over input 128 data points
AudioStream_F32::release (blockIn0);
AudioStream_F32::transmit(blockOut0, 0); // send the delayed or blanked data
AudioStream_F32::release (blockOut0);
if(twoChannel) {
AudioStream_F32::release (blockIn1);
AudioStream_F32::transmit(blockOut1, 1); // send second "Q" channel
AudioStream_F32::release (blockOut1);
}
// Update pointer in_index to delay line for next 128 update
in_index = (in_index + block_size) & delayBufferMask;
}