您可以在此处找到使用 WasAPI 的简单 Delphi 应用程序示例:
https://web.archive.org/web/20130403023149/http://4coder.org/delphi-source-code/547/
请注意,原网站早已下线,但 Wayback 仍然拥有所有代码。
进行实际录制的代码在这里:
// http://msdn.microsoft.com/en-us/library/ms678709(VS.85).aspx
procedure TInputRecordThread.Execute;
const
REFTIMES_PER_SEC = 10000000;
REFTIMES_PER_MILLISEC = 10000;
var
MMDev: IMMDevice;
MMDevEnum: IMMDeviceEnumerator;
AudioClient: IAudioClient;
CaptureClient: IAudioCaptureClient;
PropVar: ^tag_inner_PROPVARIANT;
hnsRequestedDuration, hnsActualDuration: Int64;
pWfx, pCloseWfx: PWaveFormatEx;
BufferFrameCount, NumFramesAvailable, Flags, StreamFlags, PacketLength, FrameSize: Cardinal;
pData: PByte;
uDummy: UInt64;
Returned: HRESULT;
Wave: TWaveImage;
Empty: array of byte;
pEx: PWaveFormatExtensible;
begin
FreeOnTerminate := True;
pCloseWfx := nil;
uDummy := 0;
PropVar := nil;
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
CoCreateInstance(CLASS_MMDeviceEnumerator,
nil,
CLSCTX_ALL,
IID_IMMDeviceEnumerator,
MMDevEnum);
if FLoopback then
Returned := MMDevEnum.GetDefaultAudioEndpoint(eRender, eConsole, MMDev)
else
Returned := MMDevEnum.GetDefaultAudioEndpoint(eCapture, eConsole, MMDev);
if Returned <> S_OK then
begin
OleCheck(Returned);
Exit;
end;
Returned := MMDev.Activate(IID_IAudioClient, CLSCTX_ALL, PropVar^, Pointer(AudioClient));
if Returned <> S_OK then
begin
OleCheck(Returned);
Exit;
end;
AudioClient.GetMixFormat(pWfx);
// http://www.ambisonic.net/mulchaud.html
case pWfx.wFormatTag of
WAVE_FORMAT_IEEE_FLOAT:
begin
pWfx.wFormatTag := WAVE_FORMAT_PCM;
pWfx.wBitsPerSample := 16;
pWfx.nBlockAlign := pWfx.nChannels * pWfx.wBitsPerSample div 8;
pWfx.nAvgBytesPerSec := pWfx.nBlockAlign * pWfx.nSamplesPerSec;
end;
WAVE_FORMAT_EXTENSIBLE:
begin
pEx := PWaveFormatExtensible(pWfx);
if not IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx.SubFormat) then
begin
Exit;
end;
pEx.SubFormat := KSDATAFORMAT_SUBTYPE_PCM;
pEx.ValidBitsPerSample := 16;
pWfx.wBitsPerSample := 16;
pWfx.nBlockAlign := pWfx.nChannels * pWfx.wBitsPerSample div 8;
pWfx.nAvgBytesPerSec := pWfx.nBlockAlign * pWfx.nSamplesPerSec;
end;
else Exit;
end;
if AudioClient.IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, pWfx, pCloseWfx) <> S_OK then
begin
Exit;
end;
// Äŕçěĺđ ôđýéěŕ.
FrameSize := pWfx.wBitsPerSample * pWfx.nChannels div 8;
hnsRequestedDuration := REFTIMES_PER_SEC;
if FLoopback then
StreamFlags := AUDCLNT_STREAMFLAGS_LOOPBACK
else
StreamFlags := 0;
Returned := AudioClient.Initialize(AUDCLNT_SHAREMODE_SHARED,
StreamFlags,
hnsRequestedDuration,
0,
pWfx,
nil);
if Returned <> S_OK then
begin
Exit;
end;
AudioClient.GetBufferSize(BufferFrameCount);
Returned := AudioClient.GetService(IID_IAudioCaptureClient, Pointer(CaptureClient));
if Returned <> S_OK then
begin
Exit;
end;
// Calculate the actual duration of the allocated buffer.
hnsActualDuration := REFTIMES_PER_SEC * BufferFrameCount div pWfx.nSamplesPerSec;
// Start recording.
AudioClient.Start();
Wave := TWaveImage.Create(FData);
try
Wave.InitHeader(pWfx^);
// Each loop fills about half of the shared buffer.
while not Terminated do
begin
// Sleep for half the buffer duration.
Sleep(hnsActualDuration div REFTIMES_PER_MILLISEC div 2);
CaptureClient.GetNextPacketSize(PacketLength);
while PacketLength <> 0 do
begin
// Get the available data in the shared buffer.
pData := nil;
Returned := CaptureClient.GetBuffer(pData,
NumFramesAvailable,
Flags,
uDummy,
uDummy);
if Returned <> S_OK then
begin
Exit;
end;
if (Flags or Cardinal(AUDCLNT_BUFFERFLAGS_SILENT)) = Flags then
begin
pData := nil; // Tell CopyData to write silence.
end;
if pData = nil then
begin
SetLength(Empty, NumFramesAvailable * FrameSize);
FillChar(Empty[0], Length(Empty), 0);
FData.Write(Empty[0], Length(Empty));
end
else
begin
// ĹîőđŕĂ˙ĺě äŕĂĂűĺ.
FData.Write(pData^, NumFramesAvailable * FrameSize);
end;
CaptureClient.ReleaseBuffer(NumFramesAvailable);
CaptureClient.GetNextPacketSize(PacketLength);
end;
end;
// ĂŽĹ„ĹĹ•Ăŕâëčâŕĺě çŕďčńü.
AudioClient.Stop();
// ĂŽĹęîđđĺĹčđóĺě çŕÄîëîâîę.
Wave.CorretHeader;
FData.Position := 0;
finally
Wave.Free;
if pWfx <> nil then
CoTaskMemFree(pWfx);
end;
end;
您可能还想查看:http ://torry.net/pages.php?id=167&sort=ID