Einzelnen Beitrag anzeigen

Gandalfus

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

Re: Dauer und Position von MP3s mittels bass.dll

  Alt 5. Apr 2004, 21:17
Nochmal meine unit:
Delphi-Quellcode:
unit U_BassPlayer;

interface

uses
  bass, Windows, dialogs, Classes, StdCtrls, SysUtils;


type
  WAVHDR = packed record
    riff: array[0..3] of Char;
    len: DWord;
    cWavFmt: array[0..7] of Char;
    dwHdrLen: DWord;
    wFormat: Word;
    wNumChannels: Word;
    dwSampleRate: DWord;
    dwBytesPerSec: DWord;
    wBlockAlign: Word;
    wBitsPerSample: Word;
    cData: array[0..3] of Char;
    dwDataLen: DWord;
  end;

  TFFTData = array[0..256] of Single;

  TBassPlayer = class
  private
    { Private declarations }
    channel: HSTREAM;

    WaveHdr: WAVHDR; // WAV header
    recordchannel: HRECORD;   // recording channel
    isrecording: boolean;

    FFilename: string;
    procedure setvolume(volume: byte); {0 bis 100}
    function getvolume: byte;
    function getposition: integer;
    function getlength: integer; {in sekunden}
    function getRightPeak: dword;
    function getLeftPeak: dword;
    function getstatus: integer;

  public
    constructor create(mainwindowhandle: HWND);
    destructor destroy; override;
    function play(filename: string): boolean;
    function getfftdata: TFFTData;
    procedure stop;
    procedure pause;
    procedure resume;

    procedure startrecording(input: integer;filename: string);
    procedure stoprecording;
    function getDatasize: int64;
    procedure setrecordvolume(input: integer;volume: integer);

    procedure initCombobox(Combobox: TCombobox);
    procedure ComboBoxChange(Sender: TObject);

    property volume: byte read getvolume write setvolume;
    procedure setposition(position: integer);
    property position: integer read getposition write setposition;{in sekunden}
    property length: integer read getlength;
    property RightPeak: dword read getRightPeak; {von 0 bis 128}
    property LeftPeak: dword read getLeftPeak; {von 0 bis 128}
    property filename: string read FFilename;
    property status: integer read getstatus; //STOPPED = 0 PLAYING = 1 STALLED = 2 PAUSED = 3
    { Public declarations }
  end;

implementation

var
  WaveStream: TFileStream;//muss leider global deklariert werden wegen callback Funktion

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.getstatus: integer;
begin //STOPPED = 0 PLAYING = 1 STALLED = 2 PAUSED = 3
  result := BASS_ChannelIsActive(channel);
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_GetConfig(BASS_CONFIG_GVOL_STREAM);
end;

procedure TBassPlayer.setvolume(volume: byte);
begin
  BASS_SetConfig(BASS_CONFIG_GVOL_STREAM,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;

procedure TBassPlayer.stop;
begin
  BASS_ChannelPause(channel);
  position := 0;
end;

procedure TBassPlayer.pause;
begin
  BASS_ChannelPause(channel);
end;

procedure TBassPlayer.resume;
begin
  BASS_ChannelResume(channel);
end;

constructor TBassPlayer.create(mainwindowhandle: HWND);
begin
  inherited create;;
  if BASS_GetVersion() <> MAKELONG(2,0) then
  begin
    showmessage('Falsche Version der bass.dll(benötigt wird 2.0)');
    Halt;
  end;
  BASS_Init(1, 44100, 0, mainwindowhandle,nil);

  if not BASS_RecordInit(0) then
  begin
    BASS_RecordFree;
    BASS_Free();
    MessageDlg('Cannot start default recording device!', mtError, [mbOk], 0);
    halt;
  end;

  isrecording := false;
end;


destructor TBassPlayer.destroy;
begin
  BASS_RecordFree;

  Bass_streamFree(channel);
  BASS_Stop;
  BASS_Free;
  inherited destroy;
end;

// This is called while recording audio
function RecordingCallback(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall;
begin
  // Copy new buffer contents to the memory buffer
  WaveStream.Write(buffer^, length);
  //Allow recording to continue
  Result := True;
end;


procedure TBassPlayer.startrecording(input: integer;filename: string);
var
  i: Integer;
begin
  //File Stream
  WaveStream := TFileStream.Create(filename,fmCreate);


  if WaveStream.Size > 0 then
  begin   // free old recording
    BASS_StreamFree(channel);
  end;

  // generate header for WAV file
  WaveHdr.riff := 'RIFF';
  WaveHdr.len := 36;
  WaveHdr.cWavFmt := 'WAVEfmt ';
  WaveHdr.dwHdrLen := 16;
  WaveHdr.wFormat := 1;
  WaveHdr.wNumChannels := 2;
  WaveHdr.dwSampleRate := 44100;
  WaveHdr.wBlockAlign := 4;
  WaveHdr.dwBytesPerSec := 176400;
  WaveHdr.wBitsPerSample := 16;
  WaveHdr.cData := 'data';
  WaveHdr.dwDataLen := 0;

  WaveStream.Write(WaveHdr, SizeOf(WAVHDR));
  i := 0;
  while BASS_RecordSetInput(i, BASS_INPUT_OFF) do
  begin
    i := i + 1;
  end;
  BASS_RecordSetInput(input, BASS_INPUT_ON);

  // start recording @ 44100hz 16-bit stereo
  recordchannel := BASS_RecordStart(44100, 0, @RecordingCallback, 0);
  if recordchannel = 0 then
  begin
    MessageDlg('Couldn''t start recording!', mtError, [mbOk], 0);
    WaveStream.Free;
  end;

  isrecording:= true;
end;

procedure TBassPlayer.stoprecording;
var
  i: integer;
begin
  BASS_ChannelStop(recordchannel);

  // complete the WAV header
  WaveStream.Position := 4;
  i := WaveStream.Size - 8;
  WaveStream.Write(i, 4);
  i := i - $24;
  WaveStream.Position := 40;
  WaveStream.Write(i, 4);
  WaveStream.Position := 0;
  // create a stream from the recorded data
  //channel := BASS_StreamCreateFile(false, pchar(FRecordfilename), 0, WaveStream.Size, 0);

  {if channel = 0 then
  begin
    MessageDlg('Error creating stream from recorded data!', mtError, [mbOk], 0);
  end;}

  WaveStream.Free;
end;

function TBassPlayer.getDatasize: int64;
begin
  IF isrecording then
  begin
    result:= WaveStream.Size
  end
  else
  begin
    result:=0;
  end;
end;

procedure TBassPlayer.setrecordvolume(input: integer;volume: integer);
begin
  BASS_RecordSetInput(input, BASS_INPUT_LEVEL or volume);
end;

end.
  Mit Zitat antworten Zitat