Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Frequenzen bei wav/mp3-dateien (https://www.delphipraxis.net/10240-frequenzen-bei-wav-mp3-dateien.html)

Illuminator-23-5 14. Okt 2003 15:59


Frequenzen bei wav/mp3-dateien
 
Wie kann ich von einer mp3/wav-Datei die Frequenzen rausfiltern? (Sprich diese Schwingungen, die auch beim Windows mediaplayer angezeigt werden)

Illuminator-23-5 15. Okt 2003 14:15

Re: Frequenzen bei wav/mp3-dateien
 
/me.try(Wiederbelebungsversuch(ThisThread));
----------------------------
hat echt niemand 'ne ahnung?

nTE 15. Okt 2003 15:07

Re: Frequenzen bei wav/mp3-dateien
 
Also bei MP3 Dateien stehen diese Informationen im Header der Datei und ich würde sagen bei WAVE sollte es genauso sein.

Zu WAVE Headern musst du mal ein wenig bei Google suchen und für Infos über MP3 Header kannst du bei mp3-tech.org mal schauen.
(Unter "Programmer's corner" -> MPEG Layer I/II/III frame header documentation)


------
Mmh, ich hoffe mal du meintest das, wenn du dir allerdings einen Equalizer bauen willst, kann ich dir nicht viel mehr helfen. Schau mal in der Programmer's Corner, da sind auch Sourcecodes.
Vielleicht ist da was für dich dabei.

Gandalfus 15. Okt 2003 15:32

Re: Frequenzen bei wav/mp3-dateien
 
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:
Delphi-Quellcode:
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. :zwinker:


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

Illuminator-23-5 17. Okt 2003 20:38

Re: Frequenzen bei wav/mp3-dateien
 
1. die lösung funktioniert perfekt!
2. kann man das auch machen, ohne dass das File abgespielt werden muss? Dass ich mit einer For-schleife von vorne bis hinten alles durchgehe und abfrage. Geht das auch?

SleepyMaster 18. Okt 2003 19:35

Re: Frequenzen bei wav/mp3-dateien
 
Bei mir läuft zwar die Musik, aber die Visualisierung fehlt!

SleepyMaster 18. Okt 2003 19:49

Re: Frequenzen bei wav/mp3-dateien
 
BitBlt(Form1.Handle, 0, 0, backbild.width, backbild.height, backbild.Handle , 0, 0 , SRCCOPY);

Die Bitmap wird nicht kopiert bei mir!!!
Weiß jemand warum???

Gandalfus 22. Okt 2003 22:07

Re: Frequenzen bei wav/mp3-dateien
 
der Fehler ist da:

Delphi-Quellcode:
BitBlt(Form1.Handle, 0, 0, backbild.width, backbild.height, backbild.Handle , 0, 0 , SRCCOPY);

richtig ist:

Delphi-Quellcode:
BitBlt(Form1.canvas.handle, 0, 0, backbild.Width, backbild.Height, backbild.canvas.handle, 0, 0, srccopy);
Hmm sowas passiert wenn man nicht testet sorry.

ich hab nochmal ein beispiel Programm geschrieben.

Für das Beispiel brachst man die neurer Version meiner Unit:

Delphi-Quellcode:
unit U_BassPlayer;

interface

uses bass, Windows, Messages;


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

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

public
  constructor create(mainwindowhandle: HWND);
  destructor destroy; override;
  function play(filename: string): boolean;
  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;
  property filename: string read FFilename;

{ 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_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;
  FFilename := filename;

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

constructor TBassPlayer.create(mainwindowhandle: HWND);
begin
  inherited create;;
  if BASS_GetVersion() <> MAKELONG(1, then Halt;
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
  BASS_Start;
end;


destructor TBassPlayer.destroy;
begin
  Bass_streamFree(channel);
  BASS_Stop;
  BASS_Free;
  inherited destroy;
end;

end.
Neue Anwendung--> Button, Timer und Opendialog auf das Formular und dann so weiter:


Delphi-Quellcode:
uses
.....,U_bassplayer,......


var
  Form1: TForm1;
  BassPlayer: TBassPlayer;
  backbild: TBitmap;

implementation

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject);
begin
  IF Opendialog1.Execute then
  bassplayer.play(Opendialog1.FileName);
  Timer1.Enabled := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  bassplayer.free;
  backbild.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: integer;
  data: TFFTdata;
begin
  Data:= BassPlayer.GetFFTData;
  for i := 1 to 256 do
  begin
    data[i] := (Data[i] * (backbild.Height)*(i * 0.25)); //Werte anpassen
  end;

  backbild.Canvas.pen.Color := clBlack;
  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*2,backbild.Height);
    backbild.canvas.lineto(i*2,backbild.Height-(round(Data[i])));
  end;

  BitBlt(Form1.canvas.handle, 0, 0, backbild.Width, backbild.Height,     backbild.canvas.handle, 0, 0, srccopy);
  //der Backpuffer wird aufs Formular kopiert
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Enabled := false;
  Timer1.Interval := 55;

  bassplayer := TBassplayer.create(Form1.handle);

  backbild := TBitmap.create;
  backbild.width := 600;
  backbild.height:= 200;
end;

SleepyMaster 23. Okt 2003 10:38

Re: Frequenzen bei wav/mp3-dateien
 
Ja! Ich weiß ich nerv! :-D

Aber es läuft immer noch nicht!
Sobald
Delphi-Quellcode:
  bassplayer := TBassplayer.create(Form1.handle);
ausgeführt wird, wird das Programm ohne Fehlermeldung beendet!

Aber vermutlich nur weil ich da was falsches reingesetzt hab (Damit Delphi das auch coplimiert):


Original:
Delphi-Quellcode:
constructor TBassPlayer.create(mainwindowhandle: HWND);
begin
  inherited create;;
  if BASS_GetVersion() <> MAKELONG(1, then Halt;
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
  BASS_Start;
end;
Meins:
Delphi-Quellcode:
constructor TBassPlayer.create(mainwindowhandle: HWND);
begin
  inherited create;;
  if BASS_GetVersion() <> MAKELONG(1,1) then Halt;
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
  BASS_Start;
end;
Was muss in die Zeile wirklich rein???
Delphi-Quellcode:
  if BASS_GetVersion() <> MAKELONG(1,1) then Halt;
Was macht makelong????

SleepyMaster 23. Okt 2003 10:43

Re: Frequenzen bei wav/mp3-dateien
 
Hab sie jetzt mal ganz weggemacht! ;)
Und es läuft!

Gandalfus 23. Okt 2003 11:05

Re: Frequenzen bei wav/mp3-dateien
 
Delphi-Quellcode:
constructor TBassPlayer.create(mainwindowhandle: HWND);
begin
  inherited create;;
  if BASS_GetVersion() <> MAKELONG(1,8) then Halt;
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
  BASS_Start;
end;
ist beim kopieren irgendwie verloren gegangen. Das ist die Abfrage ob man die richtige Version der bass.dll hat. Da müsst ihr kucken welche Version der bass.dll ihr habt(warscheinlich 1.8)

SleepyMaster 23. Okt 2003 11:22

Re: Frequenzen bei wav/mp3-dateien
 
OK! Vielen Dank!!!

Allmacht86 10. Dez 2004 10:26

Re: Frequenzen bei wav/mp3-dateien
 
Hi Leutz,

ich habe da ein Problem: bei mir funzt es nicht
Delphi-Quellcode:
  BASS_Init(-1, 44100, BASS_DEVICE_LEAVEVOL, mainwindowhandle);
-> Undefinierter Bezeichner
-> Nicht genügend wirkliche Parameter

Delphi-Quellcode:
  result := BASS_StreamPlay(channel,false,0);
-> Undefinierter Bezeichner

Was mach ich falsch? Muss das Beispiel vielleicht auf die neue Bass.dll angepasst werden? Vielleicht kann mir ja jemand helfen...

Ultimator 10. Dez 2004 17:27

Re: Frequenzen bei wav/mp3-dateien
 
Du schreibst "Undefinierter Bezeichner". OK.
Aber was ist denn der undefinierte Bezeichner?

Elspass 13. Dez 2004 11:01

Re: Frequenzen bei wav/mp3-dateien
 
Ist es möglich mit BASS.DLL bei einer bestimmten Frequenzen eine Aktion auszuführen?

Gruss Jörg

Allmacht86 13. Dez 2004 11:41

Re: Frequenzen bei wav/mp3-dateien
 
Undefiniert sind BASS_DEVICE_LEAVEVOL und BASS_StreamPlay.

alcaeus 13. Dez 2004 11:45

Re: Frequenzen bei wav/mp3-dateien
 
@Allmacht86: welche Version der Bass.dll hast du? Evtl. treten die Probleme wegen unterschiedlicher Versionen auf.

@Elspass: Stell deine Frage bitte in einem neuen Thread, sonst gehts hier wirklich durcheinander.

Greetz
alcaeus

hibbert 12. Apr 2005 16:45

Re: Frequenzen bei wav/mp3-dateien
 
Hi, ´
ich habe das mal auch mal versucht, doch leider ist dieser Fehler aufgetreten:
Zitat:

Zitat von Compiler
[Fehler] U_BassPlayer.pas(70): Undefinierter Bezeichner: 'BASS_SetGlobalVolumes'

was habe ich falsch gemacht ??

thx hibbert

Gandalfus 12. Apr 2005 20:33

Re: Frequenzen bei wav/mp3-dateien
 
Da gibts die aktuelle version von meiner unit.

hibbert 12. Apr 2005 22:11

Re: Frequenzen bei wav/mp3-dateien
 
jupp danke damit funzt es super !!! :-D

thx hibbert

// edit kann ich auch zwei lieder in ein ander faden lassen ?
ich kann nämlic(h) keine zweite kompo auf dem formblatt erstellen...
hibbert

Stundenplan 28. Feb 2009 15:40

Re: Frequenzen bei wav/mp3-dateien
 
Also, bei mir muss irgendwie das position nicht stimmen, aber wenn ich es
so abfrage, stimmt es doch!
Ich hab mir ne Funktion für Zeitausgabe (zB: 04:23) eingebaut, aber manchmal
seh ich da 4532:23! Was ist das Problem? Hier ist der Code:

Delphi-Quellcode:
function TBassPlayer.Time(State: Integer): String;
var min, sec: Integer;
    Erg, mins, secs: String;  //Ergebnis, MinString, SecString
begin
sec := position;            // State = 0  einfach: 04:23
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;
end;
min := min - 4349924 - 1492 -384 -1516-8; /Hier hab ich schon so viel abgezogen, aber es
// kommt immer mehr hinzu!
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := mins+':'+secs;
if State = 1 then           //State = 1  mit Länge: 04:23/06:23
begin
sec := length;
min := 0;
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;                // Hier funzt es anscheinend
end;
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := Erg+'/'+mins+':'+secs;
end;
if State = 2 then         //State = 2  "abgezogen": 02:00 
begin
sec := length - position;
min := 0;
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;            // Hier funzt es auch!
end;
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := mins+':'+secs;
end;
result := Erg;
end;
]

Stundenplan 1. Mär 2009 11:52

Re: Frequenzen bei wav/mp3-dateien
 
Ich habs rausgekriegt!

Ich hab vergessen, min wieder auf null zu setzen! :oops: :wink:
Jetzt stimmts:

Delphi-Quellcode:
function TBassPlayer.Time(State: Integer): String;
var min, sec: Integer;
    Erg, mins, secs: String;  //Ergebnis, MinString, SecString
begin
min := 0;            
sec := position;            // State = 0
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;
end;
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := mins+':'+secs;

if State = 1 then           //State = 1
begin
sec := length;
min := 0;
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;
end;
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := Erg+'/'+mins+':'+secs;
end;

if State = 2 then         //State = 2
begin
sec := length - position;
min := 0;
while sec > 59 do
begin
min := min + 1;
sec := sec - 60;
end;
mins := IntToStr(min);
secs := IntToStr(sec);
if min < 10 then mins := '0'+mins;
if sec < 10 then secs := '0'+secs;
Erg := mins+':'+secs;
end;
result := Erg;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:44 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