📄 dxsounds.pas
字号:
if Self<>nil then
Result := FIDSound
else
Result := nil;
end;
function TDirectSound.GetISound: IDirectSound;
begin
Result := IDSound;
if Result=nil then
raise EDirectSoundError.CreateFmt(SNotMade, ['IDirectSound']);
end;
{ TDirectSoundBuffer }
constructor TDirectSoundBuffer.Create(ADirectSound: TDirectSound);
begin
inherited Create;
FDSound := ADirectSound;
FDSound.FBufferList.Add(Self);
end;
destructor TDirectSoundBuffer.Destroy;
begin
IDSBuffer := nil;
FDSound.FBufferList.Remove(Self);
inherited Destroy;
end;
procedure TDirectSoundBuffer.Assign(Source: TPersistent);
var
TempBuffer: IDirectSoundBuffer;
begin
if Source=nil then
IDSBuffer := nil
else if Source is TDirectSoundBuffer then
begin
if TDirectSoundBuffer(Source).IDSBuffer=nil then
IDSBuffer := nil
else begin
FDSound.DXResult := FDSound.ISound.DuplicateSoundBuffer(TDirectSoundBuffer(Source).IDSBuffer,
TempBuffer);
if FDSound.DXResult=0 then
begin
IDSBuffer := TempBuffer;
end;
end;
end else
inherited Assign(Source);
end;
procedure TDirectSoundBuffer.Check;
begin
FDSound.CheckBuffer(Self);
end;
function TDirectSoundBuffer.CreateBuffer(const BufferDesc: TDSBufferDesc): Boolean;
var
TempBuffer: IDirectSoundBuffer;
begin
IDSBuffer := nil;
FDSound.DXResult := FDSound.ISound.CreateSoundBuffer(BufferDesc, TempBuffer, nil);
FDXResult := FDSound.DXResult;
Result := DXResult=DS_OK;
if Result then
IDSBuffer := TempBuffer;
end;
function TDirectSoundBuffer.GetBitCount: Longint;
begin
Result := Format.wBitsPerSample;
end;
function TDirectSoundBuffer.GetFormat: PWaveFormatEx;
begin
GetIBuffer;
Result := FFormat;
end;
function TDirectSoundBuffer.GetFrequency: Integer;
begin
DXResult := IBuffer.GetFrequency(DWORD(Result));
end;
function TDirectSoundBuffer.GetIDSBuffer: IDirectSoundBuffer;
begin
if Self<>nil then
Result := FIDSBuffer
else
Result := nil;
end;
function TDirectSoundBuffer.GetIBuffer: IDirectSoundBuffer;
begin
Result := IDSBuffer;
if Result=nil then
raise EDirectSoundBufferError.CreateFmt(SNotMade, ['IDirectSoundBuffer']);
end;
function TDirectSoundBuffer.GetPlaying: Boolean;
begin
Result := (GetStatus and (DSBSTATUS_PLAYING or DSBSTATUS_LOOPING))<>0;
end;
function TDirectSoundBuffer.GetPan: Integer;
begin
DXResult := IBuffer.GetPan(Longint(Result));
end;
function TDirectSoundBuffer.GetPosition: Longint;
var
dwCurrentWriteCursor: Longint;
begin
IBuffer.GetCurrentPosition(DWORD(Result), DWORD(dwCurrentWriteCursor));
end;
function TDirectSoundBuffer.GetSize: Integer;
begin
Result := FCaps.dwBufferBytes;
end;
function TDirectSoundBuffer.GetStatus: Integer;
begin
DXResult := IBuffer.GetStatus(DWORD(Result));
end;
function TDirectSoundBuffer.GetVolume: Integer;
begin
DXResult := IBuffer.GetVolume(Longint(Result));
end;
procedure TDirectSoundBuffer.LoadFromMemory(const Format: TWaveFormatEx;
Data: Pointer; Size: Integer);
var
Data1, Data2: Pointer;
Data1Size, Data2Size: Longint;
begin
SetSize(Format, Size);
if Data<>nil then
begin
if Lock(0, Size, Data1, Data1Size, Data2, Data2Size) then
begin
try
Move(Data^, Data1^, Data1Size);
if Data2<>nil then
Move(Pointer(Longint(Data)+Data1Size)^, Data2^, Data2Size);
finally
UnLock;
end;
end else
begin
FIDSBuffer := nil;
raise EDirectSoundBufferError.CreateFmt(SCannotLock, [SDirectSoundBuffer]);
end;
end;
end;
function TDirectSoundBuffer.Lock(LockPosition, LockSize: Longint;
var AudioPtr1: Pointer; var AudioSize1: Longint;
var AudioPtr2: Pointer; var AudioSize2: Longint): Boolean;
begin
Result := False;
if IDSBuffer=nil then Exit;
if FLockCount>High(FLockAudioPtr1) then Exit;
DXResult := IBuffer.Lock(LockPosition, LockSize,
FLockAudioPtr1[FLockCount], FLockAudioSize1[FLockCount],
FLockAudioPtr2[FLockCount], FLockAudioSize2[FLockCount], 0);
Result := DXResult=DS_OK;
if Result then
begin
AudioPtr1 := FLockAudioPtr1[FLockCount];
AudioPtr2 := FLockAudioPtr2[FLockCount];
AudioSize1 := FLockAudioSize1[FLockCount];
AudioSize2 := FLockAudioSize2[FLockCount];
Inc(FLockCount);
end;
end;
function TDirectSoundBuffer.Play(Loop: Boolean): Boolean;
begin
if Loop then
DXResult := IBuffer.Play(0, 0, DSBPLAY_LOOPING)
else
DXResult := IBuffer.Play(0, 0, 0);
Result := DXResult=DS_OK;
end;
function TDirectSoundBuffer.Restore: Boolean;
begin
DXResult := IBuffer.Restore;
Result := DXResult=DS_OK;
end;
function TDirectSoundBuffer.SetFormat(const Format: TWaveFormatEx): Boolean;
begin
DXResult := IBuffer.SetFormat(Format);
Result := DXResult=DS_OK;
if Result then
begin
FreeMem(FFormat);
FFormat := nil;
FFormatSize := 0;
if IBuffer.GetFormat(PWaveFormatEx(nil)^, 0, DWORD(FFormatSize))=DS_OK then
begin
GetMem(FFormat, FFormatSize);
IBuffer.GetFormat(FFormat^, FFormatSize, PDWORD(nil)^);
end;
end;
end;
procedure TDirectSoundBuffer.SetFrequency(Value: Integer);
begin
DXResult := IBuffer.SetFrequency(Value);
end;
procedure TDirectSoundBuffer.SetIDSBuffer(Value: IDirectSoundBuffer);
begin
if FIDSBuffer=Value then Exit;
FIDSBuffer := Value;
FillChar(FCaps, SizeOf(FCaps), 0);
FreeMem(FFormat);
FFormat := nil;
FFormatSize := 0;
FLockCount := 0;
if FIDSBuffer<>nil then
begin
FCaps.dwSize := SizeOf(FCaps);
IBuffer.GetCaps(FCaps);
if IBuffer.GetFormat(PWaveFormatEx(nil)^, 0, DWORD(FFormatSize))=DS_OK then
begin
GetMem(FFormat, FFormatSize);
IBuffer.GetFormat(FFormat^, FFormatSize, PDWORD(nil)^);
end;
end;
end;
procedure TDirectSoundBuffer.SetPan(Value: Integer);
begin
DXResult := IBuffer.SetPan(Value);
end;
procedure TDirectSoundBuffer.SetPosition(Value: Longint);
begin
DXResult := IBuffer.SetCurrentPosition(Value);
end;
procedure TDirectSoundBuffer.SetSize(const Format: TWaveFormatEx; Size: Integer);
var
BufferDesc: TDSBufferDesc;
begin
{ IDirectSoundBuffer made. }
FillChar(BufferDesc, SizeOf(BufferDesc), 0);
with BufferDesc do
begin
dwSize := SizeOf(TDSBufferDesc);
dwFlags := DSBCAPS_CTRLDEFAULT;
if DSound.FStickyFocus then
dwFlags := dwFlags or DSBCAPS_STICKYFOCUS
else if DSound.FGlobalFocus then
dwFlags := dwFlags or DSBCAPS_GLOBALFOCUS;
dwBufferBytes := Size;
lpwfxFormat := @Format;
end;
if not CreateBuffer(BufferDesc) then
raise EDirectSoundBufferError.CreateFmt(SCannotMade, [SDirectSoundBuffer]);
end;
procedure TDirectSoundBuffer.SetVolume(Value: Integer);
begin
DXResult := IBuffer.SetVolume(Value);
end;
procedure TDirectSoundBuffer.Stop;
begin
DXResult := IBuffer.Stop;
end;
procedure TDirectSoundBuffer.Unlock;
begin
if IDSBuffer=nil then Exit;
if FLockCount=0 then Exit;
Dec(FLockCount);
DXResult := IBuffer.UnLock(FLockAudioPtr1[FLockCount], FLockAudioSize1[FLockCount],
FLockAudioPtr2[FLockCount], FLockAudioSize2[FLockCount]);
end;
{ TSoundCaptureFormats }
constructor TSoundCaptureFormats.Create;
begin
inherited Create(TSoundCaptureFormat);
end;
function TSoundCaptureFormats.GetItem(Index: Integer): TSoundCaptureFormat;
begin
Result := TSoundCaptureFormat(inherited Items[Index]);
end;
function TSoundCaptureFormats.IndexOf(ASamplesPerSec, ABitsPerSample, AChannels: Integer): Integer;
var
i: Integer;
begin
Result := -1;
for i:=0 to Count-1 do
with Items[i] do
if (FSamplesPerSec=ASamplesPerSec) and (FBitsPerSample=ABitsPerSample) and (FChannels=AChannels) then
begin
Result := i;
Break;
end;
end;
{ TSoundCaptureStream }
type
TSoundCaptureStreamNotify = class(TThread)
private
FCapture: TSoundCaptureStream;
FSleepTime: Integer;
constructor Create(Capture: TSoundCaptureStream);
destructor Destroy; override;
procedure Execute; override;
procedure Update;
end;
constructor TSoundCaptureStreamNotify.Create(Capture: TSoundCaptureStream);
begin
FCapture := Capture;
FCapture.FNotifyEvent := CreateEvent(nil, False, False, nil);
//FSleepTime := Min(FCapture.FBufferLength div 4, 1000 div 20);
FSleepTime := 20;
FreeOnTerminate := True;
inherited Create(True);
end;
destructor TSoundCaptureStreamNotify.Destroy;
begin
FreeOnTerminate := False;
SetEvent(FCapture.FNotifyEvent);
inherited Destroy;
CloseHandle(FCapture.FNotifyEvent);
FCapture.FNotifyThread := nil;
if Assigned(FCapture.FOnFilledBuffer) then FCapture.Stop;
end;
procedure TSoundCaptureStreamNotify.Execute;
begin
while WaitForSingleObject(FCapture.FNotifyEvent, FSleepTime)=WAIT_TIMEOUT do
begin
Synchronize(Update);
end;
end;
procedure TSoundCaptureStreamNotify.Update;
begin
if FCapture.FilledSize>0 then
begin
try
FCapture.DoFilledBuffer;
except
on E: Exception do
begin
Application.HandleException(E);
SetEvent(FCapture.FNotifyEvent);
end;
end;
end;
end;
constructor TSoundCaptureStream.Create(GUID: PGUID);
const
SamplesPerSecList: array[0..6] of Integer = (8000, 11025, 22050, 33075, 44100, 48000, 96000);
BitsPerSampleList: array[0..3] of Integer = (8, 16, 24, 32);
ChannelsList: array[0..1] of Integer = (1, 2);
var
ASamplesPerSec, ABitsPerSample, AChannels: Integer;
dscbd: TDSCBufferDesc;
TempBuffer: IDirectSoundCaptureBuffer;
Format: TWaveFormatEx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -