Hallo !
Es gab schon mal einen ähnlichen Thread hier aber genau auf die Frage wo
ich jetzt auch habe wurde leider keine Antwort gegeben.
Ich möchte in Octave einen FIR berechnen aber nicht mit den Funktionen
die Octave zur Verfügung stellt sondern eben "mit der Hand am Arm".
Ich habe eine Sweep-WAV generiert die ich in Octave einlesen kann. Die
Frequenz läuft von 50Hz bis 18kHz mit 22050 Samples bei einer Samplerate
von 44100Hz. Mein LP-Filter soll z.B. bei 2.5KHz dicht machen. Wie
erwartet zeigt die FFT-Analyse (siehe Bild) wie der Sweep im
Frequenz-Bereich aussieht. Lass ich aber den Filter mit 20 Tabs drüber
laufen ergibt sich nur in der Amplitude eine Änderung. Auch mit 100 Tabs
oder ungeraden oder geraden Anzahl von Tabs sieht das immer gleich aus.
OK, der Code in Octave ist nicht effizient, aber wie gesagt, es sollte
ja erst mal nur zum testen sein. Die Koeffizienten wurden über Tone FIR
Designer errechnet und der Code habe ich von
http://www.fh-schmalkalden.de/schmalkaldenmedia/Realisierung_Digitaler_Filter_in_C-p-419.pdf
An was kann es liegen das man ab 2.5kHz keinen Abfall der Frequenz sieht
?
Gruß Uli
Hier mal der Octave-Code: 1 | % Octave
| 2 |
| 3 | %// FilterType = LoPass, fcut1 = 2.5kHz
| 4 | %// fsample = 44100Hz, Window = Hamming,
| 5 | nc = 20;
| 6 | b=[
| 7 | -0.011433, 0.007947, 0.060518, 0.184715, 0.406822, 0.726661,
| 8 | 1.111126, 1.498814, 1.815087, 1.992966, 2.003541, 1.815087,
| 9 | 1.498814, 1.111126, 0.726661, 0.406822, 0.184715, 0.060518,
| 10 | 0.007947, -0.011433,
| 11 | ];
| 12 |
| 13 | % ----------------------------------------
| 14 | function y=G(ys,nc,b,in_buffer)
| 15 |
| 16 | % alle Werte nach rechts shiften
| 17 | for i=nc:-1:2
| 18 | in_buffer(i) = in_buffer(i-1);
| 19 | end
| 20 |
| 21 | % Schreibe neuen Wert ys in Buffer
| 22 | in_buffer(1) = ys;
| 23 |
| 24 | % Berechne neuen Ausgangswert
| 25 | y = 0;
| 26 | for i=1:+1:nc
| 27 | y += ( b(i)*in_buffer(i) );
| 28 | end
| 29 | endfunction
| 30 | % ----------------------------------------
| 31 | clf
| 32 | t=1; y=0; ys1=0; samplerate=44100;
| 33 | ys = wavread ("ttt.wav");
| 34 | samples=length(ys);
| 35 |
| 36 | % in_buffer loeschen
| 37 | for i=1:+1:nc
| 38 | in_buffer(i) = 0;
| 39 | end
| 40 |
| 41 | for t=1:+1:samples
| 42 | ym(t)=G(ys(t),nc,b,in_buffer);
| 43 | end
| 44 |
| 45 | ym1=abs(fft(ym));
| 46 | yo1=abs(fft(ys));
| 47 |
| 48 | t=1:+1:samples;
| 49 |
| 50 | % FFT-Plot
| 51 | subplot(4,1,1)
| 52 | plot(t*(samplerate/samples),yo1);grid on;
| 53 | axis([0 20000])
| 54 | title("FFT ohne Filter")
| 55 |
| 56 | subplot(4,1,2)
| 57 | plot(t*(samplerate/samples),ym1);grid on;
| 58 | axis([0 20000])
| 59 | title("FFT nach Filter")
| 60 |
| 61 | %Signal-Plot
| 62 | subplot(4,1,3)
| 63 | plot(t,ys(t));grid on;
| 64 | title("Signal ohne Filter")
| 65 |
| 66 | subplot(4,1,4)
| 67 | plot(t,ym(t));grid on;
| 68 | title("Signal mit Filter")
|
Servus Uli,
Ich hab Dir mit Octave (freqz Funktion) den Frequenzgang Deines Filters
gerechnet.
Willst Du wirklich so ein Filter?
BTW:
Du gibst den State (Gedächtnis) Deines Filters nicht zurück, MATLAB und
ich nehme an auch OCTAVE übergeben Werte durch kopieren, nicht durch
Referenz. Im (hab ich mir jetzt nicht angeschaut) Beispiel wo Du den
C-Code nachgetippt hast wird sicher ein Pointer auf deinen in_buffer
übergeben.
Das gibts in MATLAB/Octave nicht!
Du musst als zweite Variable den State zurückgeben! 1 | function [y, in_buffer] = G(ys,nc,b,in_buffer)
|
lg
Markus
PS:
Effizientes umkopieren (was Du in einer Schleife erledigst)
Inprodukt zweier Vektoren (Berechnung Deines Ausgangswertes y, Ersatz
für die zweite Schleife in Deiner Funktion) 1 | y = b(:)' * in_buffer(:);
|
Erzeugen eines Null-Initialisierten Buffers: 1 | in_buffer = zeros(numel(b),1);
|
Hallo Markus !
Erstmal danke für die Antwort.
Markus B. schrieb:
> Servus Uli,
>
> Ich hab Dir mit Octave (freqz Funktion) den Frequenzgang Deines Filters
> gerechnet.
> Willst Du wirklich so ein Filter?
>
Nein Markus natürlich nicht, aber das ist wie beschrieben eben nur zum
Test.
>
> BTW:
> Du gibst den State (Gedächtnis) Deines Filters nicht zurück, MATLAB und
> ich nehme an auch OCTAVE übergeben Werte durch kopieren, nicht durch
> Referenz. Im (hab ich mir jetzt nicht angeschaut) Beispiel wo Du den
> C-Code nachgetippt hast wird sicher ein Pointer auf deinen in_buffer
> übergeben.
> Das gibts in MATLAB/Octave nicht!
>
Ebent ;-) Das gibt es nicht. Deshalb hab ich mal abgeprüft ob Variablen
wie in_buffer oder eben die Koeffizienten b(i) in der Funktion zur
Verfügung stehen. Ich übergebe sie ja beim Aufruf mit z.B. G(...b,,,)
Und sie stehen auch drin !
>
> Du musst als zweite Variable den State zurückgeben!function [y,
> in_buffer] = G(ys,nc,b,in_buffer)
> lg
> Markus
>
Klar, man hätte korrektehalber y und in_buffer mit einem "return"
zurückgeben können, aber nachdem die Werte außerhalb und innerhalb der
Funktion(Scope) identisch sind(hab ich mir durch printf anzeigen
lassen), hab ich mir das an der Stelle erspart.
Ich weiß das klingt wie hingeschludert, aber ich befürchte selbst wenn
alles 1000% korrekt programmiert ist, dass das Ergebnis nicht besser
aussieht als wie oben im Bild ! In dem anderen Thread sagte der
Thread-Eröffner man muss mit den Koeffizienten einbischen
herum-experimentieren dann bekommt man den Filter tatsächlich zum
laufen, aber genau das möchte ich eben nicht.
Gruß Uli
Hallo Uli,
das rechtsshiften der Werte kommt nicht zurück. Machs' so wie Markus das
beschrieben hat, Deine Variante funktioniert nicht.
Cheers
Detlef
Detlef _a schrieb:
> Hallo Uli,
>
> das rechtsshiften der Werte kommt nicht zurück. Machs' so wie Markus das
> beschrieben hat, Deine Variante funktioniert nicht.
>
> Cheers
> Detlef
Ups....da hab ich etwas nicht in Octave nicht gewußt....Shit happens...
denn als ich das von Markus einbaute...sieht das ganze jetzt so
aus...siehe Bild...und genau das wollte ich !
Dank euch beiden :-)
Grüßle Uli
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|