踩雷:IDirectSoundCapture(8)不支持32位应用程序

一不小心踩到了微软的巨坑,在DirectX中,IDirectSound8.CreateSoundBuffer是支持32位应用程序创建缓冲区并正常可以使用,但是在IDirectSoundCapture(8)中,使用32位的DSCBUFFERDESC会导致CreateCaptureBuffer返回DSERR_INVALIDPARAM,非常坑爹的问题,严重怀疑是微软BUG!附Delphi测试代码,在64位下可以正常调用CreateCaptureBuffer。

var
//  GUID:TGUID;
  DscCap:TDSCcaps;
  dsbd:TDSCBufferDesc;
  DSCBuffer: IDirectSoundCaptureBuffer;
  DSCBBUFF8:IDirectSoundCaptureBuffer8;
  RE:HRESULT;
begin
  DirectSoundCaptureEnumerate(callback,nil);

  DirectSoundCaptureCreate8(@CAP,myDCapture,NIL);

  FillChar(DscCap,SizeOf(TDSCcaps),0);

  FillChar(dsbd,SizeOf(DSBUFFERDESC),0);

  DscCap.dwSize := SizeOf(TDSCcaps);

  myDCapture.GetCaps(DscCap);

  dsbd.dwSize := SizeOf(_DSCBUFFERDESC);

  dsbd.dwFlags := 0;

  dsbd.lpwfxFormat := AllocMem(SizeOf(tWaveFormatEx));

  dsbd.lpwfxFormat.wFormatTag := WAVE_FORMAT_PCM;

  dsbd.lpwfxFormat.nChannels := DscCap.dwChannels;

  dsbd.lpwfxFormat.nSamplesPerSec := 48000;

  dsbd.lpwfxFormat.wBitsPerSample := 16;

  dsbd.lpwfxFormat.nBlockAlign := 4;

  dsbd.lpwfxFormat.nAvgBytesPerSec := dsbd.lpwfxFormat.nSamplesPerSec * dsbd.lpwfxFormat.nBlockAlign;

  dsbd.lpwfxFormat.cbSize := 0;

  dsbd.dwBufferBytes := dsbd.lpwfxFormat.nAvgBytesPerSec;

  RE := myDCapture.CreateCaptureBuffer(dsbd,DSCBuffer,NIL);

  if Succeeded(RE) then
  begin

    DSCBuffer.QueryInterface(IID_IDirectSoundCaptureBuffer8,DSCBBUFF8);
    ShowMessage('');
   // DSCBuffer._Release;
  end
  else
  begin
    IF RE = DSERR_INVALIDPARAM THEN
    begin
       ShowMessage('向返回函数传递了无效参数。');
       Exit;
    end
    ELSE
    IF RE = DSERR_BADFORMAT THEN
    BEGIN
       ShowMessage('不支持指定的波形格式');
       Exit;
    END
    ELSE
    IF RE = DSERR_GENERIC THEN
    BEGIN
       ShowMessage('DirectSound 子系统内部出现未确定的错误');
       Exit;
    END
    ELSE
    IF RE = DSERR_NODRIVER THEN
    BEGIN
       ShowMessage('没有可用的声音驱动程序,或者给定的 GUID 不是有效的 DirectSound 设备 ID。');
       Exit;
    END
    ELSE
    IF RE = DSERR_OUTOFMEMORY THEN
    BEGIN
       ShowMessage('DirectSound 子系统无法分配足够的内存来完成调用者的请求。');
       Exit;
    END
    ELSE
    IF RE = DSERR_UNINITIALIZED THEN
    BEGIN
       ShowMessage('IDirectSound8::Initialize 方法未被调用或未在其他方法之前调用成功');
       Exit;
    END;
  end;

标签