- •Аппаратно-программные средства цифровой обработки сигналов
- •230100.62 Информатика и вычислительная техника
- •Введение
- •1 Лабораторная работа № 1. Знакомство с системой Mathcad
- •Теоретическая часть
- •Постановка задачи
- •Теоретическая часть
- •1.3 Порядок выполнения работы
- •1.4 Контрольные вопросы
- •2 Лабораторная работа № 2. Моделирование сигнала
- •Постановка задачи
- •2.3 Порядок выполнения работы
- •2.4 Контрольные вопросы
- •3 Лабораторная работа № 3. Прямое и обратное дискретное преобразование Фурье
- •Теоретическая часть
- •3.2 Постановка задачи
- •3.3 Порядок выполнения работы
- •3.4 Контрольные вопросы
- •4 Лабораторная работа № 4. Фильтрация сигналов
- •Теоретическая часть
- •4.2 Постановка задачи
- •4.3 Порядок выполнения работы
- •4.4 Контрольные вопросы
- •5 Лабораторная работа № 5. Вычисление скользящего спектра сигнала
- •Теоретическая часть
- •5.2 Постановка задачи
- •5.3 Порядок выполнения работы
- •5.4 Контрольные вопросы
- •6 Лабораторная работа № 6. Исследование спектров солнечной активности
- •6.1 Теоретическая часть
- •6.2 Постановка задачи
- •6.3 Порядок выполнения работы
- •6.4 Контрольные вопросы
- •7 Лабораторная работа № 7. Классификация периодов солнечной активности
- •7.1 Теоретическая часть
- •7.2 Постановка задачи
- •7.3 Порядок выполнения работы
- •7.4 Контрольные вопросы
- •8 Лабораторная работа № 8. Работа с ацп и цап
- •8.1 Теоретическая часть
- •8.2 Постановка задачи
- •8.3 Порядок выполнения работы
- •8.4 Контрольные вопросы
- •9 Лабораторная работа № 9. Фильтр с конечной импульсной характеристикой
- •9.1 Теоретическая часть
- •9.2 Постановка задачи
- •9.3 Порядок выполнения работы
- •9.4 Контрольные вопросы
- •10 Литература, рекомендуемая для изучения тем
- •10.1 Основная литература
- •10.2 Дополнительная литература
- •Список сокращений и условных обозначений
- •Приложение а
- •(Обязательное)
- •Среднемесячные относительные числа солнечных пятен
- •За период 1700 -1984 годы.
- •Приложение б (обязательное) Листинг программы
- •Приложение в (обязательное) Листинг программы
Приложение в (обязательное) Листинг программы
MyFilter.h
#include "Windows.h"
struct TitleWave { //формат секции fmt звукового файла
WORD type; //тип звуковых данных. Для нашей работы нужно значение 1 (просто
// данные без сжатия)
WORD channels; // количество каналов
long freq; //частота дискретизации
long bytes; //частота выдачи байтов
WORD align; //выравнивание
WORD bits; //число бит на выборку
};
bool KoeffOkno (float *koeff,int count); //расчет коэффициентов весового окна Блэкмена
bool IdealFilterKoeff(float *koeff,float fc,int count);// расчет коэффициентов идеального фильтра
bool KoeffFilter(float Fc,float* H,int count);//расчет коэффициентов фильтра
bool DecodeToShort(float* src,short* dst,int count);
void Filter(short* x,float* y,float* coeff,float* buf,int countDates,int N);//процедура фильтрации
//блока данных
bool WriteTitleWAV(FILE* F,TitleWave* tw,long size);//функция записи заголовка WAV файла
MyFilter.сpp
#define _USE_MATH_DEFINES
#include <math.h>
#include "MyFilter.h"
bool KoeffOkno (float *koeff,int count)//расчет коэффициентов окна
{ //в данном случае Блэкмена
float a,b,c;
int n=count/2;
for (int i=0;i<=n;i++)
{
a=0.5*cos(((2*M_PI*i)/(count)));
b=0.08*cos(((4*M_PI*i)/(count)));
koeff[i+n]=0.42+a+b;
}
return true;
}
bool IdealFilterKoeff(float *koeff,float fc,int count)//расчет коэффициентов идеального фильтра
{
float wc=2*M_PI*fc;
int n=count/2;
for (int i=1;i<=n;i++)
{
koeff[i+n]=-2*fc*(sin(wc*i))/(i*wc);
}
koeff[n]=1-2*fc;
return true;
}
bool KoeffFilter(float Fc,float* H,int count)//расчет коэффициентов фильтра
{
int n=count/2;
float* Ko=new float[count];
float* Hid=new float[count];
KoeffOkno (Ko,count);
IdealFilterKoeff(Hid,Fc,count);
for (int i=0;i<=n;i++)
{
H[i+n]=Ko[i+n]*Hid[i+n];
H[n-i]=H[i+n];
}
delete [] Ko;
delete [] Hid;
return true;
}
bool DecodeToShort(float * src,short* dst,int count)//изменение типа массива значений из
{ // вещественного в целое
for (int i=0;i<count;i++)
{
dst[i]=(short)src[i];
}
return true;
}
bool WriteTitleWAV(FILE* F,TitleWave* tw,long size)//запись заголовка WAV файла
{
char* id="RIFF";
long wChunkSize;
fwrite(id,sizeof(id),1,F);
fwrite(&size,sizeof(size),1,F);
id="WAVE";
fwrite(id,sizeof(id),1,F);
id="fmt ";
fwrite(id,sizeof(id),1,F);
wChunkSize=sizeof(TitleWave);
fwrite(&wChunkSize,sizeof(wChunkSize),1,F);
fwrite(tw,sizeof(TitleWave),1,F);
id="data";
fwrite(id,sizeof(id),1,F);
wChunkSize=size;
fwrite(&wChunkSize,sizeof(wChunkSize),1,F);
return true;
}
void Filter(short* x,float* y,float* coeff,float* buf,int size,int L) //процедура фильтрации блока
{ // входных данных размером 4096
float sum=0;
for (int i=0;i<size+L-1;i++)
{
sum=0;
for (int j=0;j<L;j++)
{
if (i>=j&&i-j<size)//!!!!!!!!!!!!!!!!!!!!
sum+=x[i-j]*coeff[j];
if (i<size)
{
y[i]=sum;
if (i<L-1)
y[i]+=buf[i];
}
else
buf[i-size]=sum;
}
}
}
Filter.cpp
#include "stdafx.h"
#include "Windows.h"
#include "iostream"
#include "MyFilter.h"
#define BLOCK_SIZE 4096 //размер блока обработки данных
int main(int argc, char* argv[])
{
setlocale(LC_ALL,"Rus"); //поддержка кириллицы
printf("Фильтер\n");
if (argc!=5)
{
printf("Не корректоное количество параметров (должно быть 4 параметра)");
return 1;
}
printf("Файл-источник:%s\n",argv[1]);
printf("Файл-приемник:%s\n",argv[2]);
printf("Частота среза(Гц):%s\n",argv[3]);
printf("Ширина перехода (Гц):%s\n",argv[4]);
FILE* fRead; //файл-источник
FILE* fSave; //файл-приемник
fRead=fopen(argv[1],"rb");
if (!fRead)
{
printf("Невозможно открыть файл=%s",argv[1]);
return 1;
}
fSave=fopen(argv[2],"wb");
if (!fRead)
{
printf("Невозможно создать файл=%s",argv[2]);
fclose(fRead);
return 1;
}
float Fc=atof(argv[3]); //частота среза
TitleWave tw; //заголовок WAV-файла
char id_chunk[4]; //далее идет чтение заголовка звукового файла
long FileSize;
fread(&id_chunk,sizeof(id_chunk),1,fRead);
if (strncmp(id_chunk,"RIFF",4))
{
printf("Не коректный формат файла-источника");
return 1;
}
fread(&FileSize,sizeof(FileSize),1,fRead);
fread(&id_chunk,sizeof(id_chunk),1,fRead);
if (strncmp(id_chunk,"WAVE",4)!=0)
{
printf("Не коректный формат файла-источника\n");
return 1;
}
long wChunkSize=0;
do
{
fseek(fRead,wChunkSize,SEEK_CUR);
if (!fread(&id_chunk,sizeof(id_chunk),1,fRead))
{
printf("Не найдена секция fmt\n");
return FALSE;
}
fread(&wChunkSize,sizeof(wChunkSize),1,fRead);
}
while (strncmp(id_chunk,"fmt ",4)!=0);
fread(&tw,sizeof(tw),1,fRead);
if (tw.type!=1)
{
printf("Программа работает только с файлами без сжатия\n");
return 1;
};
if (tw.channels!=1)
{
printf("Программа работает только с файлами c 1 каналом\n");
return 1;
} //чтение заголовка звукового файла зваерешено
printf("Чатота дискретизации=%d\n",tw.freq);
printf("Количество бит=%d\n",tw.bits);
int N=0.9*tw.freq/atof(argv[4]); //расчет порядка фильтра
printf("Порядок фильтра=%d\n",N);
if (wChunkSize>sizeof(tw)) //поиск секции данных в звуковом файле
fseek(fRead,wChunkSize-sizeof(tw),SEEK_CUR);
wChunkSize=0;
do
{
fseek(fRead,wChunkSize,SEEK_CUR);
if (!fread(&id_chunk,sizeof(id_chunk),1,fRead))
{
printf("Не найдена секция data\n");
return 1;
}
fread(&wChunkSize,sizeof(wChunkSize),1,fRead);
}
while (strncmp(id_chunk,"data",4)!=0); //поиск секции данных в звуковом файле завершен
//успешно
float* H=new float(N); //выделяем память для коэффициентов фильтра
Fc=Fc/tw.freq; //рассчитываем нормированное значение частоты среза
KoeffFilter(Fc,H,N); //функция расчета коэффициентов фильтра
long DateSize=wChunkSize; //размер данных звукового файла в байтах
long countDates=DateSize/sizeof(short); //количество отсчетов
WriteTitleWAV(fSave,&tw,DateSize); //запись заголовка WAV в файл-приемник
float * buf=new float[N-1]; //вспомогательный буффер
memset(buf,0,(N-1)*sizeof(float));
int blocks=countDates/BLOCK_SIZE; //количество обрабатываемых блоков
if (countDates % BLOCK_SIZE>0) blocks++;//
int n;
short xf[BLOCK_SIZE]; //буфер для входных данных
float y[BLOCK_SIZE]; //буфер для выходных данных
int k=0;
for (k=0;k<blocks;k++)
{
n=min(BLOCK_SIZE,countDates-k*BLOCK_SIZE);
if (!fread(&xf,sizeof(short),n,fRead))//чтение блока данных из звукового файла
{
printf("Не удалось прочитать");
return 1;
}
Filter((short*)xf,(float*)y,(float*)H,buf,n,N);//функции фильтрации
DecodeToShort(y,xf,n); //перевод данных из
// вещественного формата в целый
fwrite(&xf,sizeof(short),n,fSave);//запись результатов фильтрации
//в файл-приемник
}
fclose(fRead);
fclose(fSave);
printf("Фильтрация завершена успешно!");
return 0;
}
