Subversion Repositories spacemission

Rev

Rev 1 | Rev 16 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1 Rev 4
1
unit DXSounds;
1
unit DXSounds;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
{$INCLUDE DelphiXcfg.inc}
5
{$INCLUDE DelphiXcfg.inc}
6
 
6
 
7
uses
7
uses
8
  Windows, Messages, SysUtils, Classes, Controls, Forms, ExtCtrls, MMSystem,
8
  Windows, Messages, SysUtils, Classes, Controls, Forms, ExtCtrls, MMSystem, ActiveX,
-
 
9
  DXClass, DXWave, D3DUtils, {$IFDEF VER17UP} Types, {$ENDIF}
-
 
10
{$IFDEF StandardDX}
9
  DirectX, DXClass, Wave;
11
  DirectSound, DirectMusic;
-
 
12
{$ELSE}
-
 
13
  DirectX;
-
 
14
{$ENDIF}
10
 
15
 
11
type
16
type
12
 
17
 
13
  {  EDirectSoundError  }
18
  {  EDirectSoundError  }
14
 
19
 
15
  EDirectSoundError = class(EDirectXError);
20
  EDirectSoundError = class(EDirectXError);
16
  EDirectSoundBufferError = class(EDirectSoundError);
21
  EDirectSoundBufferError = class(EDirectSoundError);
17
 
22
 
18
  {  TDirectSound  }
23
  {  TDirectSound  }
19
 
24
 
20
  TDirectSoundBuffer = class;
25
  TDirectSoundBuffer = class;
21
 
26
 
22
  TDirectSound = class(TDirectX)
27
  TDirectSound = class(TDirectX)
23
  private
28
  private
24
    FBufferList: TList;
29
    FBufferList: TList;
25
    FGlobalFocus: Boolean;
30
    FGlobalFocus: Boolean;
26
    FIDSound: IDirectSound;
31
    FIDSound: IDirectSound;
27
    FInRestoreBuffer: Boolean;
32
    FInRestoreBuffer: Boolean;
28
    FStickyFocus: Boolean;
33
    FStickyFocus: Boolean;
29
    function GetBuffer(Index: Integer): TDirectSoundBuffer;
34
    function GetBuffer(Index: Integer): TDirectSoundBuffer;
30
    function GetBufferCount: Integer;
35
    function GetBufferCount: Integer;
31
    function GetIDSound: IDirectSound;
36
    function GetIDSound: IDirectSound;
32
    function GetISound: IDirectSound;
37
    function GetISound: IDirectSound;
33
  protected          
38
  protected
34
    procedure CheckBuffer(Buffer: TDirectSoundBuffer);
39
    procedure CheckBuffer(Buffer: TDirectSoundBuffer);
35
    procedure DoRestoreBuffer; virtual;
40
    procedure DoRestoreBuffer; virtual;
36
  public
41
  public
37
    constructor Create(GUID: PGUID);
42
    constructor Create(GUID: PGUID);
38
    destructor Destroy; override;
43
    destructor Destroy; override;
39
    class function Drivers: TDirectXDrivers;
44
    class function Drivers: TDirectXDrivers;
40
    property BufferCount: Integer read GetBufferCount;
45
    property BufferCount: Integer read GetBufferCount;
41
    property Buffers[Index: Integer]: TDirectSoundBuffer read GetBuffer;
46
    property Buffers[Index: Integer]: TDirectSoundBuffer read GetBuffer;
42
    property IDSound: IDirectSound read GetIDSound;
47
    property IDSound: IDirectSound read GetIDSound;
43
    property ISound: IDirectSound read GetISound;
48
    property ISound: IDirectSound read GetISound;
44
  end;
49
  end;
45
 
50
 
-
 
51
  {  TD3DSParams  }
-
 
52
 
-
 
53
  TConeAngle = record
-
 
54
    Inside,Outside:DWord;
-
 
55
  end;
-
 
56
  TD3DSParams = class
-
 
57
  private
-
 
58
    FOwner: TDirectSoundBuffer;
-
 
59
 
-
 
60
    FDsb: TDS3DBUFFER;
-
 
61
 
-
 
62
    function GetPosition: TD3DVector;
-
 
63
    function GetVelocity: TD3DVector;
-
 
64
    function GetConeOrientation: TD3DVector;
-
 
65
    function GetConeAngle: TConeAngle;
-
 
66
    function GetConeOutsideVolume: Integer;
-
 
67
    function GetMinDistance: TD3DValue;
-
 
68
    function GetMaxDistance: TD3DValue;
-
 
69
    function GetRaw: TDS3DBuffer;
-
 
70
 
-
 
71
    procedure SetPosition(const v: TD3DVector);
-
 
72
    procedure SetVelocity(const v: TD3DVector);
-
 
73
    procedure SetConeOrientation(const v: TD3DVector);
-
 
74
    procedure SetConeAngle(const v: TConeAngle);
-
 
75
    procedure SetConeOutsideVolume(const v: Integer);
-
 
76
    procedure SetMinDistance(const v: TD3DValue);
-
 
77
    procedure SetMaxDistance(const v: TD3DValue);
-
 
78
    procedure SetRaw(const v: TDS3DBuffer);
-
 
79
 
-
 
80
    function CheckValidity: Boolean;
-
 
81
  public
-
 
82
    constructor Create(Owner: TDirectSoundBuffer);
-
 
83
    destructor Destroy; override;
-
 
84
    property Position: TD3DVector read getPosition write setPosition;
-
 
85
    property Velocity: TD3DVector read getVelocity write setVelocity;
-
 
86
    property ConeOrientation: TD3DVector read getConeOrientation write setConeOrientation;
-
 
87
    property ConeAngle: TConeAngle read getConeAngle write setConeAngle;
-
 
88
    property ConeOutsideVolume: Integer read getConeOutsideVolume write setConeOutsideVolume;
-
 
89
    property MinDistance: TD3DValue read getMinDistance write setMinDistance;
-
 
90
    property MaxDistance: TD3DValue read getMaxDistance write setMaxDistance;
-
 
91
    property RawParams: TDS3DBuffer read getRaw write setRaw;
-
 
92
    procedure Assign(Prms: TD3DSParams);
-
 
93
  end;
-
 
94
 
46
  {  TDirectSoundBuffer  }
95
  {  TDirectSoundBuffer  }
47
 
96
 
48
  TDirectSoundBuffer = class(TDirectX)
97
  TDirectSoundBuffer = class(TDirectX)
49
  private
98
  private
50
    FDSound: TDirectSound;
99
    FDSound: TDirectSound;
51
    FIDSBuffer: IDirectSoundBuffer;
100
    FIDSBuffer: IDirectSoundBuffer;
-
 
101
    FIDS3DBuffer:IDirectSound3DBuffer;
-
 
102
    FD3DSParams: TD3DSParams;
52
    FCaps: TDSBCaps;
103
    FCaps: TDSBCaps;
53
    FFormat: PWaveFormatEx;
104
    FFormat: PWaveFormatEx;
54
    FFormatSize: Integer;
105
    FFormatSize: Integer;
55
    FLockAudioPtr1, FLockAudioPtr2: array[0..0] of Pointer;
106
    FLockAudioPtr1, FLockAudioPtr2: array[0..0] of Pointer;
56
    FLockAudioSize1, FLockAudioSize2: array[0..0] of DWORD;
107
    FLockAudioSize1, FLockAudioSize2: array[0..0] of DWORD;
57
    FLockCount: Integer;
108
    FLockCount: Integer;
-
 
109
    FIsD3D: Boolean;
58
    function GetBitCount: Longint;
110
    function GetBitCount: Longint;
59
    function GetFormat: PWaveFormatEx;
111
    function GetFormat: PWaveFormatEx;
60
    function GetFrequency: Integer;
112
    function GetFrequency: Integer;
61
    function GetIDSBuffer: IDirectSoundBuffer;
113
    function GetIDSBuffer: IDirectSoundBuffer;
62
    function GetIBuffer: IDirectSoundBuffer;
114
    function GetIBuffer: IDirectSoundBuffer;
63
    function GetPlaying: Boolean;
115
    function GetPlaying: Boolean;
64
    function GetPan: Integer;
116
    function GetPan: Integer;
65
    function GetPosition: Longint;
117
    function GetPosition: Longint;
66
    function GetSize: Integer;
118
    function GetSize: Integer;
67
    function GetStatus: Integer;
119
    function GetStatus: Integer;
68
    function GetVolume: Integer;
120
    function GetVolume: Integer;
69
    procedure SetFrequency(Value: Integer);
121
    procedure SetFrequency(Value: Integer);
70
    procedure SetIDSBuffer(Value: IDirectSoundBuffer);
122
    procedure SetIDSBuffer(Value: IDirectSoundBuffer);
71
    procedure SetPan(Value: Integer);
123
    procedure SetPan(Value: Integer);
72
    procedure SetPosition(Value: Longint);
124
    procedure SetPosition(Value: Longint);
73
    procedure SetVolume(Value: Integer);
125
    procedure SetVolume(Value: Integer);
-
 
126
    function GetIDS3DBuffer: IDirectSound3DBuffer;
-
 
127
    procedure SetIDS3DBuffer(const Value: IDirectSound3DBuffer);
-
 
128
    procedure SetD3DSParams(const Value: TD3DSParams);
74
  protected
129
  protected
75
    procedure Check; override;
130
    procedure Check; override;
76
  public
131
  public
77
    constructor Create(ADirectSound: TDirectSound);
132
    constructor Create(ADirectSound: TDirectSound);
78
    destructor Destroy; override;
133
    destructor Destroy; override;
79
    procedure Assign(Source: TPersistent); override;
134
    procedure Assign(Source: TPersistent); override;
80
    function CreateBuffer(const BufferDesc: TDSBufferDesc): Boolean;
135
    function CreateBuffer(const BufferDesc: TDSBufferDesc): Boolean;
81
    procedure LoadFromFile(const FileName: string);
136
    procedure LoadFromFile(const FileName: string);
82
    procedure LoadFromMemory(const Format: TWaveFormatEx;
137
    procedure LoadFromMemory(const Format: TWaveFormatEx;
83
      Data: Pointer; Size: Integer);
138
      Data: Pointer; Size: Integer);
84
    procedure LoadFromStream(Stream: TStream);
139
    procedure LoadFromStream(Stream: TStream);
85
    procedure LoadFromWave(Wave: TWave);
140
    procedure LoadFromWave(Wave: TWave);
86
    function Lock(LockPosition, LockSize: Longint;
141
    function Lock(LockPosition, LockSize: Longint;
87
      var AudioPtr1: Pointer; var AudioSize1: Longint;
142
      var AudioPtr1: Pointer; var AudioSize1: Longint;
88
      var AudioPtr2: Pointer; var AudioSize2: Longint): Boolean;
143
      var AudioPtr2: Pointer; var AudioSize2: Longint): Boolean;
89
    function Play(Loop: Boolean{$IFNDEF VER100}=False{$ENDIF}): Boolean;
144
    function Play(Loop: Boolean{$IFNDEF VER100} = False{$ENDIF}): Boolean;
90
    function Restore: Boolean;
145
    function Restore: Boolean;
91
    function SetFormat(const Format: TWaveFormatEx): Boolean;
146
    function SetFormat(const Format: TWaveFormatEx): Boolean;
92
    procedure SetSize(const Format: TWaveFormatEx; Size: Integer);
147
    procedure SetSize(const Format: TWaveFormatEx; Size: Integer; D3D: Boolean {$IFNDEF VER100}= False{$ENDIF});
93
    procedure Stop;
148
    procedure Stop;
94
    procedure UnLock;
149
    procedure UnLock;
95
    property BitCount: Longint read GetBitCount;
150
    property BitCount: Longint read GetBitCount;
96
    property DSound: TDirectSound read FDSound;
151
    property DSound: TDirectSound read FDSound;
97
    property Format: PWaveFormatEx read GetFormat;
152
    property Format: PWaveFormatEx read GetFormat;
98
    property FormatSize: Integer read FFormatSize;
153
    property FormatSize: Integer read FFormatSize;
99
    property Frequency: Integer read GetFrequency write SetFrequency;
154
    property Frequency: Integer read GetFrequency write SetFrequency;
100
    property IBuffer: IDirectSoundBuffer read GetIBuffer;
155
    property IBuffer: IDirectSoundBuffer read GetIBuffer;
101
    property IDSBuffer: IDirectSoundBuffer read GetIDSBuffer write SetIDSBuffer;
156
    property IDSBuffer: IDirectSoundBuffer read GetIDSBuffer write SetIDSBuffer;
-
 
157
    property IDS3DBuffer: IDirectSound3DBuffer read GetIDS3DBuffer write SetIDS3DBuffer;
102
    property Playing: Boolean read GetPlaying;
158
    property Playing: Boolean read GetPlaying;
103
    property Pan: Integer read GetPan write SetPan;
159
    property Pan: Integer read GetPan write SetPan;
-
 
160
    property D3DSParams: TD3DSParams read FD3DSParams write SetD3DSParams;
-
 
161
    property IsD3D: Boolean read FIsD3D write FIsD3D default False;
104
    property Position: Longint read GetPosition write SetPosition;
162
    property Position: Longint read GetPosition write SetPosition;
105
    property Size: Integer read GetSize;
163
    property Size: Integer read GetSize;
106
    property Volume: Integer read GetVolume write SetVolume;
164
    property Volume: Integer read GetVolume write SetVolume;
107
  end;
165
  end;
108
 
166
 
109
  {  EAudioStreamError  }
167
  {  EAudioStreamError  }
110
 
168
 
111
  EAudioStreamError = class(Exception);
169
  EAudioStreamError = class(Exception);
112
 
170
 
113
  {  TAudioStream  }
171
  {  TAudioStream  }
114
 
172
 
115
  TAudioStream = class
173
  TAudioStream = class
116
  private
174
  private
117
    FAutoUpdate: Boolean;
175
    FAutoUpdate: Boolean;
118
    FBuffer: TDirectSoundBuffer;
176
    FBuffer: TDirectSoundBuffer;
119
    FBufferLength: Integer;
177
    FBufferLength: Integer;
120
    FBufferPos: DWORD;
178
    FBufferPos: DWORD;
121
    FPlayBufferPos: DWORD;
179
    FPlayBufferPos: DWORD;
122
    FBufferSize: DWORD;
180
    FBufferSize: DWORD;
123
    FDSound: TDirectSound;
181
    FDSound: TDirectSound;
124
    FLooped: Boolean;
182
    FLooped: Boolean;
125
    FPlayedSize: Integer;
183
    FPlayedSize: Integer;
126
    FPlaying: Boolean;
184
    FPlaying: Boolean;
127
    FPosition: Integer;
185
    FPosition: Integer;
128
    FWaveStream: TCustomWaveStream;
186
    FWaveStream: TCustomWaveStream;
129
    FWritePosition: Integer;
187
    FWritePosition: Integer;
130
    FNotifyEvent: THandle;
188
    FNotifyEvent: THandle;
131
    FNotifyThread: TThread;
189
    FNotifyThread: TThread;
132
    function GetFormat: PWaveFormatEX;
190
    function GetFormat: PWaveFormatEX;
133
    function GetFormatSize: Integer;
191
    function GetFormatSize: Integer;
134
    function GetFrequency: Integer;
192
    function GetFrequency: Integer;
135
    function GetPan: Integer;
193
    function GetPan: Integer;
136
    function GetPlayedSize: Integer;
194
    function GetPlayedSize: Integer;
137
    function GetSize: Integer;
195
    function GetSize: Integer;
138
    function GetVolume: Integer;
196
    function GetVolume: Integer;
139
    function GetWriteSize: Integer;
197
    function GetWriteSize: Integer;
140
    procedure SetAutoUpdate(Value: Boolean);
198
    procedure SetAutoUpdate(Value: Boolean);
141
    procedure SetBufferLength(Value: Integer);
199
    procedure SetBufferLength(Value: Integer);
142
    procedure SetFrequency(Value: Integer);
200
    procedure SetFrequency(Value: Integer);
143
    procedure SetLooped(Value: Boolean);
201
    procedure SetLooped(Value: Boolean);
144
    procedure SetPan(Value: Integer);
202
    procedure SetPan(Value: Integer);
145
    procedure SetPlayedSize(Value: Integer);
203
    procedure SetPlayedSize(Value: Integer);
146
    procedure SetPosition(Value: Integer);
204
    procedure SetPosition(Value: Integer);
147
    procedure SetVolume(Value: Integer);
205
    procedure SetVolume(Value: Integer);
148
    procedure SetWaveStream(Value: TCustomWaveStream);
206
    procedure SetWaveStream(Value: TCustomWaveStream);
149
    procedure Update2(InThread: Boolean);
207
    procedure Update2(InThread: Boolean);
150
    procedure UpdatePlayedSize;
208
    procedure UpdatePlayedSize;
151
    function WriteWave(WriteSize: Integer): Integer;
209
    function WriteWave(WriteSize: Integer): Integer;
152
  public
210
  public
153
    constructor Create(ADirectSound: TDirectSound);
211
    constructor Create(ADirectSound: TDirectSound);
154
    destructor Destroy; override;
212
    destructor Destroy; override;
155
    procedure Play;
213
    procedure Play;
156
    procedure RecreateBuf;
214
    procedure RecreateBuf;
157
    procedure Stop;
215
    procedure Stop;
158
    procedure Update;
216
    procedure Update;
159
    property AutoUpdate: Boolean read FAutoUpdate write SetAutoUpdate;
217
    property AutoUpdate: Boolean read FAutoUpdate write SetAutoUpdate;
160
    property BufferLength: Integer read FBufferLength write SetBufferLength;
218
    property BufferLength: Integer read FBufferLength write SetBufferLength;
161
    property Format: PWaveFormatEx read GetFormat;
219
    property Format: PWaveFormatEx read GetFormat;
162
    property FormatSize: Integer read GetFormatSize;
220
    property FormatSize: Integer read GetFormatSize;
163
    property Frequency: Integer read GetFrequency write SetFrequency;
221
    property Frequency: Integer read GetFrequency write SetFrequency;
164
    property Pan: Integer read GetPan write SetPan;
222
    property Pan: Integer read GetPan write SetPan;
165
    property PlayedSize: Integer read GetPlayedSize write SetPlayedSize;
223
    property PlayedSize: Integer read GetPlayedSize write SetPlayedSize;
166
    property Playing: Boolean read FPlaying;
224
    property Playing: Boolean read FPlaying;
167
    property Position: Integer read FPosition write SetPosition;
225
    property Position: Integer read FPosition write SetPosition;
168
    property Looped: Boolean read FLooped write SetLooped;
226
    property Looped: Boolean read FLooped write SetLooped;
169
    property Size: Integer read GetSize;
227
    property Size: Integer read GetSize;
170
    property Volume: Integer read GetVolume write SetVolume;
228
    property Volume: Integer read GetVolume write SetVolume;
171
    property WaveStream: TCustomWaveStream read FWaveStream write SetWaveStream;
229
    property WaveStream: TCustomWaveStream read FWaveStream write SetWaveStream;
172
  end;
230
  end;
173
   
231
 
174
  {  TAudioFileStream  }
232
  {  TAudioFileStream  }
175
 
233
 
176
  TAudioFileStream = class(TAudioStream)
234
  TAudioFileStream = class(TAudioStream)
177
  private
235
  private
178
    FFileName: string;
236
    FFileName: string;
179
    FWaveFileStream: TWaveFileStream;
237
    FWaveFileStream: TWaveFileStream;
180
    procedure SetFileName(const Value: string);
238
    procedure SetFileName(const Value: string);
181
  public
239
  public
182
    destructor Destroy; override;
240
    destructor Destroy; override;
183
    property FileName: string read FFileName write SetFileName;
241
    property FileName: string read FFileName write SetFileName;
184
  end;
242
  end;
185
 
243
 
186
  {  TSoundCaptureFormat  }
244
  {  TSoundCaptureFormat  }
187
 
245
 
188
  TSoundCaptureFormat = class(TCollectionItem)
246
  TSoundCaptureFormat = class(TCollectionItem)
189
  private
247
  private
190
    FBitsPerSample: Integer;
248
    FBitsPerSample: Integer;
191
    FChannels: Integer;
249
    FChannels: Integer;
192
    FSamplesPerSec: Integer;
250
    FSamplesPerSec: Integer;
193
  public
251
  public
194
    property BitsPerSample: Integer read FBitsPerSample;
252
    property BitsPerSample: Integer read FBitsPerSample;
195
    property Channels: Integer read FChannels;
253
    property Channels: Integer read FChannels;
196
    property SamplesPerSec: Integer read FSamplesPerSec;
254
    property SamplesPerSec: Integer read FSamplesPerSec;
197
  end;
255
  end;
198
 
256
 
199
  {  TSoundCaptureFormats  }
257
  {  TSoundCaptureFormats  }
200
 
258
 
201
  TSoundCaptureFormats = class(TCollection)
259
  TSoundCaptureFormats = class(TCollection)
202
  private
260
  private
203
    function GetItem(Index: Integer): TSoundCaptureFormat;
261
    function GetItem(Index: Integer): TSoundCaptureFormat;
204
  public
262
  public
205
    constructor Create;
263
    constructor Create;
206
    function IndexOf(ASamplesPerSec, ABitsPerSample, AChannels: Integer): Integer;
264
    function IndexOf(ASamplesPerSec, ABitsPerSample, AChannels: Integer): Integer;
207
    property Items[Index: Integer]: TSoundCaptureFormat read GetItem; default;
265
    property Items[Index: Integer]: TSoundCaptureFormat read GetItem; default;
208
  end;
266
  end;
209
 
267
 
210
  {  TSoundCaptureStream  }
268
  {  TSoundCaptureStream  }
211
 
269
 
212
  ESoundCaptureStreamError = class(EWaveStreamError);
270
  ESoundCaptureStreamError = class(EWaveStreamError);
213
 
271
 
214
  TSoundCaptureStream = class(TCustomWaveStream2)
272
  TSoundCaptureStream = class(TCustomWaveStream2)
215
  private
273
  private
216
    FBuffer: IDirectSoundCaptureBuffer;
274
    FBuffer: IDirectSoundCaptureBuffer;
217
    FBufferLength: Integer;
275
    FBufferLength: Integer;
218
    FBufferPos: DWORD;
276
    FBufferPos: DWORD;
219
    FBufferSize: DWORD;
277
    FBufferSize: DWORD;
220
    FCapture: IDirectSoundCapture;
278
    FCapture: IDirectSoundCapture;
221
    FCaptureFormat: Integer;
279
    FCaptureFormat: Integer;
222
    FCapturing: Boolean;
280
    FCapturing: Boolean;
223
    FNotifyEvent: THandle;
281
    FNotifyEvent: THandle;
224
    FNotifyThread: TThread;
282
    FNotifyThread: TThread;
225
    FOnFilledBuffer: TNotifyEvent;
283
    FOnFilledBuffer: TNotifyEvent;
226
    FSupportedFormats: TSoundCaptureFormats;
284
    FSupportedFormats: TSoundCaptureFormats;
227
    function GetReadSize: Integer;
285
    function GetReadSize: Integer;
228
    procedure SetBufferLength(Value: Integer);
286
    procedure SetBufferLength(Value: Integer);
229
    procedure SetOnFilledBuffer(Value: TNotifyEvent);
287
    procedure SetOnFilledBuffer(Value: TNotifyEvent);
230
  protected
288
  protected
231
    procedure DoFilledBuffer; virtual;
289
    procedure DoFilledBuffer; virtual;
232
    function GetFilledSize: Integer; override;
290
    function GetFilledSize: Integer; override;
233
    function ReadWave(var Buffer; Count: Integer): Integer; override;
291
    function ReadWave(var Buffer; Count: Integer): Integer; override;
234
  public
292
  public
235
    constructor Create(GUID: PGUID);
293
    constructor Create(GUID: PGUID);
236
    destructor Destroy; override;
294
    destructor Destroy; override;
237
    class function Drivers: TDirectXDrivers;
295
    class function Drivers: TDirectXDrivers;
238
    procedure Start;
296
    procedure Start;
239
    procedure Stop;
297
    procedure Stop;
240
    property BufferLength: Integer read FBufferLength write SetBufferLength;
298
    property BufferLength: Integer read FBufferLength write SetBufferLength;
241
    property CaptureFormat: Integer read FCaptureFormat write FCaptureFormat;
299
    property CaptureFormat: Integer read FCaptureFormat write FCaptureFormat;
242
    property Capturing: Boolean read FCapturing;
300
    property Capturing: Boolean read FCapturing;
243
    property OnFilledBuffer: TNotifyEvent read FOnFilledBuffer write SetOnFilledBuffer;
301
    property OnFilledBuffer: TNotifyEvent read FOnFilledBuffer write SetOnFilledBuffer;
244
    property SupportedFormats: TSoundCaptureFormats read FSupportedFormats;
302
    property SupportedFormats: TSoundCaptureFormats read FSupportedFormats;
245
  end;
303
  end;
246
 
304
 
247
  {  TSoundEngine  }
305
  {  TSoundEngine  }
248
 
306
 
249
  TSoundEngine = class
307
  TSoundEngine = class
250
  private
308
  private
251
    FDSound: TDirectSound;
309
    FDSound: TDirectSound;
252
    FEffectList: TList;
310
    FEffectList: TList;
253
    FEnabled: Boolean;
311
    FEnabled: Boolean;
254
    FTimer: TTimer;
312
    FTimer: TTimer;
255
    function GetEffect(Index: Integer): TDirectSoundBuffer;
313
    function GetEffect(Index: Integer): TDirectSoundBuffer;
256
    function GetEffectCount: Integer;
314
    function GetEffectCount: Integer;
257
    procedure SetEnabled(Value: Boolean);
315
    procedure SetEnabled(Value: Boolean);
258
    procedure TimerEvent(Sender: TObject);
316
    procedure TimerEvent(Sender: TObject);
259
  public
317
  public
260
    constructor Create(ADSound: TDirectSound);
318
    constructor Create(ADSound: TDirectSound);
261
    destructor Destroy; override;
319
    destructor Destroy; override;
262
    procedure Clear;
320
    procedure Clear;
263
    procedure EffectFile(const Filename: string; Loop, Wait: Boolean);
321
    procedure EffectFile(const Filename: string; Loop, Wait: Boolean);
264
    procedure EffectStream(Stream: TStream; Loop, Wait: Boolean);
322
    procedure EffectStream(Stream: TStream; Loop, Wait: Boolean);
265
    procedure EffectWave(Wave: TWave; Loop, Wait: Boolean);
323
    procedure EffectWave(Wave: TWave; Loop, Wait: Boolean);
266
    property EffectCount: Integer read GetEffectCount;
324
    property EffectCount: Integer read GetEffectCount;
267
    property Effects[Index: Integer]: TDirectSoundBuffer read GetEffect;
325
    property Effects[Index: Integer]: TDirectSoundBuffer read GetEffect;
268
    property Enabled: Boolean read FEnabled write SetEnabled;
326
    property Enabled: Boolean read FEnabled write SetEnabled;
269
  end;
327
  end;
270
 
328
 
271
  {  EDXSoundError  }
329
  {  EDXSoundError  }
272
 
330
 
273
  EDXSoundError = class(Exception);
331
  EDXSoundError = class(Exception);
274
 
332
 
275
  {  TCustomDXSound  }
333
  {  TCustomDXSound  }
276
 
334
 
277
  TCustomDXSound = class;
335
  TCustomDXSound = class;
278
 
336
 
279
  TDXSoundOption = (soGlobalFocus, soStickyFocus, soExclusive);
337
  TDXSoundOption = (soGlobalFocus, soStickyFocus, soExclusive);
280
  TDXSoundOptions = set of TDXSoundOption;
338
  TDXSoundOptions = set of TDXSoundOption;
281
 
339
 
282
  TDXSoundNotifyType = (dsntDestroying, dsntInitializing, dsntInitialize, dsntFinalize, dsntRestore);
340
  TDXSoundNotifyType = (dsntDestroying, dsntInitializing, dsntInitialize, dsntFinalize, dsntRestore);
283
  TDXSoundNotifyEvent = procedure(Sender: TCustomDXSound; NotifyType: TDXSoundNotifyType) of object;
341
  TDXSoundNotifyEvent = procedure(Sender: TCustomDXSound; NotifyType: TDXSoundNotifyType) of object;
284
 
342
 
285
  TCustomDXSound = class(TComponent)
343
  TCustomDXSound = class(TComponent)
286
  private
344
  private
287
    FAutoInitialize: Boolean;
345
    FAutoInitialize: Boolean;
288
    FCalledDoInitialize: Boolean;
346
    FCalledDoInitialize: Boolean;
289
    FDriver: PGUID;
347
    FDriver: PGUID;
290
    FDriverGUID: TGUID;
348
    FDriverGUID: TGUID;
291
    FDSound: TDirectSound;
349
    FDSound: TDirectSound;
292
    FForm: TCustomForm;
350
    FForm: TCustomForm;
293
    FInitialized: Boolean;
351
    FInitialized: Boolean;
294
    FInternalInitialized: Boolean;
352
    FInternalInitialized: Boolean;
295
    FNotifyEventList: TList;
353
    FNotifyEventList: TList;
296
    FNowOptions: TDXSoundOptions;
354
    FNowOptions: TDXSoundOptions;
297
    FOnFinalize: TNotifyEvent;
355
    FOnFinalize: TNotifyEvent;
298
    FOnInitialize: TNotifyEvent;
356
    FOnInitialize: TNotifyEvent;
299
    FOnInitializing: TNotifyEvent;
357
    FOnInitializing: TNotifyEvent;
300
    FOnRestore: TNotifyEvent;
358
    FOnRestore: TNotifyEvent;
301
    FOptions: TDXSoundOptions;
359
    FOptions: TDXSoundOptions;
302
    FPrimary: TDirectSoundBuffer;
360
    FPrimary: TDirectSoundBuffer;
303
    FSubClass: TControlSubClass;
361
    FSubClass: TControlSubClass;
304
    procedure FormWndProc(var Message: TMessage; DefWindowProc: TWndMethod);
362
    procedure FormWndProc(var Message: TMessage; DefWindowProc: TWndMethod);
305
    procedure NotifyEventList(NotifyType: TDXSoundNotifyType);
363
    procedure NotifyEventList(NotifyType: TDXSoundNotifyType);
306
    procedure SetDriver(Value: PGUID);
364
    procedure SetDriver(Value: PGUID);
307
    procedure SetForm(Value: TCustomForm);
365
    procedure SetForm(Value: TCustomForm);
308
    procedure SetOptions(Value: TDXSoundOptions);
366
    procedure SetOptions(Value: TDXSoundOptions);
309
  protected
367
  protected
310
    procedure DoFinalize; virtual;
368
    procedure DoFinalize; virtual;
311
    procedure DoInitialize; virtual;
369
    procedure DoInitialize; virtual;
312
    procedure DoInitializing; virtual;
370
    procedure DoInitializing; virtual;
313
    procedure DoRestore; virtual;
371
    procedure DoRestore; virtual;
314
    procedure Loaded; override;
372
    procedure Loaded; override;
315
  public
373
  public
316
    constructor Create(AOwner: TComponent); override;
374
    constructor Create(AOwner: TComponent); override;
317
    destructor Destroy; override;
375
    destructor Destroy; override;
318
    class function Drivers: TDirectXDrivers;
376
    class function Drivers: TDirectXDrivers;
319
    procedure Finalize;
377
    procedure Finalize;
320
    procedure Initialize;
378
    procedure Initialize;
321
    procedure Restore;
379
    procedure Restore;
322
    procedure RegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
380
    procedure RegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
323
    procedure UnRegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
381
    procedure UnRegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
324
 
382
 
325
    property AutoInitialize: Boolean read FAutoInitialize write FAutoInitialize;
383
    property AutoInitialize: Boolean read FAutoInitialize write FAutoInitialize;
326
    property Driver: PGUID read FDriver write SetDriver;
384
    property Driver: PGUID read FDriver write SetDriver;
327
    property DSound: TDirectSound read FDSound;
385
    property DSound: TDirectSound read FDSound;
328
    property Initialized: Boolean read FInitialized;
386
    property Initialized: Boolean read FInitialized;
329
    property NowOptions: TDXSoundOptions read FNowOptions;
387
    property NowOptions: TDXSoundOptions read FNowOptions;
330
    property Primary: TDirectSoundBuffer read FPrimary;
388
    property Primary: TDirectSoundBuffer read FPrimary;
331
    property OnFinalize: TNotifyEvent read FOnFinalize write FOnFinalize;
389
    property OnFinalize: TNotifyEvent read FOnFinalize write FOnFinalize;
332
    property OnInitialize: TNotifyEvent read FOnInitialize write FOnInitialize;
390
    property OnInitialize: TNotifyEvent read FOnInitialize write FOnInitialize;
333
    property OnInitializing: TNotifyEvent read FOnInitializing write FOnInitializing;
391
    property OnInitializing: TNotifyEvent read FOnInitializing write FOnInitializing;
334
    property OnRestore: TNotifyEvent read FOnRestore write FOnRestore;
392
    property OnRestore: TNotifyEvent read FOnRestore write FOnRestore;
335
    property Options: TDXSoundOptions read FOptions write SetOptions;
393
    property Options: TDXSoundOptions read FOptions write SetOptions;
336
  end;
394
  end;
337
 
395
 
338
  {  TDXSound  }
396
  {  TDXSound  }
339
 
397
 
340
  TDXSound = class(TCustomDXSound)
398
  TDXSound = class(TCustomDXSound)
341
  published
399
  published
342
    property AutoInitialize;
400
    property AutoInitialize;
343
    property Options;
401
    property Options;
344
    property OnFinalize;
402
    property OnFinalize;
345
    property OnInitialize;
403
    property OnInitialize;
346
    property OnInitializing;
404
    property OnInitializing;
347
    property OnRestore;
405
    property OnRestore;
348
  end;
406
  end;
349
 
407
 
350
  {  EWaveCollectionError  }
408
  {  EWaveCollectionError  }
351
 
409
 
352
  EWaveCollectionError = class(Exception);
410
  EWaveCollectionError = class(Exception);
353
 
411
 
354
  {  TWaveCollectionItem  }
412
  {  TWaveCollectionItem  }
355
 
413
 
356
  TWaveCollection = class;
414
  TWaveCollection = class;
357
 
415
 
358
  TWaveCollectionItem = class(THashCollectionItem)
416
  TWaveCollectionItem = class(THashCollectionItem)
359
  private
417
  private
360
    FBuffer: TDirectSoundBuffer;
418
    FBuffer: TDirectSoundBuffer;
361
    FBufferList: TList;
419
    FBufferList: TList;
362
    FFrequency: Integer;
420
    FFrequency: Integer;
363
    FInitialized: Boolean;
421
    FInitialized: Boolean;
364
    FLooped: Boolean;
422
    FLooped: Boolean;
365
    FMaxPlayingCount: Integer;
423
    FMaxPlayingCount: Integer;
366
    FPan: Integer;
424
    FPan: Integer;
367
    FVolume: Integer;
425
    FVolume: Integer;
368
    FWave: TWave;
426
    FWave: TWave;
369
    function CreateBuffer: TDirectSoundBuffer;
427
    function CreateBuffer: TDirectSoundBuffer;
370
    procedure Finalize;
428
    procedure Finalize;
371
    procedure Initialize;
429
    procedure Initialize;
372
    function GetBuffer: TDirectSoundBuffer;
430
    function GetBuffer: TDirectSoundBuffer;
373
    function GetWaveCollection: TWaveCollection;
431
    function GetWaveCollection: TWaveCollection;
374
    procedure SetFrequency(Value: Integer);
432
    procedure SetFrequency(Value: Integer);
375
    procedure SetLooped(Value: Boolean);
433
    procedure SetLooped(Value: Boolean);
376
    procedure SetMaxPlayingCount(Value: Integer);
434
    procedure SetMaxPlayingCount(Value: Integer);
377
    procedure SetPan(Value: Integer);
435
    procedure SetPan(Value: Integer);
378
    procedure SetVolume(Value: Integer);
436
    procedure SetVolume(Value: Integer);
379
    procedure SetWave(Value: TWave);
437
    procedure SetWave(Value: TWave);
-
 
438
  protected
-
 
439
    function GetPlaying: boolean;
380
  public
440
  public
381
    constructor Create(Collection: TCollection); override;
441
    constructor Create(Collection: TCollection); override;
382
    destructor Destroy; override;
442
    destructor Destroy; override;
383
    procedure Assign(Source: TPersistent); override;
443
    procedure Assign(Source: TPersistent); override;
384
    procedure Play(Wait: Boolean);
444
    procedure Play(Wait: Boolean);
385
    procedure Restore;
445
    procedure Restore;
386
    procedure Stop;
446
    procedure Stop;
387
    property Frequency: Integer read FFrequency write SetFrequency;
447
    property Frequency: Integer read FFrequency write SetFrequency;
388
    property Initialized: Boolean read FInitialized;
448
    property Initialized: Boolean read FInitialized;
389
    property Pan: Integer read FPan write SetPan;
449
    property Pan: Integer read FPan write SetPan;
390
    property Volume: Integer read FVolume write SetVolume;
450
    property Volume: Integer read FVolume write SetVolume;
391
    property WaveCollection: TWaveCollection read GetWaveCollection;
451
    property WaveCollection: TWaveCollection read GetWaveCollection;
-
 
452
 
-
 
453
    property Playing: boolean read GetPlaying;
392
  published
454
  published
393
    property Looped: Boolean read FLooped write SetLooped;
455
    property Looped: Boolean read FLooped write SetLooped;
394
    property MaxPlayingCount: Integer read FMaxPlayingCount write SetMaxPlayingCount;
456
    property MaxPlayingCount: Integer read FMaxPlayingCount write SetMaxPlayingCount;
395
    property Wave: TWave read FWave write SetWave;
457
    property Wave: TWave read FWave write SetWave;
396
  end;
458
  end;
397
 
459
 
398
  {  TWaveCollection  }
460
  {  TWaveCollection  }
399
 
461
 
400
  TWaveCollection = class(THashCollection)
462
  TWaveCollection = class(THashCollection)
401
  private
463
  private
402
    FDXSound: TCustomDXSound;
464
    FDXSound: TCustomDXSound;
403
    FOwner: TPersistent;
465
    FOwner: TPersistent;
404
    function GetItem(Index: Integer): TWaveCollectionItem;
466
    function GetItem(Index: Integer): TWaveCollectionItem;
405
    function Initialized: Boolean;
467
    function Initialized: Boolean;
406
  protected
468
  protected
407
    function GetOwner: TPersistent; override;
469
    function GetOwner: TPersistent; override;
408
  public
470
  public
409
    constructor Create(AOwner: TPersistent);
471
    constructor Create(AOwner: TPersistent);
410
    function Find(const Name: string): TWaveCollectionItem;
472
    function Find(const Name: string): TWaveCollectionItem;
411
    procedure Finalize;
473
    procedure Finalize;
412
    procedure Initialize(DXSound: TCustomDXSound);
474
    procedure Initialize(DXSound: TCustomDXSound);
413
    procedure Restore;
475
    procedure Restore;
414
    procedure LoadFromFile(const FileName: string);
476
    procedure LoadFromFile(const FileName: string);
415
    procedure LoadFromStream(Stream: TStream);
477
    procedure LoadFromStream(Stream: TStream);
416
    procedure SaveToFile(const FileName: string);
478
    procedure SaveToFile(const FileName: string);
417
    procedure SaveToStream(Stream: TStream);
479
    procedure SaveToStream(Stream: TStream);
418
    property DXSound: TCustomDXSound read FDXSound;
480
    property DXSound: TCustomDXSound read FDXSound;
419
    property Items[Index: Integer]: TWaveCollectionItem read GetItem; default;
481
    property Items[Index: Integer]: TWaveCollectionItem read GetItem; default;
420
  end;
482
  end;
421
 
483
 
422
  {  TCustomDXWaveList  }
484
  {  TCustomDXWaveList  }
423
 
485
 
424
  TCustomDXWaveList = class(TComponent)
486
  TCustomDXWaveList = class(TComponent)
425
  private
487
  private
426
    FDXSound: TCustomDXSound;
488
    FDXSound: TCustomDXSound;
427
    FItems: TWaveCollection;
489
    FItems: TWaveCollection;
428
    procedure DXSoundNotifyEvent(Sender: TCustomDXSound; NotifyType: TDXSoundNotifyType);
490
    procedure DXSoundNotifyEvent(Sender: TCustomDXSound; NotifyType: TDXSoundNotifyType);
429
    procedure SetDXSound(Value: TCustomDXSound);
491
    procedure SetDXSound(Value: TCustomDXSound);
430
    procedure SetItems(Value: TWaveCollection);
492
    procedure SetItems(Value: TWaveCollection);
431
  protected
493
  protected
432
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
494
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
433
  public
495
  public
434
    constructor Create(AOwner: TComponent); override;
496
    constructor Create(AOwner: TComponent); override;
435
    destructor Destroy; override;
497
    destructor Destroy; override;
436
    property DXSound: TCustomDXSound read FDXSound write SetDXSound;
498
    property DXSound: TCustomDXSound read FDXSound write SetDXSound;
437
    property Items: TWaveCollection read FItems write SetItems;
499
    property Items: TWaveCollection read FItems write SetItems;
438
  end;
500
  end;
439
 
501
 
440
  {  TDXWaveList  }
502
  {  TDXWaveList  }
441
 
503
 
442
  TDXWaveList = class(TCustomDXWaveList)
504
  TDXWaveList = class(TCustomDXWaveList)
443
  published
505
  published
444
    property DXSound;
506
    property DXSound;
445
    property Items;
507
    property Items;
446
  end;
508
  end;
447
 
509
 
-
 
510
  {  EDXMusicError  }
-
 
511
 
-
 
512
  EDXMusicError = class(Exception);
-
 
513
 
-
 
514
  TMusicListCollection = class;
-
 
515
 
-
 
516
  {  TMusicListCollectionItem  }
-
 
517
 
-
 
518
  TMusicDataProp = class(TPersistent)
-
 
519
  private
-
 
520
    FMusicData: string;
-
 
521
    FMidiname: string;
-
 
522
    function GetMusicData: string;
-
 
523
    procedure SetMusicData(const Value: string);
-
 
524
  protected
-
 
525
    procedure DefineProperties(Filer: TFiler); override;
-
 
526
    procedure ReadMidiData(Stream: TStream);
-
 
527
    procedure WriteMidiData(Stream: TStream);
-
 
528
  public
-
 
529
    property MusicData: string read GetMusicData write SetMusicData;
-
 
530
  published
-
 
531
    property MidiName: string read FMidiname write FMidiname;
-
 
532
  end;
-
 
533
 
-
 
534
  TMusicListCollectionItem = class(THashCollectionItem)
-
 
535
  private
-
 
536
    { Private declarations }
-
 
537
    FDirectMusicPerformance: IDirectMusicPerformance;
-
 
538
    FDirectSound: IDirectSound;
-
 
539
    FDirectMusic: IDirectMusic;
-
 
540
    FDirectMusicLoader: IDirectMusicLoader;
-
 
541
    FDirectMusicSegment: IDirectMusicSegment;
-
 
542
    FMusicObjDesc: TDMus_ObjectDesc;
-
 
543
    FDirectMusicSegmentState: IDirectMusicSegmentState;
-
 
544
    FRepeats: Cardinal;
-
 
545
    FStartpoint: Integer;
-
 
546
    FDuration: Integer;
-
 
547
    // startpoint props in seconds these used to hold millisecond value
-
 
548
    FActualDuration: Integer;
-
 
549
    FActualStartPoint: Integer;
-
 
550
    FIsInitialized: Boolean;
-
 
551
    FMusicDataProp: TMusicDataProp;
-
 
552
    procedure SetDuration(const Value: integer);
-
 
553
    procedure SetRepeats(const Value: Cardinal);
-
 
554
    procedure SetStartPoint(const Value: integer);
-
 
555
    function GetMusicListCollection: TMusicListCollection;
-
 
556
  protected
-
 
557
    function GetDisplayName: string; override;
-
 
558
  public
-
 
559
    constructor Create(Collection: TCollection); override;
-
 
560
    destructor Destroy; override;
-
 
561
    function Size: Integer;
-
 
562
    procedure Play;
-
 
563
    function IsPlaying: Boolean;
-
 
564
    procedure Stop;
-
 
565
    procedure Load;
-
 
566
    procedure Init;
-
 
567
    procedure LoadFromFile(const MidiFileName: string);
-
 
568
    procedure SaveToFile(const MidiFileName: string);
-
 
569
    property MusicCollection: TMusicListCollection read GetMusicListCollection;
-
 
570
    property IsInitialized: Boolean read FIsInitialized write FIsInitialized;
-
 
571
  published
-
 
572
    property Name;
-
 
573
    property Repeats: Cardinal read Frepeats write SetRepeats;
-
 
574
    property Duration: integer read FDuration write SetDuration;
-
 
575
    property StartPoint: integer read FStartPoint write SetStartPoint;
-
 
576
    property Midi: TMusicDataProp read FMusicDataProp write FMusicDataProp;
-
 
577
  end;
-
 
578
 
-
 
579
  {  TMusicListCollection  }
-
 
580
 
-
 
581
  TMusicListCollection = class(THashCollection)
-
 
582
  private
-
 
583
    FOwner: TPersistent;
-
 
584
    FDirectSound: IDirectSound;
-
 
585
  protected
-
 
586
    function GetItem(Index: Integer): TMusicListCollectionItem;
-
 
587
    procedure SetItem(Index: Integer; Value: TMusicListCollectionItem);
-
 
588
    procedure Update(Item: TCollectionItem); override;
-
 
589
    function GetOwner: TPersistent; override;
-
 
590
  public
-
 
591
    constructor Create(AOwner: TComponent);
-
 
592
    function Add: TMusicListCollectionItem;
-
 
593
    function Find(const Name: string): TMusicListCollectionItem;
-
 
594
    procedure Restore;
-
 
595
    procedure LoadFromFile(const FileName: string);
-
 
596
    procedure LoadFromStream(Stream: TStream);
-
 
597
    procedure SaveToFile(const FileName: string);
-
 
598
    procedure SaveToStream(Stream: TStream);
-
 
599
{$IFDEF VER4UP}
-
 
600
    function Insert(Index: Integer): TMusicListCollectionItem;
-
 
601
{$ENDIF}
-
 
602
    property Items[Index: Integer]: TMusicListCollectionItem read GetItem write SetItem;
-
 
603
  published
-
 
604
  end;
-
 
605
 
-
 
606
  {  TDXMusic  }
-
 
607
 
-
 
608
  TDXMusic = class(TComponent)
-
 
609
  private
-
 
610
    FDXSound: TDXSound;
-
 
611
    FMidis: TMusicListCollection;
-
 
612
    procedure SetMidis(const value: TMusicListCollection);
-
 
613
    procedure SetDXSound(const Value: TDXSound);
-
 
614
  public
-
 
615
    constructor Create(AOwner: TComponent); override;
-
 
616
    destructor Destroy; override;
-
 
617
  published
-
 
618
    property DXSound: TDXSound read FDXSound write SetDXSound;
-
 
619
    property Midis: TMusicListCollection read FMidis write SetMidis;
-
 
620
  end;
-
 
621
 
448
implementation
622
implementation
449
 
623
 
450
uses DXConsts;
624
uses DXConsts;
451
 
625
 
-
 
626
const
-
 
627
  dm_OK = 0;
-
 
628
 
452
function DXDirectSoundCreate(lpGUID: PGUID; out lpDS: IDirectSound;
629
function DXDirectSoundCreate(lpGUID: PGUID; out lpDS: IDirectSound;
453
  pUnkOuter: IUnknown): HRESULT;
630
  pUnkOuter: IUnknown): HRESULT;
454
type
631
type
455
  TDirectSoundCreate = function(lpGUID: PGUID; out lplpDD: IDirectSound;
632
  TDirectSoundCreate = function(lpGUID: PGUID; out lplpDD: IDirectSound;
456
    pUnkOuter: IUnknown): HRESULT; stdcall;
633
    pUnkOuter: IUnknown): HRESULT; stdcall;
457
begin
634
begin
458
  Result := TDirectSoundCreate(DXLoadLibrary('DSound.dll', 'DirectSoundCreate'))
635
  Result := TDirectSoundCreate(DXLoadLibrary('DSound.dll', 'DirectSoundCreate'))
459
    (lpGUID, lpDS, pUnkOuter);
636
    (lpGUID, lpDS, pUnkOuter);
460
end;
637
end;
461
 
638
 
462
function DXDirectSoundEnumerate(lpCallback: TDSEnumCallbackA;
639
function DXDirectSoundEnumerate(lpCallback: TDSEnumCallbackA;
463
    lpContext: Pointer): HRESULT;
640
  lpContext: Pointer): HRESULT;
464
type
641
type
465
  TDirectSoundEnumerate = function(lpCallback: TDSEnumCallbackA;
642
  TDirectSoundEnumerate = function(lpCallback: TDSEnumCallbackA;
466
    lpContext: Pointer): HRESULT; stdcall;
643
    lpContext: Pointer): HRESULT; stdcall;
467
begin
644
begin
468
  Result := TDirectSoundEnumerate(DXLoadLibrary('DSound.dll', 'DirectSoundEnumerateA'))
645
  Result := TDirectSoundEnumerate(DXLoadLibrary('DSound.dll', 'DirectSoundEnumerateA'))
469
    (lpCallback, lpContext);
646
    (lpCallback, lpContext);
470
end;
647
end;
471
 
648
 
472
function DXDirectSoundCaptureCreate(lpGUID: PGUID; out lplpDSC: IDirectSoundCapture;
649
function DXDirectSoundCaptureCreate(lpGUID: PGUID; out lplpDSC: IDirectSoundCapture;
473
  pUnkOuter: IUnknown): HRESULT;
650
  pUnkOuter: IUnknown): HRESULT;
474
type
651
type
475
  TDirectSoundCaptureCreate = function(lpGUID: PGUID; out lplpDD: IDirectSoundCapture;
652
  TDirectSoundCaptureCreate = function(lpGUID: PGUID; out lplpDD: IDirectSoundCapture;
476
    pUnkOuter: IUnknown): HRESULT; stdcall;
653
    pUnkOuter: IUnknown): HRESULT; stdcall;
477
begin
654
begin
478
  try
655
  try
479
    Result := TDirectSoundCaptureCreate(DXLoadLibrary('DSound.dll', 'DirectSoundCaptureCreate'))
656
    Result := TDirectSoundCaptureCreate(DXLoadLibrary('DSound.dll', 'DirectSoundCaptureCreate'))
480
      (lpGUID, lplpDSC, pUnkOuter);
657
      (lpGUID, lplpDSC, pUnkOuter);
481
  except
658
  except
482
    raise EDirectXError.Create(SSinceDirectX5);
659
    raise EDirectXError.Create(SSinceDirectX5);
483
  end;
660
  end;
484
end;
661
end;
485
 
662
 
486
function DXDirectSoundCaptureEnumerate(lpCallback: TDSEnumCallbackA;
663
function DXDirectSoundCaptureEnumerate(lpCallback: TDSEnumCallbackA;
487
    lpContext: Pointer): HRESULT;
664
  lpContext: Pointer): HRESULT;
488
type
665
type
489
  TDirectSoundCaptureEnumerate = function(lpCallback: TDSEnumCallbackA;
666
  TDirectSoundCaptureEnumerate = function(lpCallback: TDSEnumCallbackA;
490
    lpContext: Pointer): HRESULT; stdcall;
667
    lpContext: Pointer): HRESULT; stdcall;
491
begin
668
begin
492
  try
669
  try
493
    Result := TDirectSoundCaptureEnumerate(DXLoadLibrary('DSound.dll', 'DirectSoundCaptureEnumerateA'))
670
    Result := TDirectSoundCaptureEnumerate(DXLoadLibrary('DSound.dll', 'DirectSoundCaptureEnumerateA'))
494
      (lpCallback, lpContext);
671
      (lpCallback, lpContext);
495
  except
672
  except
496
    raise EDirectXError.Create(SSinceDirectX5);
673
    raise EDirectXError.Create(SSinceDirectX5);
497
  end;
674
  end;
498
end;
675
end;
499
 
676
 
500
var
677
var
501
  DirectSoundDrivers: TDirectXDrivers;
678
  DirectSoundDrivers: TDirectXDrivers;
502
  DirectSoundCaptureDrivers: TDirectXDrivers;
679
  DirectSoundCaptureDrivers: TDirectXDrivers;
503
 
680
 
504
function EnumDirectSoundDrivers_DSENUMCALLBACK(lpGuid: PGUID; lpstrDescription: LPCSTR;
681
function EnumDirectSoundDrivers_DSENUMCALLBACK(lpGuid: PGUID; lpstrDescription: {$IFDEF UNICODE}LPCTSTR{$ELSE}LPCSTR{$ENDIF};
505
  lpstrModule: LPCSTR; lpContext: Pointer): BOOL; stdcall;
682
  lpstrModule: {$IFDEF UNICODE}LPCTSTR{$ELSE}LPCSTR{$ENDIF}; lpContext: Pointer): BOOL; stdcall;
506
begin
683
begin
507
  Result := True;
684
  Result := True;
508
  with TDirectXDriver.Create(TDirectXDrivers(lpContext)) do
685
  with TDirectXDriver.Create(TDirectXDrivers(lpContext)) do
509
  begin
686
  begin
510
    Guid := lpGuid;
687
    Guid := lpGuid;
511
    Description := lpstrDescription;
688
    Description := lpstrDescription;
512
    DriverName := lpstrModule;
689
    DriverName := lpstrModule;
513
  end;
690
  end;
514
end;
691
end;
515
 
692
 
516
function EnumDirectSoundDrivers: TDirectXDrivers;
693
function EnumDirectSoundDrivers: TDirectXDrivers;
517
begin
694
begin
518
  if DirectSoundDrivers=nil then
695
  if DirectSoundDrivers = nil then
519
  begin
696
  begin
520
    DirectSoundDrivers := TDirectXDrivers.Create;
697
    DirectSoundDrivers := TDirectXDrivers.Create;
521
    try
698
    try
522
      DXDirectSoundEnumerate(@EnumDirectSoundDrivers_DSENUMCALLBACK, DirectSoundDrivers);
699
      DXDirectSoundEnumerate(@EnumDirectSoundDrivers_DSENUMCALLBACK, DirectSoundDrivers);
523
    except
700
    except
524
      DirectSoundDrivers.Free;
701
      DirectSoundDrivers.Free;
525
      raise;
702
      raise;
526
    end;
703
    end;
527
  end;
704
  end;
528
 
705
 
529
  Result := DirectSoundDrivers;
706
  Result := DirectSoundDrivers;
530
end;
707
end;
531
 
708
 
532
function EnumDirectSoundCaptureDrivers: TDirectXDrivers;
709
function EnumDirectSoundCaptureDrivers: TDirectXDrivers;
533
begin
710
begin
534
  if DirectSoundCaptureDrivers=nil then
711
  if DirectSoundCaptureDrivers = nil then
535
  begin
712
  begin
536
    DirectSoundCaptureDrivers := TDirectXDrivers.Create;
713
    DirectSoundCaptureDrivers := TDirectXDrivers.Create;
537
    try
714
    try
538
      DXDirectSoundCaptureEnumerate(@EnumDirectSoundDrivers_DSENUMCALLBACK, DirectSoundCaptureDrivers);
715
      DXDirectSoundCaptureEnumerate(@EnumDirectSoundDrivers_DSENUMCALLBACK, DirectSoundCaptureDrivers);
539
    except
716
    except
540
      DirectSoundCaptureDrivers.Free;
717
      DirectSoundCaptureDrivers.Free;
541
      raise;
718
      raise;
542
    end;
719
    end;
543
  end;
720
  end;
544
 
721
 
545
  Result := DirectSoundCaptureDrivers;
722
  Result := DirectSoundCaptureDrivers;
546
end;
723
end;
547
 
724
 
548
{  TDirectSound  }
725
{  TDirectSound  }
549
 
726
 
550
constructor TDirectSound.Create(GUID: PGUID);
727
constructor TDirectSound.Create(GUID: PGUID);
551
begin
728
begin
552
  inherited Create;
729
  inherited Create;
553
  FBufferList := TList.Create;
730
  FBufferList := TList.Create;
554
 
731
 
555
  if DXDirectSoundCreate(GUID, FIDSound, nil)<>DS_OK then
732
  if DXDirectSoundCreate(GUID, FIDSound, nil) <> DS_OK then
556
    raise EDirectSoundError.CreateFmt(SCannotInitialized, [SDirectSound]);
733
    raise EDirectSoundError.CreateFmt(SCannotInitialized, [SDirectSound]);
557
end;
734
end;
558
 
735
 
559
destructor TDirectSound.Destroy;
736
destructor TDirectSound.Destroy;
560
begin
737
begin
561
  while BufferCount>0 do
738
  while BufferCount > 0 do
562
    Buffers[BufferCount-1].Free;
739
    Buffers[BufferCount - 1].Free;
563
  FBufferList.Free;
740
  FBufferList.Free;
564
 
741
 
565
  FIDSound := nil;
742
  FIDSound := nil;
566
  inherited Destroy;
743
  inherited Destroy;
567
end;
744
end;
568
 
745
 
569
class function TDirectSound.Drivers: TDirectXDrivers;
746
class function TDirectSound.Drivers: TDirectXDrivers;
570
begin
747
begin
571
  Result := EnumDirectSoundDrivers;
748
  Result := EnumDirectSoundDrivers;
572
end;
749
end;
573
 
750
 
574
procedure TDirectSound.CheckBuffer(Buffer: TDirectSoundBuffer);
751
procedure TDirectSound.CheckBuffer(Buffer: TDirectSoundBuffer);
575
begin
752
begin
576
  case Buffer.DXResult of
753
  case Buffer.DXResult of
577
    DSERR_BUFFERLOST:
754
    DSERR_BUFFERLOST:
578
      begin
755
      begin
579
        if not FInRestoreBuffer then
756
        if not FInRestoreBuffer then
580
        begin
757
        begin
581
          FInRestoreBuffer := True;
758
          FInRestoreBuffer := True;
582
          try
759
          try
583
            DoRestoreBuffer;
760
            DoRestoreBuffer;
584
          finally
761
          finally
585
            FInRestoreBuffer := False;
762
            FInRestoreBuffer := False;
586
          end;
763
          end;
587
        end;
764
        end;
588
      end;
765
      end;
589
  end;
766
  end;
590
end;
767
end;
591
 
768
 
592
procedure TDirectSound.DoRestoreBuffer;
769
procedure TDirectSound.DoRestoreBuffer;
593
begin
770
begin
594
end;
771
end;
595
 
772
 
596
function TDirectSound.GetBuffer(Index: Integer): TDirectSoundBuffer;
773
function TDirectSound.GetBuffer(Index: Integer): TDirectSoundBuffer;
597
begin
774
begin
598
  Result := FBufferList[Index];
775
  Result := FBufferList[Index];
599
end;
776
end;
600
 
777
 
601
function TDirectSound.GetBufferCount: Integer;
778
function TDirectSound.GetBufferCount: Integer;
602
begin
779
begin
603
  Result := FBufferList.Count;
780
  Result := FBufferList.Count;
604
end;
781
end;
605
 
782
 
606
function TDirectSound.GetIDSound: IDirectSound;
783
function TDirectSound.GetIDSound: IDirectSound;
607
begin
784
begin
608
  if Self<>nil then
785
  if Self <> nil then
609
    Result := FIDSound
786
    Result := FIDSound
610
  else
787
  else
611
    Result := nil;
788
    Result := nil;
612
end;
789
end;
613
 
790
 
614
function TDirectSound.GetISound: IDirectSound;
791
function TDirectSound.GetISound: IDirectSound;
615
begin
792
begin
616
  Result := IDSound;
793
  Result := IDSound;
617
  if Result=nil then
794
  if Result = nil then
618
    raise EDirectSoundError.CreateFmt(SNotMade, ['IDirectSound']);
795
    raise EDirectSoundError.CreateFmt(SNotMade, ['IDirectSound']);
619
end;
796
end;
620
 
797
 
621
{  TDirectSoundBuffer  }
798
{  TDirectSoundBuffer  }
622
 
799
 
623
constructor TDirectSoundBuffer.Create(ADirectSound: TDirectSound);
800
constructor TDirectSoundBuffer.Create(ADirectSound: TDirectSound);
624
begin
801
begin
625
  inherited Create;
802
  inherited Create;
-
 
803
  FIsD3D := False;
626
  FDSound := ADirectSound;
804
  FDSound := ADirectSound;
-
 
805
  FIDS3DBuffer := nil;
627
  FDSound.FBufferList.Add(Self);
806
  FDSound.FBufferList.Add(Self);
628
end;
807
end;
629
 
808
 
630
destructor TDirectSoundBuffer.Destroy;
809
destructor TDirectSoundBuffer.Destroy;
631
begin
810
begin
632
  IDSBuffer := nil;
811
  IDSBuffer := nil;
-
 
812
  IDS3DBuffer := nil;
633
  FDSound.FBufferList.Remove(Self);
813
  FDSound.FBufferList.Remove(Self);
634
  inherited Destroy;
814
  inherited Destroy;
635
end;
815
end;
636
 
816
 
637
procedure TDirectSoundBuffer.Assign(Source: TPersistent);
817
procedure TDirectSoundBuffer.Assign(Source: TPersistent);
638
var
818
var
639
  TempBuffer: IDirectSoundBuffer;
819
  TempBuffer: IDirectSoundBuffer;
640
begin
820
begin
641
  if Source=nil then
821
  if Source = nil then
642
    IDSBuffer := nil
822
    IDSBuffer := nil
-
 
823
  else
643
  else if Source is TWave then
824
  if Source is TWave then
644
    LoadFromWave(TWave(Source))
825
    LoadFromWave(TWave(Source))
-
 
826
  else
645
  else if Source is TDirectSoundBuffer then
827
  if Source is TDirectSoundBuffer then
646
  begin
828
  begin
647
    if TDirectSoundBuffer(Source).IDSBuffer=nil then
829
    if TDirectSoundBuffer(Source).IDSBuffer = nil then
648
      IDSBuffer := nil
830
      IDSBuffer := nil
-
 
831
    else
649
    else begin
832
    begin
650
      FDSound.DXResult := FDSound.ISound.DuplicateSoundBuffer(TDirectSoundBuffer(Source).IDSBuffer,
833
      FDSound.DXResult := FDSound.ISound.DuplicateSoundBuffer(TDirectSoundBuffer(Source).IDSBuffer, TempBuffer);
651
        TempBuffer);
-
 
652
      if FDSound.DXResult=0 then
834
      if FDSound.DXResult = DS_OK then
653
      begin
835
      begin
654
        IDSBuffer := TempBuffer;
836
        IDSBuffer := TempBuffer;
655
      end;
837
      end;
656
    end;
838
    end;
-
 
839
 
-
 
840
    if FIsD3D then
-
 
841
      if TDirectSoundBuffer(Source).IDS3DBuffer = nil then
-
 
842
        IDS3DBuffer := nil
657
  end else
843
      else
-
 
844
      begin
-
 
845
        FDSound.DXResult := FDSound.ISound.QueryInterface(IID_IDirectSound3DBuffer, FIDS3DBuffer);
-
 
846
        if FDSound.DXResult = DS_OK then
-
 
847
          FD3DSParams := TDirectSoundBuffer(Source).FD3DSParams;
-
 
848
      end;
-
 
849
 
-
 
850
  end
-
 
851
  else
658
    inherited Assign(Source);
852
    inherited Assign(Source);
659
end;
853
end;
660
 
854
 
661
procedure TDirectSoundBuffer.Check;
855
procedure TDirectSoundBuffer.Check;
662
begin
856
begin
663
  FDSound.CheckBuffer(Self);
857
  FDSound.CheckBuffer(Self);
664
end;
858
end;
665
 
859
 
666
function TDirectSoundBuffer.CreateBuffer(const BufferDesc: TDSBufferDesc): Boolean;
860
function TDirectSoundBuffer.CreateBuffer(const BufferDesc: TDSBufferDesc): Boolean;
667
var
861
var
668
  TempBuffer: IDirectSoundBuffer;
862
  TempBuffer: IDirectSoundBuffer;
669
begin
863
begin
670
  IDSBuffer := nil;
864
  IDSBuffer := nil;
671
 
865
 
672
  FDSound.DXResult := FDSound.ISound.CreateSoundBuffer(BufferDesc, TempBuffer, nil);
866
  FDSound.DXResult := FDSound.ISound.CreateSoundBuffer(BufferDesc, TempBuffer, nil);
673
  FDXResult := FDSound.DXResult;
867
  FDXResult := FDSound.DXResult;
674
  Result := DXResult=DS_OK;
868
  Result := DXResult = DS_OK;
675
  if Result then
869
  if Result then
676
    IDSBuffer := TempBuffer;
870
    IDSBuffer := TempBuffer;
677
end;
871
end;
678
 
872
 
679
function TDirectSoundBuffer.GetBitCount: Longint;
873
function TDirectSoundBuffer.GetBitCount: Longint;
680
begin
874
begin
681
  Result := Format.wBitsPerSample;
875
  Result := Format.wBitsPerSample;
682
end;
876
end;
683
 
877
 
684
function TDirectSoundBuffer.GetFormat: PWaveFormatEx;
878
function TDirectSoundBuffer.GetFormat: PWaveFormatEx;
685
begin
879
begin
686
  GetIBuffer;
880
  GetIBuffer;
687
  Result := FFormat;
881
  Result := FFormat;
688
end;
882
end;
689
 
883
 
690
function TDirectSoundBuffer.GetFrequency: Integer;
884
function TDirectSoundBuffer.GetFrequency: Integer;
691
begin
885
begin
692
  DXResult := IBuffer.GetFrequency(DWORD(Result));
886
  DXResult := IBuffer.GetFrequency(DWORD(Result));
693
end;
887
end;
694
 
888
 
-
 
889
function TDirectSoundBuffer.GetIDS3DBuffer: IDirectSound3DBuffer;
-
 
890
begin
-
 
891
  if Self <> nil then
-
 
892
    Result := FIDS3DBuffer
-
 
893
  else
-
 
894
    Result := nil;
-
 
895
end;
-
 
896
 
695
function TDirectSoundBuffer.GetIDSBuffer: IDirectSoundBuffer;
897
function TDirectSoundBuffer.GetIDSBuffer: IDirectSoundBuffer;
696
begin
898
begin
697
  if Self<>nil then
899
  if Self <> nil then
698
    Result := FIDSBuffer
900
    Result := FIDSBuffer
699
  else
901
  else
700
    Result := nil;
902
    Result := nil;
701
end;
903
end;
702
 
904
 
703
function TDirectSoundBuffer.GetIBuffer: IDirectSoundBuffer;
905
function TDirectSoundBuffer.GetIBuffer: IDirectSoundBuffer;
704
begin
906
begin
705
  Result := IDSBuffer;
907
  Result := IDSBuffer;
706
  if Result=nil then
908
  if Result = nil then
707
    raise EDirectSoundBufferError.CreateFmt(SNotMade, ['IDirectSoundBuffer']);
909
    raise EDirectSoundBufferError.CreateFmt(SNotMade, ['IDirectSoundBuffer']);
708
end;
910
end;
709
 
911
 
710
function TDirectSoundBuffer.GetPlaying: Boolean;
912
function TDirectSoundBuffer.GetPlaying: Boolean;
711
begin
913
begin
712
  Result := (GetStatus and (DSBSTATUS_PLAYING or DSBSTATUS_LOOPING))<>0;
914
  Result := (GetStatus and (DSBSTATUS_PLAYING or DSBSTATUS_LOOPING)) <> 0;
713
end;
915
end;
714
 
916
 
715
function TDirectSoundBuffer.GetPan: Integer;
917
function TDirectSoundBuffer.GetPan: Integer;
716
begin
918
begin
717
  DXResult := IBuffer.GetPan(Longint(Result));
919
  DXResult := IBuffer.GetPan(Longint(Result));
718
end;
920
end;
719
 
921
 
720
function TDirectSoundBuffer.GetPosition: Longint;
922
function TDirectSoundBuffer.GetPosition: Longint;
721
var                                    
923
var
722
  dwCurrentWriteCursor: Longint;
924
  dwCurrentWriteCursor: Longint;
723
begin
925
begin
724
  IBuffer.GetCurrentPosition(DWORD(Result), DWORD(dwCurrentWriteCursor));
926
  IBuffer.GetCurrentPosition(@DWORD(Result), @DWORD(dwCurrentWriteCursor));
725
end;
927
end;
726
 
928
 
727
function TDirectSoundBuffer.GetSize: Integer;
929
function TDirectSoundBuffer.GetSize: Integer;
728
begin
930
begin
729
  Result := FCaps.dwBufferBytes;
931
  Result := FCaps.dwBufferBytes;
730
end;
932
end;
731
 
933
 
732
function TDirectSoundBuffer.GetStatus: Integer;
934
function TDirectSoundBuffer.GetStatus: Integer;
733
begin
935
begin
734
  DXResult := IBuffer.GetStatus(DWORD(Result));
936
  DXResult := IBuffer.GetStatus(DWORD(Result));
735
end;
937
end;
736
 
938
 
737
function TDirectSoundBuffer.GetVolume: Integer;
939
function TDirectSoundBuffer.GetVolume: Integer;
738
begin
940
begin
739
  DXResult := IBuffer.GetVolume(Longint(Result));
941
  DXResult := IBuffer.GetVolume(Longint(Result));
740
end;
942
end;
741
 
943
 
742
procedure TDirectSoundBuffer.LoadFromFile(const FileName: string);
944
procedure TDirectSoundBuffer.LoadFromFile(const FileName: string);
743
var
945
var
744
  Stream : TFileStream;
946
  Stream: TFileStream;
745
begin
947
begin
746
  Stream := TFileStream.Create(FileName, fmOpenRead);
948
  Stream := TFileStream.Create(FileName, fmOpenRead);
747
  try
949
  try
748
    LoadFromStream(Stream);
950
    LoadFromStream(Stream);
749
  finally
951
  finally
750
    Stream.Free;
952
    Stream.Free;
751
  end;
953
  end;
752
end;
954
end;
753
 
955
 
754
procedure TDirectSoundBuffer.LoadFromMemory(const Format: TWaveFormatEx;
956
procedure TDirectSoundBuffer.LoadFromMemory(const Format: TWaveFormatEx;
755
  Data: Pointer; Size: Integer);
957
  Data: Pointer; Size: Integer);
756
var
958
var
757
  Data1, Data2: Pointer;
959
  Data1, Data2: Pointer;
758
  Data1Size, Data2Size: Longint;
960
  Data1Size, Data2Size: Longint;
759
begin
961
begin
760
  SetSize(Format, Size);
962
  SetSize(Format, Size, FIsD3D);
761
 
963
 
762
  if Data<>nil then
964
  if Data <> nil then
763
  begin
965
  begin
764
    if Lock(0, Size, Data1, Data1Size, Data2, Data2Size) then
966
    if Lock(0, Size, Data1, Data1Size, Data2, Data2Size) then
765
    begin
967
    begin
766
      try
968
      try
767
        Move(Data^, Data1^, Data1Size);
969
        Move(Data^, Data1^, Data1Size);
768
        if Data2<>nil then
970
        if Data2 <> nil then
769
          Move(Pointer(Longint(Data)+Data1Size)^, Data2^, Data2Size);
971
          Move(Pointer(Longint(Data) + Data1Size)^, Data2^, Data2Size);
770
      finally
972
      finally
771
        UnLock;
973
        UnLock;
772
      end;
974
      end;
-
 
975
    end
773
    end else
976
    else
774
    begin
977
    begin
775
      FIDSBuffer := nil;
978
      FIDSBuffer := nil;
-
 
979
      FIDS3DBuffer := nil;
776
      raise EDirectSoundBufferError.CreateFmt(SCannotLock, [SDirectSoundBuffer]);
980
      raise EDirectSoundBufferError.CreateFmt(SCannotLock, [SDirectSoundBuffer]);
777
    end;
981
    end;
778
  end;
982
  end;
779
end;
983
end;
780
 
984
 
781
procedure TDirectSoundBuffer.LoadFromStream(Stream: TStream);
985
procedure TDirectSoundBuffer.LoadFromStream(Stream: TStream);
782
var  
986
var
783
  Wave: TWave;
987
  Wave: TWave;
784
begin
988
begin
785
  Wave := TWave.Create;
989
  Wave := TWave.Create;
786
  try
990
  try
787
    Wave.LoadFromStream(Stream);
991
    Wave.LoadFromStream(Stream);
788
    LoadFromWave(Wave);
992
    LoadFromWave(Wave);
789
  finally
993
  finally
790
    Wave.Free;
994
    Wave.Free;
791
  end;
995
  end;
792
end;
996
end;
793
 
997
 
794
procedure TDirectSoundBuffer.LoadFromWave(Wave: TWave);
998
procedure TDirectSoundBuffer.LoadFromWave(Wave: TWave);
795
begin
999
begin
796
  LoadFromMemory(Wave.Format^, Wave.Data, Wave.Size);
1000
  LoadFromMemory(Wave.Format^, Wave.Data, Wave.Size);
797
end;
1001
end;
798
 
1002
 
799
function TDirectSoundBuffer.Lock(LockPosition, LockSize: Longint;
1003
function TDirectSoundBuffer.Lock(LockPosition, LockSize: Longint;
800
  var AudioPtr1: Pointer; var AudioSize1: Longint;
1004
  var AudioPtr1: Pointer; var AudioSize1: Longint;
801
  var AudioPtr2: Pointer; var AudioSize2: Longint): Boolean;
1005
  var AudioPtr2: Pointer; var AudioSize2: Longint): Boolean;
802
begin
1006
begin
803
  Result := False;
1007
  Result := False;
804
  if IDSBuffer=nil then Exit;
1008
  if IDSBuffer = nil then Exit;
805
 
1009
 
806
  if FLockCount>High(FLockAudioPtr1) then Exit;
1010
  if FLockCount > High(FLockAudioPtr1) then Exit;
807
 
-
 
808
  DXResult := IBuffer.Lock(LockPosition, LockSize,
1011
  DXResult := IBuffer.Lock(LockPosition, LockSize,
809
    FLockAudioPtr1[FLockCount], FLockAudioSize1[FLockCount],
1012
    {$IFNDEF DX7}@{$ENDIF}FLockAudioPtr1[FLockCount], {$IFNDEF DX7}@{$ENDIF}FLockAudioSize1[FLockCount],
810
    FLockAudioPtr2[FLockCount], FLockAudioSize2[FLockCount], 0);
1013
    {$IFNDEF DX7}@{$ENDIF}FLockAudioPtr2[FLockCount], {$IFNDEF DX7}@{$ENDIF}FLockAudioSize2[FLockCount], 0);
811
  Result := DXResult=DS_OK;
1014
  Result := DXResult = DS_OK;
812
 
1015
 
813
  if Result then
1016
  if Result then
814
  begin
1017
  begin
815
    AudioPtr1 := FLockAudioPtr1[FLockCount];
1018
    AudioPtr1 := FLockAudioPtr1[FLockCount];
816
    AudioPtr2 := FLockAudioPtr2[FLockCount];
1019
    AudioPtr2 := FLockAudioPtr2[FLockCount];
817
    AudioSize1 := FLockAudioSize1[FLockCount];
1020
    AudioSize1 := FLockAudioSize1[FLockCount];
818
    AudioSize2 := FLockAudioSize2[FLockCount];
1021
    AudioSize2 := FLockAudioSize2[FLockCount];
819
    Inc(FLockCount);
1022
    Inc(FLockCount);
820
  end;
1023
  end;
821
end;
1024
end;
822
 
1025
 
823
function TDirectSoundBuffer.Play(Loop: Boolean): Boolean;
1026
function TDirectSoundBuffer.Play(Loop: Boolean): Boolean;
824
begin
1027
begin
825
  if Loop then
1028
  if Loop then
826
    DXResult := IBuffer.Play(0, 0, DSBPLAY_LOOPING)
1029
    DXResult := IBuffer.Play(0, 0, DSBPLAY_LOOPING)
827
  else
1030
  else
828
    DXResult := IBuffer.Play(0, 0, 0);
1031
    DXResult := IBuffer.Play(0, 0, 0);
829
  Result := DXResult=DS_OK;
1032
  Result := DXResult = DS_OK;
830
end;
1033
end;
831
 
1034
 
832
function TDirectSoundBuffer.Restore: Boolean;
1035
function TDirectSoundBuffer.Restore: Boolean;
833
begin
1036
begin
834
  DXResult := IBuffer.Restore;
1037
  DXResult := IBuffer.Restore;
835
  Result := DXResult=DS_OK;
1038
  Result := DXResult = DS_OK;
836
end;
1039
end;
837
 
1040
 
-
 
1041
procedure TDirectSoundBuffer.SetD3DSParams(const Value: TD3DSParams);
-
 
1042
begin
-
 
1043
  FD3DSParams.Assign(Value);
-
 
1044
end;
-
 
1045
 
838
function TDirectSoundBuffer.SetFormat(const Format: TWaveFormatEx): Boolean;
1046
function TDirectSoundBuffer.SetFormat(const Format: TWaveFormatEx): Boolean;
839
begin
1047
begin
840
  DXResult := IBuffer.SetFormat(Format);
1048
  DXResult := IBuffer.SetFormat(FFormat{$IFDEF DX7}^{$ENDIF});
841
  Result := DXResult=DS_OK;
1049
  Result := DXResult = DS_OK;
842
 
1050
 
843
  if Result then
1051
  if Result then
844
  begin
1052
  begin
845
    FreeMem(FFormat);
1053
    FreeMem(FFormat);
846
    FFormat := nil;
1054
    FFormat := nil;
847
    FFormatSize := 0;
1055
    FFormatSize := 0;
848
    if IBuffer.GetFormat(PWaveFormatEx(nil)^, 0, DWORD(FFormatSize))=DS_OK then
1056
    if IBuffer.GetFormat(PWaveFormatEx(nil), 0, @DWORD(FFormatSize)) = DS_OK then
849
    begin
1057
    begin
850
      GetMem(FFormat, FFormatSize);
1058
      GetMem(FFormat, FFormatSize);
851
      IBuffer.GetFormat(FFormat^, FFormatSize, PDWORD(nil)^);
1059
      IBuffer.GetFormat(FFormat, FFormatSize, nil);
852
    end;            
1060
    end;
853
  end;
1061
  end;
854
end;
1062
end;
855
 
1063
 
856
procedure TDirectSoundBuffer.SetFrequency(Value: Integer);
1064
procedure TDirectSoundBuffer.SetFrequency(Value: Integer);
857
begin
1065
begin
858
  DXResult := IBuffer.SetFrequency(Value);
1066
  DXResult := IBuffer.SetFrequency(Value);
859
end;
1067
end;
860
 
1068
 
-
 
1069
procedure TDirectSoundBuffer.SetIDS3DBuffer(const Value: IDirectSound3DBuffer);
-
 
1070
begin
-
 
1071
  if FIDS3DBuffer = Value then Exit;
-
 
1072
 
-
 
1073
  FIDS3DBuffer := Value;
-
 
1074
  FillChar(FCaps, SizeOf(FCaps), 0);
-
 
1075
  FreeMem(FFormat);
-
 
1076
  FFormat := nil;
-
 
1077
  FFormatSize := 0;
-
 
1078
  FLockCount := 0;
-
 
1079
 
-
 
1080
  if FIDS3DBuffer <> nil then
-
 
1081
  begin
-
 
1082
    FCaps.dwSize := SizeOf(FCaps);
-
 
1083
    IBuffer.GetCaps(FCaps);
-
 
1084
 
-
 
1085
    if IBuffer.GetFormat(PWaveFormatEx(nil), 0, @DWORD(FFormatSize)) = DS_OK then
-
 
1086
    begin
-
 
1087
      GetMem(FFormat, FFormatSize);
-
 
1088
      IBuffer.GetFormat(FFormat, FFormatSize, nil);
-
 
1089
    end;
-
 
1090
  end;
-
 
1091
end;
-
 
1092
 
861
procedure TDirectSoundBuffer.SetIDSBuffer(Value: IDirectSoundBuffer);
1093
procedure TDirectSoundBuffer.SetIDSBuffer(Value: IDirectSoundBuffer);
862
begin
1094
begin
863
  if FIDSBuffer=Value then Exit;
1095
  if FIDSBuffer = Value then Exit;
864
 
1096
 
865
  FIDSBuffer := Value;
1097
  FIDSBuffer := Value;
866
  FillChar(FCaps, SizeOf(FCaps), 0);
1098
  FillChar(FCaps, SizeOf(FCaps), 0);
867
  FreeMem(FFormat);
1099
  FreeMem(FFormat);
868
  FFormat := nil;
1100
  FFormat := nil;
869
  FFormatSize := 0;
1101
  FFormatSize := 0;
870
  FLockCount := 0;
1102
  FLockCount := 0;
871
 
1103
 
872
  if FIDSBuffer<>nil then
1104
  if FIDSBuffer <> nil then
873
  begin
1105
  begin
874
    FCaps.dwSize := SizeOf(FCaps);
1106
    FCaps.dwSize := SizeOf(FCaps);
875
    IBuffer.GetCaps(FCaps);
1107
    IBuffer.GetCaps(FCaps);
876
 
1108
 
877
    if IBuffer.GetFormat(PWaveFormatEx(nil)^, 0, DWORD(FFormatSize))=DS_OK then
1109
    if IBuffer.GetFormat(PWaveFormatEx(nil), 0, @DWORD(FFormatSize)) = DS_OK then
878
    begin
1110
    begin
879
      GetMem(FFormat, FFormatSize);
1111
      GetMem(FFormat, FFormatSize);
880
      IBuffer.GetFormat(FFormat^, FFormatSize, PDWORD(nil)^);
1112
      IBuffer.GetFormat(FFormat, FFormatSize, nil);
881
    end;                
1113
    end;
882
  end;
1114
  end;
883
end;
1115
end;
884
 
1116
 
885
procedure TDirectSoundBuffer.SetPan(Value: Integer);
1117
procedure TDirectSoundBuffer.SetPan(Value: Integer);
886
begin
1118
begin
887
  DXResult := IBuffer.SetPan(Value);
1119
  DXResult := IBuffer.SetPan(Value);
888
end;
1120
end;
889
 
1121
 
890
procedure TDirectSoundBuffer.SetPosition(Value: Longint);
1122
procedure TDirectSoundBuffer.SetPosition(Value: Longint);
891
begin
1123
begin
892
  DXResult := IBuffer.SetCurrentPosition(Value);
1124
  DXResult := IBuffer.SetCurrentPosition(Value);
893
end;
1125
end;
-
 
1126
{$IFNDEF DX7}
-
 
1127
const
-
 
1128
  DSBCAPS_CTRLDEFAULT = DSBCAPS_CTRLFREQUENCY or DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME;
-
 
1129
{$ENDIF}
894
 
1130
 
895
procedure TDirectSoundBuffer.SetSize(const Format: TWaveFormatEx; Size: Integer);
1131
procedure TDirectSoundBuffer.SetSize(const Format: TWaveFormatEx; Size: Integer; D3D: Boolean {$IFNDEF VER100}= False{$ENDIF});
896
var
1132
var
897
  BufferDesc: TDSBufferDesc;
1133
  BufferDesc: TDSBufferDesc;
898
begin
1134
begin
899
  {  IDirectSoundBuffer made.  }
1135
  {  IDirectSoundBuffer made.  }
900
  FillChar(BufferDesc, SizeOf(BufferDesc), 0);
1136
  FillChar(BufferDesc, SizeOf(BufferDesc), 0);
901
 
1137
 
902
  with BufferDesc do
1138
  with BufferDesc do
903
  begin
1139
  begin
904
    dwSize := SizeOf(TDSBufferDesc);
1140
    dwSize := SizeOf(TDSBufferDesc);
905
    dwFlags := DSBCAPS_CTRLDEFAULT;
1141
    dwFlags := DSBCAPS_CTRLDEFAULT;
906
    if DSound.FStickyFocus then
1142
    if DSound.FStickyFocus then
907
      dwFlags := dwFlags or DSBCAPS_STICKYFOCUS
1143
      dwFlags := dwFlags or DSBCAPS_STICKYFOCUS
908
    else if DSound.FGlobalFocus then
1144
    else if DSound.FGlobalFocus then
909
      dwFlags := dwFlags or DSBCAPS_GLOBALFOCUS;
1145
      dwFlags := dwFlags or DSBCAPS_GLOBALFOCUS;
-
 
1146
    if D3D then
-
 
1147
      dwFlags := DSBCAPS_STATIC + DSBCAPS_CTRLDEFAULT + DSBCAPS_CTRL3D - DSBCAPS_CTRLPAN;
910
    dwBufferBytes := Size;
1148
    dwBufferBytes := Size;
911
    lpwfxFormat := @Format;
1149
    lpwfxFormat := @Format;
912
  end;
1150
  end;
913
 
1151
 
914
  if not CreateBuffer(BufferDesc) then
1152
  if not CreateBuffer(BufferDesc) then
915
    raise EDirectSoundBufferError.CreateFmt(SCannotMade, [SDirectSoundBuffer]);
1153
    raise EDirectSoundBufferError.CreateFmt(SCannotMade, [SDirectSoundBuffer]);
916
end;
1154
end;
917
 
1155
 
918
procedure TDirectSoundBuffer.SetVolume(Value: Integer);
1156
procedure TDirectSoundBuffer.SetVolume(Value: Integer);
919
begin
1157
begin
920
  DXResult := IBuffer.SetVolume(Value);
1158
  DXResult := IBuffer.SetVolume(Value);
921
end;
1159
end;
922
 
1160
 
923
procedure TDirectSoundBuffer.Stop;
1161
procedure TDirectSoundBuffer.Stop;
924
begin
1162
begin
925
  DXResult := IBuffer.Stop;
1163
  DXResult := IBuffer.Stop;
926
end;
1164
end;
927
 
1165
 
928
procedure TDirectSoundBuffer.Unlock;
1166
procedure TDirectSoundBuffer.Unlock;
929
begin
1167
begin
930
  if IDSBuffer=nil then Exit;
1168
  if IDSBuffer = nil then Exit;
931
  if FLockCount=0 then Exit;
1169
  if FLockCount = 0 then Exit;
932
 
1170
 
933
  Dec(FLockCount);
1171
  Dec(FLockCount);
934
  DXResult := IBuffer.UnLock(FLockAudioPtr1[FLockCount], FLockAudioSize1[FLockCount],
1172
  DXResult := IBuffer.UnLock(FLockAudioPtr1[FLockCount], FLockAudioSize1[FLockCount],
935
    FLockAudioPtr2[FLockCount], FLockAudioSize2[FLockCount]);
1173
    FLockAudioPtr2[FLockCount], FLockAudioSize2[FLockCount]);
936
end;
1174
end;
937
 
1175
 
-
 
1176
{  TD3DSParams  }
-
 
1177
 
-
 
1178
function TD3DSParams.CheckValidity: Boolean;
-
 
1179
begin
-
 
1180
  Result := (FOwner <> nil) and (TDirectSoundBuffer(FOwner).IDS3DBuffer <> nil)
-
 
1181
end;
-
 
1182
 
-
 
1183
constructor TD3DSParams.Create(Owner: TDirectSoundBuffer);
-
 
1184
  {$IFDEF VER14UP}
-
 
1185
  function MakeD3DVector(x, y, z: TD3DValue): TD3DVector; {$IFDEF VER9UP}inline; {$ENDIF}
-
 
1186
  begin
-
 
1187
    Result.x := x;
-
 
1188
    Result.y := y;
-
 
1189
    Result.z := z;
-
 
1190
  end;
-
 
1191
  {$ENDIF}
-
 
1192
begin
-
 
1193
  inherited Create;
-
 
1194
  FOwner := Owner;
-
 
1195
  with FDsb do
-
 
1196
  begin
-
 
1197
    dwSize := SizeOf(TDS3DBuffer);
-
 
1198
    vPosition := MakeD3DVector(0, 0, 0);
-
 
1199
    vVelocity := MakeD3DVector(0, 0, 0);
-
 
1200
    dwInsideConeAngle := DS3D_DEFAULTCONEANGLE;
-
 
1201
    dwOutsideConeAngle := DS3D_DEFAULTCONEANGLE;
-
 
1202
    vConeOrientation := MakeD3DVector(0, 0, 0);
-
 
1203
    lConeoutsideVolume := DS3D_DEFAULTCONEOUTSIDEVOLUME;
-
 
1204
    flMinDistance := 5;
-
 
1205
    flMaxDistance := 100.0;
-
 
1206
    dwMode := DS3DMODE_NORMAL;
-
 
1207
  end;
-
 
1208
end;
-
 
1209
 
-
 
1210
destructor TD3DSParams.destroy;
-
 
1211
begin
-
 
1212
  inherited destroy;
-
 
1213
end;
-
 
1214
 
-
 
1215
function TD3DSParams.getPosition: TD3DVector;
-
 
1216
begin
-
 
1217
  if CheckValidity then
-
 
1218
  begin
-
 
1219
    FOwner.IDS3DBuffer.GetPosition(FDsb.vPosition);
-
 
1220
  end;
-
 
1221
  result := FDsb.vPosition;
-
 
1222
end;
-
 
1223
 
-
 
1224
function TD3DSParams.getVelocity: TD3DVector;
-
 
1225
begin
-
 
1226
  if CheckValidity then
-
 
1227
  begin
-
 
1228
    FOwner.IDS3DBuffer.GetVelocity(FDsb.vVelocity);
-
 
1229
  end;
-
 
1230
  result := FDsb.vVelocity;
-
 
1231
end;
-
 
1232
 
-
 
1233
function TD3DSParams.getConeOrientation: TD3DVector;
-
 
1234
begin
-
 
1235
  if CheckValidity then
-
 
1236
  begin
-
 
1237
    FOwner.IDS3DBuffer.GetConeOrientation(FDsb.vConeOrientation);
-
 
1238
  end;
-
 
1239
  result := FDsb.vConeOrientation;
-
 
1240
end;
-
 
1241
 
-
 
1242
function TD3DSParams.getConeAngle: TConeAngle;
-
 
1243
begin
-
 
1244
  if CheckValidity then
-
 
1245
  begin
-
 
1246
    FOwner.IDS3DBuffer.GetConeAngles(FDsb.dwInsideConeAngle, FDsb.dwOutsideConeAngle);
-
 
1247
  end;
-
 
1248
  with result do
-
 
1249
  begin
-
 
1250
    Inside := FDsb.dwInsideConeAngle;
-
 
1251
    OutSide := FDsb.dwOutsideConeAngle;
-
 
1252
  end;
-
 
1253
end;
-
 
1254
 
-
 
1255
function TD3DSParams.getConeOutsideVolume: Integer;
-
 
1256
begin
-
 
1257
  if CheckValidity then
-
 
1258
  begin
-
 
1259
    FOwner.IDS3DBuffer.GetConeOutsideVolume(FDsb.lConeOutsideVolume);
-
 
1260
  end;
-
 
1261
  result := FDsb.lConeOutsideVolume;
-
 
1262
end;
-
 
1263
 
-
 
1264
function TD3DSParams.getMinDistance: TD3DValue;
-
 
1265
begin
-
 
1266
  if CheckValidity then
-
 
1267
  begin
-
 
1268
    FOwner.IDS3DBuffer.GetMinDistance(FDsb.flMinDistance);
-
 
1269
  end;
-
 
1270
  result := FDsb.flMinDistance;
-
 
1271
end;
-
 
1272
 
-
 
1273
function TD3DSParams.getMaxDistance: TD3DValue;
-
 
1274
begin
-
 
1275
  if CheckValidity then
-
 
1276
  begin
-
 
1277
    FOwner.IDS3DBuffer.GetMaxDistance(FDsb.flMaxDistance);
-
 
1278
  end;
-
 
1279
  result := FDsb.flMaxDistance;
-
 
1280
end;
-
 
1281
 
-
 
1282
function TD3DSParams.getRaw: TDS3DBuffer;
-
 
1283
begin
-
 
1284
  if CheckValidity then
-
 
1285
  begin
-
 
1286
    FOwner.IDS3DBuffer.GetAllParameters(FDsb);
-
 
1287
  end;
-
 
1288
  result := FDsb;
-
 
1289
end;
-
 
1290
 
-
 
1291
 
-
 
1292
procedure TD3DSParams.setPosition(const v: TD3DVector);
-
 
1293
begin
-
 
1294
  if CheckValidity then
-
 
1295
  begin
-
 
1296
    FOwner.IDS3DBuffer.SetPosition(v.x, v.y, v.z, DS3D_IMMEDIATE);
-
 
1297
  end;
-
 
1298
  FDsb.vPosition := v;
-
 
1299
end;
-
 
1300
 
-
 
1301
procedure TD3DSParams.setVelocity(const v: TD3DVector);
-
 
1302
begin
-
 
1303
  if CheckValidity then
-
 
1304
  begin
-
 
1305
    FOwner.IDS3DBuffer.SetVelocity(v.x, v.y, v.z, DS3D_IMMEDIATE);
-
 
1306
  end;
-
 
1307
  FDsb.vVelocity := v;
-
 
1308
end;
-
 
1309
 
-
 
1310
procedure TD3DSParams.setConeOrientation(const v: TD3DVector);
-
 
1311
begin
-
 
1312
  if CheckValidity then
-
 
1313
  begin
-
 
1314
    FOwner.IDS3DBuffer.SetConeOrientation(v.x, v.y, v.z, DS3D_IMMEDIATE);
-
 
1315
  end;
-
 
1316
  FDsb.vConeOrientation := v;
-
 
1317
end;
-
 
1318
 
-
 
1319
procedure TD3DSParams.setConeAngle(const v: TConeAngle);
-
 
1320
begin
-
 
1321
  if CheckValidity then
-
 
1322
  begin
-
 
1323
    FOwner.IDS3DBuffer.SetConeAngles(v.Inside, v.Outside, DS3D_IMMEDIATE);
-
 
1324
  end;
-
 
1325
  FDsb.dwInsideConeAngle := v.Inside;
-
 
1326
  FDsb.dwInsideConeAngle := v.Outside;
-
 
1327
end;
-
 
1328
 
-
 
1329
procedure TD3DSParams.setConeOutsideVolume(const v: Integer);
-
 
1330
begin
-
 
1331
  if CheckValidity then
-
 
1332
  begin
-
 
1333
    FOwner.IDS3DBuffer.SetConeOutsideVolume(v, DS3D_IMMEDIATE);
-
 
1334
  end;
-
 
1335
  FDsb.lConeOutsideVolume := v;
-
 
1336
end;
-
 
1337
 
-
 
1338
procedure TD3DSParams.setMinDistance(const v: TD3DValue);
-
 
1339
begin
-
 
1340
  if CheckValidity then
-
 
1341
  begin
-
 
1342
    FOwner.IDS3DBuffer.SetMinDistance(v, DS3D_IMMEDIATE);
-
 
1343
  end;
-
 
1344
  FDsb.flMinDistance := v;
-
 
1345
end;
-
 
1346
 
-
 
1347
procedure TD3DSParams.setMaxDistance(const v: TD3DValue);
-
 
1348
begin
-
 
1349
  if CheckValidity then
-
 
1350
  begin
-
 
1351
    FOwner.IDS3DBuffer.SetMaxDistance(v, DS3D_IMMEDIATE);
-
 
1352
  end;
-
 
1353
  FDsb.flMaxDistance := v;
-
 
1354
end;
-
 
1355
 
-
 
1356
procedure TD3DSParams.setRaw(const v: TDS3DBuffer);
-
 
1357
begin
-
 
1358
  if CheckValidity then
-
 
1359
  begin
-
 
1360
    if FOwner.IDS3DBuffer.SetAllParameters(v, DS3D_IMMEDIATE) <> DS_OK then
-
 
1361
      {'Parameter is invalid for Params3D'};
-
 
1362
  end;
-
 
1363
  FDsb := v;
-
 
1364
end;
-
 
1365
 
-
 
1366
procedure TD3DSParams.Assign(Prms: TD3DSParams);
-
 
1367
begin
-
 
1368
  FDsb := Prms.RawParams;
-
 
1369
 
-
 
1370
  if CheckValidity then
-
 
1371
  begin
-
 
1372
    if FOwner.IDS3DBuffer.SetAllParameters(FDsb, DS3D_IMMEDIATE) <> DS_OK then
-
 
1373
      {'Parameter is invalid for Params3D'};
-
 
1374
  end;
-
 
1375
end;
-
 
1376
 
938
{  TAudioStream  }
1377
{  TAudioStream  }
939
 
1378
 
940
type
1379
type
941
  TAudioStreamNotify = class(TThread)
1380
  TAudioStreamNotify = class(TThread)
942
  private
1381
  private
943
    FAudio: TAudioStream;
1382
    FAudio: TAudioStream;
944
    FSleepTime: Integer;
1383
    FSleepTime: Integer;
945
    FStopOnTerminate: Boolean;
1384
    FStopOnTerminate: Boolean;
946
    constructor Create(Audio: TAudioStream);
1385
    constructor Create(Audio: TAudioStream);
947
    destructor Destroy; override;
1386
    destructor Destroy; override;
948
    procedure Execute; override;
1387
    procedure Execute; override;
949
    procedure Update;
1388
    procedure Update;
950
    procedure ThreadTerminate(Sender: TObject);
1389
    procedure ThreadTerminate(Sender: TObject);
951
  end;
1390
  end;
952
 
1391
 
953
constructor TAudioStreamNotify.Create(Audio: TAudioStream);
1392
constructor TAudioStreamNotify.Create(Audio: TAudioStream);
954
begin
1393
begin
955
  FAudio := Audio;
1394
  FAudio := Audio;
956
 
1395
 
957
  OnTerminate := ThreadTerminate;
1396
  OnTerminate := ThreadTerminate;
958
 
1397
 
959
  FAudio.FNotifyEvent := CreateEvent(nil, False, False, nil);
1398
  FAudio.FNotifyEvent := CreateEvent(nil, False, False, nil);
960
  FAudio.FNotifyThread := Self;
1399
  FAudio.FNotifyThread := Self;
961
 
1400
 
962
  FSleepTime := Min(FAudio.FBufferLength div 4, 1000 div 20);
1401
  FSleepTime := Min(FAudio.FBufferLength div 4, 1000 div 20);
963
  FStopOnTerminate := True;
1402
  FStopOnTerminate := True;
964
 
1403
 
965
  FreeOnTerminate := True;
1404
  FreeOnTerminate := True;
966
  inherited Create(False);
1405
  inherited Create(False);
967
end;
1406
end;
968
 
1407
 
969
destructor TAudioStreamNotify.Destroy;
1408
destructor TAudioStreamNotify.Destroy;
970
begin
1409
begin
971
  FreeOnTerminate := False;
1410
  FreeOnTerminate := False;
972
 
1411
 
973
  SetEvent(FAudio.FNotifyEvent);
1412
  SetEvent(FAudio.FNotifyEvent);
974
  inherited Destroy;
1413
  inherited Destroy;
975
  CloseHandle(FAudio.FNotifyEvent);
1414
  CloseHandle(FAudio.FNotifyEvent);
976
 
1415
 
977
  FAudio.FNotifyThread := nil;
1416
  FAudio.FNotifyThread := nil;
978
end;
1417
end;
979
 
1418
 
980
procedure TAudioStreamNotify.ThreadTerminate(Sender: TObject);
1419
procedure TAudioStreamNotify.ThreadTerminate(Sender: TObject);
981
begin
1420
begin
982
  FAudio.FNotifyThread := nil;
1421
  FAudio.FNotifyThread := nil;
983
  if FStopOnTerminate then FAudio.Stop;
1422
  if FStopOnTerminate then FAudio.Stop;
984
end;
1423
end;
985
 
1424
 
986
procedure TAudioStreamNotify.Execute;
1425
procedure TAudioStreamNotify.Execute;
987
begin
1426
begin
988
  while WaitForSingleObject(FAudio.FNotifyEvent, FSleepTime)=WAIT_TIMEOUT do
1427
  while WaitForSingleObject(FAudio.FNotifyEvent, FSleepTime) = WAIT_TIMEOUT do
989
    Synchronize(Update);
1428
    Synchronize(Update);
990
end;
1429
end;
991
 
1430
 
992
procedure TAudioStreamNotify.Update;
1431
procedure TAudioStreamNotify.Update;
993
begin
1432
begin
994
  if not FAudio.Playing then
1433
  if not FAudio.Playing then
995
  begin
1434
  begin
996
    SetEvent(FAudio.FNotifyEvent);
1435
    SetEvent(FAudio.FNotifyEvent);
997
    EXit;
1436
    EXit;
998
  end;
1437
  end;
999
 
1438
 
1000
  try
1439
  try
1001
    FAudio.Update2(True);
1440
    FAudio.Update2(True);
1002
  except
1441
  except
1003
    on E: Exception do
1442
    on E: Exception do
1004
    begin
1443
    begin
1005
      Application.HandleException(E);
1444
      Application.HandleException(E);
1006
      SetEvent(FAudio.FNotifyEvent);
1445
      SetEvent(FAudio.FNotifyEvent);
1007
    end;
1446
    end;
1008
  end;
1447
  end;
1009
end;
1448
end;
1010
 
1449
 
1011
constructor TAudioStream.Create(ADirectSound: TDirectSound);
1450
constructor TAudioStream.Create(ADirectSound: TDirectSound);
1012
begin
1451
begin
1013
  inherited Create;
1452
  inherited Create;
1014
  FDSound := ADirectSound;
1453
  FDSound := ADirectSound;
1015
  FAutoUpdate := True;
1454
  FAutoUpdate := True;
1016
  FBuffer := TDirectSoundBuffer.Create(FDSound);
1455
  FBuffer := TDirectSoundBuffer.Create(FDSound);
1017
  FBufferLength := 1000;
1456
  FBufferLength := 1000;
1018
end;
1457
end;
1019
 
1458
 
1020
destructor TAudioStream.Destroy;
1459
destructor TAudioStream.Destroy;
1021
begin
1460
begin
1022
  Stop;
1461
  Stop;
1023
  WaveStream := nil;
1462
  WaveStream := nil;
1024
  FBuffer.Free;
1463
  FBuffer.Free;
1025
  inherited Destroy;
1464
  inherited Destroy;
1026
end;
1465
end;
1027
 
1466
 
1028
function TAudioStream.GetFormat: PWaveFormatEX;
1467
function TAudioStream.GetFormat: PWaveFormatEX;
1029
begin
1468
begin
1030
  if WaveStream=nil then
1469
  if WaveStream = nil then
1031
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1470
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1032
  Result := WaveStream.Format;
1471
  Result := WaveStream.Format;
1033
end;
1472
end;
1034
 
1473
 
1035
function TAudioStream.GetFormatSize: Integer;
1474
function TAudioStream.GetFormatSize: Integer;
1036
begin
1475
begin
1037
  if WaveStream=nil then
1476
  if WaveStream = nil then
1038
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1477
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1039
  Result := WaveStream.FormatSize;
1478
  Result := WaveStream.FormatSize;
1040
end;
1479
end;
1041
 
1480
 
1042
function TAudioStream.GetFrequency: Integer;
1481
function TAudioStream.GetFrequency: Integer;
1043
begin
1482
begin
1044
  Result := FBuffer.Frequency;
1483
  Result := FBuffer.Frequency;
1045
end;
1484
end;
1046
 
1485
 
1047
function TAudioStream.GetPan: Integer;
1486
function TAudioStream.GetPan: Integer;
1048
begin
1487
begin
1049
  Result := FBuffer.Pan;
1488
  Result := FBuffer.Pan;
1050
end;
1489
end;
1051
 
1490
 
1052
function TAudioStream.GetPlayedSize: Integer;
1491
function TAudioStream.GetPlayedSize: Integer;
1053
begin
1492
begin
1054
  if Playing then UpdatePlayedSize;
1493
  if Playing then UpdatePlayedSize;
1055
  Result := FPlayedSize;
1494
  Result := FPlayedSize;
1056
end;
1495
end;
1057
 
1496
 
1058
function TAudioStream.GetSize: Integer;
1497
function TAudioStream.GetSize: Integer;
1059
begin
1498
begin
1060
  if WaveStream<>nil then
1499
  if WaveStream <> nil then
1061
    Result := WaveStream.Size
1500
    Result := WaveStream.Size
1062
  else
1501
  else
1063
    Result := 0;
1502
    Result := 0;
1064
end;
1503
end;
1065
 
1504
 
1066
function TAudioStream.GetVolume: Integer;
1505
function TAudioStream.GetVolume: Integer;
1067
begin
1506
begin
1068
  Result := FBuffer.Volume;
1507
  Result := FBuffer.Volume;
1069
end;
1508
end;
1070
 
1509
 
1071
procedure TAudioStream.UpdatePlayedSize;
1510
procedure TAudioStream.UpdatePlayedSize;
1072
var
1511
var
1073
  PlayPosition, PlayedSize: DWORD;
1512
  PlayPosition, PlayedSize: DWORD;
1074
begin
1513
begin
1075
  PlayPosition := FBuffer.Position;
1514
  PlayPosition := FBuffer.Position;
1076
 
1515
 
1077
  if FPlayBufferPos <= PlayPosition then
1516
  if FPlayBufferPos <= PlayPosition then
1078
  begin
1517
  begin
1079
    PlayedSize := PlayPosition - FPlayBufferPos
1518
    PlayedSize := PlayPosition - FPlayBufferPos
1080
  end else
1519
  end else
1081
  begin
1520
  begin
1082
    PlayedSize := PlayPosition + (FBufferSize - FPlayBufferPos);
1521
    PlayedSize := PlayPosition + (FBufferSize - FPlayBufferPos);
1083
  end;
1522
  end;
1084
 
1523
 
1085
  Inc(FPlayedSize, PlayedSize);
1524
  Inc(FPlayedSize, PlayedSize);
1086
 
1525
 
1087
  FPlayBufferPos := PlayPosition;
1526
  FPlayBufferPos := PlayPosition;
1088
end;
1527
end;
1089
 
1528
 
1090
function TAudioStream.GetWriteSize: Integer;
1529
function TAudioStream.GetWriteSize: Integer;
1091
var
1530
var
1092
  PlayPosition: DWORD;
1531
  PlayPosition: DWORD;
1093
  i: Integer;
1532
  i: Integer;
1094
begin
1533
begin
1095
  PlayPosition := FBuffer.Position;
1534
  PlayPosition := FBuffer.Position;
1096
 
1535
 
1097
  if FBufferPos <= PlayPosition then
1536
  if FBufferPos <= PlayPosition then
1098
  begin
1537
  begin
1099
    Result := PlayPosition - FBufferPos
1538
    Result := PlayPosition - FBufferPos
1100
  end else
1539
  end else
1101
  begin
1540
  begin
1102
    Result := PlayPosition + (FBufferSize - FBufferPos);
1541
    Result := PlayPosition + (FBufferSize - FBufferPos);
1103
  end;
1542
  end;
1104
 
1543
 
1105
  i := WaveStream.FilledSize;
1544
  i := WaveStream.FilledSize;
1106
  if i>=0 then Result := Min(Result, i);
1545
  if i >= 0 then Result := Min(Result, i);
1107
end;
1546
end;
1108
 
1547
 
1109
procedure TAudioStream.Play;
1548
procedure TAudioStream.Play;
1110
begin
1549
begin
1111
  if not FPlaying then
1550
  if not FPlaying then
1112
  begin
1551
  begin
1113
    if WaveStream=nil then
1552
    if WaveStream = nil then
1114
      raise EAudioStreamError.Create(SWaveStreamNotSet);
1553
      raise EAudioStreamError.Create(SWaveStreamNotSet);
1115
 
1554
 
1116
    if Size=0 then Exit;
1555
    if Size = 0 then Exit;
1117
 
1556
 
1118
    FPlaying := True;
1557
    FPlaying := True;
1119
    try
1558
    try
1120
      SetPosition(FPosition);
1559
      SetPosition(FPosition);
1121
      if FAutoUpdate then
1560
      if FAutoUpdate then
1122
        FNotifyThread := TAudioStreamNotify.Create(Self);
1561
        FNotifyThread := TAudioStreamNotify.Create(Self);
1123
    except
1562
    except
1124
      Stop;
1563
      Stop;
1125
      raise;
1564
      raise;
1126
    end;
1565
    end;
1127
  end;
1566
  end;
1128
end;
1567
end;
1129
 
1568
 
1130
procedure TAudioStream.RecreateBuf;
1569
procedure TAudioStream.RecreateBuf;
1131
var
1570
var
1132
  APlaying: Boolean;
1571
  APlaying: Boolean;
1133
  APosition: Integer;
1572
  APosition: Integer;
1134
  AFrequency: Integer;
1573
  AFrequency: Integer;
1135
  APan: Integer;
1574
  APan: Integer;
1136
  AVolume: Integer;
1575
  AVolume: Integer;
1137
begin
1576
begin
1138
  APlaying := Playing;
1577
  APlaying := Playing;
1139
     
1578
 
1140
  APosition := Position;
1579
  APosition := Position;
1141
  AFrequency := Frequency;
1580
  AFrequency := Frequency;
1142
  APan := Pan;
1581
  APan := Pan;
1143
  AVolume := Volume;
1582
  AVolume := Volume;
1144
                       
1583
 
1145
  SetWaveStream(WaveStream);
1584
  SetWaveStream(WaveStream);
1146
 
1585
 
1147
  Position := APosition;
1586
  Position := APosition;
1148
  Frequency := AFrequency;
1587
  Frequency := AFrequency;
1149
  Pan := APan;
1588
  Pan := APan;
1150
  Volume := AVolume;
1589
  Volume := AVolume;
1151
                 
1590
 
1152
  if APlaying then Play;
1591
  if APlaying then Play;
1153
end;
1592
end;
1154
 
1593
 
1155
procedure TAudioStream.SetAutoUpdate(Value: Boolean);
1594
procedure TAudioStream.SetAutoUpdate(Value: Boolean);
1156
begin
1595
begin
1157
  if FAutoUpdate<>Value then
1596
  if FAutoUpdate <> Value then
1158
  begin
1597
  begin
1159
    FAutoUpdate := Value;
1598
    FAutoUpdate := Value;
1160
    if FPlaying then
1599
    if FPlaying then
1161
    begin
1600
    begin
1162
      if FNotifyThread<>nil then
1601
      if FNotifyThread <> nil then
1163
      begin
1602
      begin
1164
        (FNotifyThread as TAudioStreamNotify).FStopOnTerminate := False;
1603
        (FNotifyThread as TAudioStreamNotify).FStopOnTerminate := False;
1165
        FNotifyThread.Free;
1604
        FNotifyThread.Free;
1166
      end;
1605
      end;
1167
 
1606
 
1168
      if FAutoUpdate then
1607
      if FAutoUpdate then
1169
        FNotifyThread := TAudioStreamNotify.Create(Self);
1608
        FNotifyThread := TAudioStreamNotify.Create(Self);
1170
    end;
1609
    end;
1171
  end;
1610
  end;
1172
end;
1611
end;
1173
 
1612
 
1174
procedure TAudioStream.SetBufferLength(Value: Integer);
1613
procedure TAudioStream.SetBufferLength(Value: Integer);
1175
begin
1614
begin
1176
  if Value<10 then Value := 10;
1615
  if Value < 10 then Value := 10;
1177
  if FBufferLength<>Value then
1616
  if FBufferLength <> Value then
1178
  begin
1617
  begin
1179
    FBufferLength := Value;
1618
    FBufferLength := Value;
1180
    if WaveStream<>nil then RecreateBuf;
1619
    if WaveStream <> nil then RecreateBuf;
1181
  end;
1620
  end;
1182
end;
1621
end;
1183
 
1622
 
1184
procedure TAudioStream.SetFrequency(Value: Integer);
1623
procedure TAudioStream.SetFrequency(Value: Integer);
1185
begin
1624
begin
1186
  FBuffer.Frequency := Value;
1625
  FBuffer.Frequency := Value;
1187
end;
1626
end;
1188
 
1627
 
1189
procedure TAudioStream.SetLooped(Value: Boolean);
1628
procedure TAudioStream.SetLooped(Value: Boolean);
1190
begin
1629
begin
1191
  if FLooped<>Value then
1630
  if FLooped <> Value then
1192
  begin
1631
  begin
1193
    FLooped := Value;
1632
    FLooped := Value;
1194
    Position := Position;
1633
    Position := Position;
1195
  end;
1634
  end;
1196
end;
1635
end;
1197
 
1636
 
1198
procedure TAudioStream.SetPan(Value: Integer);
1637
procedure TAudioStream.SetPan(Value: Integer);
1199
begin
1638
begin
1200
  FBuffer.Pan := Value;
1639
  FBuffer.Pan := Value;
1201
end;
1640
end;
1202
 
1641
 
1203
procedure TAudioStream.SetPlayedSize(Value: Integer);
1642
procedure TAudioStream.SetPlayedSize(Value: Integer);
1204
begin
1643
begin
1205
  if Playing then UpdatePlayedSize;
1644
  if Playing then UpdatePlayedSize;
1206
  FPlayedSize := Value;
1645
  FPlayedSize := Value;
1207
end;
1646
end;
1208
 
1647
 
1209
procedure TAudioStream.SetPosition(Value: Integer);
1648
procedure TAudioStream.SetPosition(Value: Integer);
1210
begin
1649
begin
1211
  if WaveStream=nil then
1650
  if WaveStream = nil then
1212
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1651
    raise EAudioStreamError.Create(SWaveStreamNotSet);
1213
 
1652
 
1214
  Value := Max(Min(Value, Size-1), 0);
1653
  Value := Max(Min(Value, Size - 1), 0);
1215
  Value := Value div Format^.nBlockAlign * Format^.nBlockAlign;
1654
  Value := Value div Format^.nBlockAlign * Format^.nBlockAlign;
1216
 
1655
 
1217
  FPosition := Value;
1656
  FPosition := Value;
1218
 
1657
 
1219
  if Playing then
1658
  if Playing then
1220
  begin
1659
  begin
1221
    try
1660
    try
1222
      FBuffer.Stop;
1661
      FBuffer.Stop;
1223
 
1662
 
1224
      FBufferPos := 0;
1663
      FBufferPos := 0;
1225
      FPlayBufferPos := 0;
1664
      FPlayBufferPos := 0;
1226
      FWritePosition := Value;
1665
      FWritePosition := Value;
1227
 
1666
 
1228
      WriteWave(FBufferSize);
1667
      WriteWave(FBufferSize);
1229
 
1668
 
1230
      FBuffer.Position := 0;
1669
      FBuffer.Position := 0;
1231
      FBuffer.Play(True);
1670
      FBuffer.Play(True);
1232
    except
1671
    except
1233
      Stop;
1672
      Stop;
1234
      raise;
1673
      raise;
1235
    end;
1674
    end;
1236
  end;
1675
  end;
1237
end;
1676
end;
1238
 
1677
 
1239
procedure TAudioStream.SetVolume(Value: Integer);
1678
procedure TAudioStream.SetVolume(Value: Integer);
1240
begin
1679
begin
1241
  FBuffer.Volume := Value;
1680
  FBuffer.Volume := Value;
1242
end;
1681
end;
1243
 
1682
 
1244
procedure TAudioStream.SetWaveStream(Value: TCustomWaveStream);
1683
procedure TAudioStream.SetWaveStream(Value: TCustomWaveStream);
1245
var
1684
var
1246
  BufferDesc: TDSBufferDesc;
1685
  BufferDesc: TDSBufferDesc;
1247
begin
1686
begin
1248
  Stop;
1687
  Stop;
1249
 
1688
 
1250
  FWaveStream := nil;
1689
  FWaveStream := nil;
1251
  FBufferPos := 0;
1690
  FBufferPos := 0;
1252
  FPosition := 0;
1691
  FPosition := 0;
1253
  FWritePosition := 0;
1692
  FWritePosition := 0;
1254
 
1693
 
1255
  if (Value<>nil) and (FBufferLength>0) then
1694
  if (Value <> nil) and (FBufferLength > 0) then
1256
  begin
1695
  begin
1257
    FBufferSize := FBufferLength * Integer(Value.Format^.nAvgBytesPerSec) div 1000;
1696
    FBufferSize := FBufferLength * Integer(Value.Format^.nAvgBytesPerSec) div 1000;
1258
 
1697
 
1259
    FillChar(BufferDesc, SizeOf(BufferDesc), 0);
1698
    FillChar(BufferDesc, SizeOf(BufferDesc), 0);
1260
    with BufferDesc do
1699
    with BufferDesc do
1261
    begin
1700
    begin
1262
      dwSize := SizeOf(TDSBufferDesc);
1701
      dwSize := SizeOf(TDSBufferDesc);
1263
      dwFlags := DSBCAPS_CTRLDEFAULT or DSBCAPS_GETCURRENTPOSITION2;
1702
      dwFlags := DSBCAPS_CTRLDEFAULT or DSBCAPS_GETCURRENTPOSITION2;
1264
      if FDSound.FStickyFocus then
1703
      if FDSound.FStickyFocus then
1265
        dwFlags := dwFlags or DSBCAPS_STICKYFOCUS
1704
        dwFlags := dwFlags or DSBCAPS_STICKYFOCUS
1266
      else if FDSound.FGlobalFocus then
1705
      else if FDSound.FGlobalFocus then
1267
        dwFlags := dwFlags or DSBCAPS_GLOBALFOCUS;
1706
        dwFlags := dwFlags or DSBCAPS_GLOBALFOCUS;
1268
      dwBufferBytes := FBufferSize;
1707
      dwBufferBytes := FBufferSize;
1269
      lpwfxFormat := Value.Format;
1708
      lpwfxFormat := Value.Format;
1270
    end;
1709
    end;
1271
 
1710
 
1272
    if not FBuffer.CreateBuffer(BufferDesc) then
1711
    if not FBuffer.CreateBuffer(BufferDesc) then
1273
      raise EDirectSoundBufferError.CreateFmt(SCannotMade, [SDirectSoundBuffer]);
1712
      raise EDirectSoundBufferError.CreateFmt(SCannotMade, [SDirectSoundBuffer]);
1274
  end else
1713
  end else
1275
  begin
1714
  begin
1276
    FBuffer.IDSBuffer := nil;
1715
    FBuffer.IDSBuffer := nil;
1277
    FBufferSize := 0;
1716
    FBufferSize := 0;
1278
  end;
1717
  end;
1279
 
1718
 
1280
  FWaveStream := Value;
1719
  FWaveStream := Value;
1281
end;
1720
end;
1282
 
1721
 
1283
procedure TAudioStream.Stop;
1722
procedure TAudioStream.Stop;
1284
begin
1723
begin
1285
  if FPlaying then
1724
  if FPlaying then
1286
  begin
1725
  begin
1287
    FPlaying := False;
1726
    FPlaying := False;
1288
    FBuffer.Stop;
1727
    FBuffer.Stop;
1289
    FNotifyThread.Free;
1728
    FNotifyThread.Free;
1290
  end;
1729
  end;
1291
end;
1730
end;
1292
 
1731
 
1293
procedure TAudioStream.Update;
1732
procedure TAudioStream.Update;
1294
begin
1733
begin
1295
  Update2(False);
1734
  Update2(False);
1296
end;
1735
end;
1297
 
1736
 
1298
procedure TAudioStream.Update2(InThread: Boolean);
1737
procedure TAudioStream.Update2(InThread: Boolean);
1299
var
1738
var
1300
  WriteSize: Integer;
1739
  WriteSize: Integer;
1301
begin
1740
begin
1302
  if not FPlaying then Exit;
1741
  if not FPlaying then Exit;
1303
 
1742
 
1304
  try
1743
  try
1305
    UpdatePlayedSize;
1744
    UpdatePlayedSize;
1306
 
1745
 
1307
    if Size<0 then
1746
    if Size < 0 then
1308
    begin
1747
    begin
1309
      WriteSize := GetWriteSize;
1748
      WriteSize := GetWriteSize;
1310
      if WriteSize>0 then
1749
      if WriteSize > 0 then
1311
      begin
1750
      begin
1312
        WriteSize := WriteWave(WriteSize);
1751
        WriteSize := WriteWave(WriteSize);
1313
        FPosition := FPosition + WriteSize;
1752
        FPosition := FPosition + WriteSize;
1314
      end;
1753
      end;
1315
    end else
1754
    end else
1316
    begin
1755
    begin
1317
      if FLooped then
1756
      if FLooped then
1318
      begin
1757
      begin
1319
        WriteSize := GetWriteSize;
1758
        WriteSize := GetWriteSize;
1320
        if WriteSize>0 then
1759
        if WriteSize > 0 then
1321
        begin
1760
        begin
1322
          WriteWave(WriteSize);
1761
          WriteWave(WriteSize);
1323
          FPosition := (FPosition + WriteSize) mod Size;
1762
          FPosition := (FPosition + WriteSize) mod Size;
1324
        end;
1763
        end;
1325
      end else
1764
      end else
1326
      begin
1765
      begin
1327
        if FPosition<Size then
1766
        if FPosition < Size then
1328
        begin
1767
        begin
1329
          WriteSize := GetWriteSize;
1768
          WriteSize := GetWriteSize;
1330
          if WriteSize>0 then
1769
          if WriteSize > 0 then
1331
          begin
1770
          begin
1332
            WriteWave(WriteSize);
1771
            WriteWave(WriteSize);
1333
            FPosition := FPosition + WriteSize;
1772
            FPosition := FPosition + WriteSize;
1334
            if FPosition>Size then FPosition := Size;
1773
            if FPosition > Size then FPosition := Size;
1335
          end;
1774
          end;
1336
        end else
1775
        end else
1337
        begin
1776
        begin
1338
          if InThread then
1777
          if InThread then
1339
            SetEvent(FNotifyEvent)
1778
            SetEvent(FNotifyEvent)
1340
          else
1779
          else
1341
            Stop;
1780
            Stop;
1342
        end;
1781
        end;
1343
      end;
1782
      end;
1344
    end;
1783
    end;
1345
  except
1784
  except
1346
    if InThread then
1785
    if InThread then
1347
      SetEvent(FNotifyEvent)
1786
      SetEvent(FNotifyEvent)
1348
    else
1787
    else
1349
      Stop;
1788
      Stop;
1350
    raise;
1789
    raise;
1351
  end;
1790
  end;
1352
end;
1791
end;
1353
 
1792
 
1354
function TAudioStream.WriteWave(WriteSize: Integer): Integer;
1793
function TAudioStream.WriteWave(WriteSize: Integer): Integer;
1355
 
1794
 
1356
  procedure WriteData(Size: Integer);
1795
  procedure WriteData(Size: Integer);
1357
  var
1796
  var
1358
    Data1, Data2: Pointer;
1797
    Data1, Data2: Pointer;
1359
    Data1Size, Data2Size: Longint;
1798
    Data1Size, Data2Size: Longint;
1360
  begin
1799
  begin
1361
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1800
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1362
    begin
1801
    begin
1363
      try
1802
      try
1364
        FWaveStream.Position := FWritePosition;
1803
        FWaveStream.Position := FWritePosition;
1365
        FWaveStream.ReadBuffer(Data1^, Data1Size);
1804
        FWaveStream.ReadBuffer(Data1^, Data1Size);
1366
        FWritePosition := FWritePosition + Data1Size;
1805
        FWritePosition := FWritePosition + Data1Size;
1367
 
1806
 
1368
        if Data2<>nil then
1807
        if Data2 <> nil then
1369
        begin
1808
        begin
1370
          FWaveStream.ReadBuffer(Data2^, Data2Size);
1809
          FWaveStream.ReadBuffer(Data2^, Data2Size);
1371
          FWritePosition := FWritePosition + Data2Size;
1810
          FWritePosition := FWritePosition + Data2Size;
1372
        end;
1811
        end;
1373
 
1812
 
1374
        FBufferPos := (FBufferPos + DWORD(Data1Size) + DWORD(Data2Size)) mod FBufferSize;
1813
        FBufferPos := (FBufferPos + DWORD(Data1Size) + DWORD(Data2Size)) mod FBufferSize;
1375
      finally
1814
      finally
1376
        FBuffer.UnLock;
1815
        FBuffer.UnLock;
1377
      end;
1816
      end;
1378
    end;
1817
    end;
1379
  end;
1818
  end;
1380
 
1819
 
1381
  procedure WriteData2(Size: Integer);
1820
  procedure WriteData2(Size: Integer);
1382
  var
1821
  var
1383
    Data1, Data2: Pointer;
1822
    Data1, Data2: Pointer;
1384
    Data1Size, Data2Size, s1, s2: Longint;
1823
    Data1Size, Data2Size, s1, s2: Longint;
1385
  begin
1824
  begin
1386
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1825
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1387
    begin
1826
    begin
1388
      try
1827
      try
1389
        FWaveStream.Position := FWritePosition;
1828
        FWaveStream.Position := FWritePosition;
1390
        s1 := FWaveStream.Read(Data1^, Data1Size);
1829
        s1 := FWaveStream.Read(Data1^, Data1Size);
1391
        FWritePosition := FWritePosition + s1;
1830
        FWritePosition := FWritePosition + s1;
1392
        FBufferPos := (FBufferPos + DWORD(s1)) mod FBufferSize;
1831
        FBufferPos := (FBufferPos + DWORD(s1)) mod FBufferSize;
1393
        Inc(Result, s1);
1832
        Inc(Result, s1);
1394
 
1833
 
1395
        if (Data2<>nil) and (s1=Data1Size) then
1834
        if (Data2 <> nil) and (s1 = Data1Size) then
1396
        begin
1835
        begin
1397
          s2 := FWaveStream.Read(Data2^, Data2Size);
1836
          s2 := FWaveStream.Read(Data2^, Data2Size);
1398
          FWritePosition := FWritePosition + s2;
1837
          FWritePosition := FWritePosition + s2;
1399
          FBufferPos := (FBufferPos + DWORD(s2)) mod FBufferSize;
1838
          FBufferPos := (FBufferPos + DWORD(s2)) mod FBufferSize;
1400
          Inc(Result, s2);
1839
          Inc(Result, s2);
1401
        end;
1840
        end;
1402
      finally
1841
      finally
1403
        FBuffer.UnLock;
1842
        FBuffer.UnLock;
1404
      end;
1843
      end;
1405
    end;
1844
    end;
1406
  end;
1845
  end;
1407
 
1846
 
1408
  procedure WriteSilence(Size: Integer);
1847
  procedure WriteSilence(Size: Integer);
1409
  var
1848
  var
1410
    C: Byte;
1849
    C: Byte;
1411
    Data1, Data2: Pointer;
1850
    Data1, Data2: Pointer;
1412
    Data1Size, Data2Size: Longint;
1851
    Data1Size, Data2Size: Longint;
1413
  begin
1852
  begin
1414
    if Format^.wBitsPerSample=8 then C := $80 else C := 0;
1853
    if Format^.wBitsPerSample = 8 then C := $80 else C := 0;
1415
 
1854
 
1416
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1855
    if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size) then
1417
    begin
1856
    begin
1418
      try
1857
      try
1419
        FillChar(Data1^, Data1Size, C);
1858
        FillChar(Data1^, Data1Size, C);
1420
 
1859
 
1421
        if Data2<>nil then
1860
        if Data2 <> nil then
1422
          FillChar(Data2^, Data2Size, C);
1861
          FillChar(Data2^, Data2Size, C);
1423
      finally
1862
      finally
1424
        FBuffer.UnLock;
1863
        FBuffer.UnLock;
1425
      end;
1864
      end;
1426
      FBufferPos := (FBufferPos + DWORD(Data1Size) + DWORD(Data2Size)) mod FBufferSize;
1865
      FBufferPos := (FBufferPos + DWORD(Data1Size) + DWORD(Data2Size)) mod FBufferSize;
1427
      FWritePosition := FWritePosition + Data1Size + Data2Size;
1866
      FWritePosition := FWritePosition + Data1Size + Data2Size;
1428
    end;
1867
    end;
1429
  end;
1868
  end;
1430
 
1869
 
1431
var
1870
var
1432
  DataSize: Integer;
1871
  DataSize: Integer;
1433
begin
1872
begin
1434
  if Size>=0 then
1873
  if Size >= 0 then
1435
  begin
1874
  begin
1436
    Result := WriteSize;
1875
    Result := WriteSize;
1437
    if FLooped then
1876
    if FLooped then
1438
    begin
1877
    begin
1439
      while WriteSize>0 do
1878
      while WriteSize > 0 do
1440
      begin
1879
      begin
1441
        DataSize := Min(Size-FWritePosition, WriteSize);
1880
        DataSize := Min(Size - FWritePosition, WriteSize);
1442
 
1881
 
1443
        WriteData(DataSize);
1882
        WriteData(DataSize);
1444
        FWritePosition := FWritePosition mod Size;
1883
        FWritePosition := FWritePosition mod Size;
1445
 
1884
 
1446
        Dec(WriteSize, DataSize);
1885
        Dec(WriteSize, DataSize);
1447
      end;
1886
      end;
1448
    end else
1887
    end else
1449
    begin
1888
    begin
1450
      DataSize := Size-FWritePosition;
1889
      DataSize := Size - FWritePosition;
1451
 
1890
 
1452
      if DataSize<=0 then
1891
      if DataSize <= 0 then
1453
      begin
1892
      begin
1454
        WriteSilence(WriteSize);
1893
        WriteSilence(WriteSize);
1455
      end else
1894
      end else
1456
      if DataSize>=WriteSize then
1895
        if DataSize >= WriteSize then
1457
      begin
1896
        begin
1458
        WriteData(WriteSize);
1897
          WriteData(WriteSize);
1459
      end else
1898
        end else
1460
      begin
1899
        begin
1461
        WriteData(DataSize);
1900
          WriteData(DataSize);
1462
        WriteSilence(WriteSize-DataSize);
1901
          WriteSilence(WriteSize - DataSize);
1463
      end;
1902
        end;
1464
    end;
1903
    end;
1465
  end else
1904
  end else
1466
  begin
1905
  begin
1467
    Result := 0;
1906
    Result := 0;
1468
    WriteData2(WriteSize);
1907
    WriteData2(WriteSize);
1469
  end;
1908
  end;
1470
end;
1909
end;
1471
 
1910
 
1472
{  TAudioFileStream  }
1911
{  TAudioFileStream  }
1473
 
1912
 
1474
destructor TAudioFileStream.Destroy;
1913
destructor TAudioFileStream.Destroy;
1475
begin
1914
begin
1476
  inherited Destroy;
1915
  inherited Destroy;
1477
  FWaveFileStream.Free;
1916
  FWaveFileStream.Free;
1478
end;
1917
end;
1479
 
1918
 
1480
procedure TAudioFileStream.SetFileName(const Value: string);
1919
procedure TAudioFileStream.SetFileName(const Value: string);
1481
begin
1920
begin
1482
  if FFileName=Value then Exit;
1921
  if FFileName = Value then Exit;
1483
 
1922
 
1484
  FFileName := Value;
1923
  FFileName := Value;
1485
 
1924
 
1486
  if FWaveFileStream<>nil then
1925
  if FWaveFileStream <> nil then
1487
  begin
1926
  begin
1488
    WaveStream := nil;
1927
    WaveStream := nil;
1489
    FWaveFileStream.Free;
1928
    FWaveFileStream.Free;
1490
    FWaveFileStream := nil;
1929
    FWaveFileStream := nil;
1491
  end;
1930
  end;
1492
 
1931
 
1493
  if Value<>'' then
1932
  if Value <> '' then
1494
  begin
1933
  begin
1495
    try
1934
    try
1496
      FWaveFileStream := TWaveFileStream.Create(Value, fmOpenRead or fmShareDenyWrite);
1935
      FWaveFileStream := TWaveFileStream.Create(Value, fmOpenRead or fmShareDenyWrite);
1497
      FWaveFileStream.Open(False);
1936
      FWaveFileStream.Open(False);
1498
      WaveStream := FWaveFileStream;
1937
      WaveStream := FWaveFileStream;
1499
    except
1938
    except
1500
      WaveStream := nil;
1939
      WaveStream := nil;
1501
      FFileName := '';
1940
      FFileName := '';
1502
      raise;
1941
      raise;
1503
    end;
1942
    end;
1504
  end;
1943
  end;
1505
end;
1944
end;
1506
 
1945
 
1507
{  TSoundCaptureFormats  }
1946
{  TSoundCaptureFormats  }
1508
 
1947
 
1509
constructor TSoundCaptureFormats.Create;
1948
constructor TSoundCaptureFormats.Create;
1510
begin
1949
begin
1511
  inherited Create(TSoundCaptureFormat);
1950
  inherited Create(TSoundCaptureFormat);
1512
end;
1951
end;
1513
 
1952
 
1514
function TSoundCaptureFormats.GetItem(Index: Integer): TSoundCaptureFormat;
1953
function TSoundCaptureFormats.GetItem(Index: Integer): TSoundCaptureFormat;
1515
begin
1954
begin
1516
  Result := TSoundCaptureFormat(inherited Items[Index]);
1955
  Result := TSoundCaptureFormat(inherited Items[Index]);
1517
end;
1956
end;
1518
 
1957
 
1519
function TSoundCaptureFormats.IndexOf(ASamplesPerSec, ABitsPerSample, AChannels: Integer): Integer;
1958
function TSoundCaptureFormats.IndexOf(ASamplesPerSec, ABitsPerSample, AChannels: Integer): Integer;
1520
var
1959
var
1521
  i: Integer;
1960
  i: Integer;
1522
begin
1961
begin
1523
  Result := -1;
1962
  Result := -1;
1524
  for i:=0 to Count-1 do
1963
  for i := 0 to Count - 1 do
1525
    with Items[i] do
1964
    with Items[i] do
1526
      if (FSamplesPerSec=ASamplesPerSec) and (FBitsPerSample=ABitsPerSample) and (FChannels=AChannels) then
1965
      if (FSamplesPerSec = ASamplesPerSec) and (FBitsPerSample = ABitsPerSample) and (FChannels = AChannels) then
1527
      begin
1966
      begin
1528
        Result := i;
1967
        Result := i;
1529
        Break;
1968
        Break;
1530
      end;
1969
      end;
1531
end;
1970
end;
1532
 
1971
 
1533
{  TSoundCaptureStream  }
1972
{  TSoundCaptureStream  }
1534
 
1973
 
1535
type
1974
type
1536
  TSoundCaptureStreamNotify = class(TThread)
1975
  TSoundCaptureStreamNotify = class(TThread)
1537
  private
1976
  private
1538
    FCapture: TSoundCaptureStream;
1977
    FCapture: TSoundCaptureStream;
1539
    FSleepTime: Integer;
1978
    FSleepTime: Integer;
1540
    constructor Create(Capture: TSoundCaptureStream);
1979
    constructor Create(Capture: TSoundCaptureStream);
1541
    destructor Destroy; override;
1980
    destructor Destroy; override;
1542
    procedure Execute; override;
1981
    procedure Execute; override;
1543
    procedure Update;
1982
    procedure Update;
1544
  end;
1983
  end;
1545
 
1984
 
1546
constructor TSoundCaptureStreamNotify.Create(Capture: TSoundCaptureStream);
1985
constructor TSoundCaptureStreamNotify.Create(Capture: TSoundCaptureStream);
1547
begin
1986
begin
1548
  FCapture := Capture;
1987
  FCapture := Capture;
1549
 
1988
 
1550
  FCapture.FNotifyEvent := CreateEvent(nil, False, False, nil);
1989
  FCapture.FNotifyEvent := CreateEvent(nil, False, False, nil);
1551
  FSleepTime := Min(FCapture.FBufferLength div 4, 1000 div 20);
1990
  FSleepTime := Min(FCapture.FBufferLength div 4, 1000 div 20);
1552
 
1991
 
1553
  FreeOnTerminate := True;
1992
  FreeOnTerminate := True;
1554
  inherited Create(True);
1993
  inherited Create(True);
1555
end;
1994
end;
1556
 
1995
 
1557
destructor TSoundCaptureStreamNotify.Destroy;
1996
destructor TSoundCaptureStreamNotify.Destroy;
1558
begin
1997
begin
1559
  FreeOnTerminate := False;
1998
  FreeOnTerminate := False;
1560
  SetEvent(FCapture.FNotifyEvent);
1999
  SetEvent(FCapture.FNotifyEvent);
1561
 
2000
 
1562
  inherited Destroy;
2001
  inherited Destroy;
1563
 
2002
 
1564
  CloseHandle(FCapture.FNotifyEvent);
2003
  CloseHandle(FCapture.FNotifyEvent);
1565
  FCapture.FNotifyThread := nil;
2004
  FCapture.FNotifyThread := nil;
1566
 
2005
 
1567
  if Assigned(FCapture.FOnFilledBuffer) then FCapture.Stop;
2006
  if Assigned(FCapture.FOnFilledBuffer) then FCapture.Stop;
1568
end;
2007
end;
1569
 
2008
 
1570
procedure TSoundCaptureStreamNotify.Execute;
2009
procedure TSoundCaptureStreamNotify.Execute;
1571
begin
2010
begin
1572
  while WaitForSingleObject(FCapture.FNotifyEvent, FSleepTime)=WAIT_TIMEOUT do
2011
  while WaitForSingleObject(FCapture.FNotifyEvent, FSleepTime) = WAIT_TIMEOUT do
1573
  begin
2012
  begin
1574
    Synchronize(Update);
2013
    Synchronize(Update);
1575
  end;
2014
  end;
1576
end;
2015
end;
1577
 
2016
 
1578
procedure TSoundCaptureStreamNotify.Update;
2017
procedure TSoundCaptureStreamNotify.Update;
1579
begin
2018
begin
1580
  if FCapture.FilledSize>0 then
2019
  if FCapture.FilledSize > 0 then
1581
  begin
2020
  begin
1582
    try
2021
    try
1583
      FCapture.DoFilledBuffer;
2022
      FCapture.DoFilledBuffer;
1584
    except
2023
    except
1585
      on E: Exception do
2024
      on E: Exception do
1586
      begin
2025
      begin
1587
        Application.HandleException(E);
2026
        Application.HandleException(E);
1588
        SetEvent(FCapture.FNotifyEvent);
2027
        SetEvent(FCapture.FNotifyEvent);
1589
      end;
2028
      end;
1590
    end;
2029
    end;
1591
  end;
2030
  end;
1592
end;
2031
end;
1593
 
2032
 
1594
constructor TSoundCaptureStream.Create(GUID: PGUID);
2033
constructor TSoundCaptureStream.Create(GUID: PGUID);
1595
const
2034
const
1596
  SamplesPerSecList: array[0..6] of Integer = (8000, 11025, 22050, 33075, 44100, 48000, 96000);
2035
  SamplesPerSecList: array[0..6] of Integer = (8000, 11025, 22050, 33075, 44100, 48000, 96000);
1597
  BitsPerSampleList: array[0..3] of Integer = (8, 16, 24, 32);
2036
  BitsPerSampleList: array[0..3] of Integer = (8, 16, 24, 32);
1598
  ChannelsList: array[0..1] of Integer = (1, 2);
2037
  ChannelsList: array[0..1] of Integer = (1, 2);
1599
var
2038
var
1600
  ASamplesPerSec, ABitsPerSample, AChannels: Integer;
2039
  ASamplesPerSec, ABitsPerSample, AChannels: Integer;
1601
  dscbd: TDSCBufferDesc;
2040
  dscbd: TDSCBufferDesc;
1602
  TempBuffer: IDirectSoundCaptureBuffer;
2041
  TempBuffer: IDirectSoundCaptureBuffer;
1603
  Format: TWaveFormatEx;
2042
  Format: TWaveFormatEx;
1604
begin
2043
begin
1605
  inherited Create;
2044
  inherited Create;
1606
  FBufferLength := 1000;
2045
  FBufferLength := 1000;
1607
  FSupportedFormats := TSoundCaptureFormats.Create;
2046
  FSupportedFormats := TSoundCaptureFormats.Create;
1608
 
2047
 
1609
  if DXDirectSoundCaptureCreate(GUID, FCapture, nil)<>DS_OK then
2048
  if DXDirectSoundCaptureCreate(GUID, FCapture, nil) <> DS_OK then
1610
    raise ESoundCaptureStreamError.CreateFmt(SCannotInitialized, [SDirectSoundCapture]);
2049
    raise ESoundCaptureStreamError.CreateFmt(SCannotInitialized, [SDirectSoundCapture]);
1611
 
2050
 
1612
  {  The supported format list is acquired.  }
2051
  {  The supported format list is acquired.  }
1613
  for ASamplesPerSec:=Low(SamplesPerSecList) to High(SamplesPerSecList) do
2052
  for ASamplesPerSec := Low(SamplesPerSecList) to High(SamplesPerSecList) do
1614
    for ABitsPerSample:=Low(BitsPerSampleList) to High(BitsPerSampleList) do
2053
    for ABitsPerSample := Low(BitsPerSampleList) to High(BitsPerSampleList) do
1615
      for AChannels:=Low(ChannelsList) to High(ChannelsList) do
2054
      for AChannels := Low(ChannelsList) to High(ChannelsList) do
1616
      begin
2055
      begin
1617
        {  Test  }
2056
        {  Test  }
1618
        MakePCMWaveFormatEx(Format, SamplesPerSecList[ASamplesPerSec], BitsPerSampleList[ABitsPerSample], ChannelsList[AChannels]);
2057
        MakePCMWaveFormatEx(Format, SamplesPerSecList[ASamplesPerSec], BitsPerSampleList[ABitsPerSample], ChannelsList[AChannels]);
1619
 
2058
 
1620
        FillChar(dscbd, SizeOf(dscbd), 0);
2059
        FillChar(dscbd, SizeOf(dscbd), 0);
1621
        dscbd.dwSize := SizeOf(dscbd);
2060
        dscbd.dwSize := SizeOf(dscbd);
1622
        dscbd.dwBufferBytes := Format.nAvgBytesPerSec;
2061
        dscbd.dwBufferBytes := Format.nAvgBytesPerSec;
1623
        dscbd.lpwfxFormat := @Format;
2062
        dscbd.lpwfxFormat := @Format;
1624
 
2063
 
1625
        {  If the buffer can be made,  the format of present can be used.  }
2064
        {  If the buffer can be made,  the format of present can be used.  }
1626
        if FCapture.CreateCaptureBuffer(dscbd, TempBuffer, nil)=DS_OK then
2065
        if FCapture.CreateCaptureBuffer(dscbd, TempBuffer, nil) = DS_OK then
1627
        begin
2066
        begin
1628
          TempBuffer := nil;
2067
          TempBuffer := nil;
1629
          with TSoundCaptureFormat.Create(FSupportedFormats) do
2068
          with TSoundCaptureFormat.Create(FSupportedFormats) do
1630
          begin
2069
          begin
1631
            FSamplesPerSec := Format.nSamplesPerSec;
2070
            FSamplesPerSec := Format.nSamplesPerSec;
1632
            FBitsPerSample := Format.wBitsPerSample;
2071
            FBitsPerSample := Format.wBitsPerSample;
1633
            FChannels := Format.nChannels;
2072
            FChannels := Format.nChannels;
1634
          end;
2073
          end;
1635
        end;
2074
        end;
1636
      end;
2075
      end;
1637
end;
2076
end;
1638
 
2077
 
1639
destructor TSoundCaptureStream.Destroy;
2078
destructor TSoundCaptureStream.Destroy;
1640
begin
2079
begin
1641
  Stop;
2080
  Stop;
1642
  FSupportedFormats.Free;
2081
  FSupportedFormats.Free;
1643
  inherited Destroy;
2082
  inherited Destroy;
1644
end;
2083
end;
1645
 
2084
 
1646
procedure TSoundCaptureStream.DoFilledBuffer;
2085
procedure TSoundCaptureStream.DoFilledBuffer;
1647
begin
2086
begin
1648
  if Assigned(FOnFilledBuffer) then FOnFilledBuffer(Self);
2087
  if Assigned(FOnFilledBuffer) then FOnFilledBuffer(Self);
1649
end;
2088
end;
1650
 
2089
 
1651
class function TSoundCaptureStream.Drivers: TDirectXDrivers;
2090
class function TSoundCaptureStream.Drivers: TDirectXDrivers;
1652
begin
2091
begin
1653
  Result := EnumDirectSoundCaptureDrivers;
2092
  Result := EnumDirectSoundCaptureDrivers;
1654
end;
2093
end;
1655
 
2094
 
1656
function TSoundCaptureStream.GetFilledSize: Integer;
2095
function TSoundCaptureStream.GetFilledSize: Integer;
1657
begin
2096
begin
1658
  Result := GetReadSize;
2097
  Result := GetReadSize;
1659
end;
2098
end;
1660
 
2099
 
1661
function TSoundCaptureStream.GetReadSize: Integer;
2100
function TSoundCaptureStream.GetReadSize: Integer;
1662
var
2101
var
1663
  CapturePosition, ReadPosition: DWORD;
2102
  CapturePosition, ReadPosition: DWORD;
1664
begin
2103
begin
1665
  if FBuffer.GetCurrentPosition(CapturePosition, ReadPosition)=DS_OK then
2104
  if FBuffer.GetCurrentPosition(@DWORD(CapturePosition), @DWORD(ReadPosition)) = DS_OK then
1666
  begin
2105
  begin
1667
    if FBufferPos<=ReadPosition then
2106
    if FBufferPos <= ReadPosition then
1668
      Result := ReadPosition - FBufferPos
2107
      Result := ReadPosition - FBufferPos
1669
    else
2108
    else
1670
      Result := FBufferSize - FBufferPos + ReadPosition;
2109
      Result := FBufferSize - FBufferPos + ReadPosition;
1671
  end else
2110
  end else
1672
    Result := 0;
2111
    Result := 0;
1673
end;
2112
end;
1674
 
2113
 
1675
function TSoundCaptureStream.ReadWave(var Buffer; Count: Integer): Integer;
2114
function TSoundCaptureStream.ReadWave(var Buffer; Count: Integer): Integer;
1676
var
2115
var
1677
  Size: Integer;
2116
  Size: Integer;
1678
  Data1, Data2: Pointer;
2117
  Data1, Data2: Pointer;
1679
  Data1Size, Data2Size: DWORD;
2118
  Data1Size, Data2Size: DWORD;
1680
  C: Byte;
2119
  C: Byte;
1681
begin
2120
begin
1682
  if not FCapturing then
2121
  if not FCapturing then
1683
    Start;
2122
    Start;
-
 
2123
  Data1 := nil;
1684
 
2124
  Data2 := nil;
1685
  Result := 0;
2125
  Result := 0;
1686
  while Result<Count do
2126
  while Result < Count do
1687
  begin
2127
  begin
1688
    Size := Min(Count-Result, GetReadSize);
2128
    Size := Min(Count - Result, GetReadSize);
1689
    if Size>0 then
2129
    if Size > 0 then
1690
    begin
2130
    begin
1691
      if FBuffer.Lock(FBufferPos, Size, Data1, Data1Size, Data2, Data2Size, 0)=DS_OK then
2131
      if FBuffer.Lock(FBufferPos, Size, Data1, {$IFNDEF DX7}@{$ENDIF}Data1Size,
-
 
2132
        Data2, {$IFNDEF DX7}@{$ENDIF}Data2Size, 0) = DS_OK then
1692
      begin
2133
      begin
1693
        Move(Data1^, Pointer(Integer(@Buffer)+Result)^, Data1Size);
2134
        Move(Data1^, Pointer(Integer(@Buffer) + Result)^, Data1Size);
1694
        Result := Result + Integer(Data1Size);
2135
        Result := Result + Integer(Data1Size);
1695
 
2136
 
1696
        if Data2<>nil then
2137
        if Data2 <> nil then
1697
        begin
2138
        begin
1698
          Move(Data2^, Pointer(Integer(@Buffer)+Result)^, Data2Size);
2139
          Move(Data2^, Pointer(Integer(@Buffer) + Result)^, Data2Size);
1699
          Result := Result + Integer(Data1Size);
2140
          Result := Result + Integer(Data1Size);
1700
        end;
2141
        end;
1701
 
2142
 
1702
        FBuffer.UnLock(Data1, Data1Size, Data2, Data2Size);
2143
        FBuffer.UnLock(Data1, Data1Size, Data2, Data2Size);
1703
        FBufferPos := (FBufferPos + Data1Size + Data2Size) mod FBufferSize;
2144
        FBufferPos := (FBufferPos + Data1Size + Data2Size) mod FBufferSize;
1704
      end else
2145
      end else
1705
        Break;
2146
        Break;
1706
    end;
2147
    end;
1707
    if Result<Count then Sleep(50);
2148
    if Result < Count then Sleep(50);
1708
  end;
2149
  end;
1709
 
2150
 
1710
  case Format^.wBitsPerSample of
2151
  case Format^.wBitsPerSample of
1711
     8: C := $80;
2152
    8: C := $80;
1712
    16: C := $00;
2153
    16: C := $00;
1713
  else
2154
  else
1714
    C := $00;
2155
    C := $00;
1715
  end;
2156
  end;
1716
 
2157
 
1717
  FillChar(Pointer(Integer(@Buffer)+Result)^, Count-Result, C);
2158
  FillChar(Pointer(Integer(@Buffer) + Result)^, Count - Result, C);
1718
  Result := Count;
2159
  Result := Count;
1719
end;
2160
end;
1720
 
2161
 
1721
procedure TSoundCaptureStream.SetBufferLength(Value: Integer);
2162
procedure TSoundCaptureStream.SetBufferLength(Value: Integer);
1722
begin
2163
begin
1723
  FBufferLength := Max(Value, 0);
2164
  FBufferLength := Max(Value, 0);
1724
end;
2165
end;
1725
 
2166
 
1726
procedure TSoundCaptureStream.SetOnFilledBuffer(Value: TNotifyEvent);
2167
procedure TSoundCaptureStream.SetOnFilledBuffer(Value: TNotifyEvent);
1727
begin
2168
begin
1728
  if CompareMem(@TMethod(FOnFilledBuffer), @TMethod(Value), SizeOf(TMethod)) then Exit;
2169
  if CompareMem(@TMethod(FOnFilledBuffer), @TMethod(Value), SizeOf(TMethod)) then Exit;
1729
 
2170
 
1730
  if FCapturing then
2171
  if FCapturing then
1731
  begin
2172
  begin
1732
    if Assigned(FOnFilledBuffer) then
2173
    if Assigned(FOnFilledBuffer) then
1733
      FNotifyThread.Free;
2174
      FNotifyThread.Free;
1734
 
2175
 
1735
    FOnFilledBuffer := Value;
2176
    FOnFilledBuffer := Value;
1736
 
2177
 
1737
    if Assigned(FOnFilledBuffer) then
2178
    if Assigned(FOnFilledBuffer) then
1738
    begin
2179
    begin
1739
      FNotifyThread := TSoundCaptureStreamNotify.Create(Self);
2180
      FNotifyThread := TSoundCaptureStreamNotify.Create(Self);
1740
      FNotifyThread.Resume;
2181
      FNotifyThread.Resume;
1741
    end;
2182
    end;
1742
  end else
2183
  end else
1743
    FOnFilledBuffer := Value;
2184
    FOnFilledBuffer := Value;
1744
end;
2185
end;
1745
 
2186
 
1746
procedure TSoundCaptureStream.Start;
2187
procedure TSoundCaptureStream.Start;
1747
var
2188
var
1748
  dscbd: TDSCBufferDesc;
2189
  dscbd: TDSCBufferDesc;
1749
begin
2190
begin
1750
  Stop;
2191
  Stop;
1751
  try
2192
  try
1752
    FCapturing := True;
2193
    FCapturing := True;
1753
 
2194
 
1754
    FormatSize := SizeOf(TWaveFormatEx);
2195
    FormatSize := SizeOf(TWaveFormatEx);
1755
    with FSupportedFormats[CaptureFormat] do
2196
    with FSupportedFormats[CaptureFormat] do
1756
      MakePCMWaveFormatEx(Format^, SamplesPerSec, BitsPerSample, Channels);
2197
      MakePCMWaveFormatEx(Format^, SamplesPerSec, BitsPerSample, Channels);
1757
 
2198
 
1758
    FBufferSize := Max(MulDiv(Format^.nAvgBytesPerSec, FBufferLength, 1000), 8000);
2199
    FBufferSize := Max(MulDiv(Format^.nAvgBytesPerSec, FBufferLength, 1000), 8000);
1759
 
2200
 
1760
    FillChar(dscbd, SizeOf(dscbd), 0);
2201
    FillChar(dscbd, SizeOf(dscbd), 0);
1761
    dscbd.dwSize := SizeOf(dscbd);
2202
    dscbd.dwSize := SizeOf(dscbd);
1762
    dscbd.dwBufferBytes := FBufferSize;
2203
    dscbd.dwBufferBytes := FBufferSize;
1763
    dscbd.lpwfxFormat := Format;
2204
    dscbd.lpwfxFormat := Format;
1764
 
2205
 
1765
    if FCapture.CreateCaptureBuffer(dscbd, FBuffer, nil)<>DS_OK then
2206
    if FCapture.CreateCaptureBuffer(dscbd, FBuffer, nil) <> DS_OK then
1766
      raise ESoundCaptureStreamError.CreateFmt(SCannotMade, [SDirectSoundCaptureBuffer]);
2207
      raise ESoundCaptureStreamError.CreateFmt(SCannotMade, [SDirectSoundCaptureBuffer]);
1767
 
2208
 
1768
    FBufferPos := 0;
2209
    FBufferPos := 0;
1769
 
2210
 
1770
    FBuffer.Start(DSCBSTART_LOOPING);
2211
    FBuffer.Start(DSCBSTART_LOOPING);
1771
 
2212
 
1772
    if Assigned(FOnFilledBuffer) then
2213
    if Assigned(FOnFilledBuffer) then
1773
    begin
2214
    begin
1774
      FNotifyThread := TSoundCaptureStreamNotify.Create(Self);
2215
      FNotifyThread := TSoundCaptureStreamNotify.Create(Self);
1775
      FNotifyThread.Resume;
2216
      FNotifyThread.Resume;
1776
    end;
2217
    end;
1777
  except
2218
  except
1778
    Stop;
2219
    Stop;
1779
    raise;
2220
    raise;
1780
  end;
2221
  end;
1781
end;
2222
end;
1782
 
2223
 
1783
procedure TSoundCaptureStream.Stop;
2224
procedure TSoundCaptureStream.Stop;
1784
begin
2225
begin
1785
  if FCapturing then
2226
  if FCapturing then
1786
  begin
2227
  begin
1787
    FNotifyThread.Free;
2228
    FNotifyThread.Free;
1788
    FCapturing := False;
2229
    FCapturing := False;
1789
    if FBuffer<>nil then
2230
    if FBuffer <> nil then
1790
      FBuffer.Stop;
2231
      FBuffer.Stop;
1791
    FBuffer := nil;
2232
    FBuffer := nil;
1792
  end;
2233
  end;
1793
end;
2234
end;
1794
 
2235
 
1795
{  TSoundEngine  }
2236
{  TSoundEngine  }
1796
 
2237
 
1797
constructor TSoundEngine.Create(ADSound: TDirectSound);
2238
constructor TSoundEngine.Create(ADSound: TDirectSound);
1798
begin
2239
begin
1799
  inherited Create;
2240
  inherited Create;
1800
  FDSound := ADSound;
2241
  FDSound := ADSound;
1801
  FEnabled := True;
2242
  FEnabled := True;
1802
 
2243
 
1803
 
-
 
1804
  FEffectList := TList.Create;
2244
  FEffectList := TList.Create;
1805
  FTimer := TTimer.Create(nil);
2245
  FTimer := TTimer.Create(nil);
1806
  FTimer.Interval := 500;
2246
  FTimer.Interval := 500;
1807
  FTimer.OnTimer := TimerEvent;
2247
  FTimer.OnTimer := TimerEvent;
1808
end;
2248
end;
1809
 
2249
 
1810
destructor TSoundEngine.Destroy;
2250
destructor TSoundEngine.Destroy;
1811
begin
2251
begin
1812
  Clear;
2252
  Clear;
1813
  FTimer.Free;
2253
  FTimer.Free;
1814
  FEffectList.Free;
2254
  FEffectList.Free;
1815
  inherited Destroy;
2255
  inherited Destroy;
1816
end;
2256
end;
1817
 
2257
 
1818
procedure TSoundEngine.Clear;
2258
procedure TSoundEngine.Clear;
1819
var
2259
var
1820
  i: Integer;
2260
  i: Integer;
1821
begin
2261
begin
1822
  for i:=EffectCount-1 downto 0 do
2262
  for i := EffectCount - 1 downto 0 do
1823
    Effects[i].Free;
2263
    Effects[i].Free;
1824
  FEffectList.Clear;
2264
  FEffectList.Clear;
1825
end;
2265
end;
1826
 
2266
 
1827
procedure TSoundEngine.EffectFile(const Filename: string; Loop, Wait: Boolean);
2267
procedure TSoundEngine.EffectFile(const Filename: string; Loop, Wait: Boolean);
1828
var
2268
var
1829
  Stream : TFileStream;
2269
  Stream: TFileStream;
1830
begin
2270
begin
1831
  Stream :=TFileStream.Create(Filename, fmOpenRead);
2271
  Stream := TFileStream.Create(Filename, fmOpenRead);
1832
  try
2272
  try
1833
    EffectStream(Stream, Loop, Wait);
2273
    EffectStream(Stream, Loop, Wait);
1834
  finally
2274
  finally
1835
    Stream.Free;
2275
    Stream.Free;
1836
  end;
2276
  end;
1837
end;
2277
end;
1838
 
2278
 
1839
procedure TSoundEngine.EffectStream(Stream: TStream; Loop, Wait: Boolean);
2279
procedure TSoundEngine.EffectStream(Stream: TStream; Loop, Wait: Boolean);
1840
var
2280
var
1841
  Wave: TWave;
2281
  Wave: TWave;
1842
begin
2282
begin
1843
  Wave := TWave.Create;
2283
  Wave := TWave.Create;
1844
  try
2284
  try
1845
    Wave.LoadfromStream(Stream);
2285
    Wave.LoadfromStream(Stream);
1846
    EffectWave(Wave, Loop, Wait);
2286
    EffectWave(Wave, Loop, Wait);
1847
  finally
2287
  finally
1848
    Wave.Free;
2288
    Wave.Free;
1849
  end;
2289
  end;
1850
end;
2290
end;
1851
 
2291
 
1852
procedure TSoundEngine.EffectWave(Wave: TWave; Loop, Wait: Boolean);
2292
procedure TSoundEngine.EffectWave(Wave: TWave; Loop, Wait: Boolean);
1853
var
2293
var
1854
  Buffer: TDirectSoundBuffer;
2294
  Buffer: TDirectSoundBuffer;
1855
begin
2295
begin
1856
  if not FEnabled then Exit;
2296
  if not FEnabled then Exit;
1857
 
2297
 
1858
  if Wait then
2298
  if Wait then
1859
  begin
2299
  begin
1860
    Buffer := TDirectSoundBuffer.Create(FDSound);
2300
    Buffer := TDirectSoundBuffer.Create(FDSound);
1861
    try
2301
    try
1862
      Buffer.LoadFromWave(Wave);
2302
      Buffer.LoadFromWave(Wave);
1863
      Buffer.Play(False);
2303
      Buffer.Play(False);
1864
      while Buffer.Playing do
2304
      while Buffer.Playing do
1865
        Sleep(1);
2305
        Sleep(1);
1866
    finally
2306
    finally
1867
      Buffer.Free;
2307
      Buffer.Free;
1868
    end;
2308
    end;
1869
  end else
2309
  end else
1870
  begin
2310
  begin
1871
    Buffer := TDirectSoundBuffer.Create(FDSound);
2311
    Buffer := TDirectSoundBuffer.Create(FDSound);
1872
    try
2312
    try
1873
      Buffer.LoadFromWave(Wave);
2313
      Buffer.LoadFromWave(Wave);
1874
      Buffer.Play(Loop);
2314
      Buffer.Play(Loop);
1875
    except
2315
    except
1876
      Buffer.Free;
2316
      Buffer.Free;
1877
      raise;
2317
      raise;
1878
    end;
2318
    end;
1879
    FEffectList.Add(Buffer);
2319
    FEffectList.Add(Buffer);
1880
  end;
2320
  end;
1881
end;
2321
end;
1882
 
2322
 
1883
function TSoundEngine.GetEffect(Index: Integer): TDirectSoundBuffer;
2323
function TSoundEngine.GetEffect(Index: Integer): TDirectSoundBuffer;
1884
begin
2324
begin
1885
  Result := TDirectSoundBuffer(FEffectList[Index]);
2325
  Result := TDirectSoundBuffer(FEffectList[Index]);
1886
end;
2326
end;
1887
 
2327
 
1888
function TSoundEngine.GetEffectCount: Integer;
2328
function TSoundEngine.GetEffectCount: Integer;
1889
begin
2329
begin
1890
  Result := FEffectList.Count;
2330
  Result := FEffectList.Count;
1891
end;
2331
end;
1892
 
2332
 
1893
procedure TSoundEngine.SetEnabled(Value: Boolean);
2333
procedure TSoundEngine.SetEnabled(Value: Boolean);
1894
var
2334
var
1895
  i: Integer;
2335
  i: Integer;
1896
begin
2336
begin
1897
  for i:=EffectCount-1 downto 0 do
2337
  for i := EffectCount - 1 downto 0 do
1898
    Effects[i].Free;
2338
    Effects[i].Free;
1899
  FEffectList.Clear;
2339
  FEffectList.Clear;
1900
 
2340
 
1901
  FEnabled := Value;
2341
  FEnabled := Value;
1902
  FTimer.Enabled := Value;
2342
  FTimer.Enabled := Value;
1903
end;
2343
end;
1904
 
2344
 
1905
procedure TSoundEngine.TimerEvent(Sender: TObject);
2345
procedure TSoundEngine.TimerEvent(Sender: TObject);
1906
var
2346
var
1907
  i: Integer;
2347
  i: Integer;
1908
begin
2348
begin
1909
  for i:=EffectCount-1 downto 0 do
2349
  for i := EffectCount - 1 downto 0 do
1910
    if not TDirectSoundBuffer(FEffectList[i]).Playing then
2350
    if not TDirectSoundBuffer(FEffectList[i]).Playing then
1911
    begin
2351
    begin
1912
      TDirectSoundBuffer(FEffectList[i]).Free;
2352
      TDirectSoundBuffer(FEffectList[i]).Free;
1913
      FEffectList.Delete(i);
2353
      FEffectList.Delete(i);
1914
    end;
2354
    end;
1915
end;
2355
end;
1916
 
2356
 
1917
{  TCustomDXSound  }
2357
{  TCustomDXSound  }
1918
 
2358
 
1919
type
2359
type
1920
  TDXSoundDirectSound = class(TDirectSound)
2360
  TDXSoundDirectSound = class(TDirectSound)
1921
  private
2361
  private
1922
    FDXSound: TCustomDXSound;
2362
    FDXSound: TCustomDXSound;
1923
  protected
2363
  protected
1924
    procedure DoRestoreBuffer; override;
2364
    procedure DoRestoreBuffer; override;
1925
  end;
2365
  end;
1926
 
2366
 
1927
procedure TDXSoundDirectSound.DoRestoreBuffer;
2367
procedure TDXSoundDirectSound.DoRestoreBuffer;
1928
begin
2368
begin
1929
  inherited DoRestoreBuffer;
2369
  inherited DoRestoreBuffer;
1930
  FDXSound.Restore;
2370
  FDXSound.Restore;
1931
end;
2371
end;
1932
 
2372
 
1933
constructor TCustomDXSound.Create(AOwner: TComponent);
2373
constructor TCustomDXSound.Create(AOwner: TComponent);
1934
begin
2374
begin
1935
  FNotifyEventList := TList.Create;
2375
  FNotifyEventList := TList.Create;
1936
  inherited Create(AOwner);
2376
  inherited Create(AOwner);
1937
  FAutoInitialize := True;
2377
  FAutoInitialize := True;
1938
  Options := [];
2378
  Options := [];
1939
end;
2379
end;
1940
 
2380
 
1941
destructor TCustomDXSound.Destroy;
2381
destructor TCustomDXSound.Destroy;
1942
begin
2382
begin
1943
  Finalize;
2383
  Finalize;
1944
  NotifyEventList(dsntDestroying);
2384
  NotifyEventList(dsntDestroying);
1945
  FNotifyEventList.Free;
2385
  FNotifyEventList.Free;
1946
  inherited Destroy;
2386
  inherited Destroy;
1947
end;
2387
end;
1948
 
2388
 
1949
type
2389
type
1950
  PDXSoundNotifyEvent = ^TDXSoundNotifyEvent;
2390
  PDXSoundNotifyEvent = ^TDXSoundNotifyEvent;
1951
 
2391
 
1952
procedure TCustomDXSound.RegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
2392
procedure TCustomDXSound.RegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
1953
var
2393
var
1954
  Event: PDXSoundNotifyEvent;
2394
  Event: PDXSoundNotifyEvent;
1955
begin
2395
begin
1956
  UnRegisterNotifyEvent(NotifyEvent);
2396
  UnRegisterNotifyEvent(NotifyEvent);
1957
 
2397
 
1958
  New(Event);
2398
  New(Event);
1959
  Event^ := NotifyEvent;
2399
  Event^ := NotifyEvent;
1960
  FNotifyEventList.Add(Event);
2400
  FNotifyEventList.Add(Event);
1961
 
2401
 
1962
  if Initialized then
2402
  if Initialized then
1963
  begin
2403
  begin
1964
    NotifyEvent(Self, dsntInitialize);
2404
    NotifyEvent(Self, dsntInitialize);
1965
    NotifyEvent(Self, dsntRestore);
2405
    NotifyEvent(Self, dsntRestore);
1966
  end;
2406
  end;
1967
end;
2407
end;
1968
 
2408
 
1969
procedure TCustomDXSound.UnRegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
2409
procedure TCustomDXSound.UnRegisterNotifyEvent(NotifyEvent: TDXSoundNotifyEvent);
1970
var
2410
var
1971
  Event: PDXSoundNotifyEvent;
2411
  Event: PDXSoundNotifyEvent;
1972
  i: Integer;
2412
  i: Integer;
1973
begin
2413
begin
1974
  for i:=0 to FNotifyEventList.Count-1 do
2414
  for i := 0 to FNotifyEventList.Count - 1 do
1975
  begin
2415
  begin
1976
    Event := FNotifyEventList[i];
2416
    Event := FNotifyEventList[i];
1977
    if (TMethod(Event^).Code = TMethod(NotifyEvent).Code) and
2417
    if (TMethod(Event^).Code = TMethod(NotifyEvent).Code) and
1978
      (TMethod(Event^).Data = TMethod(NotifyEvent).Data) then
2418
      (TMethod(Event^).Data = TMethod(NotifyEvent).Data) then
1979
    begin
2419
    begin
1980
      Dispose(Event);
2420
      Dispose(Event);
1981
      FNotifyEventList.Delete(i);
2421
      FNotifyEventList.Delete(i);
1982
 
2422
 
1983
      if Initialized then
2423
      if Initialized then
1984
        NotifyEvent(Self, dsntFinalize);
2424
        NotifyEvent(Self, dsntFinalize);
1985
 
2425
 
1986
      Break;
2426
      Break;
1987
    end;
2427
    end;
1988
  end;
2428
  end;
1989
end;
2429
end;
1990
 
2430
 
1991
procedure TCustomDXSound.NotifyEventList(NotifyType: TDXSoundNotifyType);
2431
procedure TCustomDXSound.NotifyEventList(NotifyType: TDXSoundNotifyType);
1992
var
2432
var
1993
  i: Integer;
2433
  i: Integer;
1994
begin
2434
begin
1995
  for i:=FNotifyEventList.Count-1 downto 0 do
2435
  for i := FNotifyEventList.Count - 1 downto 0 do
1996
    PDXSoundNotifyEvent(FNotifyEventList[i])^(Self, NotifyType);
2436
    PDXSoundNotifyEvent(FNotifyEventList[i])^(Self, NotifyType);
1997
end;
2437
end;
1998
 
2438
 
1999
procedure TCustomDXSound.FormWndProc(var Message: TMessage; DefWindowProc: TWndMethod);
2439
procedure TCustomDXSound.FormWndProc(var Message: TMessage; DefWindowProc: TWndMethod);
2000
begin
2440
begin
2001
  case Message.Msg of
2441
  case Message.Msg of
2002
    WM_CREATE:
2442
    WM_CREATE:
2003
        begin
2443
      begin
2004
          DefWindowProc(Message);
2444
        DefWindowProc(Message);
2005
          SetForm(FForm);
2445
        SetForm(FForm);
2006
          Exit;
2446
        Exit;
2007
        end;
2447
      end;
2008
  end;
2448
  end;
2009
  DefWindowProc(Message);
2449
  DefWindowProc(Message);
2010
end;
2450
end;
2011
 
2451
 
2012
class function TCustomDXSound.Drivers: TDirectXDrivers;
2452
class function TCustomDXSound.Drivers: TDirectXDrivers;
2013
begin
2453
begin
2014
  Result := EnumDirectSoundDrivers;
2454
  Result := EnumDirectSoundDrivers;
2015
end;
2455
end;
2016
 
2456
 
2017
procedure TCustomDXSound.DoFinalize;
2457
procedure TCustomDXSound.DoFinalize;
2018
begin
2458
begin
2019
  if Assigned(FOnFinalize) then FOnFinalize(Self);
2459
  if Assigned(FOnFinalize) then FOnFinalize(Self);
2020
end;
2460
end;
2021
 
2461
 
2022
procedure TCustomDXSound.DoInitialize;
2462
procedure TCustomDXSound.DoInitialize;
2023
begin
2463
begin
2024
  if Assigned(FOnInitialize) then FOnInitialize(Self);
2464
  if Assigned(FOnInitialize) then FOnInitialize(Self);
2025
end;
2465
end;
2026
 
2466
 
2027
procedure TCustomDXSound.DoInitializing;
2467
procedure TCustomDXSound.DoInitializing;
2028
begin
2468
begin
2029
  if Assigned(FOnInitializing) then FOnInitializing(Self);
2469
  if Assigned(FOnInitializing) then FOnInitializing(Self);
2030
end;
2470
end;
2031
 
2471
 
2032
procedure TCustomDXSound.DoRestore;
2472
procedure TCustomDXSound.DoRestore;
2033
begin
2473
begin
2034
  if Assigned(FOnRestore) then FOnRestore(Self);
2474
  if Assigned(FOnRestore) then FOnRestore(Self);
2035
end;
2475
end;
2036
 
2476
 
2037
procedure TCustomDXSound.Finalize;
2477
procedure TCustomDXSound.Finalize;
2038
begin
2478
begin
2039
  if FInternalInitialized then
2479
  if FInternalInitialized then
2040
  begin
2480
  begin
2041
    try
2481
    try
2042
      FSubClass.Free; FSubClass := nil;
2482
      FSubClass.Free; FSubClass := nil;
2043
 
2483
 
2044
      try
2484
      try
2045
        if FCalledDoInitialize then
2485
        if FCalledDoInitialize then
2046
        begin
2486
        begin
2047
          FCalledDoInitialize := False;
2487
          FCalledDoInitialize := False;
2048
          DoFinalize;
2488
          DoFinalize;
2049
        end;
2489
        end;
2050
      finally
2490
      finally
2051
        NotifyEventList(dsntFinalize);
2491
        NotifyEventList(dsntFinalize);
2052
      end;
2492
      end;
2053
    finally
2493
    finally
2054
      FInitialized := False;
2494
      FInitialized := False;
2055
      FInternalInitialized := False;
2495
      FInternalInitialized := False;
2056
 
2496
 
2057
      SetOptions(FOptions);
2497
      SetOptions(FOptions);
2058
 
2498
 
2059
      FPrimary.Free; FPrimary := nil;
2499
      FPrimary.Free; FPrimary := nil;
2060
      FDSound.Free;  FDSound := nil;
2500
      FDSound.Free; FDSound := nil;
2061
    end;
2501
    end;
2062
  end;
2502
  end;
2063
end;
2503
end;
2064
 
2504
 
2065
procedure TCustomDXSound.Initialize;
2505
procedure TCustomDXSound.Initialize;
2066
const
2506
const
2067
  PrimaryDesc: TDSBufferDesc = (
2507
  PrimaryDesc: TDSBufferDesc = (
2068
      dwSize: SizeOf (PrimaryDesc);
2508
    dwSize: SizeOf(PrimaryDesc);
2069
      dwFlags: DSBCAPS_PRIMARYBUFFER);
2509
    dwFlags: DSBCAPS_PRIMARYBUFFER);
2070
var
2510
var
2071
  Component: TComponent;
2511
  Component: TComponent;
2072
begin
2512
begin
2073
  Finalize;
2513
  Finalize;
2074
 
2514
 
2075
  Component := Owner;
2515
  Component := Owner;
2076
  while (Component<>nil) and (not (Component is TCustomForm)) do
2516
  while (Component <> nil) and (not (Component is TCustomForm)) do
2077
    Component := Component.Owner;
2517
    Component := Component.Owner;
2078
  if Component=nil then
2518
  if Component = nil then
2079
    raise EDXSoundError.Create(SNoForm);
2519
    raise EDXSoundError.Create(SNoForm);
2080
 
2520
 
2081
  NotifyEventList(dsntInitializing);
2521
  NotifyEventList(dsntInitializing);
2082
  DoInitializing;
2522
  DoInitializing;
2083
 
2523
 
2084
  FInternalInitialized := True;
2524
  FInternalInitialized := True;
2085
  try
2525
  try
2086
    {  DirectSound initialization.  }
2526
    {  DirectSound initialization.  }
2087
    FDSound := TDXSoundDirectSound.Create(Driver);
2527
    FDSound := TDXSoundDirectSound.Create(Driver);
2088
    TDXSoundDirectSound(FDSound).FDXSound := Self;
2528
    TDXSoundDirectSound(FDSound).FDXSound := Self;
2089
 
2529
 
2090
    FDSound.FGlobalFocus := soGlobalFocus in FNowOptions;
2530
    FDSound.FGlobalFocus := soGlobalFocus in FNowOptions;
2091
 
2531
 
2092
    {  Primary buffer made.  }
2532
    {  Primary buffer made.  }
2093
    FPrimary := TDirectSoundBuffer.Create(FDSound);
2533
    FPrimary := TDirectSoundBuffer.Create(FDSound);
2094
    if not FPrimary.CreateBuffer(PrimaryDesc) then
2534
    if not FPrimary.CreateBuffer(PrimaryDesc) then
2095
      raise EDXSoundError.CreateFmt(SCannotMade, [SDirectSoundPrimaryBuffer]);
2535
      raise EDXSoundError.CreateFmt(SCannotMade, [SDirectSoundPrimaryBuffer]);
2096
 
2536
 
2097
    FInitialized := True;
2537
    FInitialized := True;
2098
 
2538
 
2099
    SetForm(TCustomForm(Component));
2539
    SetForm(TCustomForm(Component));
2100
  except
2540
  except
2101
    Finalize;
2541
    Finalize;
2102
    raise;
2542
    raise;
2103
  end;
2543
  end;
2104
 
2544
 
2105
  NotifyEventList(dsntInitialize);
2545
  NotifyEventList(dsntInitialize);
2106
 
2546
 
2107
  FCalledDoInitialize := True; DoInitialize;
2547
  FCalledDoInitialize := True; DoInitialize;
2108
 
2548
 
2109
  Restore;
2549
  Restore;
2110
end;
2550
end;
2111
 
2551
 
2112
procedure TCustomDXSound.Loaded;
2552
procedure TCustomDXSound.Loaded;
2113
begin
2553
begin
2114
  inherited Loaded;
2554
  inherited Loaded;
2115
 
2555
 
2116
  if FAutoInitialize and (not (csDesigning in ComponentState)) then
2556
  if FAutoInitialize and (not (csDesigning in ComponentState)) then
2117
  begin
2557
  begin
2118
    try
2558
    try
2119
      Initialize;
2559
      Initialize;
2120
    except
2560
    except
2121
      on E: EDirectSoundError do ;
2561
      on E: EDirectSoundError do ;
2122
      else raise;
2562
    else raise;
2123
    end;
2563
    end;
2124
  end;
2564
  end;
2125
end;
2565
end;
2126
 
2566
 
2127
procedure TCustomDXSound.Restore;
2567
procedure TCustomDXSound.Restore;
2128
begin
2568
begin
2129
  if FInitialized then
2569
  if FInitialized then
2130
  begin
2570
  begin
2131
    NotifyEventList(dsntRestore);
2571
    NotifyEventList(dsntRestore);
2132
    DoRestore;
2572
    DoRestore;
2133
  end;
2573
  end;
2134
end;
2574
end;
2135
 
2575
 
2136
procedure TCustomDXSound.SetDriver(Value: PGUID);
2576
procedure TCustomDXSound.SetDriver(Value: PGUID);
2137
begin
2577
begin
2138
  if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
2578
  if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
2139
  begin
2579
  begin
2140
    FDriverGUID := Value^;
2580
    FDriverGUID := Value^;
2141
    FDriver := @FDriverGUID;
2581
    FDriver := @FDriverGUID;
2142
  end else
2582
  end else
2143
    FDriver := Value;
2583
    FDriver := Value;
2144
end;
2584
end;
2145
 
2585
 
2146
procedure TCustomDXSound.SetForm(Value: TCustomForm);
2586
procedure TCustomDXSound.SetForm(Value: TCustomForm);
2147
var
2587
var
2148
  Level: Integer;
2588
  Level: Integer;
2149
begin
2589
begin
2150
  FForm := Value;
2590
  FForm := Value;
2151
 
2591
 
2152
  FSubClass.Free;
2592
  FSubClass.Free;
2153
  FSubClass := TControlSubClass.Create(FForm, FormWndProc);
2593
  FSubClass := TControlSubClass.Create(FForm, FormWndProc);
2154
 
2594
 
2155
  if FInitialized then
2595
  if FInitialized then
2156
  begin
2596
  begin
2157
    if soExclusive in FNowOptions then
2597
    if soExclusive in FNowOptions then
2158
      Level := DSSCL_EXCLUSIVE
2598
      Level := DSSCL_EXCLUSIVE
2159
    else
2599
    else
2160
      Level := DSSCL_NORMAL;
2600
      Level := DSSCL_NORMAL;
2161
 
2601
 
2162
    FDSound.DXResult := FDSound.ISound.SetCooperativeLevel(FForm.Handle, Level);
2602
    FDSound.DXResult := FDSound.ISound.SetCooperativeLevel(FForm.Handle, Level);
2163
  end;
2603
  end;
2164
end;
2604
end;
2165
 
2605
 
2166
procedure TCustomDXSound.SetOptions(Value: TDXSoundOptions);
2606
procedure TCustomDXSound.SetOptions(Value: TDXSoundOptions);
2167
const
2607
const
2168
  DXSoundOptions = [soGlobalFocus, soStickyFocus, soExclusive];
2608
  DXSoundOptions = [soGlobalFocus, soStickyFocus, soExclusive];
2169
  InitOptions: TDXSoundOptions = [soExclusive];
2609
  InitOptions: TDXSoundOptions = [soExclusive];
2170
var
2610
var
2171
  OldOptions: TDXSoundOptions;
2611
  OldOptions: TDXSoundOptions;
2172
begin
2612
begin
2173
  FOptions := Value;
2613
  FOptions := Value;
2174
 
2614
 
2175
  if Initialized then
2615
  if Initialized then
2176
  begin
2616
  begin
2177
    OldOptions := FNowOptions;
2617
    OldOptions := FNowOptions;
2178
 
2618
 
2179
    FNowOptions := (FNowOptions - (DXSoundOptions - InitOptions)) +
2619
    FNowOptions := (FNowOptions - (DXSoundOptions - InitOptions)) +
2180
      (Value - InitOptions);
2620
      (Value - InitOptions);
2181
 
2621
 
2182
    FDSound.FGlobalFocus := soGlobalFocus in FNowOptions;
2622
    FDSound.FGlobalFocus := soGlobalFocus in FNowOptions;
2183
    FDSound.FStickyFocus := soStickyFocus in FNowOptions;
2623
    FDSound.FStickyFocus := soStickyFocus in FNowOptions;
2184
  end else
2624
  end else
2185
    FNowOptions := FOptions;
2625
    FNowOptions := FOptions;
2186
end;
2626
end;
2187
 
2627
 
2188
{  TWaveCollectionItem  }
2628
{  TWaveCollectionItem  }
2189
 
2629
 
2190
constructor TWaveCollectionItem.Create(Collection: TCollection);
2630
constructor TWaveCollectionItem.Create(Collection: TCollection);
2191
begin
2631
begin
2192
  inherited Create(Collection);
2632
  inherited Create(Collection);
2193
  FWave := TWave.Create;
2633
  FWave := TWave.Create;
2194
  FBufferList := TList.Create;
2634
  FBufferList := TList.Create;
2195
end;
2635
end;
2196
 
2636
 
2197
destructor TWaveCollectionItem.Destroy;
2637
destructor TWaveCollectionItem.Destroy;
2198
begin
2638
begin
2199
  Finalize;
2639
  Finalize;
2200
  FWave.Free;
2640
  FWave.Free;
2201
  FBufferList.Free;
2641
  FBufferList.Free;
2202
  inherited Destroy;
2642
  inherited Destroy;
2203
end;
2643
end;
2204
 
2644
 
2205
procedure TWaveCollectionItem.Assign(Source: TPersistent);
2645
procedure TWaveCollectionItem.Assign(Source: TPersistent);
2206
var
2646
var
2207
  PrevInitialized: Boolean;
2647
  PrevInitialized: Boolean;
2208
begin
2648
begin
2209
  if Source is TWaveCollectionItem then
2649
  if Source is TWaveCollectionItem then
2210
  begin
2650
  begin
2211
    PrevInitialized := Initialized;
2651
    PrevInitialized := Initialized;
2212
    Finalize;
2652
    Finalize;
2213
 
2653
 
2214
    FLooped := TWaveCollectionItem(Source).FLooped;
2654
    FLooped := TWaveCollectionItem(Source).FLooped;
2215
    Name := TWaveCollectionItem(Source).Name;
2655
    Name := TWaveCollectionItem(Source).Name;
2216
    FMaxPlayingCount := TWaveCollectionItem(Source).FMaxPlayingCount;
2656
    FMaxPlayingCount := TWaveCollectionItem(Source).FMaxPlayingCount;
2217
 
2657
 
2218
    FFrequency := TWaveCollectionItem(Source).FFrequency;
2658
    FFrequency := TWaveCollectionItem(Source).FFrequency;
2219
    FPan := TWaveCollectionItem(Source).FPan;
2659
    FPan := TWaveCollectionItem(Source).FPan;
2220
    FVolume := TWaveCollectionItem(Source).FVolume;
2660
    FVolume := TWaveCollectionItem(Source).FVolume;
2221
 
2661
 
2222
    FWave.Assign(TWaveCollectionItem(Source).FWave);
2662
    FWave.Assign(TWaveCollectionItem(Source).FWave);
2223
 
2663
 
2224
    if PrevInitialized then
2664
    if PrevInitialized then
2225
      Restore;
2665
      Restore;
-
 
2666
  end
2226
  end else
2667
  else
2227
    inherited Assign(Source);
2668
    inherited Assign(Source);
2228
end;                        
2669
end;
2229
 
2670
 
-
 
2671
function TWaveCollectionItem.GetPlaying: boolean;
-
 
2672
var
-
 
2673
  Buffer: TDirectSoundBuffer;
-
 
2674
  index: integer;
-
 
2675
begin
-
 
2676
  Result := False;
-
 
2677
  if not FInitialized then Exit;
-
 
2678
  Assert(GetBuffer <> nil);
-
 
2679
  Assert(FBufferList <> nil);
-
 
2680
  if FLooped then
-
 
2681
  begin
-
 
2682
    Buffer := GetBuffer;
-
 
2683
    Assert(Buffer <> nil);
-
 
2684
    Result := Buffer.Playing;
-
 
2685
  end
-
 
2686
  else
-
 
2687
  begin
-
 
2688
    for index := 0 to FBufferList.Count - 1 do
-
 
2689
    begin
-
 
2690
      Result := TDirectSoundBuffer(FBufferList[index]).Playing;
-
 
2691
      if Result then
-
 
2692
        Break;
-
 
2693
    end;
-
 
2694
  end;
-
 
2695
end; {GetPlaying}
-
 
2696
 
2230
function TWaveCollectionItem.GetBuffer: TDirectSoundBuffer;
2697
function TWaveCollectionItem.GetBuffer: TDirectSoundBuffer;
2231
begin
2698
begin
2232
  if FInitialized and (FBuffer=nil) then
2699
  if FInitialized and (FBuffer = nil) then
2233
    Restore;
2700
    Restore;
2234
  Result := FBuffer;
2701
  Result := FBuffer;
2235
end;
2702
end;
2236
 
2703
 
2237
function TWaveCollectionItem.GetWaveCollection: TWaveCollection;
2704
function TWaveCollectionItem.GetWaveCollection: TWaveCollection;
2238
begin
2705
begin
2239
  Result := Collection as TWaveCollection;
2706
  Result := Collection as TWaveCollection;
2240
end;
2707
end;
2241
 
2708
 
2242
procedure TWaveCollectionItem.Finalize;
2709
procedure TWaveCollectionItem.Finalize;
2243
var
2710
var
2244
  i: Integer;
2711
  i: Integer;
2245
begin
2712
begin
2246
  if not FInitialized then Exit;
2713
  if not FInitialized then Exit;
2247
  FInitialized := False;
2714
  FInitialized := False;
2248
 
2715
 
2249
  for i:=0 to FBufferList.Count-1 do
2716
  for i := 0 to FBufferList.Count - 1 do
2250
    TDirectSoundBuffer(FBufferList[i]).Free;
2717
    TDirectSoundBuffer(FBufferList[i]).Free;
2251
  FBufferList.Clear;
2718
  FBufferList.Clear;
2252
  FBuffer.Free; FBuffer := nil;
2719
  FBuffer.Free; FBuffer := nil;
2253
end;
2720
end;
2254
 
2721
 
2255
procedure TWaveCollectionItem.Initialize;
2722
procedure TWaveCollectionItem.Initialize;
2256
begin
2723
begin
2257
  Finalize;
2724
  Finalize;
2258
  FInitialized := WaveCollection.Initialized;
2725
  FInitialized := WaveCollection.Initialized;
2259
end;
2726
end;
2260
 
2727
 
2261
function TWaveCollectionItem.CreateBuffer: TDirectSoundBuffer;
2728
function TWaveCollectionItem.CreateBuffer: TDirectSoundBuffer;
2262
begin
2729
begin
2263
  Result := nil;
2730
  Result := nil;
2264
  if GetBuffer=nil then Exit;
2731
  if GetBuffer = nil then Exit;
2265
 
2732
 
2266
  Result := TDirectSoundBuffer.Create(WaveCollection.DXSound.DSound);
2733
  Result := TDirectSoundBuffer.Create(WaveCollection.DXSound.DSound);
2267
  try
2734
  try
2268
    Result.Assign(GetBuffer);
2735
    Result.Assign(GetBuffer);
2269
  except
2736
  except
2270
    Result.Free;
2737
    Result.Free;
2271
    raise;
2738
    raise;
2272
  end;
2739
  end;
2273
end;
2740
end;
2274
 
2741
 
2275
procedure TWaveCollectionItem.Play(Wait: Boolean);
2742
procedure TWaveCollectionItem.Play(Wait: Boolean);
2276
var
2743
var
2277
  NewBuffer: TDirectSoundBuffer;
2744
  NewBuffer: TDirectSoundBuffer;
2278
  i: Integer;
2745
  i: Integer;
2279
begin
2746
begin
2280
  if not FInitialized then Exit;
2747
  if not FInitialized then Exit;
2281
 
2748
 
2282
  if FLooped then
2749
  if FLooped then
2283
  begin
2750
  begin
2284
    GetBuffer.Stop;
2751
    GetBuffer.Stop;
2285
    GetBuffer.Position := 0;
2752
    GetBuffer.Position := 0;
2286
    GetBuffer.Play(True);
2753
    GetBuffer.Play(True);
-
 
2754
  end
2287
  end else
2755
  else
2288
  begin
2756
  begin
2289
    NewBuffer := nil;
2757
    NewBuffer := nil;
2290
    for i:=0 to FBufferList.Count-1  do
2758
    for i := 0 to FBufferList.Count - 1 do
2291
      if not TDirectSoundBuffer(FBufferList[i]).Playing then
2759
      if not TDirectSoundBuffer(FBufferList[i]).Playing then
2292
      begin
2760
      begin
2293
        NewBuffer := FBufferList[i];
2761
        NewBuffer := FBufferList[i];
2294
        Break;
2762
        Break;
2295
      end;
2763
      end;
2296
                 
2764
 
2297
    if NewBuffer=nil then
2765
    if NewBuffer = nil then
2298
    begin
2766
    begin
2299
      if FMaxPlayingCount=0 then
2767
      if FMaxPlayingCount = 0 then
2300
      begin
2768
      begin
2301
        NewBuffer := CreateBuffer;
2769
        NewBuffer := CreateBuffer;
2302
        if NewBuffer=nil then Exit;
2770
        if NewBuffer = nil then Exit;
2303
 
2771
 
2304
        FBufferList.Add(NewBuffer);
2772
        FBufferList.Add(NewBuffer);
-
 
2773
      end
2305
      end else
2774
      else
2306
      begin
2775
      begin
2307
        if FBufferList.Count<FMaxPlayingCount then
2776
        if FBufferList.Count < FMaxPlayingCount then
2308
        begin
2777
        begin
2309
          NewBuffer := CreateBuffer;
2778
          NewBuffer := CreateBuffer;
2310
          if NewBuffer=nil then Exit;
2779
          if NewBuffer = nil then Exit;
2311
 
2780
 
2312
          FBufferList.Add(NewBuffer);
2781
          FBufferList.Add(NewBuffer);
-
 
2782
        end
2313
        end else
2783
        else
2314
        begin
2784
        begin
2315
          NewBuffer := FBufferList[0];
2785
          NewBuffer := FBufferList[0];
2316
          FBufferList.Move(0, FBufferList.Count-1);
2786
          FBufferList.Move(0, FBufferList.Count - 1);
2317
        end;
2787
        end;
2318
      end;
2788
      end;
2319
    end;
2789
    end;
2320
 
2790
 
2321
    NewBuffer.Stop;
2791
    NewBuffer.Stop;
2322
    NewBuffer.Position := 0;
2792
    NewBuffer.Position := 0;
2323
    NewBuffer.Frequency := FFrequency;
2793
    NewBuffer.Frequency := FFrequency;
2324
    NewBuffer.Pan := FPan;
2794
    NewBuffer.Pan := FPan;
2325
    NewBuffer.Volume := FVolume;
2795
    NewBuffer.Volume := FVolume;
2326
    NewBuffer.Play(False);
2796
    NewBuffer.Play(False);
2327
 
2797
 
2328
    if Wait then
2798
    if Wait then
2329
    begin
2799
    begin
2330
      while NewBuffer.Playing do
2800
      while NewBuffer.Playing do
2331
        Sleep(10);
2801
        Sleep(10);
2332
    end;
2802
    end;
2333
  end;
2803
  end;
2334
end;
2804
end;
2335
 
2805
 
2336
procedure TWaveCollectionItem.Restore;
2806
procedure TWaveCollectionItem.Restore;
2337
begin
2807
begin
2338
  if FWave.Size=0 then Exit;
2808
  if FWave.Size = 0 then Exit;
2339
 
2809
 
2340
  if not FInitialized then
2810
  if not FInitialized then
2341
  begin
2811
  begin
2342
    if WaveCollection.Initialized then
2812
    if WaveCollection.Initialized then
2343
      Initialize;
2813
      Initialize;
2344
    if not FInitialized then Exit;
2814
    if not FInitialized then Exit;
2345
  end;
2815
  end;
2346
 
2816
 
2347
  if FBuffer=nil then
2817
  if FBuffer = nil then
2348
    FBuffer := TDirectSoundBuffer.Create(WaveCollection.DXSound.DSound);
2818
    FBuffer := TDirectSoundBuffer.Create(WaveCollection.DXSound.DSound);
2349
 
2819
 
2350
  FBuffer.LoadFromWave(FWave);
2820
  FBuffer.LoadFromWave(FWave);
2351
  FBuffer.Frequency := FFrequency;
2821
  FBuffer.Frequency := FFrequency;
2352
  FBuffer.Pan := FPan;
2822
  FBuffer.Pan := FPan;
2353
  FBuffer.Volume := FVolume;
2823
  FBuffer.Volume := FVolume;
2354
end;
2824
end;
2355
 
2825
 
2356
procedure TWaveCollectionItem.Stop;
2826
procedure TWaveCollectionItem.Stop;
2357
var
2827
var
2358
  i: Integer;
2828
  i: Integer;
2359
begin
2829
begin
2360
  if not FInitialized then Exit;
2830
  if not FInitialized then Exit;
2361
 
2831
 
2362
  FBuffer.Stop;
2832
  FBuffer.Stop;
2363
  for i:=0 to FBufferList.Count-1  do
2833
  for i := 0 to FBufferList.Count - 1 do
2364
    TDirectSoundBuffer(FBufferList[i]).Stop;
2834
    TDirectSoundBuffer(FBufferList[i]).Stop;
2365
end;
2835
end;
2366
 
2836
 
2367
procedure TWaveCollectionItem.SetFrequency(Value: Integer);
2837
procedure TWaveCollectionItem.SetFrequency(Value: Integer);
2368
begin
2838
begin
2369
  FFrequency := Value;
2839
  FFrequency := Value;
2370
  if FInitialized then
2840
  if FInitialized then
2371
    GetBuffer.Frequency := Value;
2841
    GetBuffer.Frequency := Value;
2372
end;
2842
end;
2373
 
2843
 
2374
procedure TWaveCollectionItem.SetLooped(Value: Boolean);
2844
procedure TWaveCollectionItem.SetLooped(Value: Boolean);
2375
begin
2845
begin
2376
  if FLooped<>Value then
2846
  if FLooped <> Value then
2377
  begin
2847
  begin
2378
    Stop;
2848
    Stop;
2379
    FLooped := Value;
2849
    FLooped := Value;
2380
  end;
2850
  end;
2381
end;
2851
end;
2382
 
2852
 
2383
procedure TWaveCollectionItem.SetMaxPlayingCount(Value: Integer);
2853
procedure TWaveCollectionItem.SetMaxPlayingCount(Value: Integer);
2384
var
2854
var
2385
  i: Integer;
2855
  i: Integer;
2386
begin
2856
begin
2387
  if Value<0 then Value := 0;
2857
  if Value < 0 then Value := 0;
2388
 
2858
 
2389
  if FMaxPlayingCount<>Value then
2859
  if FMaxPlayingCount <> Value then
2390
  begin
2860
  begin
2391
    FMaxPlayingCount := Value;
2861
    FMaxPlayingCount := Value;
2392
 
2862
 
2393
    if FInitialized then
2863
    if FInitialized then
2394
    begin
2864
    begin
2395
      for i:=0 to FBufferList.Count-1 do
2865
      for i := 0 to FBufferList.Count - 1 do
2396
        TDirectSoundBuffer(FBufferList[i]).Free;
2866
        TDirectSoundBuffer(FBufferList[i]).Free;
2397
      FBufferList.Clear;
2867
      FBufferList.Clear;
2398
    end;
2868
    end;
2399
  end;
2869
  end;
2400
end;
2870
end;
2401
 
2871
 
2402
procedure TWaveCollectionItem.SetPan(Value: Integer);
2872
procedure TWaveCollectionItem.SetPan(Value: Integer);
2403
begin
2873
begin
2404
  FPan := Value;
2874
  FPan := Value;
2405
  if FInitialized then
2875
  if FInitialized then
2406
    GetBuffer.Pan := Value;
2876
    GetBuffer.Pan := Value;
2407
end;
2877
end;
2408
 
2878
 
2409
procedure TWaveCollectionItem.SetVolume(Value: Integer);
2879
procedure TWaveCollectionItem.SetVolume(Value: Integer);
2410
begin
2880
begin
2411
  FVolume := Value;
2881
  FVolume := Value;
2412
  if FInitialized then
2882
  if FInitialized then
2413
    GetBuffer.Volume := Value;
2883
    GetBuffer.Volume := Value;
2414
end;
2884
end;
2415
 
2885
 
2416
procedure TWaveCollectionItem.SetWave(Value: TWave);
2886
procedure TWaveCollectionItem.SetWave(Value: TWave);
2417
begin
2887
begin
2418
  FWave.Assign(Value);
2888
  FWave.Assign(Value);
2419
end;
2889
end;
2420
 
2890
 
2421
{  TWaveCollection  }
2891
{  TWaveCollection  }
2422
 
2892
 
2423
constructor TWaveCollection.Create(AOwner: TPersistent);
2893
constructor TWaveCollection.Create(AOwner: TPersistent);
2424
begin
2894
begin
2425
  inherited Create(TWaveCollectionItem);
2895
  inherited Create(TWaveCollectionItem);
2426
  FOwner := AOwner;
2896
  FOwner := AOwner;
2427
end;
2897
end;
2428
 
2898
 
2429
function TWaveCollection.GetItem(Index: Integer): TWaveCollectionItem;
2899
function TWaveCollection.GetItem(Index: Integer): TWaveCollectionItem;
2430
begin
2900
begin
2431
  Result := TWaveCollectionItem(inherited Items[Index]);
2901
  Result := TWaveCollectionItem(inherited Items[Index]);
2432
end;
2902
end;
2433
 
2903
 
2434
function TWaveCollection.GetOwner: TPersistent;
2904
function TWaveCollection.GetOwner: TPersistent;
2435
begin
2905
begin
2436
  Result := FOwner;
2906
  Result := FOwner;
2437
end;
2907
end;
2438
 
2908
 
2439
function TWaveCollection.Find(const Name: string): TWaveCollectionItem;
2909
function TWaveCollection.Find(const Name: string): TWaveCollectionItem;
2440
var
2910
var
2441
  i: Integer;
2911
  i: Integer;
2442
begin
2912
begin
2443
  i := IndexOf(Name);
2913
  i := IndexOf(Name);
2444
  if i=-1 then
2914
  if i = -1 then
2445
    raise EWaveCollectionError.CreateFmt(SWaveNotFound, [Name]);
2915
    raise EWaveCollectionError.CreateFmt(SWaveNotFound, [Name]);
2446
  Result := Items[i];
2916
  Result := Items[i];
2447
end;
2917
end;
2448
 
2918
 
2449
procedure TWaveCollection.Finalize;
2919
procedure TWaveCollection.Finalize;
2450
var
2920
var
2451
  i: Integer;
2921
  i: Integer;
2452
begin
2922
begin
2453
  for i:=0 to Count-1 do
2923
  for i := 0 to Count - 1 do
2454
    Items[i].Finalize;
2924
    Items[i].Finalize;
2455
  FDXSound := nil;
2925
  FDXSound := nil;
2456
end;
2926
end;
2457
 
2927
 
2458
procedure TWaveCollection.Initialize(DXSound: TCustomDXSound);
2928
procedure TWaveCollection.Initialize(DXSound: TCustomDXSound);
2459
var
2929
var
2460
  i: Integer;
2930
  i: Integer;
2461
begin
2931
begin
2462
  Finalize;
2932
  Finalize;
2463
  FDXSound := DXSound;
2933
  FDXSound := DXSound;
2464
  for i:=0 to Count-1 do
2934
  for i := 0 to Count - 1 do
2465
    Items[i].Initialize;
2935
    Items[i].Initialize;
2466
end;
2936
end;
2467
 
2937
 
2468
function TWaveCollection.Initialized: Boolean;
2938
function TWaveCollection.Initialized: Boolean;
2469
begin
2939
begin
2470
  Result := (FDXSound<>nil) and (FDXSound.Initialized);
2940
  Result := (FDXSound <> nil) and (FDXSound.Initialized);
2471
end;
2941
end;
2472
 
2942
 
2473
procedure TWaveCollection.Restore;
2943
procedure TWaveCollection.Restore;
2474
var
2944
var
2475
  i: Integer;
2945
  i: Integer;
2476
begin
2946
begin
2477
  for i:=0 to Count-1 do
2947
  for i := 0 to Count - 1 do
2478
    Items[i].Restore;
2948
    Items[i].Restore;
2479
end;
2949
end;
2480
 
2950
 
2481
type
2951
type
2482
  TWaveCollectionComponent = class(TComponent)
2952
  TWaveCollectionComponent = class(TComponent)
2483
  private
2953
  private
2484
    FList: TWaveCollection;
2954
    FList: TWaveCollection;
2485
  published
2955
  published
2486
    property List: TWaveCollection read FList write FList;
2956
    property List: TWaveCollection read FList write FList;
2487
  end;
2957
  end;
2488
 
2958
 
2489
procedure TWaveCollection.LoadFromFile(const FileName: string);
2959
procedure TWaveCollection.LoadFromFile(const FileName: string);
2490
var
2960
var
2491
  Stream: TFileStream;
2961
  Stream: TFileStream;
2492
begin
2962
begin
2493
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
2963
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
2494
  try
2964
  try
2495
    LoadFromStream(Stream);
2965
    LoadFromStream(Stream);
2496
  finally
2966
  finally
2497
    Stream.Free;
2967
    Stream.Free;
2498
  end;
2968
  end;
2499
end;
2969
end;
2500
 
2970
 
2501
procedure TWaveCollection.LoadFromStream(Stream: TStream);
2971
procedure TWaveCollection.LoadFromStream(Stream: TStream);
2502
var
2972
var
2503
  Component: TWaveCollectionComponent;
2973
  Component: TWaveCollectionComponent;
2504
begin
2974
begin
2505
  Clear;
2975
  Clear;
2506
  Component := TWaveCollectionComponent.Create(nil);
2976
  Component := TWaveCollectionComponent.Create(nil);
2507
  try
2977
  try
2508
    Component.FList := Self;
2978
    Component.FList := Self;
2509
    Stream.ReadComponentRes(Component);
2979
    Stream.ReadComponentRes(Component);
2510
 
2980
 
2511
    if Initialized then
2981
    if Initialized then
2512
    begin
2982
    begin
2513
      Initialize(FDXSound);
2983
      Initialize(FDXSound);
2514
      Restore;
2984
      Restore;
2515
    end;
2985
    end;
2516
  finally
2986
  finally
2517
    Component.Free;
2987
    Component.Free;
2518
  end;
2988
  end;
2519
end;
2989
end;
2520
 
2990
 
2521
procedure TWaveCollection.SaveToFile(const FileName: string);
2991
procedure TWaveCollection.SaveToFile(const FileName: string);
2522
var
2992
var
2523
  Stream: TFileStream;
2993
  Stream: TFileStream;
2524
begin
2994
begin
2525
  Stream := TFileStream.Create(FileName, fmCreate);
2995
  Stream := TFileStream.Create(FileName, fmCreate);
2526
  try
2996
  try
2527
    SaveToStream(Stream);
2997
    SaveToStream(Stream);
2528
  finally
2998
  finally
2529
    Stream.Free;
2999
    Stream.Free;
2530
  end;
3000
  end;
2531
end;
3001
end;
2532
 
3002
 
2533
procedure TWaveCollection.SaveToStream(Stream: TStream);
3003
procedure TWaveCollection.SaveToStream(Stream: TStream);
2534
var
3004
var
2535
  Component: TWaveCollectionComponent;
3005
  Component: TWaveCollectionComponent;
2536
begin
3006
begin
2537
  Component := TWaveCollectionComponent.Create(nil);
3007
  Component := TWaveCollectionComponent.Create(nil);
2538
  try
3008
  try
2539
    Component.FList := Self;
3009
    Component.FList := Self;
2540
    Stream.WriteComponentRes('DelphiXWaveCollection', Component);
3010
    Stream.WriteComponentRes('DelphiXWaveCollection', Component);
2541
  finally
3011
  finally
2542
    Component.Free;
3012
    Component.Free;
2543
  end;
3013
  end;
2544
end;
3014
end;
2545
 
3015
 
2546
{  TCustomDXWaveList  }
3016
{  TCustomDXWaveList  }
2547
 
3017
 
2548
constructor TCustomDXWaveList.Create(AOwner: TComponent);
3018
constructor TCustomDXWaveList.Create(AOwner: TComponent);
2549
begin
3019
begin
2550
  inherited Create(AOwner);
3020
  inherited Create(AOwner);
2551
  FItems := TWaveCollection.Create(Self);
3021
  FItems := TWaveCollection.Create(Self);
2552
end;
3022
end;
2553
 
3023
 
2554
destructor TCustomDXWaveList.Destroy;
3024
destructor TCustomDXWaveList.Destroy;
2555
begin
3025
begin
2556
  DXSound := nil;
3026
  DXSound := nil;
2557
  FItems.Free;
3027
  FItems.Free;
2558
  inherited Destroy;
3028
  inherited Destroy;
2559
end;
3029
end;
2560
 
3030
 
2561
procedure TCustomDXWaveList.Notification(AComponent: TComponent; Operation: TOperation);
3031
procedure TCustomDXWaveList.Notification(AComponent: TComponent; Operation: TOperation);
2562
begin
3032
begin
2563
  inherited Notification(AComponent, Operation);
3033
  inherited Notification(AComponent, Operation);
2564
  if (Operation=opRemove) and (DXSound=AComponent) then
3034
  if (Operation = opRemove) and (DXSound = AComponent) then
2565
    DXSound := nil;
3035
    DXSound := nil;
2566
end;
3036
end;
2567
 
3037
 
2568
procedure TCustomDXWaveList.DXSoundNotifyEvent(Sender: TCustomDXSound;
3038
procedure TCustomDXWaveList.DXSoundNotifyEvent(Sender: TCustomDXSound;
2569
  NotifyType: TDXSoundNotifyType);
3039
  NotifyType: TDXSoundNotifyType);
2570
begin
3040
begin
2571
  case NotifyType of
3041
  case NotifyType of
2572
    dsntDestroying: DXSound := nil;
3042
    dsntDestroying: DXSound := nil;
2573
    dsntInitialize: FItems.Initialize(Sender);
3043
    dsntInitialize: FItems.Initialize(Sender);
2574
    dsntFinalize  : FItems.Finalize;
3044
    dsntFinalize: FItems.Finalize;
2575
    dsntRestore   : FItems.Restore;
3045
    dsntRestore: FItems.Restore;
2576
  end;
3046
  end;
2577
end;
3047
end;
2578
 
3048
 
2579
procedure TCustomDXWaveList.SetDXSound(Value: TCustomDXSound);
3049
procedure TCustomDXWaveList.SetDXSound(Value: TCustomDXSound);
2580
begin
3050
begin
2581
  if FDXSound<>nil then
3051
  if FDXSound <> nil then
2582
    FDXSound.UnRegisterNotifyEvent(DXSoundNotifyEvent);
3052
    FDXSound.UnRegisterNotifyEvent(DXSoundNotifyEvent);
2583
 
3053
 
2584
  FDXSound := Value;
3054
  FDXSound := Value;
2585
 
3055
 
2586
  if FDXSound<>nil then
3056
  if FDXSound <> nil then
2587
    FDXSound.RegisterNotifyEvent(DXSoundNotifyEvent);
3057
    FDXSound.RegisterNotifyEvent(DXSoundNotifyEvent);
2588
end;
3058
end;
2589
 
3059
 
2590
procedure TCustomDXWaveList.SetItems(Value: TWaveCollection);
3060
procedure TCustomDXWaveList.SetItems(Value: TWaveCollection);
2591
begin
3061
begin
2592
  FItems.Assign(Value);
3062
  FItems.Assign(Value);
2593
end;
3063
end;
-
 
3064
 
-
 
3065
{(c) 2006 Jaro Benes, Play midi from memory module}
-
 
3066
 
-
 
3067
{ TMusicDataProp }
-
 
3068
 
-
 
3069
type
-
 
3070
  TMidiDataHeader = packed record
-
 
3071
    Size: Integer;
-
 
3072
  end;
-
 
3073
 
-
 
3074
procedure TMusicDataProp.DefineProperties(Filer: TFiler);
-
 
3075
begin
-
 
3076
  inherited DefineProperties(Filer);
-
 
3077
  Filer.DefineBinaryProperty('Midi', ReadMidiData, WriteMidiData, Length(Self.FMusicData) <> 0);
-
 
3078
end;
-
 
3079
 
-
 
3080
function TMusicDataProp.GetMusicData: string;
-
 
3081
begin
-
 
3082
  SetLength(Result, Length(FMusicData));
-
 
3083
  if Length(FMusicData) <> 0 then
-
 
3084
    Move(FMusicData[1], Result[1], Length(FMusicData));
-
 
3085
end;
-
 
3086
 
-
 
3087
procedure TMusicDataProp.ReadMidiData(Stream: TStream);
-
 
3088
var
-
 
3089
  Header: TMidiDataHeader;
-
 
3090
begin
-
 
3091
  Stream.ReadBuffer(Header, SizeOf(Header));
-
 
3092
  SetLength(FMusicData, Header.Size);
-
 
3093
  Stream.ReadBuffer(FMusicData[1], Header.Size);
-
 
3094
end;
-
 
3095
 
-
 
3096
procedure TMusicDataProp.SetMusicData(const Value: string);
-
 
3097
begin
-
 
3098
  SetLength(FMusicData, Length(Value));
-
 
3099
  if Length(Value) <> 0 then
-
 
3100
    Move(Value[1], FMusicData[1], Length(Value));
-
 
3101
end;
-
 
3102
 
-
 
3103
procedure TMusicDataProp.WriteMidiData(Stream: TStream);
-
 
3104
var
-
 
3105
  Header: TMidiDataHeader;
-
 
3106
begin
-
 
3107
  Header.Size := Length(FMusicData);
-
 
3108
  Stream.WriteBuffer(Header, SizeOf(Header));
-
 
3109
  Stream.WriteBuffer(FMusicData[1], Header.Size);
-
 
3110
end;
-
 
3111
 
-
 
3112
{ TMusicListCollectionItem }
-
 
3113
 
-
 
3114
procedure TMusicListCollectionItem.Load;
-
 
3115
var
-
 
3116
  MidiFilelength: Integer;
-
 
3117
begin
-
 
3118
  // kdyby nahodou uz nejaky existoval tak ho znic
-
 
3119
  if FDirectMusicSegment <> nil then
-
 
3120
    FDirectMusicSegment := nil;
-
 
3121
  ZeroMemory(@FMusicObjDesc, SizeOf(TDMUS_OBJECTDESC));
-
 
3122
  // tohle je popisek parametru - chceme hrat z pameti
-
 
3123
  with FMusicObjDesc do
-
 
3124
  begin
-
 
3125
    dwsize := SizeOf(TDMUS_OBJECTDESC);
-
 
3126
    guidclass := CLSID_DirectMusicSegment;
-
 
3127
    //tohle jen pokud je to ze souboru
-
 
3128
    //dwvaliddata := DMUS_OBJ_CLASS or DMUS_OBJ_FULLPATH or DMUS_OBJ_FILENAME;
-
 
3129
    dwvaliddata := DMUS_OBJ_CLASS or DMUS_OBJ_MEMORY or DMUS_OBJ_LOADED;
-
 
3130
    pbMemData := @FMusicDataProp.FMusicData[1];
-
 
3131
    llMemLength := Length(FMusicDataProp.FMusicData);
-
 
3132
  end;
-
 
3133
  if FDirectMusicLoader.GetObject(FMusicObjDesc, IID_IDirectMusicSegment, FDirectMusicSegment) <> dm_ok then
-
 
3134
    raise EDXMusicError.Create('Failed to Get object for Direct music'); ;
-
 
3135
  if FDirectMusicSegment.setParam(GUID_StandardMidiFile, $FFFFFFFF, 0, 0, Pointer(FDirectMusicPerformance)) <> dm_ok then
-
 
3136
    raise EDXMusicError.Create('Failed to Set param for Direct music'); ;
-
 
3137
  if FDirectMusicSegment.setParam(GUID_Download, $FFFFFFFF, 0, 0, Pointer(FDirectMusicPerformance)) <> dm_ok then
-
 
3138
    raise EDXMusicError.Create('Failed to Set param for Direct music'); ;
-
 
3139
  FDirectMusicSegment.GetLength(MidiFilelength);
-
 
3140
  if (FActualDuration < MidiFilelength) and (FActualDuration > 0) then
-
 
3141
    FDirectMusicSegment.SetLength(FActualDuration);
-
 
3142
  if FActualStartPoint < MidiFilelength - FActualDuration then
-
 
3143
    FDirectMusicSegment.SetStartpoint(FActualStartPoint);
-
 
3144
  // jak opakovat
-
 
3145
  FDirectMusicSegment.Setrepeats(repeats - 1);
-
 
3146
end;
-
 
3147
 
-
 
3148
constructor TMusicListCollectionItem.Create(Collection: TCollection);
-
 
3149
begin
-
 
3150
  inherited Create(Collection);
-
 
3151
  CoInitialize(nil);
-
 
3152
  FMusicDataProp := TMusicDataProp.Create;
-
 
3153
  SetLength(FMusicDataProp.FMusicData, 0);
-
 
3154
  FDirectMusicPerformance := nil;
-
 
3155
  FDirectMusic := nil;
-
 
3156
  FDirectSound := nil;
-
 
3157
  FDirectMusicSegment := nil;
-
 
3158
  FDirectMusicLoader := nil;
-
 
3159
  FIsInitialized := False;
-
 
3160
end;
-
 
3161
 
-
 
3162
procedure TMusicListCollectionItem.Stop;
-
 
3163
begin
-
 
3164
  if FDirectMusicPerformance <> nil then
-
 
3165
    FDirectMusicPerformance.Stop(nil, nil, 0, 0);
-
 
3166
end;
-
 
3167
 
-
 
3168
function TMusicListCollectionItem.GetDisplayName: string;
-
 
3169
begin
-
 
3170
  Result := inherited GetDisplayName
-
 
3171
end;
-
 
3172
 
-
 
3173
procedure TMusicListCollectionItem.Play;
-
 
3174
begin
-
 
3175
  if not FIsInitialized then
-
 
3176
    Init;
-
 
3177
  Load;
-
 
3178
  if FDirectMusicPerformance <> nil then
-
 
3179
    FDirectMusicPerformance.PlaySegment(FDirectMusicSegment, 0, 0, @FDirectMusicSegmentState);
-
 
3180
end;
-
 
3181
 
-
 
3182
function TMusicListCollectionItem.IsPlaying: Boolean;
-
 
3183
begin
-
 
3184
  Result := False;
-
 
3185
  if FDirectMusicPerformance <> nil then
-
 
3186
    Result := FDirectMusicPerformance.IsPlaying(FDirectMusicSegment, FDirectMusicSegmentState) = DM_OK;
-
 
3187
end;
-
 
3188
 
-
 
3189
destructor TMusicListCollectionItem.Destroy;
-
 
3190
begin
-
 
3191
  FDirectMusicPerformance := nil;
-
 
3192
  FDirectMusic := nil;
-
 
3193
  FDirectSound := nil;
-
 
3194
  FDirectMusicSegment := nil;
-
 
3195
  FDirectMusicLoader := nil;
-
 
3196
  FMusicDataProp.Free;
-
 
3197
  CoUninitialize;
-
 
3198
  inherited Destroy;
-
 
3199
end;
-
 
3200
 
-
 
3201
procedure TMusicListCollectionItem.SetRepeats(const Value: Cardinal);
-
 
3202
begin
-
 
3203
  Frepeats := Value;
-
 
3204
end;
-
 
3205
 
-
 
3206
procedure TMusicListCollectionItem.SetStartPoint(const Value: integer);
-
 
3207
begin
-
 
3208
  FStartPoint := Value;
-
 
3209
end;
-
 
3210
 
-
 
3211
procedure TMusicListCollectionItem.SetDuration(const Value: integer);
-
 
3212
begin
-
 
3213
  FDuration := Value;
-
 
3214
end;
-
 
3215
 
-
 
3216
procedure TMusicListCollectionItem.Init;
-
 
3217
var OK: Boolean;
-
 
3218
begin
-
 
3219
  FIsInitialized := False;
-
 
3220
  OK := False;
-
 
3221
  // vytvor FDirectMusicPerformance pokud uz neni vytvoreno
-
 
3222
  if FDirectMusicPerformance = nil then
-
 
3223
    OK := CoCreateInstance(CLSID_DirectMusicPerformance, nil, CLSCTX_INPROC,
-
 
3224
      IID_IDirectMusicperformance, FDirectMusicPerformance) = DM_OK;
-
 
3225
  if not OK then Exit;
-
 
3226
  if FDirectSound <> nil then
-
 
3227
    OK := FDirectMusicPerformance.Init({$IFDEF DX7}@{$ENDIF}FDirectMusic, FDirectSound, 0) = DM_OK
-
 
3228
  else
-
 
3229
    OK := FDirectMusicPerformance.Init({$IFDEF DX7}@{$ENDIF}FDirectMusic, nil, 0) = dm_OK;
-
 
3230
  if not OK then Exit;
-
 
3231
  // vychozi midi port
-
 
3232
  // pridej pokud neni nastaven
-
 
3233
  if FDirectMusicPerformance.Addport(nil) <> DM_OK then Exit;
-
 
3234
  // zkus vytvorit loader
-
 
3235
  OK := CoCreateInstance(CLSID_DirectMusicLoader, nil, CLSCTX_Inproc,
-
 
3236
    IID_IDirectMusicLoader, FDirectMusicLoader) = DM_OK;
-
 
3237
  FIsInitialized := OK;
-
 
3238
end;
-
 
3239
 
-
 
3240
function TMusicListCollectionItem.GetMusicListCollection: TMusicListCollection;
-
 
3241
begin
-
 
3242
  Result := Collection as TMusicListCollection;
-
 
3243
end;
-
 
3244
 
-
 
3245
procedure TMusicListCollectionItem.SaveToFile(const MidiFileName: string);
-
 
3246
var F: file;
-
 
3247
begin
-
 
3248
  AssignFile(F, MidiFileName);
-
 
3249
  Rewrite(F, 1);
-
 
3250
  try
-
 
3251
    BlockWrite(F, FMusicDataProp.FMusicData[1], Length(FMusicDataProp.FMusicData));
-
 
3252
  finally
-
 
3253
    CloseFile(F);
-
 
3254
  end;
-
 
3255
end;
-
 
3256
 
-
 
3257
procedure TMusicListCollectionItem.LoadFromFile(const MidiFileName: string);
-
 
3258
var F: file; S: string; I: Integer;
-
 
3259
begin
-
 
3260
  AssignFile(F, MidiFileName);
-
 
3261
  Reset(F, 1);
-
 
3262
  try
-
 
3263
    SetLength(FMusicDataProp.FMusicData, FileSize(F));
-
 
3264
    BlockRead(F, FMusicDataProp.FMusicData[1], FileSize(F));
-
 
3265
    S := ExtractFileName(MidiFileName);
-
 
3266
    I := Pos(ExtractFileExt(S), S);
-
 
3267
    if I > 0 then S := Copy(S, 1, I - 1);
-
 
3268
    FMusicDataProp.Midiname := S;
-
 
3269
  finally
-
 
3270
    CloseFile(F);
-
 
3271
  end;
-
 
3272
  Name := ExtractFileName(MidiFileName);
-
 
3273
end;
-
 
3274
 
-
 
3275
function TMusicListCollectionItem.Size: Integer;
-
 
3276
begin
-
 
3277
  Result := Length(FMusicDataProp.FMusicData);
-
 
3278
end;
-
 
3279
 
-
 
3280
{ TMusicListCollection }
-
 
3281
 
-
 
3282
constructor TMusicListCollection.Create(AOwner: TComponent);
-
 
3283
begin
-
 
3284
  inherited Create(TMusicListCollectionItem);
-
 
3285
  FOwner := AOwner;
-
 
3286
end;
-
 
3287
 
-
 
3288
function TMusicListCollection.Add: TMusicListCollectionItem;
-
 
3289
begin
-
 
3290
  Result := TMusicListCollectionItem(inherited Add);
-
 
3291
  Result.FDirectSound := Self.FDirectSound;
-
 
3292
end;
-
 
3293
 
-
 
3294
function TMusicListCollection.GetItem(Index: Integer): TMusicListCollectionItem;
-
 
3295
begin
-
 
3296
  Result := TMusicListCollectionItem(inherited GetItem(Index));
-
 
3297
end;
-
 
3298
 
-
 
3299
procedure TMusicListCollection.SetItem(Index: Integer;
-
 
3300
  Value: TMusicListCollectionItem);
-
 
3301
begin
-
 
3302
  inherited SetItem(Index, Value);
-
 
3303
end;
-
 
3304
 
-
 
3305
procedure TMusicListCollection.Update(Item: TCollectionItem);
-
 
3306
begin
-
 
3307
  inherited Update(Item);
-
 
3308
end;
-
 
3309
 
-
 
3310
function TMusicListCollection.Find(
-
 
3311
  const Name: string): TMusicListCollectionItem;
-
 
3312
var
-
 
3313
  i: Integer;
-
 
3314
begin
-
 
3315
  i := IndexOf(Name);
-
 
3316
  if i = -1 then
-
 
3317
    raise EDXMusicError.CreateFmt('The midi document does not exist: %s.', [Name]);
-
 
3318
  Result := Items[i];
-
 
3319
end;
-
 
3320
 
-
 
3321
{$IFDEF VER4UP}
-
 
3322
function TMusicListCollection.Insert(Index: Integer): TMusicListCollectionItem;
-
 
3323
begin
-
 
3324
  Result := TMusicListCollectionItem(inherited Insert(Index));
-
 
3325
end;
-
 
3326
{$ENDIF}
-
 
3327
 
-
 
3328
function TMusicListCollection.GetOwner: TPersistent;
-
 
3329
begin
-
 
3330
  Result := FOwner;
-
 
3331
end;
-
 
3332
 
-
 
3333
procedure TMusicListCollection.Restore;
-
 
3334
begin
-
 
3335
 
-
 
3336
end;
-
 
3337
 
-
 
3338
procedure TMusicListCollection.SaveToFile(const FileName: string);
-
 
3339
var
-
 
3340
  Stream: TFileStream;
-
 
3341
begin
-
 
3342
  Stream := TFileStream.Create(FileName, fmCreate);
-
 
3343
  try
-
 
3344
    SaveToStream(Stream);
-
 
3345
  finally
-
 
3346
    Stream.Free;
-
 
3347
  end;
-
 
3348
end;
-
 
3349
 
-
 
3350
procedure TMusicListCollection.LoadFromFile(const FileName: string);
-
 
3351
var
-
 
3352
  Stream: TFileStream;
-
 
3353
begin
-
 
3354
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
-
 
3355
  try
-
 
3356
    LoadFromStream(Stream);
-
 
3357
  finally
-
 
3358
    Stream.Free;
-
 
3359
  end;
-
 
3360
end;
-
 
3361
 
-
 
3362
type
-
 
3363
  TMidiCollectionComponent = class(TComponent)
-
 
3364
  private
-
 
3365
    FList: TMusicListCollection;
-
 
3366
  published
-
 
3367
    property List: TMusicListCollection read FList write FList;
-
 
3368
  end;
-
 
3369
 
-
 
3370
procedure TMusicListCollection.SaveToStream(Stream: TStream);
-
 
3371
var
-
 
3372
  Component: TMidiCollectionComponent;
-
 
3373
begin
-
 
3374
  Component := TMidiCollectionComponent.Create(nil);
-
 
3375
  try
-
 
3376
    Component.FList := Self;
-
 
3377
    Stream.WriteComponentRes('DelphiXMidiCollection', Component);
-
 
3378
  finally
-
 
3379
    Component.Free;
-
 
3380
  end;
-
 
3381
end;
-
 
3382
 
-
 
3383
procedure TMusicListCollection.LoadFromStream(Stream: TStream);
-
 
3384
var
-
 
3385
  Component: TMidiCollectionComponent;
-
 
3386
begin
-
 
3387
  Clear;
-
 
3388
  Component := TMidiCollectionComponent.Create(nil);
-
 
3389
  try
-
 
3390
    Component.FList := Self;
-
 
3391
    Stream.ReadComponentRes(Component);
-
 
3392
    Restore;
-
 
3393
  finally
-
 
3394
    Component.Free;
-
 
3395
  end;
-
 
3396
end;
-
 
3397
 
-
 
3398
{ TDXMusic }
-
 
3399
 
-
 
3400
constructor TDXMusic.Create(AOwner: TComponent);
-
 
3401
begin
-
 
3402
  inherited Create(AOwner);
-
 
3403
  FMidis := TMusicListCollection.Create(Self);
-
 
3404
  if Assigned(FDXSound) then
-
 
3405
    FMidis.FDirectSound := FDXSound.DSound.IDSound;
-
 
3406
end;
-
 
3407
 
-
 
3408
procedure TDXMusic.SetMidis(const value: TMusicListCollection);
-
 
3409
begin
-
 
3410
  FMidis.Assign(Value);
-
 
3411
end;
-
 
3412
 
-
 
3413
destructor TDXMusic.Destroy;
-
 
3414
begin
-
 
3415
  FMidis.Free;
-
 
3416
  inherited Destroy;
-
 
3417
end;
-
 
3418
 
-
 
3419
procedure TDXMusic.SetDXSound(const Value: TDXSound);
-
 
3420
begin
-
 
3421
  FDXSound := Value;
-
 
3422
  if Assigned(FDXSound) then
-
 
3423
    FMidis.FDirectSound := FDXSound.DSound.IDSound;
-
 
3424
end;
2594
 
3425
 
2595
initialization
3426
initialization
2596
finalization
3427
finalization
2597
  DirectSoundDrivers.Free;
3428
  DirectSoundDrivers.Free;
2598
  DirectSoundCaptureDrivers.Free;
3429
  DirectSoundCaptureDrivers.Free;
2599
end.
3430
end.
2600
 
3431