diff --git a/CosineFilter.c b/CosineFilter.c new file mode 100644 index 0000000..5aeeaf5 --- /dev/null +++ b/CosineFilter.c @@ -0,0 +1,53 @@ +#include + +void CosineFilter_Init(CosineFilter* cosineFilter) +{ + for (int i = 0; i < FILTER_SIZE; i++) + { + cosineFilter->real[i] = 0; + cosineFilter->imag[i] = 0; + } + SlidingBuffer_Init(&cosineFilter->input_buffer); +} +void CosineFilter_Evaluate(CosineFilter* cosineFilter, float newSample) +{ + SlidingBuffer_Write(&cosineFilter->input_buffer, newSample); + + for (int h = 0; h < FILTER_SIZE; h++) + { + float real = 0; + float imag = 0; + + for (int n = 0; n < FILTER_SIZE; n++) + { + real += SlidingBuffer_Read(&cosineFilter->input_buffer, n) * cosf((2 * M_PI * h * n) / FILTER_SIZE); + imag += SlidingBuffer_Read(&cosineFilter->input_buffer, (n + FILTER_SIZE / 4)) * cosf((2 * M_PI * h * n) / FILTER_SIZE); + } + + cosineFilter->real[h] = 2 * real / FILTER_SIZE; + cosineFilter->imag[h] = -2 * imag / FILTER_SIZE; + } +} + +float CosineFilter_GetReal(CosineFilter* cosineFilter, uint32_t harmonicIndex) +{ + return cosineFilter->real[harmonicIndex]; +} + +float CosineFilter_GetImag(CosineFilter* cosineFilter, uint32_t harmonicIndex) +{ + return cosineFilter->imag[harmonicIndex]; +} + +float CosineFilter_GetMagnitude(CosineFilter* cosineFilter, uint32_t harmonicIndex) +{ + return sqrtf( + powf(CosineFilter_GetReal(cosineFilter, harmonicIndex), 2) + + powf(CosineFilter_GetImag(cosineFilter, harmonicIndex), 2) + ); +} + +float CosineFilter_GetPhase(CosineFilter* cosineFilter, uint32_t harmonicIndex) +{ + return atanf(CosineFilter_GetImag(cosineFilter, harmonicIndex) / CosineFilter_GetReal(cosineFilter, harmonicIndex)); +} \ No newline at end of file diff --git a/FourierTransform.c b/FourierTransform.c new file mode 100644 index 0000000..23cc151 --- /dev/null +++ b/FourierTransform.c @@ -0,0 +1,53 @@ +#include + +void FourierTransform_Init(FourierTransform* fourierTransform) +{ + for (int i = 0; i < FILTER_SIZE; i++) + { + fourierTransform->real[i] = 0; + fourierTransform->imag[i] = 0; + } + SlidingBuffer_Init(&fourierTransform->input_buffer); +} +void FourierTransform_Evaluate(FourierTransform* fourierTransform, float newSample) +{ + SlidingBuffer_Write(&fourierTransform->input_buffer, newSample); + + for (int h = 0; h < FILTER_SIZE; h++) + { + float real = 0; + float imag = 0; + + for (int n = 0; n < FILTER_SIZE; n++) + { + real += SlidingBuffer_Read(&fourierTransform->input_buffer, n) * cosf((2 * M_PI * h * n) / FILTER_SIZE); + imag += SlidingBuffer_Read(&fourierTransform->input_buffer, n) * sinf((2 * M_PI * h * n) / FILTER_SIZE); + } + + fourierTransform->real[h] = 2 * real / FILTER_SIZE; + fourierTransform->imag[h] = -2 * imag / FILTER_SIZE; + } +} + +float FourierTransform_GetReal(FourierTransform* fourierTransform, uint32_t harmonicIndex) +{ + return fourierTransform->real[harmonicIndex]; +} + +float FourierTransform_GetImag(FourierTransform* fourierTransform, uint32_t harmonicIndex) +{ + return fourierTransform->imag[harmonicIndex]; +} + +float FourierTransform_GetMagnitude(FourierTransform* fourierTransform, uint32_t harmonicIndex) +{ + return sqrtf( + powf(FourierTransform_GetReal(fourierTransform, harmonicIndex), 2) + + powf(FourierTransform_GetImag(fourierTransform, harmonicIndex), 2) + ); +} + +float FourierTransform_GetPhase(FourierTransform* fourierTransform, uint32_t harmonicIndex) +{ + return atanf(FourierTransform_GetImag(fourierTransform, harmonicIndex) / FourierTransform_GetReal(fourierTransform, harmonicIndex)); +} \ No newline at end of file diff --git a/HalfCycleFourierTransform.c b/HalfCycleFourierTransform.c new file mode 100644 index 0000000..a0af01f --- /dev/null +++ b/HalfCycleFourierTransform.c @@ -0,0 +1,53 @@ +#include + +void HalfCycleFourierTransform_Init(HalfCycleFourierTransform* halfCycleFourierTransform) +{ + for (int i = 0; i < FILTER_SIZE; i++) + { + halfCycleFourierTransform->real[i] = 0; + halfCycleFourierTransform->imag[i] = 0; + } + SlidingBuffer_Init(&halfCycleFourierTransform->input_buffer); +} +void HalfCycleFourierTransform_Evaluate(HalfCycleFourierTransform* halfCycleFourierTransform, float newSample) +{ + SlidingBuffer_Write(&halfCycleFourierTransform->input_buffer, newSample); + + for (int h = 0; h < FILTER_SIZE; h++) + { + float real = 0; + float imag = 0; + + for (int n = FILTER_SIZE / 2; n < FILTER_SIZE; n++) + { + real += SlidingBuffer_Read(&halfCycleFourierTransform->input_buffer, n) * cosf((2 * M_PI * h * n) / FILTER_SIZE); + imag += SlidingBuffer_Read(&halfCycleFourierTransform->input_buffer, n) * sinf((2 * M_PI * h * n) / FILTER_SIZE); + } + + halfCycleFourierTransform->real[h] = 4 * real / FILTER_SIZE; + halfCycleFourierTransform->imag[h] = -4 * imag / FILTER_SIZE; + } +} + +float HalfCycleFourierTransform_GetReal(HalfCycleFourierTransform* halfCycleFourierTransform, uint32_t harmonicIndex) +{ + return halfCycleFourierTransform->real[harmonicIndex]; +} + +float HalfCycleFourierTransform_GetImag(HalfCycleFourierTransform* halfCycleFourierTransform, uint32_t harmonicIndex) +{ + return halfCycleFourierTransform->imag[harmonicIndex]; +} + +float HalfCycleFourierTransform_GetMagnitude(HalfCycleFourierTransform* halfCycleFourierTransform, uint32_t harmonicIndex) +{ + return sqrtf( + powf(HalfCycleFourierTransform_GetReal(halfCycleFourierTransform, harmonicIndex), 2) + + powf(HalfCycleFourierTransform_GetImag(halfCycleFourierTransform, harmonicIndex), 2) + ); +} + +float HalfCycleFourierTransform_GetPhase(HalfCycleFourierTransform* halfCycleFourierTransform, uint32_t harmonicIndex) +{ + return atanf(HalfCycleFourierTransform_GetImag(halfCycleFourierTransform, harmonicIndex) / HalfCycleFourierTransform_GetReal(halfCycleFourierTransform, harmonicIndex)); +} \ No newline at end of file diff --git a/SineFilter.c b/SineFilter.c new file mode 100644 index 0000000..2e09594 --- /dev/null +++ b/SineFilter.c @@ -0,0 +1,54 @@ +#include + +void SineFilter_Init(SineFilter* sineFilter) +{ + for (int i = 0; i < FILTER_SIZE; i++) + { + sineFilter->real[i] = 0; + sineFilter->imag[i] = 0; + } + SlidingBuffer_Init(&sineFilter->input_buffer); +} + +void SineFilter_Evaluate(SineFilter* sineFilter, float newSample) +{ + SlidingBuffer_Write(&sineFilter->input_buffer, newSample); + + for (int h = 0; h < FILTER_SIZE; h++) + { + float real = 0; + float imag = 0; + + for (int n = 0; n < FILTER_SIZE; n++) + { + real += SlidingBuffer_Read(&sineFilter->input_buffer, (n + FILTER_SIZE / 4)) * sinf((2 * M_PI * h * n) / FILTER_SIZE); + imag += SlidingBuffer_Read(&sineFilter->input_buffer, n) * sinf((2 * M_PI * h * n) / FILTER_SIZE); + } + + sineFilter->real[h] = -2 * real / FILTER_SIZE; + sineFilter->imag[h] = -2 * imag / FILTER_SIZE; + } +} + +float SineFilter_GetReal(SineFilter* sineFilter, uint32_t harmonicIndex) +{ + return sineFilter->real[harmonicIndex]; +} + +float SineFilter_GetImag(SineFilter* sineFilter, uint32_t harmonicIndex) +{ + return sineFilter->imag[harmonicIndex]; +} + +float SineFilter_GetMagnitude(SineFilter* sineFilter, uint32_t harmonicIndex) +{ + return sqrtf( + powf(SineFilter_GetReal(sineFilter, harmonicIndex), 2) + + powf(SineFilter_GetImag(sineFilter, harmonicIndex), 2) + ); +} + +float SineFilter_GetPhase(SineFilter* sineFilter, uint32_t harmonicIndex) +{ + return atanf(SineFilter_GetImag(sineFilter, harmonicIndex) / SineFilter_GetReal(sineFilter, harmonicIndex)); +} \ No newline at end of file diff --git a/SlidingBuffer.c b/SlidingBuffer.c new file mode 100644 index 0000000..b147cdf --- /dev/null +++ b/SlidingBuffer.c @@ -0,0 +1,31 @@ +#include + +void SlidingBuffer_Init(SlidingBuffer* buffer) +{ + buffer->head = 0; + buffer->tail = 0; + buffer->isFull = 0; + + for (int i = 0; i < BUFFER_SIZE; ++i) { + buffer->content[i] = 0; + } +} + +void SlidingBuffer_Write(SlidingBuffer* buffer, float data) +{ + buffer->content[buffer->tail] = data; + + if (buffer->isFull) + { + buffer->head = (buffer->head + 1) % BUFFER_SIZE; + } + + buffer->tail = (buffer->tail + 1) % BUFFER_SIZE; + buffer->isFull = buffer->tail == buffer->head; +} + +float SlidingBuffer_Read(SlidingBuffer* buffer, uint32_t index) +{ + uint32_t actualIndex = (buffer->head + index) % BUFFER_SIZE; + return buffer->content[actualIndex]; +} \ No newline at end of file