![]() |
Bass.dll Wave Data / FFT Data ?
Hi,
ich sitze gerade dran eine "Peak Spektrum" Funktion zu basteln. Nun ist meine Frage, wie ich direkt nach dem laden die daten in 2 Arrays (linker Peak und rechter Peak)laden kann. Außerdem würde mich noch interessieren was dafür geeignet ist FFT Daten oder Wave Daten ? Ich hoffe mir kann da jemand helfen. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
Weil die Daten erst geglättet werden müssen damit man keine Negativen werte bekommt. Daher jagt man sie ja auch durch den FFT(fast Fourier transformation). ![]() EDIT: Die Daten bekommst du so!
Delphi-Quellcode:
function SolvePeak(nValue : integer; nTotal : integer): integer;
var nRet : Integer; begin nRet := 0; If nTotal <> 0 Then nRet := (nValue * 100) div nTotal; Result := nRet; end;
Delphi-Quellcode:
nLpeak und nRpeak enthalten nun jeweils 128 Samples
var
nLevel, nLpeak, nRpeak : Integer; begin nLevel := BassChannelGetLevel; nLpeak := SolvePeak(Loword(nLevel), 128); nRpeak := SolvePeak(Hiword(nLevel), 128); Damit kannst nun arbeiten. gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
danke schonmal für die Hilfe. Bei der von dir geposteten Funktion habe ich allerdings doch noch ein paar Fragen. BassChannelGetLevel gibt mir doch nur das aktuelle Level zur gerade gespielten Liedstelle oder ? Also erhalte ich damit den Peak während der Spielzeit des Lied. Ich bräuchte aber ein Array in dem ich mithilfe einer Funktion die Peaks des ganzen Liedes bekomme und das ganze ohne das das Lied dazu laufen muss. Ich hoffe du verstehst was ich meine :) Achso mit Spekrtum meinte ich soetwas: Schnipp mfg Blamaster [edit=Matze]Bild angehängt. MfG, Matze[/edit] |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
|
Re: Bass.dll Wave Data / FFT Data ?
Hi,
jops ich dachte es währe ein Spektrum :wall: sorry. Die Frage ist dann allerdings trotzdem noch, wie ich an ein Array mit den Peaks kommen kann. :gruebel: mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
Meine Antwort war also richtig. ;) grmmm.. geh auf die Seite und lade dir tsampledisplay3d da steht alles drin. :) ![]() gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
die kompo hatte ich mir auch schonmal angesehen, leider habe ich sie partu nicht installiert bekommen (alles so eingebunden wie es in der Beschreibung steht). Außerdem glaube ich das, dass ganze für den Verwendugszweck etwas arge komplex und resourcen fressen ist. (Kann sein das ich mich täusche konnte es wie schon gesagt ja selber noch nicht testen). Das einfachste währe wirklich ein array mit den peaks. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
wie man an die daten gelangt. Beim besten willen kann dir hier keine komplette Anwendung bereitstellen. Das Thema kann man nicht einfach mal mit einem Array abtun damit ist es nicht getan. Letztendlich müssen die Daten ja auch verarbeitet werden. gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
Schau dir mal meinen
![]() |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
thx :)
genau das hatte ich gesucht. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 3)
Hi,
ich habe ebend mal wieder ein bisschen gebastelt und mir das Custom loop Beispiel der bass.dll mal genauer angesehen. (Custom Loop im Anhang) Dann hab ich mich dran gesetzt und versucht die Funktion zu extrhieren und abzuändern. Folgendes kam dabei raus: Deklarationen:
Delphi-Quellcode:
Scan Peaks:
WaveBufR: array of smallint;
WaveBufL: array of smallint;
Delphi-Quellcode:
GetPeak:
procedure TBassPlayer.ScanPeaks(filename: string; PB: TPaintbox);
var cpos,level : DWord; peak : array[0..1] of DWORD; position,bpp : DWORD; counter, i : integer; decoder: HStream; begin cpos := 0; peak[0] := 0; peak[1] := 0; counter := 0; setlength(wavebufL,PB.ClientWidth); setlength(wavebufR,PB.ClientWidth); decoder := BASS_StreamCreateFile(false, PChar(filename), 0, 0, BASS_STREAM_DECODE); if (decoder = 0) then decoder := BASS_MusicLoad(false, PChar(filename), 0, 0, BASS_MUSIC_DECODE, 0); bpp := BASS_ChannelGetLength(decoder) div PB.ClientWidth; // stream bytes per pixel if (bpp < BASS_ChannelSeconds2Bytes(decoder, 0.02)) then // minimum 20ms per pixel (BASS_ChannelGetLevel scans 20ms) bpp := BASS_ChannelSeconds2Bytes(decoder, 0.02); for i:= 1 to length(wavebufL) do begin level := BASS_ChannelGetLevel(decoder); // scan peaks if (peak[0]<LOWORD(level)) then peak[0]:=LOWORD(level); // set left peak if (peak[1]<HIWORD(level)) then peak[1]:=HIWORD(level); // set right peak if BASS_ChannelIsActive(decoder) <> BASS_ACTIVE_PLAYING then begin break; // reached the end end else position := BASS_ChannelGetPosition(decoder) div bpp; if position > cpos then begin inc(counter); if counter <= length(wavebufL)-1 then begin} wavebufL[i] := peak[0]; wavebufR[i] := peak[1]; end; if (position >= dword(PB.ClientWidth)) then break; cpos := position; end; peak[0] := 0; peak[1] := 0; end; BASS_StreamFree(decoder); // free the decoder end;
Delphi-Quellcode:
Und Aufruf + zeichnen im eigentlichen Programm:
function TBassPlayer.GetLPeak(position:integer): Integer;
begin result:= WaveBufL[position]; end; function TBassPlayer.GetRPeak(position:integer): Integer; begin result:= WaveBufR[position]; end;
Delphi-Quellcode:
Nun ist aber das Problem, dass die Grafik nicht richtig angezeit wird. (Im Anhang einmal ein Bild wie es aussehen müsste und eins wie es aussieht)
procedure TForm1.Button3Click(Sender: TObject);
begin MPlayer.ScanPeaks(ListBox1.Items.Strings[0],PB); DrawSpectrum; end; procedure TForm1.DrawSpectrum; var i,ht : integer; begin //draw peaks ht := PB.ClientHeight div 2; for i:=1 to PB.ClientWidth do begin bmp.Canvas.MoveTo(i, ht); bmp.Canvas.Pen.Color := clLime; bmp.Canvas.LineTo(i,ht-trunc((MPlayer.GetLPeak(i-1) / 32768) * ht)); bmp.Canvas.Pen.Color := clLime; bmp.Canvas.MoveTo(i, ht+2); bmp.Canvas.LineTo(i, ht+2+trunc((MPlayer.GetRPeak(i-1) / 32768) * ht)); end; PB.Refresh; end; Jemand eine Idee woran das liegen kann ? mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Geht mein Beispiel nicht?
|
Re: Bass.dll Wave Data / FFT Data ?
Sorry hatte garnicht gesehen das du ja extra eine Testdatei angehängt hattets. Ich hatte mit deinen BassPlayerEx geladen. :oops:
Vielen Dank mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Nachdem ich gerade noch die DrawTimeLine angepasst und eingebaut habe tut sich mir wieder ein kleines Problem auf, welches ich noch nicht lösen konnte.
Code in der BassPlayer.pas:
Delphi-Quellcode:
Aufrufen tue ich sie momentan im OnTimer Event mit 20ms:
procedure TBassPlayer.DrawTimeLine(y: integer; PB: TPaintBox; cl: TColor);
var sectime: integer; str: string; x: integer; bpp: DWORD; begin bpp := BASS_ChannelGetLength(channel) div PB.ClientWidth; // stream bytes per pixel if (bpp < BASS_ChannelSeconds2Bytes(channel, 0.02)) then // minimum 20ms per pixel (BASS_ChannelGetLevel scans 20ms) bpp := BASS_ChannelSeconds2Bytes(channel, 0.02); sectime := round(BASS_ChannelBytes2Seconds(Channel, BASS_ChannelGetPosition(Channel))); x := BASS_ChannelGetPosition(channel) div bpp; //format time str := ''; if (sectime mod 60 < 10) then str := '0'; str := str + inttostr(sectime mod 60); str := inttostr(sectime div 60) + ':' + str; //drawline PB.Canvas.Pen.Color := cl; PB.Canvas.MoveTo(x, 0); PB.Canvas.LineTo(x, PB.ClientHeight); //drawtext PB.Canvas.Font.Color := cl; PB.Canvas.Font.Style := [fsBold]; if x > PB.ClientWidth - 20 then dec(x, 40); SetBkMode(PB.Canvas.Handle, TRANSPARENT); PB.Canvas.TextOut(x + 2, y, str); PB.Refresh; end;
Delphi-Quellcode:
Nun funktioniert das ganze soweit auch ganz gut, außer das die Time Line extrem flackert. Wenn ich mir hingegen das CustomLoop Beispiel ansehe läuft sie sehr sauber. Der Aufruf erfolgt dort aber auch in einem 20ms Intervall.
procedure TFMain.Timer1Timer(Sender: TObject);
begin fBassPlayer.DrawTimeLine(10,PaintBox,clRed); end; Jemand eine Idee woran das liegen kann ? (PaintBox.Parent.DoubleBuffered:= true; habe ich im OnCreate testweise auch gesetzt, brachte aber leider keinen wirklichen Erfolg) mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
mal direkt mit DoubleBuffered:= true versucht ?
warum parent ist doch nicht das Parent der PaintBox auf das du zeichnest oder doch ? gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
Hi
parent wurde im customloop Beispiel auf DoubleBuffered gesetzt deswegen hatte ich es von dort übernommen. Hatte es jetzt aber auch allgemein versucht, brachte aber keine Besserung. Ich habe auch irgendwie das Gefühl, dass im Custom Loop Beispiel die TimeLine auch nur jede Sekunde bewegt wird, nicht alle 20ms, was ich aber nicht verstehe, da ja dort der Timer auch auf 20ms eingesetellt ist. ggf. liegt es ja daran im Beispiel wird BASS_ChannelGetPosition(chan,BASS_POS_BYTE) verwendet. das BASS_POS_BYTE akzeptiert delphi bei mir aber nicht. Könnte es daran liegen ? Wenn ja was macht BASS_POS_BYTE ? mfg blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 1)
Hm,
da ich mit meinem Problem selber durch versuchen noch nicht weitergekommen bin, habe ich nochmal meine Aktuelle Version zum ansehen angehängt. Bis auf das flackern der Time Line geht soweit alles super. BASS_ChannelGetPosition(chan,BASS_POS_BYTE) kann ich mittlerweile ausschließen, denke mal das es an meiner bass.dll Version liegt, die im customloop verwendetet scheint eine neuere zu sein. Ich hoffe mir kann da nochmal jemand auf die Sprünge helfen. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
BASS_POS_BYTE
Wird erst ab der vers. 2.4 verwendet. Da solltest du schon für sorgen das die richtige Bass.pas und Dll integriert ist. ;) gruss Emil |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
nein das hat schon seinen Grund ;) Die BassPlayer.pas ist für die Bass.dll V2.3 ausgelegt, diese ist auch im Verzeichnis und richtig eingebunden. BASS_POS_BYTE gibt es bei meiner Version noch nicht, deswegen arbeite ich ja auch nur mit der alten variante, die trotzdem die Position als Byte ausgibt :). Das ist ja auch imo garnicht das Problem, das Problem ist das Flackern der TimeLine, welches bei dem Bass.dll Custom Loop Beispiel trotz gleichem Timerintervall nicht auftritt. Ich bin nur noch nicht dahinter gekommen wieso die TimeLine bei mir (BassTest2 aus dem Anhang) flackert. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hatte das so schön realisiert, jetzt schau ich in den Quellcode und was is? Alles wieder kaputt. Da frage ich mich wirklich, warum ich mir eigentlich die Mühe mache?
|
Re: Bass.dll Wave Data / FFT Data ?
Hi,
tut mir leid, dass es für dich so rüberkam, als ob ich deine Arbeit nicht zu schätzen wüsste :( Es ist nur nunmal so, dass ich in Delphi noch nicht so ganz der Profi bin. Auch wenn es sich jetzt dumm anhört aber meistens ist es ja so, dass solche Anfragen gestellt werden und danach erwartet wird, dass eine komplett fertige procedure erwartet wird. Ich hingegen möchte ebend auch noch etwas selber dran machen um weiter draus zu lernen. Nun war es ebend so das mir die Sache mit dem OnWavePaint im Hauptprogramm etwas unkonfortabel vorkam. Und ich die Ereignisse wie z.B. DrawSpectrum oder DrawTimeline ebend gerne Manuell aufrufen wollte. (Somit wird das Handling der Funktion im Hauptprogramm in das, dass ganze intigriert werden soll auch um einiges komfortabeler). Und da hatte ich dann bei den ganzen Procedure Verknüpfungen untereinander erstmal meine Probleme gehabt mich zurecht zu finden, was nun genau wann für was zuständig ist. Mittlerweile glaube ich allerdings etwas dahinter gekommen zu sein. Eine Frage hingegen bleibt mir dabei allerdings trotzdem noch offen. Durch was wird denn das WaveBufferUpdateEvent eigentliche ausgeführt ? mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
|
Re: Bass.dll Wave Data / FFT Data ?
Ah Danke, jetzt verstehe ich den Zusammenhang.
mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
mir kam gerade eine Berechnungsfrage auf. Unzwar gibt z.B. BASS_ChannelGetPosition oder BASS_ChannelGetLength einen Byte Wert aus. Wie kann man eigentlich manuell eine Zeit wie z.B. 1:30 in das Byte Format umrechnen ? mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Einfacher Dreisatz...
1:30 -> 1 * 60 Sekunden + 30 Sekunden = 90 Sekunden. BytePosition := trunc((BASS_ChannelGetLength / GesamtSekunden) * AktuelleSekunden); Edit: Oder du schaust dir mal BASS_ChannelSeconds2Bytes an. |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
Danke damit funktioniert es. Nun kamen mir nochmal Frage aus. Irgendwie werden Elemente auf meinem Form (Buttons, Checkbox) schwarz umrandet ? Wieso wird darauf gezeichnet ? Und dann würde mich noch interessieren ob eins von beidem möglich ist. Einmal ob man auf dem Spectrum Linien auch im Millisekundenbereich zeichnen lassen kann. (ich vermute mal eher nicht da die Breitenberechungen ja auf Sekunden laufen). Und dann ob es möglich ist durch die Mausposition auf dem Spectrum die Zeit in Minuten Sekunden und Millisekunden genau auszugeben. mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
Berechnung in Millisekunden habe ich im BassPlayerEx realisiert. Die Mausposition kann wieder über einen einfachen Dreisatz umgerechnet werden... Millisekunden := round((GesamtMillisekunden / GesamtPixelBreiteDerAnzeige) * X-Mausposition); |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
in welcher Unit des BassPlayerEx wird man denn da fündig ? Sind ja einige :D mfg Blamster Aber z.B. beim zeichnen der TimeLine kann ich doch keine millisekunden übergeben, dafür müsste man dann erstmal die Auflösung also bpp an Millisekunden anpassen richtig ? mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Such doch einfach mal im Projekt (alle Dateien, Strg+F + zweiter Reiter) nach Millisekunden...
-> Unit: BassChannelU.pas |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
super dann funktioniert auch das :-D Jetzt steht nur noch die Frage offen, wieso manche Elemente des Forms auch schwarz "gepaintet" werden. Habe mal ein biold davon wie z.B.die checkBoxen aussehen angehängt. mfg und nochmal ein riesen Danke Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Zitat:
|
Re: Bass.dll Wave Data / FFT Data ?
Liste der Anhänge anzeigen (Anzahl: 1)
Stimmt, da fehlt etwas.
Sollte jetzt im anhang sein. |
Re: Bass.dll Wave Data / FFT Data ?
Hi,
ich grabe das Thema nochmal aus. Ich habe gerade eine Procedure erstellt umd die Position auch auf Millisekunden einzustellen.
Delphi-Quellcode:
Nun habe ich aber das Problem das der Song ca. 2 Sekunden Zeitfersetzt läuft.
procedure TBassPlayer.SetMilliSecPosition(Position: Longword);
var pos: Longword; begin if Channel = 0 then Exit; // Sound set Position if Modus = moSamples then BASS_ChannelSetPosition(Channel, round((BASS_ChannelGetLength(Channel) / GetSongLengthMS) * Position)); // Mod-Music set Position if Modus = moMusik then begin startmodplaytime := timegettime - (Position * 1000); pos := round(position * (SpeedinProzent / 100)) or $FFFF0000; BASS_ChannelSetPosition(Channel, pos); end; end; Wenn ich z.B. die Position auf 8000 ms setze, wird die Time Line auch korrekt auf der Position von 8 Sekunden gesetzt, der Song geht aber um ca. 2 Sekunden nach. Danach habe ich gesehen das du in deinem code auch eine solche procedure hast um habe folgende Zeile versucht:
Delphi-Quellcode:
führte aber leider zum selben Ergebnis.
BASS_ChannelSetPosition(Channel, round((BASS_ChannelGetLength(Channel) / round(BASS_ChannelBytes2Seconds(Channel, BASS_ChannelGetLength(Channel)) * 1000)) * position));
Eine Idee woran das liegen kann ? mfg blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Das BASS-System hat eben nur eine Genauigkeit in Sekunden. Deine Millisekundenangabe wird intern gerundet und dann kommt es zu solchen Ungenauigkeiten.
|
Re: Bass.dll Wave Data / FFT Data ?
Hi,
danke für die Info, wozu dient denn aber die SetMilliSec Position in deiner pas, denn den Millisekunden wert könnte man ja auch extern runden und dann SetPosition übergeben ? mfg Blamaster |
Re: Bass.dll Wave Data / FFT Data ?
Damals kam hier im Forum die Frage auf, da habe ich diese Methoden eingebaut. Ich selbst brauchte sie noch nie, habe damals beim realisieren auch keine Probleme feststellen können. Wenn du da jetzt Probleme findest, dann denke ich, hängen diese mit der Genauigkeit zusammen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:25 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