![]() |
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:15 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