Search code examples
buttoninno-setupplaybackpause

How to make Stop and Pause/Resume/Play music buttons in Inno Setup


I want to create two buttons adjacent to each-other at the bottom left corner of all the pages like reloaded.

The first button shows the Pause and the Resume command (if I click Pause, the button will switch to Resume automatically).

The other button shows the Stop command (if I click Stop, the next button will switch to Play from start automatically)

This code just adds Pause/Resume/Play from start* button and Stop button

The problem is: If I press Stop button, the music stops permanently and the Play form start button never appears.

    [Setup]
AppName=Bass Audio Project
AppVersion=1.0
DefaultDirName={pf}\Bass Audio Project

[Files]
Source: Bass.dll; Flags: dontcopy
Source: AudioFile.mp3; Flags: dontcopy


[Code]
const
  BASS_SAMPLE_LOOP = 4;
  BASS_ACTIVE_STOPPED = 0;
  BASS_ACTIVE_PLAYING = 1;
  BASS_ACTIVE_STALLED = 2;
  BASS_ACTIVE_PAUSED  = 3;
  BASS_UNICODE = $80000000;
  BASS_CONFIG_GVOL_STREAM = 5;
const
  #ifndef UNICODE
    EncodingFlag = 0;
  #else
    EncodingFlag = BASS_UNICODE;
  #endif
type
  HSTREAM = DWORD;

function BASS_Init(device: LongInt; freq, flags: DWORD;
  win: HWND; clsid: Cardinal): BOOL;
  external 'BASS_Init@files:bass.dll stdcall';
function BASS_StreamCreateFile(mem: BOOL; f: string; offset1: DWORD;
  offset2: DWORD; length1: DWORD; length2: DWORD; flags: DWORD): HSTREAM;
  external 'BASS_StreamCreateFile@files:bass.dll stdcall';
function BASS_Start: BOOL;
  external 'BASS_Start@files:bass.dll stdcall';
function BASS_Pause: BOOL;
  external 'BASS_Pause@files:bass.dll stdcall';
function BASS_Stop(): Boolean;
  external 'BASS_Stop@files:BASS.dll stdcall delayload';
function BASS_ChannelPlay(handle: DWORD; restart: BOOL): BOOL;
  external 'BASS_ChannelPlay@files:bass.dll stdcall';
function BASS_SetConfig(option: DWORD; value: DWORD ): BOOL;
  external 'BASS_SetConfig@files:bass.dll stdcall';
function BASS_ChannelIsActive(handle: DWORD): DWORD;
  external 'BASS_ChannelIsActive@files:bass.dll stdcall';
function BASS_Free: BOOL;
  external 'BASS_Free@files:bass.dll stdcall';

var
  SoundStream: HSTREAM;
  PauseResumePlayButton: TNewButton;
  StopButton: TNewButton;

procedure ResumeButtonClick(Sender: TObject); forward;

procedure PauseButtonClick(Sender: TObject);
begin
  if BASS_Pause then
  begin
    PauseResumePlayButton.Caption := 'Resume';
    PauseResumePlayButton.OnClick := @ResumeButtonClick;
  end;
end;

procedure ResumeButtonClick(Sender: TObject);
begin
  if BASS_start then
  begin
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;

procedure PlayButtonClick(Sender: TObject);
begin
  if BASS_Start then
  begin
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;


procedure StopButtonClick(Sender: TObject);
begin
  if BASS_Stop then
  begin
    PauseResumePlayButton.Caption := 'Play';
    PauseResumePlayButton.OnClick := @PlayButtonClick;
  end;
       begin
       BASS_Free;
       end;
end;

procedure InitializeWizard();
begin
  ExtractTemporaryFile('AudioFile.mp3');
  if BASS_Init(-1, 44100, 0, 0, 0) then
  begin
    SoundStream :=
      BASS_StreamCreateFile(
        False, ExpandConstant('{tmp}\AudioFile.mp3'), 0, 0, 0, 0,
        EncodingFlag or BASS_SAMPLE_LOOP);
    BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 2500);
    BASS_ChannelPlay(SoundStream, False);

    StopButton := TNewButton.Create(WizardForm);
    StopButton.Parent := WizardForm;
    StopButton.Left :=
      WizardForm.ClientWidth -
      WizardForm.CancelButton.Left - WizardForm.CancelButton.Width;
    StopButton.Top := WizardForm.CancelButton.Top;
    StopButton.Width :=  WizardForm.CancelButton.Width;
    StopButton.Height := WizardForm.CancelButton.Height;
    StopButton.Caption := 'Stop';
    StopButton.OnClick := @StopButtonClick;

    PauseResumePlayButton := TNewButton.Create(WizardForm);
    PauseResumePlayButton.Parent := WizardForm;
    PauseResumePlayButton.Left :=
      WizardForm.ClientWidth -
      WizardForm.NextButton.Left - WizardForm.NextButton.Width;
    PauseResumePlayButton.Top := WizardForm.CancelButton.Top;
    PauseResumePlayButton.Width :=  WizardForm.CancelButton.Width;
    PauseResumePlayButton.Height := WizardForm.CancelButton.Height;
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;

procedure DeinitializeSetup;
begin
  BASS_Free;
end;

Solution

  • It's not a good idea to implement this using a single OnClick handler.

    Change the OnClick handler on the fly, as needed, for more straightforward code:

    const
      BASS_SAMPLE_LOOP = 4;
      BASS_ACTIVE_STOPPED = 0;
      BASS_ACTIVE_PLAYING = 1;
      BASS_ACTIVE_STALLED = 2;
      BASS_ACTIVE_PAUSED  = 3;
      BASS_UNICODE = $80000000;
      BASS_CONFIG_GVOL_STREAM = 5;
    const
      #ifndef UNICODE
        EncodingFlag = 0;
      #else
        EncodingFlag = BASS_UNICODE;
      #endif
    type
      HSTREAM = DWORD;
    
    function BASS_Init(device: LongInt; freq, flags: DWORD;
      win: HWND; clsid: Cardinal): Boolean;
      external 'BASS_Init@files:bass.dll stdcall';
    function BASS_StreamCreateFile(mem: Boolean; f: string; offset1: DWORD;
      offset2: DWORD; length1: DWORD; length2: DWORD; flags: DWORD): HSTREAM;
      external 'BASS_StreamCreateFile@files:bass.dll stdcall';
    function BASS_ChannelPlay(handle: DWORD; restart: Boolean): Boolean;
      external 'BASS_ChannelPlay@files:bass.dll stdcall';
    function BASS_ChannelPause(handle: DWORD): Boolean;
      external 'BASS_ChannelPause@files:bass.dll stdcall';
    function BASS_SetConfig(option: DWORD; value: DWORD ): Boolean;
      external 'BASS_SetConfig@files:bass.dll stdcall';
    function BASS_ChannelIsActive(handle: DWORD): DWORD;
      external 'BASS_ChannelIsActive@files:bass.dll stdcall';
    
    var
      SoundStream: HSTREAM;
      PauseResumePlayButton: TNewButton;
      StopButton: TNewButton;
    
    procedure ResumeButtonClick(Sender: TObject); forward;
    
    procedure PauseButtonClick(Sender: TObject);
    begin
      if BASS_ChannelPause(SoundStream) then
      begin
        PauseResumePlayButton.Caption := 'Resume';
        PauseResumePlayButton.OnClick := @ResumeButtonClick;
      end;
    end;  
    
    procedure ResumeButtonClick(Sender: TObject);
    begin
      if BASS_ChannelPlay(SoundStream, False) then
      begin
        PauseResumePlayButton.Caption := 'Pause';
        PauseResumePlayButton.OnClick := @PauseButtonClick;
      end;
    end;  
    
    procedure PlayButtonClick(Sender: TObject);
    begin
      if BASS_ChannelPlay(SoundStream, True) then
      begin
        PauseResumePlayButton.Caption := 'Pause';
        PauseResumePlayButton.OnClick := @PauseButtonClick;
      end;
    end;  
    
    procedure StopButtonClick(Sender: TObject);
    begin
      if (BASS_ChannelIsActive(SoundStream) = BASS_ACTIVE_PAUSED) or
         BASS_ChannelPause(SoundStream) then
      begin
        PauseResumePlayButton.Caption := 'Play';
        PauseResumePlayButton.OnClick := @PlayButtonClick;
      end;
    end;  
    
    procedure InitializeWizard();
    begin
      if BASS_Init(-1, 44100, 0, 0, 0) then
      begin
        ExtractTemporaryFile('AudioFile.mp3');
        SoundStream :=
          BASS_StreamCreateFile(
            False, ExpandConstant('{tmp}\AudioFile.mp3'), 0, 0, 0, 0,
            EncodingFlag or BASS_SAMPLE_LOOP);
    
        if SoundStream <> 0 then
        begin
          BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 2500);
    
          if BASS_ChannelPlay(SoundStream, False) then
          begin
            StopButton := TNewButton.Create(WizardForm);
            StopButton.Parent := WizardForm;
            StopButton.Left :=
              WizardForm.ClientWidth -
              WizardForm.CancelButton.Left -  WizardForm.CancelButton.Width;
            StopButton.Top := WizardForm.CancelButton.Top;
            StopButton.Width :=  WizardForm.CancelButton.Width;
            StopButton.Height := WizardForm.CancelButton.Height;
            StopButton.Caption := 'Stop';
            StopButton.OnClick := @StopButtonClick;
    
            PauseResumePlayButton := TNewButton.Create(WizardForm);
            PauseResumePlayButton.Parent := WizardForm;
            PauseResumePlayButton.Left :=
              WizardForm.ClientWidth -
              WizardForm.NextButton.Left -  WizardForm.NextButton.Width;
            PauseResumePlayButton.Top := WizardForm.CancelButton.Top;
            PauseResumePlayButton.Width :=  WizardForm.CancelButton.Width;
            PauseResumePlayButton.Height := WizardForm.CancelButton.Height;
            PauseResumePlayButton.Caption := 'Pause';
            PauseResumePlayButton.OnClick := @PauseButtonClick;
          end;
        end;
      end;
    end;
    
    • Note that you called the BASS_StreamCreateFile, BASS_SetConfig and BASS_ChannelPlay twice with the same arguments. It does not make sense. I've removed the second set.
    • I've also tweaked placement of the buttons.

    Music control buttons