Einzelnen Beitrag anzeigen

Gandalfus

Registriert seit: 19. Apr 2003
407 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Frequenzen bei wav/mp3-dateien

  Alt 15. Okt 2003, 16:32
versuchs mal mit der bass.dll von http://www.un4seen.com/

hier mal meine alte bass unit:

Delphi-Quellcode:
unit U_BassPlayer;

interface

uses bass, Windows;
  

type
  TFFTData = array[0..256] of float;

  TBassPlayer = class
  private
    { Private declarations }
    channel: HCHANNEL;
    status: byte;


  public
    function play(filename: string): boolean;
    procedure initbassPlayer(mainwindowhandle: HWND);
    procedure freebassPlayer;
    procedure setvolume(volume: byte); {0 bis 100}
    function getvolume: byte;
    property volume: byte read getvolume write setvolume ;
    procedure setposition(position: integer);
    function getposition: integer; {in sekunden}
    property position: integer read getposition write setposition;
    function getlength: integer;
    property length: integer read getlength;
    function getRightPeak: dword;
    property RightPeak: dword read getRightPeak; {von 0 bis 128}
    function getLeftPeak: dword;
    property LeftPeak: dword read getLeftPeak; {von 0 bis 128}
    function getfftdata: TFFTData;

    { Public declarations }
  end;

implementation

function TBassPlayer.getfftdata: TFFTData;
begin
  if (BASS_ChannelGetData(Channel, @Result, BASS_DATA_FFT512) = 2048) = false then
  begin
    ZeroMemory(@Result, SizeOf(Result));
  end;
end;


function TBassPlayer.getRightPeak: dword;
begin
  result := HIWORD(BASS_ChannelGetLevel(channel));

end;

function TBassPlayer.getLeftPeak: dword;
begin
  result := LOWORD(BASS_ChannelGetLevel(channel));
end;


function TBassPlayer.getvolume: byte;
begin
  result := BASS_GetVolume;
end;

procedure TBassPlayer.setvolume(volume: byte);
begin
  //BASS_SetVolume(volume);
  BASS_SetGlobalVolumes(-1,-1,volume);
end;


function TBassPlayer.getposition: integer;
begin
   result := round(BASS_ChannelBytes2Seconds(channel,BASS_ChannelGetPosition(channel)));
end;

procedure TBassPlayer.setposition(position: integer);
begin
  BASS_ChannelSetPosition(Channel,BASS_ChannelSeconds2Bytes(Channel, position));
end;

function TBassPlayer.getlength: integer;
begin
  result := round(BASS_ChannelBytes2Seconds(channel,BASS_StreamGetLength(channel)));
end;


function TBassPlayer.play(filename: string): boolean;
begin
  If BASS_ChannelIsActive(channel)=1 then
  begin
    BASS_StreamFree(channel);
  end;

  channel:=BASS_StreamCreateFile(False,PChar(filename),0,0,BASS_STREAM_AUTOFREE or BASS_SAMPLE_FX);
  BASS_StreamPlay(channel,false,0);
end;

{es würde sich hier noch anbieten den Constructor zu überschreiben}
{das müsstest du aber selber noch verändern.}
procedure TBassPlayer.initbassPlayer(mainwindowhandle: HWND);
begin
  if BASS_GetVersion() <> MAKELONG(1,8) then Halt;
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
  BASS_Start;
end;

procedure TBassPlayer.freebassPlayer;
begin
  Bass_streamFree(channel);
  BASS_Stop;
  BASS_Free;
end;

end.
Anwendung:
Neue unit erstellen(und das von oben reinkopieren) diese in main unit einbinden und

var Bassplayer: TBassPlayer

....
create:
Delphi-Quellcode:
Bassplayer := TBassPlayer.create;
Bassplayer.initbassPlayer(Form1.handle);
play:
Bassplayer.play('c:\blablub.mp3') destroy:
Delphi-Quellcode:
Bassplayer.freebassPlayer;
Bassplayer.free;
so und jetzt noch die Visualisiereung:

Delphi-Quellcode:
var
  data: TFFTdata;
  backbild: TBitmap;
oncreate;
Delphi-Quellcode:
backbild := TBitmap.create;
backbild.width := 256;
backbild.height:= 150;

in einen Timer mit kleinem Intervall:
Delphi-Quellcode:
Data:= BassPlayer.GetFFTData;
for i := 1 to 256 do
begin
  data[i] := (Data[i] * (backbild.height)); //Werte anpassen
end;
 
backbild.Canvas.Brush.Color := clBlack; //Bild "löschen"
backbild.Canvas.Rectangle(0,0,backbild.Width,backbild.Height);
   
backbild.Canvas.Brush.Color := clred;//Farbe der Balken
backbild.Canvas.pen.Color := clred;

for i:=1 to 256 do
begin //DAs zeichnen der Balken
  backbild.canvas.moveto(i,backbild.height)
  backbild.canvas.lineto(i,backbild.height-round(Data[i]))
end;

BitBlt(Form1.Handle, 0, 0, backbild.width, backbild.height, backbild.Handle , 0, 0 , SRCCOPY);
//der Backpuffer wird aufs Formular kopiert
Ist jetzt nicht getestet.

Bei der darstellung sind dir fast keine Grenzen gesetzt. Kuck dir nur mal die vielen Visualierungs Plugins von Winamp an.


Jetzt hast du ein schöne Copy and paste Lösung. Das hättest du übrigens auch alles im Forum finden können wenn du gesucht hättest.

mfg
  Mit Zitat antworten Zitat