source: trunk/Sound.pas

Last change on this file was 75, checked in by chronos, 8 months ago
  • Modified: Removed U prefix from CoolAudio package unit names.
File size: 5.4 KB
Line 
1unit Sound;
2
3interface
4
5uses
6 Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, FileUtil
7 {$IFDEF WINDOWS}, mmsystem{$ELSE}, AsyncProcess2, Process{$ENDIF};
8
9type
10 TPlayStyle = (psAsync, psSync);
11
12 TSound = class(TComponent)
13 private
14 {$IFNDEF WINDOWS}
15 AsyncProcess: TAsyncProcess;
16 SyncProcess: TProcess;
17 {$ENDIF}
18 FPlayCommand: string;
19 FDefaultPlayCommand: string;
20 FFileName: string;
21 FStyle: TPlayStyle;
22 protected
23 function GetPlayCommand: string;
24 procedure PlaySound(const FileName: string); virtual;
25 public
26 constructor Create(AOwner: TComponent); override;
27 destructor Destroy; override;
28 procedure Play;
29 procedure StopSound;
30 published
31 property FileName: string read FFileName write FFileName;
32 property Style: TPlayStyle read FStyle write FStyle default psASync;
33 property PlayCommand: string read FPlayCommand write FPlayCommand;
34 end;
35
36procedure Register;
37
38
39implementation
40
41resourcestring
42 SUnableToPlay = 'Unable to play ';
43 {$IFDEF WINDOWS}
44 {$ELSE}
45 SPlayNotSupported = 'The play command %s does not work on your system';
46 {$ENDIF}
47
48procedure Register;
49begin
50 RegisterComponents('Common', [TSound]);
51end;
52
53function GetNonWindowsPlayCommand: string;
54begin
55 Result := '';
56 if FindDefaultExecutablePath('ffplay') <> '' then
57 Result := 'ffplay -autoexit -nodisp -loglevel quiet'
58 else if FindDefaultExecutablePath('play') <> '' then
59 Result := 'play -q'
60 else if FindDefaultExecutablePath('aplay') <> '' then
61 Result := 'aplay -q'
62 else if FindDefaultExecutablePath('paplay') <> '' then
63 Result := 'paplay'
64 else if FindDefaultExecutablePath('mplayer') <> '' then
65 Result := 'mplayer -really-quiet'
66 else if FindDefaultExecutablePath('CMus') <> '' then
67 Result := 'CMus'
68 else if FindDefaultExecutablePath('pacat') <> '' then
69 Result := 'pacat -p'
70 else if FindDefaultExecutablePath('cvlc') <> '' then
71 Result := 'cvlc -q --play-and-exit'
72 else if FindDefaultExecutablePath('canberra-gtk-play') <> '' then
73 Result := 'canberra-gtk-play -c never -f'
74 else if FindDefaultExecutablePath('afplay') <> '' then
75 Result := 'afplay'
76 else if FindDefaultExecutablePath('mpg321') <> '' then
77 Result := 'mpg321 -q';
78end;
79
80constructor TSound.Create(AOwner: TComponent);
81begin
82 inherited;
83 FStyle := psAsync;
84 {$IFDEF WINDOWS}
85 FDefaultPlayCommand := 'sndPlaySound';
86 {$ELSE}
87 FDefaultPlayCommand := GetNonWindowsPlayCommand; // Linux, Mac etc.
88 {$ENDIF}
89 if FDefaultPlayCommand <> '' then FPlayCommand := FDefaultPlayCommand;
90end;
91
92destructor TSound.Destroy;
93begin
94 {$IFNDEF WINDOWS}
95 FreeAndNil(SyncProcess);
96 FreeAndNil(AsyncProcess);
97 {$ENDIF}
98 inherited;
99end;
100
101procedure TSound.Play;
102begin
103 if not FileExists(FFileName) then
104 Exit;
105 try
106 PlaySound(FFileName);
107 except
108 on E: Exception do
109 E.CreateFmt(SUnableToPlay + '%s Message:%s', [FFileName, E.Message]);
110 end;
111end;
112
113function TSound.GetPlayCommand: String;
114begin
115 if FPlayCommand = '' then
116 Result := FDefaultPlayCommand
117 else
118 Result := FPlayCommand;
119end;
120
121procedure TSound.PlaySound(const FileName: string);
122var
123{$IFDEF WINDOWS}
124 Flags: Word;
125{$ELSE}
126 CommandParts: TStrings;
127 PlayCommand: string;
128{$ENDIF}
129begin
130{$IFDEF WINDOWS}
131 if FStyle = psASync then
132 Flags := SND_ASYNC or SND_NODEFAULT
133 else
134 Flags := SND_SYNC or SND_NODEFAULT;
135 try
136 sndPlaySound(PChar(FileName), Flags);
137 except
138 ShowMessage(SUnableToPlay + FileName);
139 end;
140{$ELSE}
141 // How to play in Linux? Use generic Linux commands
142 // Use asyncprocess to play sound as SND_ASYNC
143 // proceed if we managed to find a valid command
144 PlayCommand := GetPlayCommand;
145 if PlayCommand <> '' then begin
146 CommandParts := TStringList.Create;
147 try
148 CommandParts.Delimiter := ' ';
149 CommandParts.DelimitedText := PlayCommand;
150 if FStyle = psASync then begin
151 if AsyncProcess = nil then
152 AsyncProcess := TAsyncProcess.Create(nil);
153 AsyncProcess.CurrentDirectory := ExtractFileDir(FileName);
154 AsyncProcess.Executable := FindDefaultExecutablePath(CommandParts[0]);
155 CommandParts.Delete(0);
156 AsyncProcess.Parameters.Clear;
157 AsyncProcess.Parameters.AddStrings(CommandParts);
158 AsyncProcess.Parameters.Add(FileName);
159 try
160 AsyncProcess.Execute;
161 except
162 On E: Exception do
163 E.CreateFmt('Playstyle=paASync: ' + SUnableToPlay +
164 '%s Message:%s', [FileName, E.Message]);
165 end;
166 end else begin
167 if SyncProcess = nil then
168 SyncProcess := TProcess.Create(nil);
169 SyncProcess.CurrentDirectory := ExtractFileDir(FileName);
170 SyncProcess.Executable := FindDefaultExecutablePath(CommandParts[0]);
171 CommandParts.Delete(0);
172 SyncProcess.Parameters.Clear;
173 SyncProcess.Parameters.AddStrings(CommandParts);
174 SyncProcess.Parameters.Add(FileName);
175 try
176 SyncProcess.Execute;
177 SyncProcess.WaitOnExit;
178 except
179 On E: Exception do
180 E.CreateFmt('Playstyle=paSync: ' + SUnableToPlay +
181 '%s Message:%s', [FileName, E.Message]);
182 end;
183 end;
184 finally
185 FreeAndNil(CommandParts);
186 end;
187 end
188 else
189 raise Exception.CreateFmt(SPlayNotSupported, [FPlayCommand]);
190{$ENDIF}
191end;
192
193procedure TSound.StopSound;
194begin
195{$IFDEF WINDOWS}
196 sndPlaySound(nil, 0);
197{$ELSE}
198 if SyncProcess <> nil then SyncProcess.Terminate(1);
199 if AsyncProcess <> nil then AsyncProcess.Terminate(1);
200{$ENDIF}
201end;
202
203end.
204
Note: See TracBrowser for help on using the repository browser.