unit fftunit; {$mode objfpc}{$H+} interface uses Classes, SysUtils, lowlevelunit; {$DEFINE fftNormierung} type tFFTDatenordnung = (doResIms,doResSmi,doAlleResIms,doAlleResSmi,doRes,doBetr,doBetrQdr,doGetrennt); tFFTAlgorithmus = class private len,hLen: longint; res,ims: tExtendedArray; inO,outO: tFFTDatenordnung; procedure dumpResIms; public constructor create(laenge: longint; inputOrdnung,outputOrdnung: tFFTDatenordnung); overload; constructor create(original: tFFTAlgorithmus); overload; destructor destroy; override; procedure laden(invers: boolean; q: pSingle; schritt: longint); overload; virtual; procedure laden(invers: boolean; q: pDouble; schritt: longint); overload; virtual; procedure laden(invers: boolean; q: pExtended; schritt: longint); overload; virtual; procedure laden(invers: boolean; qRe,qIm: pSingle; schritt: longint); overload; virtual; procedure laden(invers: boolean; qRe,qIm: pDouble; schritt: longint); overload; virtual; procedure laden(invers: boolean; qRe,qIm: pExtended; schritt: longint); overload; virtual; procedure ausfuehren; virtual; abstract; procedure speichern(invers: boolean; z: pSingle; schritt: longint); overload; virtual; procedure speichern(invers: boolean; z: pDouble; schritt: longint); overload; virtual; procedure speichern(invers: boolean; z: pExtended; schritt: longint); overload; virtual; procedure speichern(invers: boolean; zRe,zIm: pSingle; schritt: longint); overload; virtual; procedure speichern(invers: boolean; zRe,zIm: pDouble; schritt: longint); overload; virtual; procedure speichern(invers: boolean; zRe,zIm: pExtended; schritt: longint); overload; virtual; procedure summen(amAnfang: boolean; var energie: extended; var nurNullen: boolean); function dumpParams: string; property inOrdnung: tFFTDatenordnung read inO; property outOrdnung: tFFTDatenordnung read outO; end; tFFTCooleyTukey = class(tFFTAlgorithmus) private wRe,wIm: tExtendedArray; perm: tLongintArray; public constructor create(laenge: longint; inputOrdnung,outputOrdnung: tFFTDatenordnung); overload; constructor create(original: tFFTCooleyTukey); overload; destructor destroy; override; procedure laden(invers: boolean; q: pSingle; schritt: longint); overload; override; procedure laden(invers: boolean; q: pDouble; schritt: longint); overload; override; procedure laden(invers: boolean; q: pExtended; schritt: longint); overload; override; procedure laden(invers: boolean; qRe,qIm: pSingle; schritt: longint); overload; override; procedure laden(invers: boolean; qRe,qIm: pDouble; schritt: longint); overload; override; procedure laden(invers: boolean; qRe,qIm: pExtended; schritt: longint); overload; override; procedure ausfuehren; override; end; tFFTBluestein = class(tFFTAlgorithmus) private rRe,rIm,sRe,sIm: array of extended; subFFT: tFFTCooleyTukey; public constructor create(laenge: longint; inputOrdnung,outputOrdnung: tFFTDatenordnung); overload; constructor create(original: tFFTBluestein); overload; destructor destroy; override; procedure ausfuehren; override; end; function createFFTAlgorithmus(laenge: longint; inputOrdnung,outputOrdnung: tFFTDatenordnung): tFFTAlgorithmus; overload; function createFFTAlgorithmus(original: tFFTAlgorithmus): tFFTAlgorithmus; overload; function strToFftDo(out fftDo: tFFTDatenordnung; s: string): boolean; function fftDoToStr(fftDo: tFFTDatenordnung): string; implementation uses math, myStringListUnit; // allgemeine Funktionen ******************************************************* function createFFTAlgorithmus(laenge: longint; inputOrdnung,outputOrdnung: tFFTDatenordnung): tFFTAlgorithmus; begin if inputOrdnung in [doBetr,doBetrQdr] then fehler('Ich brauche mehr als Beträge oder Betragsquadrate um eine FFT auszurechnen!'); if round(power(2,round(ln(laenge)/ln(2))))=laenge then result:=tFFTCooleyTukey.create(laenge,inputOrdnung,outputOrdnung) else result:=tFFTBluestein.create(laenge,inputOrdnung,outputOrdnung); end; function createFFTAlgorithmus(original: tFFTAlgorithmus): tFFTAlgorithmus; begin if original is tFFTCooleyTukey then result:=tFFTCooleyTukey.create(original as tFFTCooleyTukey) else if original is tFFTBluestein then result:=tFFTBluestein.create(original as tFFTBluestein) else fehler('Unbekannter FFT-Algorithmus-Typ '''+original.className+'!'); end; function strToFftDo(out fftDo: tFFTDatenordnung; s: string): boolean; var bekannteBefehle: tMyStringList; begin fftDo:=low(tFFTDatenordnung); bekannteBefehle:=tMyStringList.create; repeat if bekannteBefehle.count>0 then inc(fftDo); bekannteBefehle.add(fftDoToStr(fftDo)); until (s=bekannteBefehle.last) or (fftDo=high(tFFTDatenordnung)); if fftDo