Delphi-PRAXiS
Seite 3 von 10     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Circular spectrum visualizer (https://www.delphipraxis.net/200135-circular-spectrum-visualizer.html)

EWeiss 23. Mär 2019 15:08

AW: Circular spectrum visualizer
 
Zitat:

Zitat von Michael II (Beitrag 1428494)
Und im von dir verlinkten VB6 steht klar:

Zitat:

Natürlicher Logarithmus: LOG
LOG berechnet den Logarithmus zur Basis e (die Eulersche Zahl, e ist ungefähr 2.718282). Dies ist der sogenannte natürliche Logarithmus. Es sind nur positive Argumente erlaubt.
VB6 LOG() entspricht also in Delphi ln()

Du kannst schlicht alle LOG() aus VB6 in Delphi durch ln() ersetzen.

Danke dann kann ich das hier vergessen da es keinen sinn macht.
Delphi-Quellcode:
function TSpectrum.Log(x: Real): Real;
begin

    result := ln(x) / ln(10);
end;
Trotzdem Danke für den versuch.
Interessanter link ja da steht fast alles was wichtig wäre.

Zitat:

Du hast nach Tönen gesucht:
Wenn du nicht selbst eine WAV Datei schreiben willst (zum Beispiel mit MathLab und Co), dann findest du hier Töne:
Ich habe mir Audacity herunter geladen und mir eine *.mp3 erstellt wer es zum testen haben möchte ist im Anhang.
50 sec linearer Sinus Ton.
Es gibt immer noch große unterschiede zwischen Original und meiner Version.

gruss

Michael II 23. Mär 2019 15:29

AW: Circular spectrum visualizer
 
result := ln(x) / ln(10); liefert den Logarithmus zur Basis 10.

Der Autor der VB6 Texts hat aber definitiv den Logarithmus zur Basis e gemeint, also in Delphi ln(). [siehe Konstruktion der Funktion in welcher der Autor ln() verwendet - weiter oben]

Hast du in uSpectrum.pas nun die beiden sqr durch sqrt ersetzt? Du hast dann an insgesamt drei Stellen im uSpectrum.pas Code sqrt stehen. Wenn du dann dein Programm laufen lässt und ins Mikrofon singst :-D, sieht's bereits gar nicht so schlecht aus.

(Ich habe den Eindruck, dass für leise Töne etwas viel angezeigt wird. Eventuell gibt's irgendwo im Code noch ein Skalierungsproblem.)

FFT habe ich nicht überprüft. Ich sehe, dass der Autor einige der 2'048 Einheitswurzeln tabelliert hat und die restlichen aus den tabellierten berechnet.
Man könnte hier sogar alle Einheitswurzeln für ein N einmalig tabellieren und dann nutzen, aber die errechneten Werte sind für deine Anwendung auch so genau genug (Der +0.0001 "Trick" (Anheben des Spektrums in der Funktion, welche ln() verwendet) bewirkt einen höheren Fehler.).

EWeiss 23. Mär 2019 15:50

AW: Circular spectrum visualizer
 
Zitat:

Du hast dann an insgesamt drei Stellen im uSpectrum.pas Code sqrt stehen
Es funktioniert ja nur Sector case 1: in meinem source von daher war das schon stimmig da die anderen noch nicht funktionieren.
Aber auch dort habe ich jetzt sqrt addiert. Ist schon stimmig :)

Aber wie gesagt noch gravierende unterschiede.
Sehe ich wenn ich mein Wave abspiele.

SmallInt vom vorherigen Beitrag sollte stimmen von daher ist die Initialisierung eigentlich die gleiche.
Kann aber nicht mit Bestimmtheit sagen das die Probleme nicht von der FFT herrühren was die Datentypen angeht.
Wäre super wenn sich mal jemand die mühe macht das nochmal gegen zu prüfen ;) :duck:

Rings 300hz 10 Octaves (müssten so aussehen aber da kommt bei mir noch gar nichts.

Hmmm…

EDIT:
Einen Fehler habe ich gefunden.
FFT..
Delphi-Quellcode:
  if FView = 0 then
    sr := (4096 * (FGain / 100)) / FFFTSize
  else
  sr := 1 / FFFTSize;
muss aber
Delphi-Quellcode:
  if FView = 0 then
    sr := (4096 * FGain) / FFFTSize
  else
  sr := 1 / FFFTSize;
sein
Macht schon einen großen Unterschied ob 8 oder 0,08

gruss

EWeiss 23. Mär 2019 16:43

AW: Circular spectrum visualizer
 
Ein weiteres DatenType Problem

Delphi-Quellcode:
pEx := (Power(FOctaveCount + 1, 2) / 2); // in Delphi 32
Code:
pEx = ((2 ^ (mOctaveCount + 1)) / 2) ' in VB 128
ok:
sorry war verdreht..
Delphi-Quellcode:
pEx := (Power(2, FOctaveCount + 1) / 2);


kann es sein das diese Berechnung falsch ist nach der Änderung von Integer zu SmallInt?
Delphi-Quellcode:
procedure TSpectrum.ToComplex(Dat: array of SmallInt; var Out: array of TComplex);
var
  i, p: Integer;
begin
  p := 0;

  for i := 0 to (FFFTSize * 2 - 1) do
  begin
    if i mod 2 <> 0 then
      continue;

    Out[p].r := (((Dat[i]) + Dat[i + 1]) / 65536) * Window_[p];
    Out[p].i := 0;
    inc(p);
  end;
end;
Mich irritieren die / 65536
Weil irgendwas stimmt mit den Spectrumdaten nicht die sind bei mir einfach zu hoch.

gruss

Delphi.Narium 23. Mär 2019 17:34

AW: Circular spectrum visualizer
 
32 := 2^5
128 := 2^7

Überprüf' bitte mal, ob FOctaveCount unter Delphi den gleichen Wert zugewiesen bekommt, wie unter VB.

Der Unterschied zwischen
Code:
pEx = ((2 ^ (mOctaveCount + 1)) / 2) ' in VB 128
und
Code:
pEx := (Power(2, FOctaveCount + 1) / 2); // in Delphi 32
wäre für meine Begriffe nur dadurch zu erklären, dass in Delphi FOctaveCount = 5 und mOctaveCount in VB = 7 ist.
Code:
pEx = ((2 ^ (7 + 1)) / 2) ' in VB 128
pEx = ((2 ^ (8)) / 2) ' in VB 128
pEx = ((256) / 2) ' in VB 128
pEx = (128) ' in VB 128
Code:
pEx := (Power(2, 5 + 1) / 2); // in Delphi 32
pEx := (Power(2, 6) / 2); // in Delphi 32
pEx := (64 / 2); // in Delphi 32
pEx := (32); // in Delphi 32
Da der Wert aus der Ini-Datei gelesen werden kann, prüf' bitte mal, ob es dort Unterschiede gibt.

EWeiss 23. Mär 2019 17:42

AW: Circular spectrum visualizer
 
Zitat:

wäre für meine Begriffe nur dadurch zu erklären, dass in Delphi FOctaveCount = 5 und mOctaveCount in VB = 7 ist.
Ich habe mich da vertan

Vielleicht hast du die Korrektur übersehen.
Zitat:

sorry war verdreht..
pEx := (Power(2, FOctaveCount + 1) / 2);
warum ist in Delphi FOctaveCount = 5 ? ist das gleiche wie in VB "7" + die 1 dann 8 natürlich.
Ach so das war nur eine Annahme von dir.. Sorry habe ich falsch interpretiert.

so habe ich die 128..
frage mich aber noch was mit dem ist.
Zitat:

Mich irritieren die / 65536
Ist echt schwierig da auf den gleichen Nenner zu kommen.

gruss

Delphi.Narium 23. Mär 2019 18:30

AW: Circular spectrum visualizer
 
Was ich jetzt mache, ist nur noch "Spekulatius" ;-)

Delphi-Quellcode:
 Out[p].r := (((Dat[i]) + Dat[i + 1]) / 65536) * Window_[p];


Dat = SmallInt -> -32768..32767
Dat[i] + Dat[i + 1] = maximal 65536.

Wenn also Dat[i] und Dat[i + 1] irgendwo zwischen 0 und 32767 liegen, kommt irgendwas zwischen 0 und 65536 bei der Addition heraus. Dividieren wir nun durch 65536, liegt das Ergebnis irgendwo zwischen 0 und 1.

Window_[*] wird in InitHamming befüllt.
Delphi-Quellcode:
for n := 0 to FFFTSize - 1 do
    Window_[n] := 0.53836 - 0.46164 * Cos(6.28318530717959 * n / (FFFTSize {- 1}));
Code:
For n = 0 To mFFTSize - 1
   Window(n) = 0.53836 - 0.46164 * Cos(6.28318530717959 * n / (mFFTSize - 1))
In der Delphiquelle ist das -1 auskommentiert. Kann mir zwar nicht vorstellen, dass das jetzt sehr gravierende Auswirkungen hat, aber wirklich weiß ich das nicht.

Könntest Du mal den Inhalt von Window_ jeweils ausgeben und die Werte dadrin miteinander vergleichen?

Wenn hier inhaltlich irgendwelche Unterschiede sein sollten, so kann das gravierende Auswirkungen auf die weiteren Berechnungen haben.

EWeiss 23. Mär 2019 18:57

AW: Circular spectrum visualizer
 
Zitat:

Könntest Du mal den Inhalt von Window_ jeweils ausgeben und die Werte dadrin miteinander vergleichen?
Werde ich mal machen. .Danke

Zitat:

Wenn also Dat[i] und Dat[i + 1] irgendwo zwischen 0 und 32767 liegen, kommt irgendwas zwischen 0 und 65536 bei der Addition heraus. Dividieren wir nun durch 65536, liegt das Ergebnis irgendwo zwischen 0 und 1.
Scheint dann wohl in Ordnung zu sein das es mit 65536 dividiert wird.
Dachte nur der wert müsste höher sein.

gruss

EWeiss 23. Mär 2019 21:05

AW: Circular spectrum visualizer
 
Habe jetzt mal nur InitHamming Analysiert..
Daten sind wie folgt.
Code:
Delphi
// mit - 1
0,076719999313
0,076722174883
0,076728701591
0,076739571989
0,076754793525
0,0767743662
0,076798290014
0,076826557517
0,076859176159
0,076896138489

VB6
: Window(0) : 0,07672 : Single : modMain.InitHamming
: Window(1) : 7,672217E-02 : Single : modMain.InitHamming
: Window(2) : 0,0767287 : Single : modMain.InitHamming
: Window(3) : 7,673957E-02 : Single : modMain.InitHamming
: Window(4) : 7,675479E-02 : Single : modMain.InitHamming
: Window(5) : 7,677437E-02 : Single : modMain.InitHamming
: Window(6) : 7,679829E-02 : Single : modMain.InitHamming
: Window(7) : 7,682656E-02 : Single : modMain.InitHamming
: Window(8) : 7,685918E-02 : Single : modMain.InitHamming
: Window(9) : 7,689614E-02 : Single : modMain.InitHamming

Delphi
// ohne - 1
0,076719999313
0,076722174883
0,07672868669
0,076739549637
0,076754763722
0,076774314046
0,076798208058
0,076826453209
0,076859034598
0,076895967126
Wie man sehen kann weichen die Daten extrem von VB6 ab.
Habe mich gefragt warum. Das einzige das in frage kommt ist Cosinus "Cos"
Delphi-Quellcode:
Window_[n] := 0.53836 - 0.46164 * Cos(6.28318530717959 * n / (FFFTSize - 1));

also nur Cosinus analysiert und das kommt dabei raus.

VB6: Die ersten 10 Einträge
1
0,9999953
0,9999812
0,9999576
0,9999246
0,9998822
0,9998304
0,9997692
0,9996985
0,9996185
0,9995289

Delphi:
Die ersten 10 einträge von Cos() sind 1
von 11 > 18 ist die Value '0,999'

Nun da darf man sich nicht wundern das nichts funktioniert..
Was ist da wieder im argen.

Habe das Minus 1 wieder aktiviert.

gruss

Michael II 23. Mär 2019 21:36

AW: Circular spectrum visualizer
 
Deine Berechnung:
VB Window(3) : 7,673957E-02
Delphi 0,076739571989

7,673957E-02 bedeutet 7,673957 * 10^(-02) = 0,07673957
und dies entspricht dem Wert, den du mit Delphi erhältst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 Uhr.
Seite 3 von 10     123 45     Letzte »    

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