source: trunk/Packages/CoolAudio/Systems/WinAPI/AudioSystemWindows.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: 7.4 KB
Line 
1unit AudioSystemWindows;
2
3{$I CoolAudioConfig.inc}
4
5interface
6
7{$IFDEF Windows}
8uses
9 Windows, Classes, SysUtils, AudioSystem, MMSystem, DateUtils;
10
11type
12
13 { TAudioSystemWindows }
14
15 TAudioSystemWindows = class(TAudioSystem)
16 public
17 PlayerIndex: Integer;
18 function GetMediaPlayerDriverClass: TMediaPlayerDriverClass; override;
19 end;
20
21 TMPDeviceTypes = (dtAutoSelect, dtAVIVideo, dtCDAudio, dtDAT, dtDigitalVideo, dtMMMovie,
22 dtOther, dtOverlay, dtScanner, dtSequencer, dtVCR, dtVideodisc, dtWaveAudio);
23
24 { TPlayerWindows }
25
26 TPlayerWindows = class(TMediaPlayerDriver)
27 private
28 FHandle: HWND;
29 FDeviceId: MCIDEVICEID;
30 FDeviceType: TMPDeviceTypes;
31 FFlags: Longint;
32 FUseNotify: Boolean;
33 FNotify: Boolean;
34 FUseWait: Boolean;
35 FWait: Boolean;
36 FAliasName: string;
37 procedure DoClose;
38 procedure DoOpen;
39 procedure SetDeviceType(AValue: TMPDeviceTypes);
40 procedure CheckError(AValue: Integer);
41 function GetErrorMessage(Code: Integer): string;
42 procedure SetActive(AValue: Boolean); override;
43 procedure SetNotify(AValue: Boolean);
44 procedure SetWait(AValue: Boolean);
45 function GetPosition: TDateTime; override;
46 procedure SetPosition(AValue: TDateTime); override;
47 function GetLength: TDateTime; override;
48 public
49 procedure Play; override;
50 procedure Pause; override;
51 procedure Stop; override;
52 constructor Create; override;
53 destructor Destroy; override;
54 property DeviceType: TMPDeviceTypes read FDeviceType write SetDeviceType;
55 property Handle: HWND read FHandle;
56 property Wait: Boolean read FWait write SetWait;
57 property Notify: Boolean read FNotify write SetNotify;
58 end;
59{$ENDIF}
60
61resourcestring
62 SMCIUnknownError = 'Unknown error code';
63
64
65implementation
66
67{$IFDEF Windows}
68
69{ TAudioSystemWindows }
70
71function TAudioSystemWindows.GetMediaPlayerDriverClass: TMediaPlayerDriverClass;
72begin
73 Result := TPlayerWindows;
74end;
75
76
77{ TPlayerWindows }
78
79procedure TPlayerWindows.SetDeviceType(AValue: TMPDeviceTypes);
80begin
81 if FDeviceType = AValue then Exit;
82 FDeviceType := AValue;
83end;
84
85procedure TPlayerWindows.CheckError(AValue: Integer);
86begin
87 if AValue <> 0 then raise Exception.Create('Error ' + IntToStr(AValue) + ': ' + GetErrorMessage(AValue));
88end;
89
90function TPlayerWindows.GetErrorMessage(Code: Integer): string;
91var
92 ErrMsg: array[0..4095] of Char;
93begin
94 if not mciGetErrorString(Code, ErrMsg, SizeOf(ErrMsg)) then
95 Result := SMCIUnknownError
96 else SetString(Result, ErrMsg, StrLen(ErrMsg));
97end;
98
99procedure TPlayerWindows.SetActive(AValue: Boolean);
100begin
101 if FActive = AValue then Exit;
102 inherited SetActive(AValue);
103 if AValue then DoOpen else DoClose;
104end;
105
106procedure TPlayerWindows.SetNotify(AValue: Boolean);
107begin
108 if FNotify = AValue then Exit;
109 FNotify := AValue;
110 FUseNotify := True;
111end;
112
113procedure TPlayerWindows.SetWait(AValue: Boolean);
114begin
115 if FWait = AValue then Exit;
116 FWait := AValue;
117 FUseWait := True;
118end;
119
120function TPlayerWindows.GetPosition: TDateTime;
121var
122 Parm: TMCI_Status_Parms;
123begin
124 FFlags := mci_Wait or mci_Status_Item;
125 Parm.dwItem := mci_Status_Position;
126 CheckError(mciSendCommand(FDeviceID, mci_Status, FFlags, Longint(@Parm)));
127 Result := Parm.dwReturn * OneMillisecond;
128end;
129
130procedure TPlayerWindows.SetPosition(AValue: TDateTime);
131var
132 Parm: TMCI_Seek_Parms;
133begin
134 if FDeviceID <> 0 then begin
135 FFlags := 0;
136 if FUseWait then
137 begin
138 if FWait then FFlags := mci_Wait;
139 FUseWait := False;
140 end
141 else FFlags := mci_Wait;
142 if FUseNotify then
143 begin
144 if FNotify then FFlags := FFlags or mci_Notify;
145 FUseNotify := False;
146 end;
147 FFlags := FFlags or mci_To;
148 Parm.dwTo := Round(AValue / OneMillisecond);
149 CheckError(mciSendCommand(FDeviceID, mci_Seek, FFlags, Longint(@Parm)));
150 if FPlaying then Play;
151 end;
152end;
153
154function TPlayerWindows.GetLength: TDateTime;
155var
156 Parm: TMCI_Status_Parms;
157begin
158 FFlags := mci_Wait or mci_Status_Item;
159 Parm.dwItem := mci_Status_Length;
160 mciSendCommand(FDeviceID, mci_Status, FFlags, Longint(@Parm));
161 Result := Parm.dwReturn * OneMillisecond;
162end;
163
164procedure TPlayerWindows.Play;
165var
166 Parm: TMCI_Play_Parms;
167begin
168 if FDeviceID = 0 then DoOpen;
169
170 FFlags := 0;
171 if FUseNotify then
172 begin
173 if FNotify then FFlags := mci_Notify;
174 FUseNotify := False;
175 end else FFlags := mci_Notify;
176 if FUseWait then
177 begin
178 if FWait then FFlags := FFlags or mci_Wait;
179 FUseWait := False;
180 end;
181 CheckError(mciSendCommand(FDeviceID, mci_Play, FFlags, Longint(@Parm)));
182 FPlaying := True;
183end;
184
185procedure TPlayerWindows.Pause;
186var
187 Parm: TMCI_Generic_Parms;
188begin
189 if FActive then begin
190 if FPlaying then begin
191 CheckError(mciSendCommand(FDeviceID, mci_Pause, FFlags, Longint(@Parm)));
192 FPlaying := False;
193 end else begin
194 CheckError(mciSendCommand(FDeviceID, mci_Resume, FFlags, Longint(@Parm)));
195 FPlaying := True;
196 end;
197 end;
198end;
199
200procedure TPlayerWindows.Stop;
201var
202 Parm: TMCI_Generic_Parms;
203begin
204 if FActive and FPlaying then begin
205 FFlags := 0;
206 if FUseNotify then
207 begin
208 if FNotify then FFlags := mci_Notify;
209 FUseNotify := False;
210 end else FFlags := mci_Notify;
211 if FUseWait then
212 begin
213 if FWait then FFlags := FFlags or mci_Wait;
214 FUseWait := False;
215 end;
216 CheckError(mciSendCommand(FDeviceID, mci_Stop, FFlags, Longint(@Parm)));
217 FPlaying := False;
218 Position := 0;
219 end;
220end;
221
222constructor TPlayerWindows.Create;
223begin
224 inherited;
225end;
226
227destructor TPlayerWindows.Destroy;
228begin
229 Active := False;
230 inherited Destroy;
231end;
232
233procedure TPlayerWindows.DoOpen;
234const
235 DeviceName: array[TMPDeviceTypes] of PChar = ('', 'AVIVideo', 'CDAudio', 'DAT',
236 'DigitalVideo', 'MMMovie', 'Other', 'Overlay', 'Scanner', 'Sequencer',
237 'VCR', 'Videodisc', 'WaveAudio');
238var
239 Parm: TMCI_Open_Parms;
240 ParmFileName: string;
241begin
242 if FDeviceId <> 0 then DoClose;
243
244 FillChar(Parm, SizeOf(TMCI_Open_Parms), 0);
245 Parm.dwCallback := 0;
246 Parm.lpstrDeviceType := DeviceName[FDeviceType];
247 ParmFileName := UTF8Decode(FFileName);
248 Parm.lpstrElementName := PChar(ParmFileName);
249
250 FFlags := 0;
251
252 if FUseWait then
253 begin
254 if FWait then FFlags := mci_Wait;
255 FUseWait := False;
256 end
257 else
258 FFlags := mci_Wait;
259
260 if FUseNotify then
261 begin
262 if FNotify then FFlags := FFlags or mci_Notify;
263 FUseNotify := False;
264 end;
265
266 if FDeviceType <> dtAutoSelect then
267 FFlags := FFlags or mci_Open_Type;
268
269 if FDeviceType <> dtAutoSelect then
270 FFlags := FFlags or mci_Open_Type
271 else
272 FFlags := FFlags or MCI_OPEN_ELEMENT;
273
274 //Parm.dwCallback := Handle;
275 CheckError(mciSendCommand(0, mci_Open, FFlags, Longint(@Parm)));
276 FDeviceID := Parm.wDeviceID;
277 FActive := True;
278end;
279
280procedure TPlayerWindows.DoClose;
281var
282 Parm: TMCI_Generic_Parms;
283begin
284 if FDeviceId <> 0 then begin
285 FFlags := 0;
286 if FUseWait then
287 begin
288 if FWait then FFlags := mci_Wait;
289 FUseWait := False;
290 end
291 else FFlags := mci_Wait;
292 if FUseNotify then
293 begin
294 if FNotify then FFlags := FFlags or mci_Notify;
295 FUseNotify := False;
296 end;
297 CheckError(mciSendCommand(FDeviceId, mci_Close, FFlags, Longint(@Parm)));
298 FDeviceId := 0;
299 FActive := False;
300 end;
301end;
302
303{$ENDIF}
304
305end.
306
Note: See TracBrowser for help on using the repository browser.