2022-09-21 03:06:50 +02:00
|
|
|
#include <cstring>
|
2022-09-16 03:16:58 +02:00
|
|
|
#include "FIR.h"
|
|
|
|
|
|
|
|
FIR::FIR() {
|
2022-09-21 03:06:50 +02:00
|
|
|
this->offsetBlock = nullptr;
|
|
|
|
this->coeffs = nullptr;
|
|
|
|
this->block = nullptr;
|
|
|
|
this->coeffsSize = 0;
|
|
|
|
this->blockLength = 0;
|
|
|
|
this->hasCoefficients = false;
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
FIR::~FIR() {
|
2022-10-06 03:37:22 +02:00
|
|
|
delete[] this->offsetBlock;
|
|
|
|
delete[] this->coeffs;
|
|
|
|
delete[] this->block;
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
|
|
|
|
2022-09-19 04:30:42 +02:00
|
|
|
void FIR::FilterSamples(float *samples, uint32_t size) {
|
2022-09-16 03:16:58 +02:00
|
|
|
this->FilterSamplesInterleaved(samples, size, 1);
|
|
|
|
}
|
|
|
|
|
2022-09-19 04:30:07 +02:00
|
|
|
void FIR::FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t channels) {
|
2022-09-21 03:06:50 +02:00
|
|
|
if (!this->hasCoefficients || size == 0) return;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < size; i++) {
|
|
|
|
this->block[i] = samples[i * channels];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->blockLength > size) {
|
2022-10-11 00:36:38 +02:00
|
|
|
memset(this->block + size, 0, (this->blockLength - size) * sizeof(float));
|
2022-09-21 03:06:50 +02:00
|
|
|
}
|
|
|
|
|
2022-10-11 00:36:38 +02:00
|
|
|
memcpy(this->offsetBlock + this->coeffsSize - 1, this->block, this->blockLength * sizeof(float));
|
2022-09-21 03:06:50 +02:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < this->blockLength; i++) {
|
|
|
|
float sample = 0.0f;
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < this->coeffsSize; j++) {
|
|
|
|
sample += this->coeffs[j] * this->offsetBlock[this->coeffsSize + i - 1 - j];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < size) {
|
|
|
|
samples[channels * i] = sample;
|
|
|
|
}
|
|
|
|
}
|
2022-09-16 03:16:58 +02:00
|
|
|
|
2022-09-21 03:06:50 +02:00
|
|
|
if (this->coeffsSize > 1) {
|
2022-10-11 00:36:38 +02:00
|
|
|
memcpy(this->offsetBlock + this->coeffsSize - 2, this->block + this->blockLength - 1, this->blockLength - (this->coeffsSize - 1) * sizeof(float));
|
2022-09-21 03:06:50 +02:00
|
|
|
}
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
|
|
|
|
2022-09-21 03:06:50 +02:00
|
|
|
uint32_t FIR::GetBlockLength() {
|
2022-09-16 03:16:58 +02:00
|
|
|
return this->blockLength;
|
|
|
|
}
|
|
|
|
|
2022-09-21 03:06:50 +02:00
|
|
|
int FIR::LoadCoefficients(const float *coeffs, uint32_t coeffsSize, uint32_t blockLength) {
|
|
|
|
if (coeffs == nullptr || coeffsSize == 0 || blockLength == 0) return 0;
|
|
|
|
|
2022-10-06 03:37:22 +02:00
|
|
|
delete[] this->offsetBlock;
|
|
|
|
delete[] this->coeffs;
|
|
|
|
delete[] this->block;
|
2022-09-21 03:06:50 +02:00
|
|
|
|
|
|
|
this->offsetBlock = new float[coeffsSize + blockLength + 1];
|
|
|
|
this->coeffs = new float[coeffsSize];
|
|
|
|
this->block = new float[blockLength];
|
|
|
|
|
|
|
|
this->coeffsSize = coeffsSize;
|
|
|
|
this->blockLength = blockLength;
|
|
|
|
|
|
|
|
memcpy(this->coeffs, coeffs, coeffsSize * sizeof(float));
|
|
|
|
|
|
|
|
this->Reset();
|
|
|
|
this->hasCoefficients = true;
|
|
|
|
|
|
|
|
return 1;
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void FIR::Reset() {
|
2022-09-21 03:06:50 +02:00
|
|
|
if (this->offsetBlock != nullptr && this->coeffsSize + this->blockLength > 0) {
|
|
|
|
memset(this->offsetBlock, 0, (this->coeffsSize + this->blockLength) * sizeof(float));
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
|
|
|
}
|