AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Circular spectrum visualizer

Circular spectrum visualizer

Ein Thema von EWeiss · begonnen am 22. Mär 2019 · letzter Beitrag vom 23. Jun 2019
Antwort Antwort
Seite 5 von 10   « Erste     345 67     Letzte » 
EWeiss
Projekt entfernt..

Geändert von EWeiss (24. Jul 2019 um 05:46 Uhr)
 
Michael II

 
Delphi 11 Alexandria
 
#41
  Alt 24. Mär 2019, 16:53
Hoi EWeiss

mit Tests wie beschrieben

Delphi-Quellcode:
  for i := 0 to FFFTSize -1 do
  begin
     Dat[i].r := cos(i/FFFTSize*2*pi);
     Dat[i].i := 0;
  end;
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.

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.
Michael Gasser
  Mit Zitat antworten Zitat
Michael II

 
Delphi 11 Alexandria
 
#42
  Alt 24. Mär 2019, 17:07
und falls du noch daran arbeitest..

Betrifft uSpectrum.pas, TSpectrum.Draw

Im VB Code steht:
q1 = (mGain * Gain + 9) Im Delphi Code
q1 := (FGain * FGain + 9);
Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
 
#43
  Alt 24. Mär 2019, 18:41
Zitat:
@Delphi.Narium
Danke für deine ausführliche Erklärung.

und falls du noch daran arbeitest..

Betrifft uSpectrum.pas, TSpectrum.Draw

Im VB Code steht:
q1 = (mGain * Gain + 9) Im Delphi Code
q1 := (FGain * FGain + 9);
Jo bin ich noch.
Sehe keinen Widerspruch.
Delphi-Quellcode:
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;
Spätestens nach dem ändern des Property über das Knob ist FGain das gleich wie Gain.
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

Geändert von EWeiss (11. Jul 2019 um 16:56 Uhr)
  Mit Zitat antworten Zitat
Michael II

 
Delphi 11 Alexandria
 
#44
  Alt 24. Mär 2019, 19:03
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 )

Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
 
#45
  Alt 24. Mär 2019, 19:10
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 )

100% gebe ich dir recht.
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:
Ah gut spielt Gain FGain keine Rolle.
Doch schon nur ich sehe keinen sinn darin den Getter aufzurufen wenn FGain von außen gesetzt wird.
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

Geändert von EWeiss (24. Mär 2019 um 19:22 Uhr)
  Mit Zitat antworten Zitat
EWeiss
 
#46
  Alt 24. Mär 2019, 19:36
Sorry hier noch zwei shots..
Einmal mit und einmal ohne Sound..

Vielleicht muss ich den Buffer vorher nullen mit FillChar\FillMemory.

gruss

Geändert von EWeiss (11. Jul 2019 um 16:56 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

 
Delphi 7 Professional
 
#47
  Alt 25. Mär 2019, 14:35
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.
  Mit Zitat antworten Zitat
Michael II

 
Delphi 11 Alexandria
 
#48
  Alt 25. Mär 2019, 21:25
Hoi EWeiss

die von dir genutzte uSpectrum.FFT Funktion rechnet falsch.

Nimm doch eine hier aus dem Forum, zum Beispiel diese hier


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 Cooley und Tukey. Ich speichere dabei sämtliche Einheitswurzeln einmal in einer Tabelle ab und greife dann auf diese zu. Eine solche iterative Lösung ist bei der von dir gewählten Problemgrösse FFFTSize=2048 aber nur ca. 6 Mal schneller.

Selbst auf meinem langsamen Notebook benötigt obige Lösung nur ca. 2/1000 Sekunden.


Viel Spass beim Codieren.
Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
 
#49
  Alt 26. Mär 2019, 01:34
@Michael Danke werde es mal testen.
Ich habe jetzt aber das Problem Gain wird in der FFT nicht berücksichtigt.

Delphi-Quellcode:
  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;
Wo muss ich eine vergleichbare Berechnung zur FFT hinzufügen?
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

Geändert von EWeiss (26. Mär 2019 um 02:51 Uhr)
  Mit Zitat antworten Zitat
EWeiss
 
#50
  Alt 26. Mär 2019, 05:19
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

Geändert von EWeiss (11. Jul 2019 um 16:56 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz