windows 10 - Delphi / MCI Exclusive Control of Microphone

来源:http://www.itkeyword.com/doc/1444516339090183105/delphi-mci-exclusive-control-of-microphone

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 
 d 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 
 d 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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值