0

オーディオ ライブラリの DirectSound ラッパーを作成しています。私は directsound に出会いましたが、非常にうまく機能します。つまり、オーディオの再生は、ウェーブアウトなどよりもはるかに優れています。しかし今、私には問題があります。セカンダリ バッファーのボリュームを設定しようとしています。インターフェイスを変換できないなどの理由で、HResult E_NOINTERFACE があるという例外が発生します。そんなことがあるものか。Setvolume メソッドのコードは次のとおりです。 void SetVolume(int lVolume);

そして、たとえば-56の値を渡しています。

ここに正確なエラーメッセージ:

タイプ「System.__ComObject」の COM オブジェクトは、インターフェイス タイプ「AMEngine.DX.IDirectSoundBuffer」にキャストできません。IID '{279AFA85-4981-11CE-A521-0020AF0BE560} を持つインターフェイスの COM コンポーネントで QueryInterface 呼び出しを実行できなかったため、この操作を実行できませんでした: エラーにより、そのようなインターフェイスはサポートされていません (HRESULT からの例外: 0x80004002 (E_NOINTERFACE))。

私はこれを翻訳しました:

DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);

#undef INTERFACE
#define INTERFACE IDirectSoundBuffer
   DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
{
    STDMETHOD(QueryInterface)       (THIS_ __in REFIID, __deref_out LPVOID*) PURE;
    STDMETHOD_(ULONG,AddRef)        (THIS) PURE;
    STDMETHOD_(ULONG,Release)       (THIS) PURE;
    STDMETHOD(GetCaps)              (THIS_ __out LPDSBCAPS pDSBufferCaps) PURE;
    STDMETHOD(GetCurrentPosition)   (THIS_ __out_opt LPDWORD pdwCurrentPlayCursor, __out_opt LPDWORD pdwCurrentWriteCursor) PURE;
    STDMETHOD(GetFormat)            (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE;
    STDMETHOD(GetVolume)            (THIS_ __out LPLONG plVolume) PURE;
    STDMETHOD(GetPan)               (THIS_ __out LPLONG plPan) PURE;
    STDMETHOD(GetFrequency)         (THIS_ __out LPDWORD pdwFrequency) PURE;
    STDMETHOD(GetStatus)            (THIS_ __out LPDWORD pdwStatus) PURE;
    STDMETHOD(Initialize)           (THIS_ __in LPDIRECTSOUND pDirectSound, __in LPCDSBUFFERDESC pcDSBufferDesc) PURE;
    STDMETHOD(Lock)                 (THIS_ DWORD dwOffset, DWORD dwBytes,
                                           __deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1,
                                           __deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE;
    STDMETHOD(Play)                 (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE;
    STDMETHOD(SetCurrentPosition)   (THIS_ DWORD dwNewPosition) PURE;
    STDMETHOD(SetFormat)            (THIS_ __in LPCWAVEFORMATEX pcfxFormat) PURE;
    STDMETHOD(SetVolume)            (THIS_ LONG lVolume) PURE;
    STDMETHOD(SetPan)               (THIS_ LONG lPan) PURE;
    STDMETHOD(SetFrequency)         (THIS_ DWORD dwFrequency) PURE;
    STDMETHOD(Stop)                 (THIS) PURE;
    STDMETHOD(Unlock)               (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1,
                                           __in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE;
    STDMETHOD(Restore)              (THIS) PURE;
};

の中へ

    /// <summary>
/// Line 687 Dsound.h
/// </summary>
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("279AFA85-4981-11CE-A521-0020AF0BE560")]
public interface IDirectSoundBuffer
{
    //IDirectSoundBuffer methods
    void GetCaps([Out, MarshalAs(UnmanagedType.LPStruct)] DSBufferCaps pDSBufferCaps); //TODO
    void GetCurrentPosition([Out] out UInt32 pdwCurrentPlayCursor, [Out] out UInt32 pdwCurrentWriteCursor);
    void GetFormat([Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "AMEngine.Wave.WaveFormatMarshaler")] out AMEngine.Wave.WaveFormat pwfxFormat,
                    int dwSizeAllocated, [Out] out int pdwSizeWritten); //TODO implement
    [return: MarshalAs(UnmanagedType.I4) /*See http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx */]
    Int32 GetVolume();
    [return: MarshalAs(UnmanagedType.I4)]
    Int32 GetPan();
    [return: MarshalAs(UnmanagedType.I4)]
    Int32 GetFrequency();
    [return: MarshalAs(UnmanagedType.I4)]
    Int32 GetStatus();
    void Initialize([In, MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, [In] DSBufferDescription pcDSBufferDesc);
    void Lock(int dwOffset, int dwBytes,
              [Out] out IntPtr ppvAudioPtr1, [Out] out int pdwAudioBytes1,
              [Out] out IntPtr ppvAudioPtr2, [Out] out int pdwAudioBytes2,
              DSBLock dwFlags /*TODO Flags enum erstellen */);
    void Play(int dwReserved1, int dwPriority, DSBPlayFlags dwFlags); //TODO Flags enum erstellen -- Done
    void SetCurrentPosition(int dwNewPosition);
    void SetFormat([In] AMEngine.Wave.WaveFormat pcfxFormat);
    void SetVolume(int lVolume);
    void SetPan(int lPan);
    void SetFrequency(int dwFrequency);
    void Stop();
    void Unlock([In] IntPtr pvAudioPtr1, int dwAudioBytes1,
                [In] IntPtr pvAudioPtr2, int dwAudioBytes2);
    void Restore();

}

次のコードで正常に作成されます。

 DSBufferDescription secondaryBufferDesc = new DSBufferDescription();
        secondaryBufferDesc.dwBufferBytes = (uint)(bufferSize * 2);
        //http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dsbcaps%28v=vs.85%29.aspx
        secondaryBufferDesc.dwFlags = DirectSoundBufferCaps.DSBCAPS_CTRLVOLUME |
                                      DirectSoundBufferCaps.DSBCAPS_CTRLPOSITIONNOTIFY |
                                      DirectSoundBufferCaps.DSBCAPS_GETCURRENTPOSITION2 |
                                      DirectSoundBufferCaps.DSBCAPS_GLOBALFOCUS |
                                      DirectSoundBufferCaps.DSBCAPS_STICKYFOCUS;
        secondaryBufferDesc.dwReserved = 0;
        secondaryBufferDesc.dwSize = Marshal.SizeOf(secondaryBufferDesc);
        secondaryBufferDesc.guid3DAlgorithm = Guid.Empty;
        secondaryBufferDesc.guid3DAlgorithm = Guid.Empty;

        Wave.WaveFormat format = new Wave.WaveFormat(waveFormat, waveFormat.SampleRate);
        GCHandle lpwfxSecondaryPtr = GCHandle.Alloc(format, GCHandleType.Pinned);
        secondaryBufferDesc.lpwfxFormat = lpwfxSecondaryPtr.AddrOfPinnedObject();
        //IntPtr waveFormatPtr = Marshal.AllocHGlobal(Marshal.SizeOf(waveFormat));
        //Marshal.StructureToPtr(waveFormat, waveFormatPtr, false);
        //secondaryBufferDesc.lpwfxFormat = waveFormatPtr;

        object primaryBufferObj, secondaryBufferObj;
        //http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.idirectsound8.idirectsound8.createsoundbuffer%28v=vs.85%29.aspx
        directSound.CreateSoundBuffer(primaryBufferDesc, out primaryBufferObj, IntPtr.Zero);
        directSound.CreateSoundBuffer(secondaryBufferDesc, out secondaryBufferObj, IntPtr.Zero);

        lpwfxSecondaryPtr.Free();

        this.primaryBuffer = (IDirectSoundBuffer)primaryBufferObj;
        this.secondaryBuffer = (IDirectSoundBuffer)secondaryBufferObj;

音量は次のコードで設定されます: (私が渡す値は -56 です) 音なし = 0 および maxsound = -10000

        private void SetCurrentVolume()
    {
        if (secondaryBuffer != null)
        {
            secondaryBuffer.SetVolume(volume);
        }
    }
4

1 に答える 1

1

エラーは簡単です: 別のインターフェイスを照会するために使用しているインターフェイス ポインターは、それE_NOINTERFACEを提供できません。つまり、あなた (またはおそらくあなたが使用しているライブラリ) はIDirectSoundBuffer、バッファ オブジェクトではない何かから QI を行っています。エラー箇所周辺のコードスニペットを掲載していただけると助かります。

于 2012-06-16T16:58:20.993 に答える