Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_ЦОС_06_09_12.docx
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
497 Кб
Скачать
☆

Приложение в (обязательное) Листинг программы

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;

}