AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bass.dll Wave Data / FFT Data ?

Bass.dll Wave Data / FFT Data ?

Ein Thema von Blamaster · begonnen am 22. Jan 2009 · letzter Beitrag vom 7. Feb 2009
Antwort Antwort
Seite 2 von 4     12 34   
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#11

Re: Bass.dll Wave Data / FFT Data ?

  Alt 22. Jan 2009, 21:37
thx

genau das hatte ich gesucht.

mfg Blamaster
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Bass.dll Wave Data / FFT Data ?

  Alt 23. Jan 2009, 21:35
Zitat von Blamaster:
Ich habe mir gerade mal den TScanThread genauer angesehen.

Problem ist, dass ich momentan eine sogenannte "BassPlayer.pas" verwende. Lässt sich dort der TScanThread direkt einbauen oder ist der noch mit weiteren funktionen verknüpft ?

mit was würde die function zum scannen im Programm selber aufgerufen werden ?
Angehängte Dateien
Dateityp: zip basstest_114.zip (109,5 KB, 48x aufgerufen)
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#13

Re: Bass.dll Wave Data / FFT Data ?

  Alt 24. Jan 2009, 15:32
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
Miniaturansicht angehängter Grafiken
richtig_108.png   falsch_444.png  
Angehängte Dateien
Dateityp: rar custloop_110.rar (272,2 KB, 56x aufgerufen)
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#14

Re: Bass.dll Wave Data / FFT Data ?

  Alt 24. Jan 2009, 21:23
Geht mein Beispiel nicht?
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#15

Re: Bass.dll Wave Data / FFT Data ?

  Alt 25. Jan 2009, 01:03
Sorry hatte garnicht gesehen das du ja extra eine Testdatei angehängt hattets. Ich hatte mit deinen BassPlayerEx geladen.

Vielen Dank

mfg Blamaster
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#16

Re: Bass.dll Wave Data / FFT Data ?

  Alt 25. Jan 2009, 21:46
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:
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;
Aufrufen tue ich sie momentan im OnTimer Event mit 20ms:

Delphi-Quellcode:
procedure TFMain.Timer1Timer(Sender: TObject);
begin
fBassPlayer.DrawTimeLine(10,PaintBox,clRed);
end;
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.

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
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#17

Re: Bass.dll Wave Data / FFT Data ?

  Alt 25. Jan 2009, 22:08
mal direkt mit DoubleBuffered:= true versucht ?
warum parent ist doch nicht das Parent der PaintBox auf das du zeichnest oder doch ?

gruss Emil
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#18

Re: Bass.dll Wave Data / FFT Data ?

  Alt 26. Jan 2009, 14:45
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
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#19

Re: Bass.dll Wave Data / FFT Data ?

  Alt 27. Jan 2009, 15:38
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
Angehängte Dateien
Dateityp: rar basstest2_190.rar (297,0 KB, 46x aufgerufen)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#20

Re: Bass.dll Wave Data / FFT Data ?

  Alt 27. Jan 2009, 16:23
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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 22:18 Uhr.
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