/*
Original copyright 2018 Benjamin Vedder benjamin@vedder.se and the VESC Tool project ( https://github.com/vedderb/vesc_tool )
Forked to:
Copyright 2018 Danny Bokma github@diebie.nl (https://github.com/DieBieEngineering/DieBieMS-Tool)
Now forked to:
Copyright 2019 - 2020 Kevin Dionne kevin.dionne@ennoid.me (https://github.com/EnnoidMe/ENNOID-BMS-Tool)
This file is part of ENNOID-BMS Tool.
ENNOID-BMS Tool is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ENNOID-BMS Tool is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "digitalfiltering.h"
#include
#include
DigitalFiltering::DigitalFiltering()
{
}
// Found at http://paulbourke.net/miscellaneous//dft/
// Dir: 0: Forward, != 0: Reverse
// m: 2^m points
// real: Real part
// imag: Imaginary part
void DigitalFiltering::fft(int dir, int m, double *real, double *imag)
{
long n,i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;
// Calculate the number of points
n = 1 << m;
// Do the bit reversal
i2 = n >> 1;
j = 0;
for (i=0;i>= 1;
}
j += k;
}
// Compute the FFT
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l=0;l DigitalFiltering::filterSignal(const QVector &signal, const QVector &filter, bool padAfter)
{
QVector result;
int taps = filter.size();
for (int i = 0;i < taps / 2;i++) {
result.append(0.0);
}
if (!padAfter) {
for (int i = 0;i < taps / 2;i++) {
result.append(0.0);
}
}
for (int i = 0;i < signal.size() - taps;i++) {
double coeff = 0;
for (int j = 0;j < taps;j++) {
coeff += signal[i + j] * filter[j];
}
result.append(coeff);
}
if (padAfter) {
for (int i = 0;i < taps / 2;i++) {
result.append(0.0);
}
}
return result;
}
QVector DigitalFiltering::generateFirFilter(double f_break, int bits, bool useHamming)
{
int taps = 1 << bits;
double imag[taps];
double filter_vector[taps];
for(int i = 0;i < taps;i++) {
if (i < (int)((double)taps * f_break)) {
filter_vector[i] = 1.0;
} else {
filter_vector[i] = 0.0;
}
imag[i] = 0;
}
for (int i = 0;i < taps / 2;i++) {
filter_vector[taps - i - 1] = filter_vector[i];
}
fft(1, bits, filter_vector, imag);
fftshift(filter_vector, taps);
if (useHamming) {
hamming(filter_vector, taps);
}
QVector result;
for(int i = 0;i < taps;i++) {
result.append(filter_vector[i]);
}
return result;
}
QVector DigitalFiltering::fftWithShift(QVector &signal, int resultBits, bool scaleByLen)
{
QVector result;
int taps = signal.size();
int resultLen = 1 << resultBits;
double *signal_vector = new double[resultLen];
double *imag = new double[resultLen];
if (resultLen < taps) {
int sizeDiffHalf = (taps - resultLen) / 2;
signal.remove(0, sizeDiffHalf);
signal.resize(resultLen);
for(int i = 0;i < resultLen;i++) {
signal_vector[i] = signal[i];
imag[i] = 0;
}
} else {
int sizeDiffHalf = (resultLen - taps) / 2;
for(int i = 0;i < resultLen;i++) {
if (i < sizeDiffHalf) {
signal_vector[i] = 0;
} else if (i < (taps + sizeDiffHalf)) {
signal_vector[i] = signal[i - sizeDiffHalf];
} else {
signal_vector[i] = 0;
}
imag[i] = 0;
}
}
fftshift(signal_vector, resultLen);
fft(0, resultBits, signal_vector, imag);
double div_factor = scaleByLen ? (double)taps : 1.0;
for(int i = 0;i < resultLen;i++) {
result.append(fabs(signal_vector[i]) / div_factor);
}
delete[] signal_vector;
delete[] imag;
return result;
}