unit Unit1;
{========================================================================
 Plugin Delphi Demo (translated from C PluginDemo Copyright by Ian Luck)
 by (Chris Troesken)(cst-tech@foni.net)http:www.cst-development.de


 Plugin Demo the shows how to get the Info about the supported loaded Plugins
 * Requires: BASS.DLL available @ www.un4seen.com
========================================================================}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, bass, ExtCtrls, StdCtrls, ComCtrls, Dialogs;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    GroupBox1: TGroupBox;
    Button1: TButton;
    open1: TOpenDialog;
    lblInfo: TLabel;
    ListView_PlugIns: TListView;
    Timer1: TTimer;
    ScrollBar1: TScrollBar;
    lblLength: TLabel;
    lblPos: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer);
  private
    { Private-Deklarationen }
    Sliding: boolean;
    procedure Error(const Text: string);
    function GetCTypeString(ctype: DWORD; plugin: HPLUGIN): string;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Chan: HStream;

implementation

{$R *.dfm}

function TimeToStringEx(Ftime: int64; ShowMsec: Boolean = true): string;
begin
  if ShowMsec then
  begin

    if Time >= 3600000 then
      Result := Format('%d:%2.2d:%2.2d.%3.3d', [Ftime div 3600000,
          (Ftime mod 3600000) div 60000,
          (Ftime mod 60000) div 1000,
          Ftime mod 1000])
    else
      Result := Format('%d:%2.2d.%3.3d', [Ftime div 60000,
          (Ftime mod 60000) div 1000,
          Ftime mod 1000]);
  end
  else
  begin
    if Ftime >= 3600000 then
      Result := Format('%d:%2.2d:%2.2d', [Ftime div 3600000,
          (Ftime mod 3600000) div 60000,
          (Ftime mod 60000) div 1000])
    else
      Result := Format('%d:%2.2d', [Ftime div 60000,
          (Ftime mod 60000) div 1000]);
  end;
end;

function ProgDir: string;
begin
  result := ExtractFilePath(ParamStr(0));
end;

function TForm1.GetCTypeString(ctype: DWORD; plugin: HPLUGIN): string;
var
  pInfo: ^BASS_PLUGININFO;
  a: integer;
begin
  if plugin <> 0 then
  begin
//    pInfo := BASS_PluginGetInfo(plugin);
    pInfo := pointer(BASS_PluginGetInfo(plugin));
    for a := 0 to pInfo.formatc - 1 do
      if pInfo.Formats[a].ctype = ctype then
        Result := string(pInfo.Formats[a].name);
  end;
  // check built-in stream formats...
  case ctype of
    BASS_CTYPE_STREAM_OGG:
      Result := Result + '"Ogg Vorbis"';
    BASS_CTYPE_STREAM_MP1:
      Result := Result + '"MPEG layer 1"';
    BASS_CTYPE_STREAM_MP2:
      Result := Result + '"MPEG layer 2"';
    BASS_CTYPE_STREAM_MP3:
      Result := Result + '"MPEG layer 3"';
    BASS_CTYPE_STREAM_AIFF:
      Result := Result + '"Audio IFF"';
    BASS_CTYPE_STREAM_WAV_PCM:
      Result := Result + '"PCM WAVE"';
    BASS_CTYPE_STREAM_WAV_FLOAT:
      Result := Result + '"Floating-point WAVE"';
    BASS_CTYPE_STREAM_WAV:
      Result := Result + '"Wave"';
  end;
end;

procedure TForm1.Error(const Text: string);
begin
  MessageBox(Handle, PChar(Text + '  Errorcode = ' +
      inttostr(Bass_ErrorGetCode)), PChar('Error'), 16);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  fd: TWin32FindData;
  fh: THandle;
  plug: HPLUGIN;
  Info: ^Bass_PluginInfo;
  s: string;
  a: integer;
  ListItem: TListItem;
begin
  if not Bass_Init(-1, 44100, 0, handle, nil) then
  begin
    Error('Can''t initialize device');
    Application.Terminate;
  end;
  // Set The OpenDialog Filter to the Bass build In Formats
  Open1.Filter :=
    'BASS built-in *.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif)\0*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif' + '|'
    + '*.mp3;*.mp2;*.mp1;*.ogg;*.wav*;*.aif';

  // get the Modules from the currentDirectory
  fh := FindFirstFile(PChar(ProgDir + 'bass*.dll'), fd);
  if (fh <> INVALID_HANDLE_VALUE) then
  try
    repeat
      plug := BASS_PluginLoad(fd.cFileName, 0  or BASS_UNICODE );
      if plug <> 0 then
      begin
//
        Info := pointer(BASS_PluginGetInfo(plug)); // get plugin info to add to the file selector filter...
        for a := 0 to Info.formatc - 1 do
        begin
          // Set The OpenDialog additional, to the supported PlugIn Formats
          open1.Filter := Open1.Filter + ('|' + string((Info.Formats[a].name)) + ' ' + '(' +
            string(Info.Formats[a].exts + ')) , ' + string(fd.cFileName) + '|' + string(Info.Formats[a].exts)));
          // Lets Show in the Listview the supported Formats

          if (Info.Formats[a].name <> nil) then
            if (a = 0) then
              s := string(Info.Formats[a].name)
            else
              s := s + ',' + string(Info.Formats[a].name);
        end;
        ListItem := ListView_PlugIns.Items.Add;
        ListItem.Caption := fd.cFileName;
        ListItem.SubItems.Add(s);
      end;
    until FindNextFile(fh, fd) = false;
  finally
    Windows.FindClose(fh);
  end;

  if Listview_PlugIns.Items.Count = 0 then
  begin
    ListItem := ListView_PlugIns.Items.Add;
    ListItem.SubItems.Add('no plugins found - visit the BASS webpage to get some');
  end;
end;

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

procedure TForm1.Button1Click(Sender: TObject);
var
  Info: Bass_ChannelInfo;
  Len: double;

begin
  if open1.Execute then
  begin
    Timer1.Enabled := false;
    Bass_StreamFree(Chan);
    Chan := Bass_StreamCreateFile(Bass_File_Name, PChar(open1.FileName), 0, 0, BASS_SAMPLE_LOOP or BASS_UNICODE);
    if CHan <> 0 then
    begin
      BASS_ChannelGetInfo(chan, Info);
      Button1.Caption := open1.FileName;
      lblInfo.Caption := 'channel type = ' + inttostr(Info.ctype) + ' ' +
        getCTypeString(Info.ctype, Info.plugin);
      Len := BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan, BASS_POS_BYTE));

      Scrollbar1.Max := Round(Len);
      lblLength.Caption := 'Length : ' + TimeToStringEx(Round(len*1000),True);
      Bass_ChannelPlay(Chan, false);
      Timer1.Enabled := true;
    end
    else
    begin
      Button1.Caption := 'Click here to open a file';
      Error('Can''t play the file');
    end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var Fpos:Int64;
begin
  if not Sliding then
    Scrollbar1.Position := round(BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetPosition(chan, BASS_POS_BYTE)));
    Fpos := Round(BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetPosition(chan, BASS_POS_BYTE))*1000);
    lblPos.Caption := 'Pos    : ' + TimeTostringEx(Fpos,true);

end;

procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
  Sliding := ScrollCode <> scEndScroll;
  if ScrollCode = scEndScroll then
    BASS_ChannelSetPosition(chan, BASS_ChannelSeconds2Bytes(chan, Scrollbar1.position), BASS_POS_BYTE);
end;

end.

