所以我用Delphi用MCISendString录制音频。代码运行良好,但有一个例外。我让用户设置参数、通道、位、频率,在Windows7上运行良好。现在,在Windows10上,我得到了mcierr_wave_inputsinuse。
如果我将参数减少到1通道,8位,8 8khz,它记录良好。任何高于这一点的东西,MCI都会拒绝。根据我的设备,它应该是1通道,16位,48k。
我猜麦克风是被共享的。有谁知道如何让Delphi程序获得独占控制权,这样它就可以使用设备的全部功能吗?
我做了很好的挖掘,但没有发现任何有用的东西。
谢谢
这是我正在使用的代码。
MRet := mciSendString(PChar('RECORD mysound'), NIL, 0, Handle);它返回一个322结果代码。我尝试过使用和不转换为PChar。
它似乎与Cortana有关。但由于没有办法完全禁用Cortana,获得独占控制权似乎是唯一可能的解决方案。
发布于 2016-03-20 09:08:26
你可以在这里找到一个使用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
https://stackoverflow.com/questions/35991762
复制相似问题