Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //-----Начало .h файла-----//
- #pragma once
- #include <QObject>
- #include <mutex>
- #include<complex>
- #include "include/fftw3.h"
- #define FFT_PI 3.1415926535897932384626433832795
- class MyFFT : public QObject
- {
- Q_OBJECT
- public:
- MyFFT(int sizeFFT, QObject *parent = nullptr);
- int sizeFFT; //Размер FFT
- void setSizeFFT(int inputSizeFFT);
- void createWindowBlackmanHarris();
- void makeFFT();
- int currentBufferSizeFFT = 0; //Размер накопившихся отчётов
- fftw_plan planFFT = nullptr; //План для БПФ
- fftw_plan planReverseFFT = nullptr; //План для ОБПФ
- //Буферы для FFT
- std::vector<std::complex<double>> inputBuffer; //Входной буфер
- std::vector<std::complex<double>> outputBuffer; //Выходной буфер
- std::vector<double> moduleBuffer; //Буфер модуля
- std::vector<double> dB_buffer; //Буфер децибелл
- std::vector<double> vectorWindowBlackmanHarris; //Окно Блэкмана Харриса
- double maxValueADC = 1000000000.0; //Максимальное значение с АЦП
- public slots:
- void addIQ(const uint8_t* inputVectorIQ, const int len);
- };
- //-----Начало .cpp файла-----//
- #include "receiverfft.h"
- #include "qmath.h"
- #include <QCoreApplication>
- MyFFT::MyFFT(int sizeFFT, QObject *parent) : QObject{parent}
- {
- setSizeFFT(sizeFFT);
- }
- void MyFFT::setSizeFFT(int inputSizeFFT)
- {
- if(sizeFFT != inputSizeFFT)
- {
- sizeFFT = inputSizeFFT;
- inputBuffer.resize(sizeFFT, 0);
- outputBuffer.resize(sizeFFT, 0);
- moduleBuffer.resize(sizeFFT, 0);
- dB_buffer.resize(sizeFFT, 0);
- vectorWindowBlackmanHarris.resize(sizeFFT, 0);
- currentBufferSizeFFT = 0;
- createWindowBlackmanHarris();
- if(planFFT != nullptr)
- {
- fftw_destroy_plan(planFFT);
- planFFT = nullptr;
- }
- planFFT = fftw_plan_dft_1d(sizeFFT, (fftw_complex*)inputBuffer.data(), (fftw_complex*)outputBuffer.data(), FFTW_FORWARD, FFTW_ESTIMATE);
- }
- }
- void MyFFT::createWindowBlackmanHarris()
- {
- double windowEnergyMux = 0.;
- for(int i = 0; i < sizeFFT; i++)
- {
- vectorWindowBlackmanHarris[i] = 0.35875f - 0.48829 * qCos(2.*FFT_PI * i / (sizeFFT - 1))
- + 0.14128 * qCos(4.*FFT_PI * i / (sizeFFT - 1))
- - 0.01168 * qCos(6.*FFT_PI * i / (sizeFFT - 1));
- windowEnergyMux += vectorWindowBlackmanHarris[i] * vectorWindowBlackmanHarris[i];
- }
- windowEnergyMux /= sizeFFT;
- windowEnergyMux = qSqrt(1/windowEnergyMux);
- for(int i = 0; i < sizeFFT; i++)
- {
- vectorWindowBlackmanHarris[i] *= windowEnergyMux;
- }
- }
- void MyFFT::makeFFT()
- {
- //Делаем FFT
- fftw_execute(planFFT);
- //Меняем местами первую и вторую половину и при этом переводим в комплексный модуль
- int offset = outputBuffer.size()/2;
- float module = 0;
- for(int i = 0; i < offset; i++)
- {
- module = outputBuffer[i + offset].real()*outputBuffer[i + offset].real() + outputBuffer[i + offset].imag()*outputBuffer[i + offset].imag();
- moduleBuffer[i] = module;
- }
- for(int i = offset; i < outputBuffer.size(); i++)
- {
- module = outputBuffer[i - offset].real()*outputBuffer[i - offset].real() + outputBuffer[i - offset].imag()*outputBuffer[i - offset].imag();
- moduleBuffer[i] = module;
- }
- //Переводим в децибелы
- for(int i = 0; i < dB_buffer.size(); i++)
- {
- dB_buffer[i] = 10.0 * std::log10(moduleBuffer[i] + 1e-300);
- }
- }
- void MyFFT::addIQ(const uint8_t* inputVectorIQ, const int len)
- {
- //Вычисляем количество IQ содержащихся в размере байтового вектора
- int countIQ = len/(sizeof(int)*2);
- //Получаем указатель на вектор интовых комплексных чисел
- auto complexVector = (const std::complex<int>*)inputVectorIQ;
- //Если текущий размер буфера FFT + размер пришедших данных IQ больше чем размер FFT
- if((currentBufferSizeFFT + countIQ) > sizeFFT)
- {
- int offset = 0;
- //Будем вычитывать пока из пришедших данных, до тех пор пока не вычитаем всё или размер currentBufferSizeFFT + countIQ станет меньше или равен sizeFFT
- while((currentBufferSizeFFT + countIQ) > sizeFFT)
- {
- //Узнаём сколько не хватает до полноценного FFT
- const int delta = sizeFFT - currentBufferSizeFFT;
- //Вычисляем индекс последнего считанного элемента
- const int size = offset + delta;
- //Считываем с offset по size
- for(int i = offset; i < size; i++)
- {
- inputBuffer[currentBufferSizeFFT].real(complexVector[i].real() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- inputBuffer[currentBufferSizeFFT].imag(complexVector[i].imag() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- currentBufferSizeFFT++;
- }
- //Увеличиваем отступ от начала буфера данных
- offset += delta;
- //Уменьшаем количество оставшихся IQ отчётов
- countIQ -= delta;
- //Проверяем не накопилось ли FFT
- if(currentBufferSizeFFT >= sizeFFT)
- {
- //Делаем новое FFT
- makeFFT();
- //Вычитаем из текущего размера FFT размер FFT
- currentBufferSizeFFT -= sizeFFT;
- }
- }
- //Если что то осталось
- if(countIQ > 0)
- {
- //Вычисляем индекс последнего считанного элемента
- const int size = offset + countIQ;
- //Считываем с offset по size
- for(int i = offset; i < size; i++)
- {
- inputBuffer[currentBufferSizeFFT].real(complexVector[i].real() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- inputBuffer[currentBufferSizeFFT].imag(complexVector[i].imag() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- currentBufferSizeFFT++;
- }
- //Проверяем не накопилось ли FFT
- if(currentBufferSizeFFT >= sizeFFT)
- {
- //Делаем новое FFT
- makeFFT();
- //Вычитаем из текущего размера FFT размер FFT
- currentBufferSizeFFT -= sizeFFT;
- }
- }
- }
- else
- {
- //Добавляем новые отчёты
- for(int i = 0; i < countIQ; i++)
- {
- inputBuffer[currentBufferSizeFFT].real(complexVector[i].real() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- inputBuffer[currentBufferSizeFFT].imag(complexVector[i].imag() * vectorWindowBlackmanHarris[currentBufferSizeFFT] / maxValueADC / sizeFFT);
- currentBufferSizeFFT++;
- }
- //Проверяем не накопилось ли FFT
- if(currentBufferSizeFFT >= sizeFFT)
- {
- //Делаем новое FFT
- makeFFT();
- //Вычитаем из текущего размера FFT размер FFT
- currentBufferSizeFFT -= sizeFFT;
- }
- }
- }
Add Comment
Please, Sign In to add comment