Play Sound Multiplatform

From Free Pascal wiki
Revision as of 16:48, 11 September 2014 by Minesadorada (talk | contribs) (Last typo - honest!)
Jump to navigationJump to search

Summary

  • The object is to play a simple WAV sound both in Windows and Linux (Sync and ASync)
  • There are lots of libraries to do this in a complicated way, but this code should suffice for simple use

Code

  • Here is the Uses clause in the Implementation section:
..other units..
FileUtil{$IFDEF WINDOWS},mmsystem{$ELSE},asyncprocess,process{$ENDIF}
..other units..
  • Declare a type:
TPlayStyle = (psAsync,psSync);
  • Declare some variables:
{$IFDEF LINUX}
SoundPlayerAsyncProcess:Tasyncprocess;
SoundPlayerSyncProcess:Tprocess;
{$ENDIF}
fPathToSoundFile:String;
fPlayStyle:TPlayStyle;
  • And a worker function:
procedure PlaySound(Const szSoundFilename:String);
  • And a couple of constants:
{$IFDEF LINUX}
CONST // Defined in mmsystem
  SND_SYNC=0;
  SND_ASYNC=1;
  SND_NODEFAULT=2;
{$ENDIF}
  • Now you are good to go:
fPlayStyle := psASync;
fPathToSoundFile:='mysound.wav';
If FileExistsUTF8(fPathToSoundFile) then PlaySound(fPathToSoundFile);
  • Here's the PlaySound procedure
procedure PlaySound(Const szSoundFilename:String);
Var
  flags:Word;
  linuxplaycommand:String;
begin
linuxplaycommand:='';
{$IFDEF WINDOWS}
        If fPlayStyle = psASync then flags:=SND_ASYNC OR SND_NODEFAULT
        else flags:=SND_SYNC OR SND_NODEFAULT;
        TRY
        sndPlaySound(PChar(szSoundFilename:String),flags);
        except
          ShowMessage('Unable to play ' + szSoundFilename:String);
        end;
{$ELSE}
       // How to play in Linux? Use generic Linux commands
       // Use asyncprocess to play sound as SND_ASYNC

// Try play
If (FindDefaultExecutablePath('play') <> '') then linuxplaycommand:='play';
// Try aplay
If (linuxplaycommand='') then
   If (FindDefaultExecutablePath('aplay') <> '') Then linuxplaycommand:='aplay';
// Try paplay
If (linuxplaycommand='') then
   If (FindDefaultExecutablePath('aplay') <> '') Then linuxplaycommand:='paplay';
// proceed if we managed to find a valid command
If (linuxplaycommand <> '') then
BEGIN
       If fPlayStyle = psASync then
       begin
            If SoundPlayerAsyncProcess=Nil then SoundPlayerAsyncProcess:=Tasyncprocess.Create(Nil);
            SoundPlayerAsyncProcess.CurrentDirectory:=ExtractFileDir(szSoundFilename);
            SoundPlayerAsyncProcess.Executable:=FindDefaultExecutablePath(linuxplaycommand);
            SoundPlayerAsyncProcess.Parameters.Clear;
            SoundPlayerAsyncProcess.Parameters.Add(szSoundFilename);
            TRY
            SoundPlayerAsyncProcess.Execute;
            except
              ShowMessage('Playstyle=paASync: Unable to play ' + szSoundFilename);
            end;
       end
       else
       begin
           If SoundPlayerSyncProcess=Nil then SoundPlayerSyncProcess:=Tprocess.Create(Nil);
           SoundPlayerSyncProcess.CurrentDirectory:=ExtractFileDir(szSoundFilename);
           SoundPlayerSyncProcess.Executable:=FindDefaultExecutablePath(linuxplaycommand);
           SoundPlayersyncProcess.Parameters.Clear;
           SoundPlayerSyncProcess.Parameters.Add(szSoundFilename);
           TRY
           SoundPlayerSyncProcess.Execute;
           SoundPlayersyncProcess.WaitOnExit;
           except
             ShowMessage('Playstyle=paSyncSync: Unable to play ' + szSoundFilename);
           end;
       end;
END;
{$ENDIF}
end;
  • Destroy the process objects in your Destroy procedure:
FreeAndNil(SoundPlayerSyncProcess);
FreeAndNil(SoundPlayerAsyncProcess);



minesadorada