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:
WaveBufR: array of smallint;
WaveBufL: array of smallint;
Scan Peaks:
Delphi-Quellcode:
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;
GetPeak:
Delphi-Quellcode:
function TBassPlayer.GetLPeak(position:integer): Integer;
begin
result:= WaveBufL[position];
end;
function TBassPlayer.GetRPeak(position:integer): Integer;
begin
result:= WaveBufR[position];
end;
Und Aufruf + zeichnen im eigentlichen Programm:
Delphi-Quellcode:
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;
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)
Jemand eine Idee woran das liegen kann ?
mfg Blamaster