AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Circular spectrum visualizer
Thema durchsuchen
Ansicht
Themen-Optionen

Circular spectrum visualizer

Ein Thema von EWeiss · begonnen am 22. Mär 2019 · letzter Beitrag vom 23. Jun 2019
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 14:09
Für die Interessierten..
Fangen wir beim Anfang an. Und die Quelle

Integer VB = SmallInt in Delphi..

Initialisieren von WaveIn.

Code:
Public Type BUFFER
    Data() As Integer
    Header As WAVEHDR
End Type
Delphi-Quellcode:
TBuffer = Record
  Data: array of SmallInt;
  Header: TWAVEHDR;
end;
Code:
ReDim Buffers(3)
    For i = 0 To UBound(Buffers)
         With Buffers(i)
             ReDim .Data(count - 1)
             .Header.lpData = VarPtr(.Data(0))
             .Header.dwBufferLength = count * 2
             .Header.dwFlags = 0
             .Header.dwLoops = 0
             ret = waveInPrepareHeader(hWave, .Header, Len(.Header))
             If ret Then ShowMessage ret: Exit Function
         End With
    Next i

    For i = 0 To UBound(Buffers)
        ret = waveInAddBuffer(hWave, Buffers(i).Header, Len(Buffers(i).Header))
        If ret Then ShowMessage ret: Exit Function
    Next i
   
    ret = waveInStart(hWave)
    If ret Then ShowMessage ret: Exit Function
   
    InitCapture = True
Delphi-Quellcode:
SetLength(Buffers, 3);
  for i := 0 to High(Buffers) do
  begin
    SetLength(Buffers[i].Data, round(count - 1));
    Buffers[i].Header.lpData := @Buffers[i].Data[0];
    Buffers[i].Header.dwBufferLength := round(count * 2);
    Buffers[i].Header.dwFlags := 0;
    Buffers[i].Header.dwLoops := 0;
    mres := waveInPrepareHeader(WaveIn, @Buffers[i].Header, SizeOf(TWAVEHDR));
    if mres <> 0 then
    begin
      SetMessage(mres);
      exit;
    end;
  end;

  for i := 0 to High(Buffers) do
  begin
    mres := waveInAddBuffer(WaveIn, @Buffers[i].Header, SizeOf(TWAVEHDR));
    if mres <> 0 then
    begin
      SetMessage(mres);
      exit;
    end;
  end;

  mres := waveInStart(WaveIn);
  if mres <> 0 then
  begin
    SetMessage(mres);
    exit;
  end;

  Result := True;
warum er jetzt hier
Code:
Len(Buffers(i).Header))
verwendet entschließ sich mir sollte eigentlich das gleiche sein wie
Code:
Len(.Header))
Wenn nicht muss ich es noch ändern.

Auf die Zuweisungen des Headers habe ich keinen Einfluss die Datentypen sind so wie sie gegeben sind.
Ich muss DWORD in Delphi verwenden wo es angesagt ist und kann mich diesbezüglich nicht auf die Typen von VB6 einlassen.
Wenn das OK ist dann sollte die Initialisierung eigentlich korrekt sein.

Denke das ist übersichtlich und sollte für den Anfang nicht zu viel sein um zu überblicken ob alles OK ist.

Wenn ihr auch der Meinung seid geht es im nächsten Beitrag weiter.

gruss

Geändert von EWeiss (23. Mär 2019 um 14:13 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 14:50
Besten Dank für deine VB6 SQR Klarstellung (dein Link):

SQR() in VB entspricht sqrt() ["square root"] in Delphi.
Verwende also wie bereits weiter oben vorgeschlagen in deiner uSound.pas unbedingt sqrt und nicht sqr.
Beispiel VB6: SQR(25)=5 - Delphi sqr(25)=25*25=625 Delphi sqrt(25)=5.


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:

https://www.wavtones.com/functiongenerator.php
Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 14:57
Zitat:
Verwende also wie bereits weiter oben vorgeschlagen in deiner uSound.pas unbedingt sqrt und nicht sqr.
Somit ist das 100% geklärt
Wäre schön wenn das bei den anderen Datentypen auch der fall wäre.. um zu einem gleichen er Ergebnis zu gelangen.
Danke für die Richtigstellung.

gruss
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 15:01
Zitat:
Beim zweiten Mal hat er kein With und muss deswegen Buffers[i] davor schreiben.
Ja sorry habe ich übersehen habe selbst über 15 Jahre VB6 Anwendungen geschrieben im Eifer des Gefechts kann das schon mal passieren.
SizeOf(TWaveHeader) ist dann korrekt.

Zitat:
Es wäre empfehlenswert, wenn du dir ein Grundlagenwerk Mathematik der Oberstufe zu legst. Ein suchen bei Internetbuchhandlungen nach "Mathematik Abitur" sollte zum Ziel führen.
Entsprechende Websites und Tutorials gehen natürlich auch.
Danke für den Ratschlag kein Problem..
Aber ich fange jetzt mit 61 Jahren nicht mehr an mir höhere Mathematik anzueignen es geht doch nur um eine Portierung als Example für meine Bibliothek.

Es freut mich trotzdem wenn hier einige dabei sind die mir weiterhelfen möchten.
Zumal der Thread auch interessant ist für VB6 Umsteiger.. ja es gibt noch genug davon.

gruss

Geändert von EWeiss (23. Mär 2019 um 15:06 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 15:03
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.
Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 15:08
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

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

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 15:29
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 , 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.).
Michael Gasser
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#8

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 15:50
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

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

Geändert von EWeiss (11. Jul 2019 um 15:56 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 16:43
Ein weiteres DatenType Problem

pEx := (Power(FOctaveCount + 1, 2) / 2); // in Delphi 32
Code:
pEx = ((2 ^ (mOctaveCount + 1)) / 2) ' in VB 128
ok:
sorry war verdreht..
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

Geändert von EWeiss (23. Mär 2019 um 17:00 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.081 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Circular spectrum visualizer

  Alt 23. Mär 2019, 14:55
warum er jetzt hier
Code:
Len(Buffers(i).Header))
verwendet entschließ sich mir sollte eigentlich das gleiche sein wie
Code:
Len(.Header))
Wenn nicht muss ich es noch ändern.
Einfach nochmal genau hingucken.
Beim ersten Mal nimmt er ein With-Statment, deswegen kann er Len(.Header) schreiben.
Beim zweiten Mal hat er kein With und muss deswegen Buffers[i] davor schreiben.

Auch auf die Gefahr hin, dass es wieder als persönlicher Angriff aufgefasst wird:
Es wäre empfehlenswert, wenn du dir ein Grundlagenwerk Mathematik der Oberstufe zu legst. Ein suchen bei Internetbuchhandlungen nach "Mathematik Abitur" sollte zum Ziel führen.
Entsprechende Websites und Tutorials gehen natürlich auch.
  Mit Zitat antworten Zitat
Antwort Antwort


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 14:33 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-2025 by Thomas Breitkreuz