|
|
@ -23,33 +23,33 @@ class AudioFilterFIR_F32 : public AudioStream_F32 |
|
|
|
{ |
|
|
|
{ |
|
|
|
//GUI: inputs:1, outputs:1 //this line used for automatic generation of GUI node
|
|
|
|
//GUI: inputs:1, outputs:1 //this line used for automatic generation of GUI node
|
|
|
|
public: |
|
|
|
public: |
|
|
|
AudioFilterFIR_F32(void): AudioStream_F32(1,inputQueueArray), coeff_p(FIR_F32_PASSTHRU) { |
|
|
|
AudioFilterFIR_F32(void): AudioStream_F32(1,inputQueueArray),
|
|
|
|
} |
|
|
|
coeff_p(FIR_F32_PASSTHRU), n_coeffs(1), configured_block_size(0) { } |
|
|
|
void begin(const float32_t *cp, int n_coeffs) { |
|
|
|
|
|
|
|
|
|
|
|
//initialize the FIR filter by giving it the filter coefficients
|
|
|
|
|
|
|
|
void begin(const float32_t *cp, const int _n_coeffs) { begin(cp, _n_coeffs, AUDIO_BLOCK_SAMPLES); } //assume that the block size is the maximum
|
|
|
|
|
|
|
|
void begin(const float32_t *cp, const int _n_coeffs, const int block_size) { //or, you can provide it with the block size
|
|
|
|
coeff_p = cp; |
|
|
|
coeff_p = cp; |
|
|
|
|
|
|
|
n_coeffs = _n_coeffs; |
|
|
|
|
|
|
|
|
|
|
|
// Initialize FIR instance (ARM DSP Math Library)
|
|
|
|
// Initialize FIR instance (ARM DSP Math Library)
|
|
|
|
if (coeff_p && (coeff_p != FIR_F32_PASSTHRU) && n_coeffs <= FIR_MAX_COEFFS) { |
|
|
|
if (coeff_p && (coeff_p != FIR_F32_PASSTHRU) && n_coeffs <= FIR_MAX_COEFFS) { |
|
|
|
arm_fir_init_f32(&fir_inst, n_coeffs, (float32_t *)coeff_p, &StateF32[0], AUDIO_BLOCK_SAMPLES); |
|
|
|
arm_fir_init_f32(&fir_inst, n_coeffs, (float32_t *)coeff_p, &StateF32[0], block_size); |
|
|
|
//if (arm_fir_init_f32(&fir_inst, n_coeffs, (float32_t *)coeff_p, &StateF32[0], AUDIO_BLOCK_SAMPLES) != ARM_MATH_SUCCESS) {
|
|
|
|
configured_block_size = block_size; |
|
|
|
// n_coeffs must be an even number, 4 or larger
|
|
|
|
|
|
|
|
//coeff_p = NULL;
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
void end(void) { |
|
|
|
void end(void) { coeff_p = NULL; } |
|
|
|
coeff_p = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
virtual void update(void); |
|
|
|
virtual void update(void); |
|
|
|
|
|
|
|
|
|
|
|
void setBlockDC(void) { |
|
|
|
//void setBlockDC(void) {} //helper function that sets this up for a first-order HP filter at 20Hz
|
|
|
|
//helper function that sets this up for a first-order HP filter at 20Hz
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
audio_block_f32_t *inputQueueArray[1]; |
|
|
|
audio_block_f32_t *inputQueueArray[1]; |
|
|
|
|
|
|
|
|
|
|
|
// pointer to current coefficients or NULL or FIR_PASSTHRU
|
|
|
|
// pointer to current coefficients or NULL or FIR_PASSTHRU
|
|
|
|
const float32_t *coeff_p; |
|
|
|
const float32_t *coeff_p; |
|
|
|
|
|
|
|
int n_coeffs; |
|
|
|
|
|
|
|
int configured_block_size; |
|
|
|
|
|
|
|
|
|
|
|
// ARM DSP Math library filter instance
|
|
|
|
// ARM DSP Math library filter instance
|
|
|
|
arm_fir_instance_f32 fir_inst; |
|
|
|
arm_fir_instance_f32 fir_inst; |
|
|
@ -81,6 +81,13 @@ void AudioFilterFIR_F32::update(void) |
|
|
|
// get a block for the FIR output
|
|
|
|
// get a block for the FIR output
|
|
|
|
b_new = AudioStream_F32::allocate_f32(); |
|
|
|
b_new = AudioStream_F32::allocate_f32(); |
|
|
|
if (b_new) { |
|
|
|
if (b_new) { |
|
|
|
|
|
|
|
//check to make sure our FIR instance has the right size
|
|
|
|
|
|
|
|
if (block->length != configured_block_size) { |
|
|
|
|
|
|
|
//doesn't match. re-initialize
|
|
|
|
|
|
|
|
Serial.println("AudioFilterFIR_F32: block size doesn't match. Re-initializing FIR."); |
|
|
|
|
|
|
|
begin(coeff_p, n_coeffs, block->length); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//apply the FIR
|
|
|
|
arm_fir_f32(&fir_inst, (float32_t *)block->data, (float32_t *)b_new->data, block->length); |
|
|
|
arm_fir_f32(&fir_inst, (float32_t *)block->data, (float32_t *)b_new->data, block->length); |
|
|
|
AudioStream_F32::transmit(b_new); // send the FIR output
|
|
|
|
AudioStream_F32::transmit(b_new); // send the FIR output
|
|
|
|
AudioStream_F32::release(b_new); |
|
|
|
AudioStream_F32::release(b_new); |
|
|
|