LABA4_PROG
.docxМинистерство цифрового развития, связи и массовых коммуникаций Российской Федерации
Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования
«Московский технический университет связи и информатики»
Лабораторная работа №4
«Классы в С++, использование dll библиотек»
Выполнил:
студент группы БРТ2102
Епифанов Георгий
Проверил:
Кандауров Николай
Москва 2023
Задание:
Написать класс, который будет внутри генерировать сигнал, рассчитывать спектр (ДПФ) с использованием библиотеки fftw, записывать в комплексный файл .adc. У класса должно быть: конструктор с параметрами по умолчанию (размер БПФ, частота дискретизации); сеттеры и геттеры для параметров из пункта 1; приватный метод генерации сигнала; свойства (члены) класса std::vector для сигнала и результата fftw; публичный метод расчета спектра с использованием fftw; публичный метод для записи результата fftw в файл. Проверить работоспособность класса, записать файл и построить в Спектр-2.
Дано:
Листинг программы:
struct ADCFILEHEADER {
double dt; //!< Период дискретизации в секундах
unsigned long h; //!< Разрядность АЦП
unsigned long fN; //!< Общее количество отсчетов в файле
float Am; //!< Амплитуда, соответствующая максимальному значению целочисленного отсчета
unsigned long flags; //!< Флаги
char reserv[8]; //!< Резерв
};
typedef struct ADCFILEHEADER* LPADCFILEHEADER; //!< Указатель на ADCFILEHEADER
#define ADCF_DATA_INTEGER 0x00000000 //!< Тип данных - целочисленные
#define ADCF_DATA_FLOAT 0x00000001 //!< Тип данных - float
#define ADCF_TYPE_REAL 0x00000000 //!< Тип отсчетов - действительные
#define ADCF_TYPE_COMPLEX 0x00000002 //!< Тип отсчетов – комплексные
#define _USE_MATH_DEFINES
#define _SIGNAL_H
#include <iostream>
#include <fstream>
#include <math.h>
#include <complex>
#include <vector>
#include <fftw3.h>
using namespace std;
class singen {
public:
double FS = 48000.0;
int n = 12;
int k = 6;
int f1 = 100 * n;
int f2 = 512 * k;
int f3 = 50 * (n + k);
float A1 = 0.01 * n;
float A2 = k / 10;
float A3 = 0.05 * (n + k);
int freq[3] = { f1, f2, f3 };
double A[3] = { A1, A2, A3 };
unsigned int size_array = pow(2, 9);
vector<complex<float>> array_sin;
complex <float> calculate_sin_array(int n, int i)
{
float harmony = A[n] * sin(2.0 * M_PI * i * freq[n] / FS);
return harmony;
}
void GenerateSignal()
{
for (int i = 0; i < size_array; i++)
{
array_sin[i] = calculate_sin_array(0, i) + calculate_sin_array(1, i) + calculate_sin_array(2, i);
}
}
public:
singen(double _FS, float f1, float f2, float f3, float a1, float a2, float a3, unsigned int size_array)
{
set_fs(_FS);
set_array_freq(f1, f2, f3);
set_array_ampl(a1, a2, a3);
array_sin.resize(size_array);
}
void set_fs(double _FS)
{
FS = _FS;
}
void set_array_freq(float _A, float _B, float _C)
{
freq[0] = _A;
freq[1] = _B;
freq[2] = _C;
}
void set_array_ampl(float _A, float _B, float _C)
{
A[0] = _A;
A[1] = _B;
A[2] = _C;
}
// Метод класса, получения расчитанных значений
vector<complex<float>> get_sin_array()
{
return array_sin;
}
// Геттер для получения значения свойства size_array
unsigned int get_size_array()
{
return size_array;
}
// Сеттер для установки значения свойства size_array
void set_size_array(unsigned int n)
{
array_sin.resize(n);
}
bool write_adc(vector<complex<float>> data, double freq_sampling)
{
ADCFILEHEADER head;
head.Am = 1.0;
head.h = 32;
head.dt = 1.0 / freq_sampling;
head.fN = data.size();
head.flags = ADCF_TYPE_COMPLEX | ADCF_DATA_FLOAT;
const char* FName = "E:\\XFILE.adc"; //Путь к файлу
float im = 0.0;
/*РАБОТА С БИНАРНЫМ ФАЙЛОМ*/
ofstream out(FName, ios::binary); //Ставим режим "бинарный файл"
out.write((char*)&head, sizeof(head)); //Записываем в файл структуру заголовка
for (int i = 0; i < data.size(); ++i)
{
out.write((char*)&data[i], sizeof(data[i])); // Записываем действительные отсчеты из вектора
}
out.close();
return true;
}
void CalculateFFTW()
{
GenerateSignal();
fftwf_plan plan = fftwf_plan_dft_1d(array_sin.size(),
(fftwf_complex*)&array_sin[0],
(fftwf_complex*)&array_sin[0],
FFTW_FORWARD, FFTW_ESTIMATE);
// преобразование Фурье
fftwf_execute(plan);
fftwf_destroy_plan(plan);
ofstream out("E:\\SPECTR.txt");
for (size_t i = 0; i < array_sin.size(); ++i)
{
out << array_sin[i] << endl;
}
}
};
int main()
{
int nn = 12;
int kk = 6;
int ff1 = 100 * nn;
int ff2 = 512 * kk;
int ff3 = 50 * (nn + kk);
int AA1 = 0.01 * nn;
double AA2 = kk / 10;
float AA3 = 0.05 * (nn + kk);
unsigned int ssize_array = pow(2, 9);
vector<complex<float>> data;
// Выделение памяти для объекта SinGen_100Hz
singen* generator = new singen(48000, ff1, ff2, ff3, AA1, AA2, AA3, ssize_array);
// Вызываем метод генерации
generator->CalculateFFTW();
// Вызываем метод получения данных и получаем объект std::vector<float>
data = generator->get_sin_array();
// Удаление объекта SinGen_100Hz из памяти
generator->write_adc(data, 48000);
delete generator;
}
Результат