/* 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; }