Changeset 173 for trunk/Packages/CevoComponents/Sound.pas
- Timestamp:
- Jun 16, 2019, 10:57:17 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/CevoComponents/Sound.pas
r135 r173 4 4 5 5 uses 6 Messages, SysUtils, Classes, Graphics, Controls, Forms, fgl 7 {$IFDEF WINDOWS}, MMSystem, Windows{$ENDIF}; 6 Messages, SysUtils, Classes, Graphics, Controls, Forms, fgl, FileUtil, 7 StringTables, Directories 8 {$IFDEF WINDOWS}, MMSystem, Windows{$ENDIF} 9 {$IFDEF LINUX}, Process, AsyncProcess{$ENDIF}; 8 10 9 11 type 12 TPlayStyle = (psAsync, psSync); 13 10 14 TSoundPlayer = class(TForm) 11 15 private … … 15 19 end; 16 20 17 function PrepareSound(FileName: string): integer; 18 procedure PlaySound(FileName: string); 19 20 implementation 21 22 {$R *.lfm} 23 24 type 21 { TSound } 22 25 23 TSound = class 24 private 25 PlayCommand: string; 26 {$IFDEF LINUX} 27 SoundPlayerAsyncProcess: TAsyncProcess; 28 SoundPlayerSyncProcess: TProcess; 29 {$ENDIF} 30 function GetNonWindowsPlayCommand: string; 26 31 public 27 FDeviceID: word;32 FDeviceID: Word; 28 33 FFileName: string; 34 PlayStyle: TPlayStyle; 29 35 constructor Create(const FileName: string); 30 36 destructor Destroy; override; … … 34 40 end; 35 41 42 function PrepareSound(FileName: string): Integer; 43 procedure PlaySound(FileName: string); 44 function Play(Item: string; Index: Integer = -1): Boolean; 45 procedure PreparePlay(Item: string; Index: Integer = -1); 46 47 const 48 // sound modes 49 smOff = 0; 50 smOn = 1; 51 smOnAlt = 2; 52 53 var 54 Sounds: TStringTable; 55 SoundMode: Integer; 56 SoundPlayer: TSoundPlayer; 57 SoundList: TFPGObjectList<TSound>; 58 PlayingSound: TSound; 59 60 61 implementation 62 63 {$R *.lfm} 64 65 resourcestring 66 SUnableToPlay = 'PlayStyle=%s: Unable to play %s Message:%s'; 67 SPlayCommandNotWork = 'The play command %s does not work on your system'; 36 68 37 69 constructor TSound.Create(const FileName: string); … … 41 73 {$ENDIF} 42 74 begin 75 PlayStyle := psAsync; 76 FFileName := FileName; 43 77 {$IFDEF WINDOWS} 44 78 FDeviceID := 0; 45 FFileName := FileName; 46 if FileExists(FFileName) then 47 begin 79 if FileExists(FFileName) then begin 48 80 OpenParm.dwCallback := 0; 49 81 OpenParm.lpstrDeviceType := 'WaveAudio'; … … 54 86 end 55 87 {$ENDIF} 88 {$IFDEF LINUX} 89 PlayCommand := GetNonWindowsPlayCommand; 90 FDeviceID := 1; 91 {$ENDIF} 56 92 end; 57 93 … … 62 98 mciSendCommand(FDeviceID, MCI_CLOSE, MCI_WAIT, 0); 63 99 {$ENDIF} 100 {$IFDEF LINUX} 101 {$IFNDEF WINDOWS} 102 FreeAndNil(SoundPlayerSyncProcess); 103 FreeAndNil(SoundPlayerAsyncProcess); 104 {$ENDIF} 105 {$ENDIF} 64 106 inherited Destroy; 65 107 end; 108 109 function TSound.GetNonWindowsPlayCommand: string; 110 begin 111 Result := ''; 112 // Try play 113 if (FindDefaultExecutablePath('play') <> '') then 114 Result := 'play'; 115 // Try aplay 116 if (result = '') then 117 if (FindDefaultExecutablePath('aplay') <> '') then 118 Result := 'aplay -q'; 119 // Try paplay 120 if (Result = '') then 121 if (FindDefaultExecutablePath('paplay') <> '') then 122 Result := 'paplay'; 123 // Try mplayer 124 if (Result = '') then 125 if (FindDefaultExecutablePath('mplayer') <> '') then 126 Result := 'mplayer -really-quiet'; 127 // Try CMus 128 if (Result = '') then 129 if (FindDefaultExecutablePath('CMus') <> '') then 130 Result := 'CMus'; 131 // Try pacat 132 if (Result = '') then 133 if (FindDefaultExecutablePath('pacat') <> '') then 134 Result := 'pacat -p'; 135 // Try ffplay 136 if (Result = '') then 137 if (FindDefaultExecutablePath('ffplay') <> '') then 138 result := 'ffplay -autoexit -nodisp'; 139 // Try cvlc 140 if (Result = '') then 141 if (FindDefaultExecutablePath('cvlc') <> '') then 142 result := 'cvlc -q --play-and-exit'; 143 // Try canberra-gtk-play 144 if (Result = '') then 145 if (FindDefaultExecutablePath('canberra-gtk-play') <> '') then 146 Result := 'canberra-gtk-play -c never -f'; 147 // Try Macintosh command? 148 if (Result = '') then 149 if (FindDefaultExecutablePath('afplay') <> '') then 150 Result := 'afplay'; 151 end; 152 66 153 67 154 procedure TSound.Play(HWND: DWORD); … … 69 156 var 70 157 PlayParm: TMCI_Play_Parms; 158 {$ENDIF} 159 {$IFDEF LINUX} 160 var 161 L: TStringList; 162 I: Integer; 71 163 {$ENDIF} 72 164 begin … … 78 170 end 79 171 {$ENDIF} 172 {$IFDEF LINUX} 173 // How to play in Linux? Use generic Linux commands 174 // Use asyncprocess to play sound as SND_ASYNC 175 // proceed if we managed to find a valid command 176 if PlayCommand <> '' then begin 177 L := TStringList.Create; 178 try 179 L.Delimiter := ' '; 180 L.DelimitedText := PlayCommand; 181 if PlayStyle = psASync then begin 182 if SoundPlayerAsyncProcess = nil then 183 SoundPlayerAsyncProcess := TAsyncProcess.Create(nil); 184 SoundPlayerAsyncProcess.CurrentDirectory := ExtractFileDir(FFilename); 185 SoundPlayerAsyncProcess.Executable := FindDefaultExecutablePath(L[0]); 186 SoundPlayerAsyncProcess.Parameters.Clear; 187 for I := 1 to L.Count - 1 do 188 SoundPlayerAsyncProcess.Parameters.Add(L[I]); 189 SoundPlayerAsyncProcess.Parameters.Add(FFilename); 190 try 191 SoundPlayerAsyncProcess.Execute; 192 except 193 On E: Exception do 194 E.CreateFmt(SUnableToPlay, ['paASync', FFilename, E.Message]); 195 end; 196 PlayingSound := nil; 197 end else begin 198 if SoundPlayerSyncProcess = nil then 199 SoundPlayerSyncProcess := TProcess.Create(nil); 200 SoundPlayerSyncProcess.CurrentDirectory := ExtractFileDir(FFilename); 201 SoundPlayerSyncProcess.Executable := FindDefaultExecutablePath(L[0]); 202 SoundPlayersyncProcess.Parameters.Clear; 203 for I := 1 to L.Count - 1 do 204 SoundPlayerSyncProcess.Parameters.Add(L[I]); 205 SoundPlayerSyncProcess.Parameters.Add(FFilename); 206 try 207 SoundPlayerSyncProcess.Execute; 208 SoundPlayersyncProcess.WaitOnExit; 209 except 210 On E: Exception do 211 E.CreateFmt(SUnableToPlay, ['paSync', FFilename, E.Message]); 212 end; 213 PlayingSound := nil; 214 end; 215 finally 216 L.Free; 217 end; 218 end 219 else 220 raise Exception.CreateFmt(SPlayCommandNotWork, [PlayCommand]); 221 {$ENDIF} 80 222 end; 81 223 … … 85 227 mciSendCommand(FDeviceID, MCI_STOP, 0, 0); 86 228 {$ENDIF} 229 {$IFDEF LINUX} 230 if SoundPlayerSyncProcess <> nil then SoundPlayerSyncProcess.Terminate(1); 231 if SoundPlayerAsyncProcess <> nil then SoundPlayerAsyncProcess.Terminate(1); 232 {$ENDIF} 87 233 end; 88 234 … … 93 239 {$ENDIF} 94 240 end; 95 96 97 var98 SoundPlayer: TSoundPlayer;99 SoundList: TFPGObjectList<TSound>;100 PlayingSound: TSound;101 241 102 242 {$IFDEF WINDOWS} … … 111 251 {$ENDIF} 112 252 113 function PrepareSound(FileName: string): integer;253 function PrepareSound(FileName: string): Integer; 114 254 begin 115 255 Result := 0; 116 while ( result < SoundList.Count) and (SoundList[result].FFileName <> FileName) do117 inc(result);118 if result = SoundList.Count then begin119 // first time this sound is played256 while (Result < SoundList.Count) and (SoundList[result].FFileName <> FileName) do 257 Inc(Result); 258 if Result = SoundList.Count then begin 259 // First time this sound is played 120 260 SoundList.Add(TSound.Create(FileName)); 121 261 Result := SoundList.Count - 1; … … 125 265 procedure PlaySound(FileName: string); 126 266 begin 127 if PlayingSound <> nil then 128 exit; 267 if PlayingSound <> nil then Exit; 129 268 if SoundPlayer = nil then 130 269 Application.CreateForm(TSoundPlayer, SoundPlayer); … … 136 275 end; 137 276 277 function Play(Item: string; Index: Integer = -1): Boolean; 278 {$IFNDEF DEBUG} 279 var 280 WavFileName: string; 281 {$ENDIF} 282 begin 283 Result := False; 284 {$IFNDEF DEBUG} 285 if (Sounds = nil) or (SoundMode = smOff) or (Item = '') then 286 begin 287 Result := True; 288 Exit; 289 end; 290 WavFileName := Sounds.Lookup(Item, Index); 291 Assert(WavFileName[1] <> '['); 292 Result := (WavFileName <> '') and (WavFileName[1] <> '[') and (WavFileName <> '*'); 293 if Result then 294 // SndPlaySound(pchar(HomeDir+'Sounds' +DirectorySeparator+WavFileName+'.wav'),SND_ASYNC) 295 PlaySound(HomeDir + 'Sounds' + DirectorySeparator + WavFileName); 296 {$ENDIF} 297 end; 298 299 procedure PreparePlay(Item: string; Index: Integer = -1); 300 {$IFNDEF DEBUG} 301 var 302 WavFileName: string; 303 {$ENDIF} 304 begin 305 {$IFNDEF DEBUG} 306 if (Sounds = nil) or (SoundMode = smOff) or (Item = '') then 307 Exit; 308 WavFileName := Sounds.Lookup(Item, Index); 309 Assert(WavFileName[1] <> '['); 310 if (WavFileName <> '') and (WavFileName[1] <> '[') and (WavFileName <> '*') then 311 PrepareSound(HomeDir + 'Sounds' + DirectorySeparator + WavFileName); 312 {$ENDIF} 313 end; 314 138 315 procedure UnitInit; 139 316 begin … … 150 327 end; 151 328 FreeAndNil(SoundList); 329 if Sounds <> nil then 330 FreeAndNil(Sounds); 152 331 end; 153 332
Note:
See TracChangeset
for help on using the changeset viewer.