FIR: Initial implementation

This commit is contained in:
Iscle 2022-09-21 03:06:50 +02:00
parent 40981f156e
commit 9e81c8b1d0
2 changed files with 62 additions and 15 deletions

View File

@ -1,7 +1,13 @@
#include <cstring>
#include "FIR.h" #include "FIR.h"
FIR::FIR() { FIR::FIR() {
this->offsetBlock = nullptr;
this->coeffs = nullptr;
this->block = nullptr;
this->coeffsSize = 0;
this->blockLength = 0;
this->hasCoefficients = false;
} }
FIR::~FIR() { FIR::~FIR() {
@ -15,21 +21,63 @@ void FIR::FilterSamples(float *samples, uint32_t size) {
} }
void FIR::FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t channels) { void FIR::FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t channels) {
if (!this->hasCoefficients || size == 0) return;
for (uint32_t i = 0; i < size; i++) {
this->block[i] = samples[i * channels];
}
if (this->blockLength > size) {
memset(&this->block[size], 0, (this->blockLength - size) * sizeof(float));
}
memcpy(&this->offsetBlock[this->coeffsSize - 1], this->block, this->blockLength * sizeof(float));
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;
}
}
if (this->coeffsSize > 1) {
memcpy(&this->offsetBlock[this->coeffsSize - 2], &this->block[this->blockLength - 1], this->blockLength - (this->coeffsSize - 1) * sizeof(float));
}
} }
int FIR::GetBlockLength() { uint32_t FIR::GetBlockLength() {
return this->blockLength; return this->blockLength;
} }
int FIR::LoadCoefficients(const float *coeffs, uint32_t coeffsize, int blockLength) { int FIR::LoadCoefficients(const float *coeffs, uint32_t coeffsSize, uint32_t blockLength) {
return 0; if (coeffs == nullptr || coeffsSize == 0 || blockLength == 0) return 0;
delete this->offsetBlock;
delete this->coeffs;
delete this->block;
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;
} }
void FIR::Reset() { void FIR::Reset() {
if (this->offsetBlock != nullptr && this->coeffsize + this->blockLength > -1) { if (this->offsetBlock != nullptr && this->coeffsSize + this->blockLength > 0) {
for (int i = 0; i < this->coeffsize + this->blockLength; i++) { memset(this->offsetBlock, 0, (this->coeffsSize + this->blockLength) * sizeof(float));
this->offsetBlock[i] = 0;
}
} }
} }

View File

@ -9,18 +9,17 @@ public:
void FilterSamples(float *samples, uint32_t size); void FilterSamples(float *samples, uint32_t size);
void FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t channels); void FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t channels);
int GetBlockLength(); uint32_t GetBlockLength();
int LoadCoefficients(const float *coeffs, uint32_t coeffsize, int blockLength); int LoadCoefficients(const float *coeffs, uint32_t coeffsSize, uint32_t blockLength);
void Reset(); void Reset();
private: private:
int *offsetBlock; float *offsetBlock;
float *coeffs; float *coeffs;
float *block; float *block;
int coeffsize; uint32_t coeffsSize;
int blockLength; uint32_t blockLength;
bool enabled; bool hasCoefficients;
}; };