Обработка дискретных сигналов



Содержание

1.                  Введение                                                                                                                             

2.                  Постановка задачи

3.                  Дискретизация сигнала

4.                  Квантование сигнала                                                                                                 

5.                  Прямое и обратное преобразование Фурье                                         

6.                  Фильтрация сигнала                                                                                                   

7.                  Структура WAV файла

8.                  Инструкция пользователя                                                                                   

9.                  Заключение                                                                                                                 

10.             Список источников                                                                                                   

11.             Листинг программы                                                                                                   


1. Введение

Анализ Фурье закладывает основы многих методов, применяющихся в области цифровой обработки сигналов (ЦОС). По сути дела, преобразование Фурье (фактически существует несколько вариантов таких преобразований) позволяет сопоставить сигналу, заданному во временной области, его эквивалентное представление в частотной области. Наоборот, если известна частотная характеристика сигнала, то обратное преобразование Фурье позволяет определить соответствующий сигнал во временной области.

В дополнение к частотному анализу, эти преобразования полезны при проектировании фильтров. Частотная характеристика фильтра может быть получена посредством преобразования Фурье его импульсной реакции. И наоборот, если определена частотная характеристика сигнала, то требуемая импульсная реакция может быть получена с помощью обратного преобразования Фурье над его частотной характеристикой.

Цифровые фильтры могут быть созданы на основе их импульсной реакции, поскольку коэффициенты фильтра с конечной импульсной характеристикой (КИХ) идентичны дискретной импульсной реакции фильтра.

В данной работе рассмотрено прямое и обратное преобразования Фурье, принципы математического описания и ана­лиза дискретных сигналов, а также обработка сигнала с помощью фильтров.


2. Постановка задачи

Согласно варианта в виде сигнала задан звуковой файл wav100_1000_44100_16.

1.                  Выполнить квантование сигнала для заданного пользователем числа уровней квантования.

2.                  Выполнить фильтрацию сигнала с помощью ФВЧ с частотой среза 600 Гц.

3.                  Восстановить во временной области отфильтрованный сигнал

4.                  Показать на одном графике исходный, восстановленный и разностный сигнал.

5.      Рассчитать ошибку. Критерий ошибки - Суммарно-квадратичная (SSE)


3. Дискретизация сигнала.

              Сигнал — в теории информации и связи называется материальный носитель информации, используемый для передачи сообщений по системе связи. Сигналом может быть любой физический процесс, параметры которого изменяются в соответствии с передаваемым сообщением.

              Дискретизация - процесс превращения непрерывного сигнала в цифровой, путем измерения числовых значений амплитуды сигнала через равные интервалы времени.

              Согласно варианта задан уже дискретизированный сигнал, внешний вид которого приведен на рисунке 1.

 

Рисунок 1 – Исходный сигнал


4. Квантование сигнала

              Квантование - представляет собой замену величины отсчета сигнала ближайшим значением из набора фиксированных величин - уровней квантования. Другими словами, квантование - это округление до величины отсчета. Уровни квантования делят весь диапазон возможного изменения значений сигнала на конечное число интервалов - шагов квантования. Расположение уровней квантования обусловлено шкалой квантования. Используются как равномерные, так и неравномерные шкалы.

              На рисунке 2 показаны изображение, квантованное на 15 уровней. Сейчас считается нормой квантовать видеосигнал на 1024 уровня. Число уровней квантования при формировании цифрового звукового сигнала намного больше: от десятков тысяч до миллионов.

Рисунок 2 – Квантованный сигнал

5 Прямое и обратное преобразование Фурье.

              Любая периодическая функция f (t) – ограниченная, кусочно-гладкая может быть разложена в ряд Фурье

                                                                                                                (1)

где:

                                                                                                                                                          (2)

есть основная круговая частота, определяемая величиной T периода повторения, а 

                                                                                                                                            (3)

есть среднее значение функции f(t) в интервале от – Т/2 до Т/2,

              ;                                                                                                                              (4)

              ;                                                                                                                                            (5)

              ;                                                                                                                (6)

              ;                                                                                                                (7)

              Согласно формуле (1) функция f(t) представляется в виде суммы константы и гармоник, частота первой из которых (основная) , второй 2, 3, и т.д. Число k гармоник в разложении (1) бесконечно большое, однако чаще всего для достаточно полного представления функций f(t) практически можно взять лишь несколько первых гармоник.              

              Для апериодических процессов разложение в ряд Фурье заменяется разложение в интеграл Фурье.

                                                                                                                              (8)

где

                                                                                                                              (9)

и

                                                                                                                                                          (10)

Формулами (8) и (9) можно пользоваться при условии, что функция f(t) – абсолютно интегрированная, то есть

             

              Преобразования, определяемые формулами (8) и (9) являются соответственно обратным и прямым интегральными преобразованиями Фурье.

              В практической плоскости чаще имеют дело не с исходной функцией f(t) , которая зачастую бывает неизвестной, а с последовательным набором мгновенных значений некоторой функции. В этом случае, говоря о дискретном бесконечном ряде Фурье, имеют ввиду следующие преобразования:

прямое  [1]                                                                                                    (11)

и обратное [1]                                                                                                  (12)

              Дискретное преобразование Фурье (ДПФ) является широко применяемым в цифровой технике методом представления информации. Прямое ДПФ выполняется над последовательностью дискретных величин конечной длительности. В результате получается так же конечной длительности дискретная последовательность величин, дающих частотно-спектральное представление указанной исходной последовательности. При обратном ДПФ по второй последовательности находится первая из них. Каждая из этих последовательностей содержит одинаковое количество N дискретных величин.

              Для дискретных величин конечной длительности N используются следующие формулы ДПФ:

формула прямого ДПФ [3]                                                                       (13)

формула обратного ДПФ [7]                                                                      (14)

              В первом случае , во втором . Считается, что при иных значениях k и n соответственно X(k) = 0 и x(n) = 0.

Рисунок 3 Спектр частот исходного сигнала

 

6. Фильтрация сигнала

              Фильтрация- процесс преобразования исходного сигнала, в результате которого меняются его частотные и фазовые характеристики. В зависимости от воздействия  фильтра на амплитудно-частотную характеристику  сигнала (АЧХ) различают фильтры:

   нижних частот (ФНЧ)

   высоких частот (ФВЧ)

   полосно-пропускающие (полосовые)

   полосно-задерживающие (режекторные)

              Фильтр верхних часто́т (ФНЧ) — электронный или любой другой фильтр, пропускающий высокие частоты входного сигнала, при этом подавляя частоты сигнала меньше, чем частота среза. Степень подавления зависит от конкретного типа фильтра.

После прямого дискретного преобразования сигнала и соответственно представление его в частотном спектре становится особенно удобно реализация фильтрации по его частотной составляющей. Достаточно оставить без изменения амплитуды гармоник  входящие в заданный частотный диапазон и  обнулить все остальные, после чего восстановить  с помощью обратного дискретного преобразования Фурье измененный отфильтрованный сигнал.  

Рисунок 4 – Отфильтрованный сигнал.

Рисунок 5 - Восстановленный сигнал


7. Организация WAV файлов

Рассмотрим структуру стандартного WAV-файла. Он представляет собой две, четко делящиеся, области. Одна из них – заголовок файла, другая – область данных. В заголовке файла хранится следующая информация:

Размер файла.

Количество каналов.

Частота дискретизации.

Количество бит в сэмпле (глубина звучания).

Звук состоит из колебаний, которые при оцифровке приобретают ступенчатый вид. Этот вид обусловлен тем, что компьютер может воспроизводить в любой короткий промежуток времени звук определенной амплитуды (громкости) и этот короткий момент далеко не бесконечно короткий. Продолжительность этого промежутка определяет частота дискретизации. Например, если файл с частотой дискретизации 44.1 kHz, это значит, что тот короткий промежуток времени равен 1/44100 секунды (следует из размерности величины Гц = 1/с). Современные звуковые карты поддерживают частоту дискретизации до 192 kHz. Так, со временем разобрались.

Амплитуда сигнала выражается числом, занимаемым в памяти (файле) 8, 16, 24, 32 бит (теоретически можно и больше). Таким образом, чем больше число занимает места в памяти (файле), тем больше диапазон значений для этого числа, а значит и для амплитуды.


Зашифрованный WAV файл имеет следующую структуру:

Местоположение

(адрес)

размер

Описание

0..3

4 байта

Должно быть "RIFF". Является началом RIFF-цепочки.

4..7

4 байта

Размер RIFF-цепочки в байтах.

8..11

4 байта

Должно быть "WAVE"

12..15

4 байта

Должно быть "fmt "

16..19

4 байта

Должно быть 16

20..21

2 байта

Формат.

22..23

2 байта

Количество каналов

24..27

4 байта

Частота дискретизации

28..31

4 байта

Количество байт, переданных за секунду воспроизведения

32..33

2 байта

Количество байт в сэмпле

34..35

2 байта

Количество бит в сэмпле

36..39

4 байта

Должно быть "data"

40..43

4 байта

Количество байт в области данных

 


Для обработки таких файлов удобно пользоваться структурами вида (синтаксис языка С++):

Struct RIFF {
              char ID[4]; /              "RIFF"
              long Len; // длина файла без этого заголовка
              }

Дальше обычно заголовок собственно WAVа:
struct WAVE {
              char ID[4]; // "WAVE" - заголовок WAV
              char Fmt[4]; // "fmt " - thunk формата
              long Len; // длинна етого thunka
              int Format; // собственно формат
              int Channels; // число каналов (1/2)
              long SamplesPerSecond; // отсчетов/сек
              long AvgBytesPerSecond; // байтов/сек
              int BlockAlign; // выравнивание блоков
              int BitsPerSample; // битов на отсчет
}

struct DATA {
              char ID[4]; // "data"
              long Len; // длина этого thunkа (должен быть выровнен на границу слова)

}


8. Инструкция пользователя             

Программа реализована на языке Microsoft Visual C++  с использованием GUI. Интерфейс программы понятен. Он содержит несколько вкладок, каждая из которых выполняет свою функцию.

              1. Во вкладке «Открыть файл» выполняется поиск звукового файла, соответствующего варианту, его считывание. После открытия файла становятся доступными пункты меню «Обработка», «Графики».

              2. Пункт меню  «Обработка» отвечает за все операции над звуковым файлом, а именно: квантование, разложение на составляющие (получение спектра), фильтрация и восстановление.

              3. Пункт меню «Графики» отвечает за графическое отображение каждого шага пользователя по обработке сигнала, т.е. после каждого действия становится доступным тот или иной график.

              При написании программы был предусмотрен режим последовательного выполнения действий пользователя. Реализовано это за счет «недоступности» определенного действия, пока не будет выполнено предыдущее.

Разработанная программа легка  и понятна в эксплуатации и выполняет все заданные согласно варианта функции.


9. Заключение

              В результате выполнения курсовой работы были практически закреплены знания теоретической части курса «Методы и способы компьютерных информационных технологий».

              Составленная программа на основе полученных знаний  позволяет на примере дискретизированного цифрового сигнала графически визуализировать процесс обработки сигнала  для заданного пользователем уровня квантования, а также осуществить фильтрацию с заданным диапазоном частоты и восстановить исходный и отфильтрованный сигналы, рассчитать заданную ошибку.


10. Список источников

1.                 Фролов А.В, Фролов Г.В "Мультимедиа для Windows", Москва, "Диалог-МИФИ", 1995 г.

2. Рабинер Л., Гоулд Б. Теория и применение цифровой обработки 3. сигналов. М.:Мир, 1978.

4. Марпл-мл. С.Л. Цифровой спектральный анализ и его приложения: Пер. с англ. -М.: Мир, 1990.

5. Либерти Дж., Хорват Д.Б., «Программирование в среде С++», 2006. – 448 с.

6. http://ru.wikipedia.org/wiki/Фильтр_высоких_частот

7. http://coolreferat.com/Описание_сигналов

 


11. Листинг программы

Основной файл программы Sound8.cpp

#include "stdafx.h"

#include "Form1.h"

 

 

#ifndef M_PI

#define M_PI 3.14159265358979323846

#endif

 

 

using namespace sound_8;

using namespace std;

using namespace System::Runtime::InteropServices;

using namespace System::Drawing;

 

 

 

bool flKvant = false;

 

 

WAV wavFile;

Draw draw;

 

[STAThreadAttribute]

int main(array<System::String ^> ^args)

{

              // Enabling Windows XP visual effects before any controls are created

              Application::EnableVisualStyles();

              Application::SetCompatibleTextRenderingDefault(false);

 

              // Create the main window and run it

              Application::Run(gcnew Form1());

              return 0;

}

//выбор файла и чтение

Void Form1::OpenFileToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              //выбор файла

              if(openFileDialog1->ShowDialog()==System::Windows::Forms::DialogResult::OK)

              {                           

                            wavFile.SetFileName(openFileDialog1->FileName);

                            if(wavFile.WAVRead()==true)

                            {

                                          menu->Items[1]->Enabled = true;

                                          menu->Items[2]->Enabled = true;

                                          groupBox1->Visible = true;

                                          KvanToolStripMenuItem1->Enabled = true;

                                          SpectrToolStripMenuItem->Enabled = true;

                                          FilteredToolStripMenuItem->Enabled = false;

                                          RestoreToolStripMenuItem->Enabled = false;

                                          GrKvantSignalToolStripMenuItem->Enabled = false;

                                          GrSpectrSignalToolStripMenuItem->Enabled = false;

                                          GrRestorSignalToolStripMenuItem->Enabled = false;

                            }

                            else MessageBox::Show("Ошибка при открытии файла!","Внимание");

              }

}

 

//Квантование

Void Form1::KvanToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

             

              if ((Form1::tbKvant->Text == "")||(System::Convert::ToInt32(Form1::tbKvant->Text)<2)||(System::Convert::ToInt32(Form1::tbKvant->Text)>100))

              {

                            MessageBox::Show("Не введен или не правиильный уровень квантования","!!!");

                            return;

              }

              else

              {

                            if(wavFile.Kvant(wavFile.lChannel, Convert::ToInt32(Form1::tbKvant->Text))==true)

                            {                                         

                                          Kvant ^kv = gcnew Kvant();             

                                          kv->setWavFile(wavFile);

                                          kv->ShowDialog();

                                          GrKvantSignalToolStripMenuItem->Enabled = true;

                                         

                            }

                            //if (kvant) MessageBox::Show("Квантование закончено успешно!","Квантование сигнала");

                            flKvant = true;

              }

             

             

}

 

 

 

 

 

//разложение на составляющие

Void Form1::SpectrToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              wavFile.FFT(wavFile.lChannel);

              wavFile.FFT(wavFile.rChannel);

              wavFile.lChannel.spectr = true;

              //активация кнопок

              FilteredToolStripMenuItem->Enabled = true;

              SpectrToolStripMenuItem->Enabled = false;

              RestoreToolStripMenuItem->Enabled = true;

              GrSpectrSignalToolStripMenuItem->Enabled = true;

 

              MessageBox::Show("Выполнено успешно!","Спектр");

}

 

//фильтрация

Void Form1::FilteredToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              wavFile.Filter(wavFile.lChannel);

              wavFile.Filter(wavFile.rChannel);             

              MessageBox::Show("Выполнено успешно!","Фильтрация");

              FilteredToolStripMenuItem->Enabled = false;

}

//Восстановление

Void Form1::RestoreToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              wavFile.RFFT(wavFile.lChannel);

              wavFile.RFFT(wavFile.rChannel);

              wavFile.WriteFile(wavFile.lChannel,wavFile.rChannel);

              wavFile.lChannel.restored = true;

              MessageBox::Show("Выполнено успешно!","Восстановление");

 

              //кнопки

              RestoreToolStripMenuItem->Enabled = false;

              SpectrToolStripMenuItem->Enabled = true;

              FilteredToolStripMenuItem->Enabled = false;

              GrRestorSignalToolStripMenuItem->Enabled = true;

}

//ГРАФИКИ

//квантование

Void Form1::GrKvantSignalToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              Kvant ^kv = gcnew Kvant();             

              kv->setWavFile(wavFile);

              kv->ShowDialog();             

}

 

//спектр

Void Form1::GrSpectrSignalToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              Spectr ^sp = gcnew Spectr();

              sp->setWavFile(wavFile);

              sp->ShowDialog();

}

 

 

Void Form1::GrRestorSignalToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)

{

              Restored ^rs = gcnew Restored();

              rs->setWavFile(wavFile);

              rs->ShowDialog();

}

 

Файл работы со звуковым заданным файлом(WAV.cpp)

//установка имени файла

void WAV::SetFileName(System::String^ wavFile)

{

              this->FileName = (char*)(void*)Marshal::StringToHGlobalAnsi(wavFile);

}

 

char *WAV::getFileName()

{

              return this->FileName;

}

 

//---чтение звукового файла

bool WAV::WAVRead()

{             

              FILE *file;

              char *data_tmp;

             

 

              //открытие файла

              file = fopen(this->FileName, "rb");

 

              //-------------------------------------

              //чтение из файла RIFF-chunk

              //-------------------------------------   

              fread(&HRiff, sizeof(RIFF), 1,  file);             

              if (strnicmp(HRiff.ID,"RIFF",4)!=0)

              {                           

                            return false;

                            exit(0);

              }

 

              //-------------------------------------

              //чтение WAVE-chunk

              //-------------------------------------

              char blockID[4],blockFmt[4];

              long blockLen;

              int blockID2=0;

 

              fread(&HWave, sizeof(WAVE), 1,  file);             

              //fread(&blockID, sizeof(blockID), 1, file);             

              if (strnicmp(HWave.ID,"WAVE",4)!=0)

              {                           

                            return false;

                            exit(0);

              }

              //fseek(file,sizeof(RIFF),SEEK_SET);

              //fread(&HWave, blockLen+12, 1,  file);

              this->kolByte = HWave.BitsPerSample / 8;

 

 

              //-------------------------------------

              //Поиск блока данных

              //-------------------------------------

 

              bool flag = true;

              do

              {             

                            fread(&HData, sizeof(DATA), 1,  file);

                            if (strnicmp(HData.ID,"data",4)==0)

                                          flag = false;

                            else fseek(file, HData.Len, SEEK_CUR);                           

              } while (flag==true);

 

 

              short int data_t;

              data = new long[(HData.Len+1)/kolByte];

              dataSize = (HData.Len+1)/kolByte;

              for (int i=0;i<dataSize;i++)

              {

                            data_t =0;

                            fread(&data_t, kolByte, 1, file);

                            data[i] = data_t;

              }

 

              //разбиение на правый и левый каналы

              lChannel.data = new long[dataSize/2];

              lChannel.size = dataSize/2;

 

              rChannel.data = new long[dataSize/2];

              rChannel.size = dataSize/2;

              int j=0;

              for (int i=0;i<dataSize;i+=2)

              {

                            lChannel.data[j] = data[i];

                            rChannel.data[j] = data[i+1];

                            j++;

              }

 

              fclose(file);

              return true;

}

 

//---быстрое преобразование Фурье

void WAV::FFT(Channel &ch)

{             

              ch.Power = 18;

              // Процедура БПФ

              int i=0,j=0,n=0,teknum,adr;

              ch.N = ch.size;

              double tmp_size = ch.size;

              for( i=0; tmp_size>1; tmp_size/=2,i++ ) ;

                int fft_size = 1 << (i-1) ;

              ch.Power = i;

              tmp_size = pow(2.,i);

              ch.c = new std::complex<double>[ tmp_size ] ;             

              ch.restData = new long[tmp_size];

              for (i=0;i<ch.N;i++)

              {

                            ch.restData[i]=ch.data[i];

              }

              for (i=ch.N;i<tmp_size;i++)

              {

                            ch.restData[i]=0;

              }

              i = 0;

              ch.N = tmp_size;

              while(i<ch.N)

              {

                            j=Reverse(i,ch.Power);

                            ch.c[i]=ch.restData[j];

                            i++;

              }

              i=1;

              complex <double> Tmp,W;

 

              while(i<ch.N)// определяет порядок коэффициентов Фурье

              {

                            n=0;

                            while(n<i)

                            {

                                          teknum=0;

                                          W=Ww(n,i<<1);

                                          while(teknum<ch.N/2/i)

                                          {

                                                        adr=teknum*(i<<1)+n;

                                                        Tmp=ch.c[adr];

                                                        ch.c[adr]=Tmp+W*ch.c[adr+i];

                                                        ch.c[adr+i]=Tmp-W*ch.c[adr+i];

                                                        teknum++;

                                          }

                                          n++;

                            }

                            i=i<<1;

              }

              Norm(ch);

              ch.Amplitude = new double[ch.N];

              for (i=0;i<ch.N;i++)

              {

                            ch.Amplitude[i] = (ch.c[i].real())*(ch.N);                           

              }

 

}

//---обратное преобразование Фурье

void WAV::RFFT(Channel &ch)

{

             

Обработка дискретных сигналов