Tone FIR Designer, ein einfaches praktisches Programm zum Erstellen
von FIR-Filter-Koeffizienten-Dateien sowie ToneCirc FIR-Elementen

Der Clou von ToneFIRDesigner ist aber die große Einsatzbandbreite, die durch Erstellen und Hinzufügen
von einfachen Script-Dateien beliebig erweiterbar ist. Es gibt Scripte für die eigentliche Filterfunktion, aber
auch für die Fenster-Funktion sowie für das Ausgabe-Format der Koeffizienten-Datei. Somit ist auch das
Erstellen von Tabellen von beliebigen Funktionen (z.Bsp. Sinus-Tabelle für DSP) möglich.

Erst kommt ein Kapitel über die Bedienung, dann beschäftigen wir uns mit den Sripten, dann ein paar Zeilen
was  DownLoad/Installation angeht, und zum Abschluss noch ein wenig Theorie.


Bedienung/Funktionen:

ToneFIRDesigner nach Berechnung eines Band-Passes

Koeffizienten berechnen:
Erstmal trägt man in den oberen Feldern die gewünschten Parameter, wie CutFrequenzen, Sample-Freq.,
sowie die Anzahl der Tabs (Number Tabs) ein. Die Sample-Frequenz ist bei Analog-FIR-Filtern gleich-
bedeutend mit dem Delay (=1/fsample) und bei Digital-FIR-Filtern mit der Abtastrate. Weiterhin wählt
man noch Filter-Type und Window-Type aus. Bei Ausführen von Calc Filter Coffs werden dann die
Koeffizienten berechnet und im oberen Chart-Fenster dargestellt. Im unteren Chart-Fenster kann man
wählen zwischen Transfer-Funktion (Trf), Sprung-Antwort (StR) sowie Sinus-Antwort (SiR). Die Frequenz
für die SiR gibt man im Edit-Feld (SiR Freq) links neben dem unteren Chart an. Im SiR-Chart werden 2
Kurven dargestellt, eine ist die Filter-Antwort, die Andere stellt die Sinus-Antwort eines Allpasses mit dem
selben GroupDelay dar. Nach dem Ausführen von Calc Filter Coffs wird auch ein Vorschlag für den
Filternamen in das entsprechende Feld geladen.
Hinweis: Die meisten von den schon vordefinierten Filtern benötigen eine ungerade Tab-Anzahl.

Koeffizienten-Datei generieren:
Nach erfolgreicher Koeffizienten-Berechnung wählt man nun das gewünschte File-Format, sowie das
Format jedes Koeffizienten in der Datei aus. Nach dem Drücken von Save Formatted CoffFile wird
eine Koeffizienten-Datei unter dem angegebenen Filter-Folder und dem Namen <FilterName>.dat
als Text-Datei abgespeichert.
Mit den speziellen ToneCirc-Save-Buttons kann ein vollständiges FIR-Element für die Simulation in
ToneCirc erstellt werden (Coff-Datei + Selfdef bzw. DSelfdef-Datei).

Eigene Scripte erstellen:

Scripte können erstellt bzw. modifiziert werden um Anpassungen an die eigenen Erfordernisse oder
Erweiterungen vorzunehmen. Es gibt folgende Script-Typen: für die Definition der Filter-Funktion,
für die Definition der Fenster-Funktion, für die Festlegung des Ausgabe-File-Formats. Jeder Script-
Typ hat sein eigenes Unterverzeichniss und natürlich auch sein eigenes Format. Für jede Aufgabe
muß ein Script-File des entsprechenden Typs vorhanden sein.

Script-Typ Definition der Filterfunktion:

Dateien dieses Typs müssen immer im Verzeichniss Data/FilterTypes stehen und enden mit ".txt".
Alle Namen dieser Dateien erscheinen in der Auswahlliste Filter Type im Dialog.
In einer solchen Datei wird definiert, wie die Koeffizienten H[i] als auch die Gruppenlaufzeit(GroupDelay)
berechnet werden.
Schauen wir uns das am Beispiel der Datei Data/FilterTypes/BandPass.txt mal an:

#Description = "Creation with WinSync Method"

#InputSettings
EnableFcut1 = 1
EnableFcut2 = 1
DefaultFcut1 = 8k
DefaultFcut2 = 14k
DefaultWindowType = "Blackman"
DefaultFilterName = "FIR_Bandpass_<fcut1>Hz_<fcut2>Hz_<fsample>Hz_<NumTabs>"
#END

#ComputeFilterCoffs
Ocut1 = fcut1/fsample
Ocut2 = fcut2/fsample
M2 = (NumTabs-1)/2
$FOR i=0 TO NumTabs-1
    $IF i = M2
        h[i] = c_2pi*(ocut2 - ocut1);
    $ELSE
        h[i] = ( sin(c_2pi*ocut2*(i-M2)) - sin(c_2pi*ocut1*(i-M2)) )/(i-M2); 
    $ENDIF
    h[i] = h[i]*gain/c_pi
$ENDFOR
GroupDelay = M2/fsample
#END

In der Zeile hinter #Description trägt man den Kommentar ein, der nach dem Ausführen von Calc Filter Coffs
im Dialog angezeigt wird.

Im Block #InputSettings....#End kann folgendes festgelegt werden:
Mit EnableFcut1/2 kann man das entsprechnde Eingabefeld im Dialog enablen (=1) oder dissablen (=0). Für
viele Filterfunktionen werden diese nämlich gar nicht bzw. nur eine (Fcut1) benötigt.
Bei DefaultFcut1/2 können Standartwerte vorgelegt werden, die dann nach Auswahl dieser Filter-Funktion
in die Felder Fcutoff1/2 des Dialogs geladen werden.
Bei DefaultWindowType trägt man eine Fenster-Funktion (Dateiname einer vorhandenen Script-Datei des
Typs Window-Funktion) ein. Diese wird automatisch nach Auswahl dieses Filters in den Dialog geladen.
Das Selbe gilt für DefautFilterName wo der Vorschlag für den Filternamen bestimmt wird. Es stehen hier
die Ersetzer <fcut1>, <fcut2>, <fsample> ,<numtabs> und <gain> zur Verfügung um aus den aktuellen Werten
den Namen automatisch zu generieren. 

Im Block #ComputeFilterCoffs....#End finden die eigentlichen Berechnungen statt. Hier stehen folgende
Eingabe-Parameter (reservierte Symbole) zur Verfügung: fcut1, fcut2, fsample, numtabs, gain. Denen wird
natürlich vor der Ausführung der entsprechende aktuelle Wert (aus Dialog) zugewiesen. Eine einfache Art von
Programmiersprache macht es nun möglich die Filter-Koeffizienten H[i] für alle i (0...numtabs-1) zu berechnen.
Welche Funktionen und Konstanten benutzt werden können steht hier.  Für die Ablaufsteuerung stehen
folgende Konstrukte zur Verfügung:

Funktion / Anweisung Beschreibung
$FOR <ind>=<start> TO <end> <ind> wird mit <start> initialisiert, bei jedem Schleifendurchgang um 1 erhöht
bis <end> erreicht ist. Bei jedem Durchgang wird der Block bis $ENDFOR
gerechnet. <ind> ist nur innerhalb des $FOR-Blocks definiert
$ENDFOR schließt den $FOR-Block ab
$IF <val1> > <val2> $IF-Block wird ausgeführt wenn <val1> größer <val2> ist
$IF <val1> < <val2> $IF-Block wird ausgeführt wenn <val1> kleiner <val2> ist
$IF <val1> = <val2> $IF-Block wird ausgeführt wenn <val1> gleich <val2> ist, val1 und val2 werden voher auf Integer gerundet
$ELSE schließt $IF-Block ab und beginnt Alternativ-Block
$ENDIF schließt den $IF-Block oder $ELSE-Block ab

Bitte am Ende nicht vergessen, dem Symbol GroupDelay einen Wert zuzuweisen.

Script-Typ Definition der Fensterfunktion:

Dateien dieses Typs müssen immer im Verzeichniss Data/WindowTypes stehen und enden mit ".txt".
Alle Namen dieser Dateien erscheinen in der Auswahlliste Window Type im Dialog.
In einer solchen Datei wird definiert, wie die Koeffizienten des Vektors W[i]  berechnet werden.
Schauen wir uns das am Beispiel der Datei Data/WindowTypes/Blackman.txt mal an:

#ComputeWindow
N = NumTabs-1
$FOR i=0 TO N
    w[i] = 0.42 - 0.5*cos(c_2pi*i/N) + 0.08*cos(2*c_2pi*i/N)
$ENDFOR
#END

Im Block #ComputeWindow....#End finden die Berechnungen statt. Hier steht nur der Eingabe-Parameter
(reserviertes Symbol) numtabs zur Verfügung. Dem wird natürlich vor der Ausführung der entsprechende
aktuelle Wert (aus Dialog) zugewiesen. Ansonsten gilt hier das Gleiche wie bei der Definition der Filter-
Funktion.

Script-Typ Definition des Coff-File-Formats:

Dateien dieses Typs müssen immer im Verzeichniss Data/CoffFileFormats stehen und enden mit ".txt".
Alle Namen dieser Dateien erscheinen in der Auswahlliste Select CoffFile Format im Dialog.
In einer solchen Datei werden keine Berechnungen definiert sondern nur Formatierungen festgelegt.
Schauen wir uns das am Beispiel der Datei Data/CoffFileFormats/C_Like.txt mal an:

#DefineHead
// FilterType = <FilterType>, fcut1 = <fcut1>Hz, fcut2 = <fcut2>Hz
// fsample = <fsample>Hz, Window = <WindowName>, Tabs = <NumTabs>

float <FilterName>[] =
{
#End

#DefineCoffField
<h_i>,
#End

#DefineTail
};
#End

Für die gesamte Datei stehen folgende Ersetzer zur Verfügung: <FilterType>, <fcut1>, <fcut2>, <fsample>,
<WindowName>, <FilterName>
und <NumTabs>. Diese können unter anderem eingesetzt werden, um Kommentare
zu bilden. <FilterType> ist der Name der Filter-Funktions-Script-Datei, <FilterName> der Name dieser Coff-Datei.

Im Block #DefineHead....#End wird das Aussehen des Datei-Kopfes definiert. Hier können beliebige Zeichen und
die soeben genannten Ersetzer verwendet werden.

Im Block #DefineCoffField....#End kommt noch der Ersetzer <h_i> dazu. Für jedes i (i=0...numtabs-1) werden die
Einträge in diesem Block wiederholt. <h_i> wird dabei durch das zuvor berechnete h[i] ersetzt. Dieser Block kann
auch mehrere Zeilen umfassen.

Im Block #DefineTail....#End kann noch ein Abschluss hinzugefügt werden. Alle Zeichen und Ersetzer (außer <h_i>)
können hier verwendet werden.

P.S. Jede Zeile (auch Leer-Zeile) wird immer mit einem Zeilenvorschub abgeschlossen.


DownLoad/Installation

Das Programm könnt ihr kostenlos benutzen, solange es nur für private Zwecke oder für Ausbildung/Studium
verwendet wird. Das Kopieren von Teilen dieses Dokuments ist normalerweise nicht erlaubt, aber nach persönlicher
Anfrage möglich.

Das Programm steht hier in der Version 1.00 (16.10.2010) als ZIP-Datei zum DownLoad bereit.
Das ZIP-File muß dann nur noch unter dem gewünschten Folder entpackt werden, und die EXE kann sofort
gestartet werden. Dieses Programm ist full portable, macht nämlich keinerlei Einträge ins System.

Für Impressum und Kontakt-Möglichkeit bitte auf die ToneCirc-Hauptseite wechseln.


Jetzt noch ein wenig Theorie

Wer sich schon immer gefragt hat, wo eigentlich der Unterschied zwischen einem Analog-FIR-Filter und einem
Digitalen FIR-Filter liegt, sollte jetzt unbedingt weiterlesen.

Ein analoges Signal x(t) wird abgetastet und über ein Digitales FIR-Filter in ein Ausgangs-Signal y~(t) umgewandelt.
Nach einer längeren Ableitung ergibt sich im Frequenz-Bereich dann folgende Formel:

In den rechteckigen Klammern wird das Spektrum von x(t) mit der Sigma-Summe gefaltet. Diese Faltung führt zu
einer Wiederholung des Spektrums an allen Vielfachen der Sample-Frequenz (n/T = n*fs). Da eine reale Abtastung
(Rechteck-Funktion) durchgeführt wird, muß dieses Spektrum noch mit der Spaltfunktion sync(f, T) multipliziert
werden. Der hintere exp-Multiplikator beschreibt nur eine gewisse Verzögerung (konstante Gruppenlaufzeit für
alle Frequenzen), ist also für diese Betrachtung hier unwichtig.

Wenn man genau hinsieht, ist der Teil in den geschweiften Klammern das Spektrum des abgetasteten Signals ohne
Filterung. Wir schreiben das also mal raus:

Wir dividieren nun Formel (1) durch Formel (2) und erhalten:

Und das ist genau die Übertragungsfunktion für ein analoges FIR-Filter, nur dass das Eingangs- und Ausgangs-
Signal rechteck-abgetastete Zeitfunktionen sind. Rein theoretisch gibt es also keinen Unterschied zwischen den
beiden Filter-Typen. Rein gedanklich ist ein Digital-FIR-Filter also nichts Anderes als ein Analog-FIR-Filter, das mit
einer "treppigen" Zeitfunktion gespeisst wird. Absofort reden wir also über das FIR-Filter.

Hier mal ein Beispiel für den Input/Output eines gesampelten FIR-Filtern (Digi-Filter) erstellt mit ToneCirc:
Input: gesampeltes weisses Rauschen (0Hz...20kHz), LoPass-Filter 0...5kHz, fs = 50kHz

Input Spektrum:                                                                         gefiltertes Spektrum:

Man erkennt deutlich das sich wiederholende Spektrum des Eingangs-Signals, das durch die Spalt-Funktion abnimmt.
Nach Betrachtung des zweiten Charts kommt man zur Erkenntniss, dass das FIR-Filter, obwohl es ein LoPass ist, die
hohen Frequenzen oberhalb fs/2 durchläßt. Das kann mit folgenden Ansatz leicht bewiesen werden:

Also:         

Das FIR-Filter wiederholt also seine Wirkung an allen Vielfachen der Sample-Frequenz.

Warum ist die Sprung-Antwort eines FIR-Filters "treppig", die Sinus-Antwort aber nicht ?
Hier die Sprung-Antwort eines LowPasses und die Sinus-Antwort eines Hilbert-Transformers mit ToneFIRDesigner
erstellt:

Mit den oben gewonnenen Erkenntnissen ist das leicht zu erklären: Der Sprung hat ein breites (unendliches)
Frequenz-Spektrum, die hohen Frequenzen um die Vielfache von fs werden vom Filter durchgelassen und erzeugen
so die Treppigkeit der Antwort. Bei einem rein analogen Filter (ohne Abtastung) wäre die Kurven-Form die Selbe,
aber ohne die Stufen.  Beim Sinus ist das nicht so, da er keinerlei Oberwellen beinhaltet.

Zur ToneCirc Hauptseite