Einzelnen Beitrag anzeigen

aphexx

Registriert seit: 23. Apr 2010
19 Beiträge
 
#3

Re: Prozedur: Sound zu Array of Float mittels BASS

  Alt 2. Jun 2010, 00:34
mmh, ich wollte gerade editieren, hat aber leider nicht geklappt :/

Nach langem Hin und Her habe ich mit Hilfe der Dokumentation einen guten Schritt nach vorn gemacht.
Ich verstehe noch nicht so ganz, warum es verschiedene Ergebnisse zwischen wav und mp3 gibt
(die wav, die benutzt hab wurde ursprünglich mal vom mp3 transcodiert).
Zudem kommt noch, dass die Ergebnisse für fft[0] ungewöhnlich niedrig erscheinen, ist aber evtl. nur Einbildung.

Naja, das ist auf jeden Fall mein Zwischenergebnis (wenn auch mit 'play'):

EDIT:
Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Bass, Buttons, StdCtrls;

type
  TForm1 = class(TForm)
    OD: TOpenDialog;
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    Memo1: TMemo;
    Label2: TLabel;
    Edit1: TEdit;
    Memo2: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Laenge;
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    procedure SetPosition(Value: Longword);
    procedure SetProgress(Value: Double);
  end;

  TWaveData = array [ 0..2048] of DWORD;
  TFFTData = array [0..512] of Single;

var
  Form1: TForm1;
  Channel: DWORD;
  len: QWord;
  time, timeMS, MS:Double;
  timeByte: QWord;
  schritte: Integer;

implementation

{$R *.dfm}

procedure TForm1.Laenge;
begin
  len := BASS_ChannelGetLength(channel, BASS_POS_BYTE); // the length in bytes
  time:= BASS_ChannelBytes2Seconds(channel, len); // the length in seconds
  timeMS := time*1000;
  MS := 1000/StrToFloat(Edit1.Text);
  schritte := Round(timeMS/MS);
  timeByte := len div schritte;
end;

procedure TForm1.SetPosition(Value: Longword);
begin
  BASS_ChannelSetPosition(channel, Value, BASS_POS_BYTE);
end;

procedure TForm1.SetProgress(Value: Double);
begin
  if Value < 0 then Value := 0;
  if Value > 1 then Value := 1;
  SetPosition(Round(BASS_ChannelGetLength(channel, BASS_POS_BYTE) * Value));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, t, level: Integer;
  levelF, C, temp: Extended;
  L, R: QWord;
  WaveData: TWaveData;
  FFT: TFFTData;
begin
  Memo1.Clear;
  Memo2.Clear;
  BASS_ChannelSetPosition(channel, 0, BASS_POS_BYTE);
  BASS_ChannelSetAttribute(channel, BASS_ATTRIB_VOL, 0);
  BASS_ChannelPlay(channel, false);
  temp := 0;
  for i := 0 to Schritte - 1 do
  begin
    BASS_ChannelSetPosition(channel, i*timeByte, BASS_POS_BYTE);
    Level := BASS_ChannelGetLevel(channel);
    L := LOWORD(level); // the left level
    R := HIWORD(level); // the right level
    C := (R + L) / (2*65535);
    if temp < c then temp := c;
    //Memo1.Lines.Add(FloatToStr(c));
  end;

  BASS_ChannelStop(channel);
  ShowMessage('Highest peak was: ' + FloatToStr(temp));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  BASS_Init(-1, 44100, 0, Application.Handle, nil);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Bass_Free;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  if not OD.Execute then exit;
    Channel := BASS_StreamCreateFile(FALSE, PChar(OD.FileName), 0, 0, 0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
  Laenge;
  Label1.Caption := 'Length: ' + FloatTOStr(timeMS) + ' MS' +#13 + 'in Bytes: ' + IntToStr(len);
end;

end.
Über Korrekturen/Hilfestellungen freue ich mich nach wie vor.

EDIT:
Ich hab grad festgestellt, dass meine grundlegende Berechnung der Schritte Firlefanz war.
Daher gibt es eine neue Variable "Schritte". Diese wird nun auch in einer normalen Schleife verwendet (siehe Source oben);
Jetzt bleibt eigentlich nur noch die Unterscheidung von Sounddateien mit einem oder mehreren Channels,
damit die Berechnung C := (R + L) / (2 * 65535); auf diese speziellen Fälle reagiert, also bei Mono-Dateien das "2*" raus.
  Mit Zitat antworten Zitat