Рекурсивное быстрое преобразование Фурье п ометоду Кули-Тьюки, страница 2

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

На данном рисунке представлена синусоида с частой 1.25Гц и окно преобразования содержит 1723 отсчета. Число 1723 является простым числом, и следовательно не раскладывается на множители, соответственно скорость преобразования в этом случае будет минимальна.

5. Текст основного модуля программы.

unit ffttest;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, TeEngine, Series, ExtCtrls, TeeProcs, Chart, Buttons, Placemnt,

RXSplit;

type

TForm1 = class(TForm)

Panel1: TPanel;

Label1: TLabel;

Impulse_Button: TSpeedButton;

Sinus_Button: TSpeedButton;

Bevel1: TBevel;

Run_Button: TSpeedButton;

Label2: TLabel;

Label3: TLabel;

fft_lab: TLabel;

rft_lab: TLabel;

Label4: TLabel;

Label5: TLabel;

N_otch_Edit: TEdit;

N_period_Edit: TEdit;

Label6: TLabel;

Duration_Edit: TEdit;

Panel2: TPanel;

Chart1: TChart;

Series1: TFastLineSeries;

Series3: TFastLineSeries;

RxSplitter1: TRxSplitter;

Chart2: TChart;

Series2: TBarSeries;

RxSplitter2: TRxSplitter;

Panel3: TPanel;

Chart3: TChart;

Chart4: TChart;

Series5: TBarSeries;

RxSplitter3: TRxSplitter;

Series4: TBarSeries;

FormStorage1: TFormStorage;

procedure Chart1DblClick(Sender: TObject);

procedure Run_ButtonClick(Sender: TObject);

procedure N_otch_EditChange(Sender: TObject);

procedure Impulse_ButtonClick(Sender: TObject);

procedure Sinus_ButtonClick(Sender: TObject);

procedure Duration_EditChange(Sender: TObject);

procedure N_period_EditChange(Sender: TObject);

end;

var

Form1: TForm1;

implementation

uses fftn;

{$R *.DFM}

procedure TForm1.Run_ButtonClick(Sender: TObject);

type complex=record re, im :single;end;

var in_, out_: array of complex;n,i,j,duration:cardinal;np:single;

begin

series1.clear;series2.clear;series3.clear;series4.clear;series5.clear;

n:=strtoint(N_otch_edit.text);

np:=strtofloat(N_period_edit.text);

duration:=strtoint(Duration_edit.text);

SetLength(in_, n);SetLength(out_, n);

for i:=0 to n-1 do begin in_[i].re:=0;in_[i].im:=0;out_[i].re:=0;out_[i].im:=0;end;//Обнуление массивов

if sinus_button.down then for i:=0 to n-1 do in_[i].re:=sin(2*pi*i*np/n); //Создание входного массива - синус

i:=0;

if impulse_button.down then while i<n-duration do begin

for j:=i to i+duration-1 do in_[j].re:=1;

i:=i+trunc(n/np);

end;

for i:=0 to n-1 do Series1.AddXY(i,in_[i].re,'',0); //Вывод созданного массива на график

j:=gettickcount;

f_ft(in_,n,out_); //Прямое преобразование фурье

fft_lab.caption:=inttostr(gettickcount-j);

for i:=0 to n div 2 do begin

Series2.AddXY(i,2*sqrt(out_[i].im*out_[i].im+out_[i].re*out_[i].re),'',0);

Series4.AddXY(i,2*out_[i].re,'',0);

Series5.AddXY(i,2*out_[i].im,'',0);

end;

for i:=0 to n-1 do begin in_[i].re:=0;in_[i].im:=0;end; //Обнуление массива in

j:=gettickcount;

r_ft(out_,n,in_);//Обратное преобразование

rft_lab.caption:=inttostr(gettickcount-j);

for i:=0 to n-1 do Series3.AddXY(i,in_[i].re,'',0);

end;

function is_float(value:string):boolean;

var i:byte; num:set of char;

begin

num:=['0','1','2','3','4','5','6','7','8','9',','];

if (length(value)>7) or (length(value)<1) then begin result:=false; exit;end;

for i:=1 to length(value) do if value[i] in num then else begin result:=false; exit; end;

result:=true;

end;

function is_int(value:string):boolean;

var i:byte; num:set of char;

begin

num:=['0','1','2','3','4','5','6','7','8','9'];

if (length(value)>7) or (length(value)<1)  then begin result:=false; exit;end;

for i:=1 to length(value) do if value[i] in num then else begin result:=false; exit; end;

result:=true;

end;

procedure test_bounds;

begin

with form1 do begin

if (is_int(N_otch_edit.text)) and (is_float(N_period_edit.text)) and (is_int(Duration_edit.text))

then Run_button.enabled:=true else Run_button.enabled:=false;

if Run_Button.Enabled and Impulse_Button.Down then

if strtoint(Duration_Edit.text)>=StrToInt(N_otch_Edit.text)/StrToFloat(N_Period_Edit.text)   then Run_Button.Enabled:=false;

end;end;

procedure TForm1.Impulse_ButtonClick(Sender: TObject);

begin

label6.enabled:=true;Duration_Edit.enabled:=true;

end;

procedure TForm1.Sinus_ButtonClick(Sender: TObject);

begin

label6.enabled:=false;Duration_Edit.enabled:=false;

end;

procedure TForm1.Duration_EditChange(Sender: TObject);

begin

test_bounds

end;

procedure TForm1.N_period_EditChange(Sender: TObject);

begin

test_bounds

end;

procedure TForm1.N_otch_EditChange(Sender: TObject);

begin

test_bounds

end;

end.