![]() |
AW: Circular spectrum visualizer
Hoi EWeiss
mit Tests wie beschrieben
Delphi-Quellcode:
kannst du prüfen, ob deine FFT überhaupt korrekte Resultate zurückmeldet. Du kannst deine FFT direkt mit diesem Test-Dat-Array aufrufen oder den Test-Code wie beschrieben einfügen in deine FFT.
for i := 0 to FFFTSize -1 do
begin Dat[i].r := cos(i/FFFTSize*2*pi); Dat[i].i := 0; end; Dann setzt du einen Breakpoint am Ende deiner FFT Prozedur und überprüfst, ob FFT korrekt rechnet (ob korrekte Werte in Dat stehen). Wenn keine korrekten Werte drin stehen, dann - musst du deine FFT proc checken. oder - du nimmst eine fertige FFT proc hier aus dem Forum. |
AW: Circular spectrum visualizer
und falls du noch daran arbeitest..
Betrifft uSpectrum.pas, TSpectrum.Draw Im VB Code steht:
Delphi-Quellcode:
Im Delphi Code
q1 = (mGain * Gain + 9)
Delphi-Quellcode:
q1 := (FGain * FGain + 9);
|
AW: Circular spectrum visualizer
Zitat:
Zitat:
Sehe keinen Widerspruch.
Delphi-Quellcode:
Spätestens nach dem ändern des Property über das Knob ist FGain das gleich wie Gain.
property Gain: Single read GetGain write SetGain;
function TSpectrum.GetGain: Single; begin Result := FGain; end; procedure TSpectrum.SetGain(const Value: Single); begin FGain := Value; end; Innerhalb der FFT ändere ich den wert nicht er bleibt dort immer gleich. also ist FGain = 4 dann ist es Gain ebenfalls Es mag für eine Mikrosekunde ein unterschied sein danach ist es aber ausgeglichen, dreh ja nicht ständig am Knob. Kurz um FGain ist immer Gain solange ich das Knob nicht betätige. Warum soll ich mich also des Getter bedienen wenn die Value von FGain von außerhalb gesetzt wird. Im Anhang 2 Shots in denen man sehen kann was "var" bei FFT bewirkt. Volllast es wird keine Musik wiedergegeben. gruss |
AW: Circular spectrum visualizer
Ah gut spielt Gain FGain keine Rolle.
Wegen var oder nicht var: Es gibt schon einen Unterschied zwischen procedure A( var x : integer ) und procedure A( x : integer ) ;-) |
AW: Circular spectrum visualizer
Zitat:
Das sehe ich ja auch wenn ich die beiden Bilder so betrachte. ohne var wird Rings gar nicht angezeigt mit var in Vollausschlag. (wohlbemerkt ohne Musik) Spectrum müsste eigentlich 0 sein. Ich glaube dir das es richtig ist habe nur jetzt ein Problem das ich herausfinden muss warum nur das var eine solch immense Veränderung hervorruft. Das ist mein Problem ;) Zitat:
Wenn jetzt im Getter 1 Millionen von Berechnungen stattfinden würden die ich bereits außerhalb von Getter getätigt habe wäre der Code redundant.. So heißt das Wort denke ich mal. ;) Es wäre unnötige rechen zeit da der wert FGain = Gain schon bekannt ist. Wäre in dem Fall doppelt gemoppelt. gruss |
AW: Circular spectrum visualizer
Sorry hier noch zwei shots..
Einmal mit und einmal ohne Sound.. Vielleicht muss ich den Buffer vorher nullen mit FillChar\FillMemory. gruss |
AW: Circular spectrum visualizer
Oder kann es doch noch irgendwo zu 'nem Überlauf kommen.
Eigentlich hätte ich nach den bisherigen Analysen immer mit Werte rund um 0 gerechnet (so wie im zweiten Screenshot). Die Werte im ersten Screenshot liegen irgendwie alle weit außerhalb des Bereiches, den man in 'nem Integer unterbringen kann. Solange es sich nur um positive Werte handeln sollte, also > 0, würden sie so gerade eben in 'nen Cardinal passen. Da es aber (wie mir scheint) auch negative Werte geben kann, muss es wohl Int64 werden. |
AW: Circular spectrum visualizer
Hoi EWeiss
die von dir genutzte uSpectrum.FFT Funktion rechnet falsch. Nimm doch eine hier aus dem Forum, zum Beispiel diese ![]() Ich habe die Unit aus dem Forum etwas gekürzt (Code hier unten). Diese Unit fügst du zu deinem Projekt hinzu:
Delphi-Quellcode:
unit uDFT;
interface uses Math; // // Autor Matze - siehe: https://www.delphipraxis.net/597828-post1.html // type TComplex = record re, im: Extended; end; TComplexArray = array of TComplex; procedure DFT(var a: TComplexArray); implementation function AddC(a, b: TComplex): TComplex; begin Result.re := a.re + b.re; Result.im := a.im + b.im; end; function SubC(a, b: TComplex): TComplex; begin Result.re := a.re - b.re; Result.im := a.im - b.im; end; function MulC(a, b: TComplex): TComplex; begin Result.re := a.re * b.re - a.im * b.im; Result.im := a.re * b.im + a.im * b.re; end; function MakeC(re, im: extended): TComplex; begin Result.re := re; Result.im := im; end; procedure shuffle(var a: TComplexArray; n, lo: Integer); var I, m: Integer; b: TComplexArray; begin m := n shr 1; setlength(b, m); for I := 0 to m - 1 do b[i] := a[lo + i]; for I := 0 to m - 1 do a[lo + i + i + 1] := a[lo + i + m]; for I := 0 to m - 1 do a[lo + i + i] := b[i]; end; procedure DoFFT(var a: TComplexArray; n, lo: Integer; w: TComplex); var I, m: Integer; z, v, h: TComplex; begin if n and (n - 1) = 0 then begin if n > 1 then begin m := n shr 1; z := MakeC(1, 0); for I := lo to lo + m - 1 do begin h := SubC(a[i], a[i + m]); a[i] := AddC(a[i], a[i + m]); a[i + m] := MulC(h, z); z:=MulC(z,w); end; v := MulC(w, w); DoFFT(a, m, lo, v); DoFFT(a, m, lo + m, v); shuffle(a, n, lo); end; end; end; procedure DFT(var a: TComplexArray); begin DoFFT(a, length(a), 0, MakeC(cos(2 * Pi / length(a)), sin(2 * Pi / length(a)))); end; end. Wenn du die verwendeten Dateitypen (dein TComplex und Matzes TComplex) nicht anpassen magst, dann ersetze in uSpectrum.pas die FFT Funktion durch diese hier (Code unten). (uDFT unter uses hinzuzufügen.)
Delphi-Quellcode:
uses ….uDFT;
… … procedure TSpectrum.FFT( var Dat : array of TComplex ); var a : uDFT.TComplexArray; i, n : integer; begin n := length( Dat ); setlength( a, n ); for i := 0 to n-1 do begin a[i].re := Dat[i].r; a[i].im := Dat[i].i; end; DFT( a ); for i := 0 to n-1 do begin Dat[i].r := a[i].re/n; Dat[i].i := a[i].im/n; end; end; Ich verwende für meine Programme eine iterative Version von ![]() Selbst auf meinem langsamen Notebook benötigt obige Lösung nur ca. 2/1000 Sekunden. Viel Spass beim Codieren. |
AW: Circular spectrum visualizer
@Michael Danke werde es mal testen.
Ich habe jetzt aber das Problem Gain wird in der FFT nicht berücksichtigt.
Delphi-Quellcode:
Wo muss ich eine vergleichbare Berechnung zur FFT hinzufügen?
if FView = 0 then
sr := (4096 * FGain) / FFFTSize else sr := 1 / FFFTSize; for i := 0 to (FFFTSize div 2) - 1 do begin Dat[i].r := LimitedSingleValue(Dat[i].r * sr); Dat[i].i := LimitedSingleValue(Dat[i].i * sr); end; Mit deinen neuen FFT habe ich vielleicht 10 Pixel bei normaler Visualisierung. Mit der von Matze wird die Visualisierung fast korrekt angezeigt aber mit einer Auslastung von 80% eines CPU Kerns. gruss |
AW: Circular spectrum visualizer
Der FFT von Matze ist leider auch nicht korrekt aber destotrotz mein Ergebnis ist jetzt zu 98% richtig. Einen Tick zu wenig! CPU last 2%
Den Rest bekomme ich auch noch hin. Bin also doch nicht ganz so blöd wie ich hier hingestellt werde brauche lediglich etwas mehr zeit! Benötigte nur einen Funktionierenden FFT! Weil meine Mathe Kenntnisse dafür nicht ausreichen (niemand ist perfekt) Ich habe jetzt Zeit investiert aber was zählt das schon die wird mit unter für weniger sinnvolles verplempert. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz