unsafe public bool IsFormatSupported(ShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { int hret; IntPtr closestMatchPtr = IntPtr.Zero; if (shareMode == ShareMode.Exclusive) { hret = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, IntPtr.Zero); } else { hret = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, (IntPtr)(&closestMatchPtr)); } if (closestMatchPtr != IntPtr.Zero) { closestMatchFormat = Marshal.PtrToStructure <WaveFormatExtensible>(closestMatchPtr); Marshal.FreeCoTaskMem(closestMatchPtr); } else { closestMatchFormat = null; } if (hret == 0 || closestMatchPtr != null) { return(true); } else if (hret == 1 || hret == (int)AudioClientErrors.UnsupportedFormat) { return(false); } Marshal.ThrowExceptionForHR(hret); return(false); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns> /// <c>true</c> if [is format supported] [the specified share mode]; otherwise, <c>false</c>. /// </returns> public bool IsFormatSupported(EAudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { int hresult = _realAudioClient.IsFormatSupported(shareMode, desiredFormat, out closestMatchFormat); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } //else if (hresult == (int)AudioClientErrors.UnsupportedFormat) //{ // return false; //} else { Marshal.ThrowExceptionForHR(hresult); } // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult.ToString()); }
/// <summary> /// Tries to resolve a valid format pointer for the audio client. /// </summary> /// <param name="audioClient">The audio client to use.</param> /// <param name="shareMode">The share mode to use.</param> /// <returns>A pointer to a valid format, or zero if one cannot be found.</returns> public static IntPtr GetFormatPointer(IAudioClient audioClient, AUDCLNT_SHAREMODE shareMode) { var formatPtr = IntPtr.Zero; if (shareMode == AUDCLNT_SHAREMODE.AUDCLNT_SHAREMODE_SHARED) { audioClient.GetMixFormat(out formatPtr); } else { // Otherwise we need to find a supported format foreach (var format in TestWaveFormats) { var formatMatch = IntPtr.Zero; var supported = audioClient.IsFormatSupported(shareMode, format, out formatMatch); if (supported == 0) { formatPtr = format; break; } else if (supported == 1) { formatPtr = formatMatch; break; } } if (formatPtr == IntPtr.Zero) { Assert.Inconclusive("Unable to find a valid format pointer."); } } return(formatPtr); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns>True if the format is supported</returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { IntPtr pointerToPtr = GetPointerToPointer(); // IntPtr.Zero; // Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormatExtensible>()); closestMatchFormat = null; int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, pointerToPtr); var closestMatchPtr = MarshalHelpers.PtrToStructure <IntPtr>(pointerToPtr); if (closestMatchPtr != IntPtr.Zero) { closestMatchFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(closestMatchPtr); Marshal.FreeCoTaskMem(closestMatchPtr); } Marshal.FreeHGlobal(pointerToPtr); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } if (hresult == (int)AudioClientErrors.UnsupportedFormat) { // Succeeded but the specified format is not supported in exclusive mode. return(shareMode != AudioClientShareMode.Exclusive); } Marshal.ThrowExceptionForHR(hresult); // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult); }
public bool IsFormatSupported(AudioClientShareMode shareMode, WAVEFORMATEXTENSIBLE format, ref WAVEFORMATEXTENSIBLE closestMatch) { int hr = _RealClient.IsFormatSupported(shareMode, format, out closestMatch); bool ret = false; if (hr == 0) { ret = true; } else if (hr == 1) { ret = false; } else { Marshal.ThrowExceptionForHR(hr); } return(ret); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns>True if the format is supported</returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, out closestMatchFormat); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } if (hresult == (int)AudioClientErrors.UnsupportedFormat) { return(false); } Marshal.ThrowExceptionForHR(hresult); // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns>True if the format is supported</returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { IntPtr pointerToPtr = GetPointerToPointer(); // IntPtr.Zero; // Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormatExtensible>()); closestMatchFormat = null; int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, pointerToPtr); var closestMatchPtr = MarshalHelpers.PtrToStructure <IntPtr>(pointerToPtr); if (closestMatchPtr != IntPtr.Zero) { closestMatchFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(closestMatchPtr); Marshal.FreeCoTaskMem(closestMatchPtr); } Marshal.FreeHGlobal(pointerToPtr); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } if (hresult == (int)AudioClientErrors.UnsupportedFormat) { // documentation is confusing as to what this flag means // https://docs.microsoft.com/en-us/windows/desktop/api/audioclient/nf-audioclient-iaudioclient-isformatsupported // "Succeeded but the specified format is not supported in exclusive mode." return(false); // shareMode != AudioClientShareMode.Exclusive; } Marshal.ThrowExceptionForHR(hresult); // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns> /// <c>true</c> if [is format supported] [the specified share mode]; otherwise, <c>false</c>. /// </returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormatExtensible desiredFormat, out WaveFormatExtensible closestMatchFormat) { int hresult = audioClientInterface.IsFormatSupported(shareMode, ref desiredFormat, out closestMatchFormat); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } else if (hresult == unchecked ((int)0x88890008)) // UnsupportedFormat { return(false); } else { this.EventWriterDLL.WriteLine(EventWriterDLL.SeverityTypes.Error, 0x01, "Error Code in AudioClient::IsFormatSupported: " + hresult); return(false); } }
public CoreAudio(bool microphone = false) { const uint REFTIMES_PER_SEC = 10000000; const uint CLSCTX_INPROC_SERVER = 1; Guid clsid = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"); Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); oEnumerator = null; uint hResult = CoCreateInstance(ref clsid, null, CLSCTX_INPROC_SERVER, ref IID_IUnknown, out oEnumerator); if (hResult != 0 || oEnumerator == null) { throw new Exception("CoCreateInstance() pInvoke failed"); } iMde = oEnumerator as IMMDeviceEnumerator; if (iMde == null) { throw new Exception("COM cast failed to IMMDeviceEnumerator"); } IntPtr pDevice = IntPtr.Zero; //iMde.EnumAudioEndpoints(EDataFlow.eCapture, DEVICE_STATE_ACTIVE,ref pDevice); int retVal; if (microphone) { retVal = iMde.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eConsole, ref pDevice); } else { retVal = iMde.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eConsole, ref pDevice); } if (retVal != 0) { throw new Exception("IMMDeviceEnumerator.GetDefaultAudioEndpoint()"); } //int dwStateMask = DEVICE_STATE_ACTIVE | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED; //IntPtr pCollection = IntPtr.Zero; //retVal = iMde.EnumAudioEndpoints(EDataFlow.eRender, dwStateMask, ref pCollection); //if (retVal != 0) //{ // throw new Exception("IMMDeviceEnumerator.EnumAudioEndpoints()"); //} imd = (IMMDevice)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(pDevice); if (imd == null) { throw new Exception("COM cast failed to IMMDevice"); } Guid iid = new Guid("5CDF2C82-841E-4546-9722-0CF74078229A"); uint dwClsCtx = (uint)CLSCTX.CLSCTX_ALL; IntPtr pActivationParams = IntPtr.Zero; IntPtr pEndPoint = IntPtr.Zero; retVal = imd.Activate(iid, dwClsCtx, pActivationParams, out pEndPoint); if (retVal != 0) { throw new Exception("IMMDevice.Activate()"); } iAudioEndpoint = (IAudioEndpointVolume)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(pEndPoint); if (iAudioEndpoint == null) { throw new Exception("COM cast failed to IAudioEndpointVolume"); } iid = new Guid("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2"); dwClsCtx = (uint)CLSCTX.CLSCTX_ALL; pActivationParams = IntPtr.Zero; pEndPoint = IntPtr.Zero; retVal = imd.Activate(iid, dwClsCtx, pActivationParams, out pEndPoint); if (retVal != 0) { throw new Exception("IAudioClient.Activate() " + Convert.ToString(retVal, 2)); } iAudioClient = (IAudioClient)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(pEndPoint); if (iAudioClient == null) { throw new Exception("COM cast failed to iAudioClient"); } ulong processInterval; ulong minimumInterval; retVal = iAudioClient.GetDevicePeriod(out processInterval, out minimumInterval); if (retVal != 0) { throw new Exception("iAudioClient.GetDevicePeriod()"); } waveformat = new WAVEFORMATEX(); waveformat.wFormatTag = (ushort)WaveFormatEncoding.Pcm; waveformat.nChannels = 2; waveformat.nBlockAlign = 4; waveformat.wBitsPerSample = 16; waveformat.nSamplesPerSec = 44100; waveformat.cbSize = 0; waveformat.nAvgBytesPerSec = 176400; IntPtr reqForm = Marshal.AllocHGlobal(Marshal.SizeOf(waveformat)); Marshal.StructureToPtr(waveformat, reqForm, false); IntPtr propForm = Marshal.AllocHGlobal(Marshal.SizeOf(waveformat)); retVal = iAudioClient.IsFormatSupported(AUDCLNT_SHAREMODE.AUDCLNT_SHAREMODE_SHARED, reqForm, out propForm); if (retVal != 0) { throw new Exception("IAudioClient.IsFormatSupported()"); } if (microphone) { retVal = iAudioClient.Initialize(AUDCLNT_SHAREMODE.AUDCLNT_SHAREMODE_EXCLUSIVE, 0, 2000000, 0, reqForm, Guid.Empty); } else { retVal = iAudioClient.Initialize(AUDCLNT_SHAREMODE.AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 2000000, 0, reqForm, Guid.Empty); } if (retVal != 0) { throw new Exception("IAudioClient.Initialize() " + retVal); } uint buffersize = 0; retVal = iAudioClient.GetBufferSize(out buffersize); if (retVal != 0) { throw new Exception("IAudioClient.GetBufferSize()"); } iid = new Guid("C8ADBD64-E71E-48a0-A4DE-185C395CD317"); IntPtr capclient = IntPtr.Zero; retVal = iAudioClient.GetService(iid, out capclient); if (retVal != 0) { throw new Exception("IAudioClient.GetService()"); } iAudioCaptureClient = (IAudioCaptureClient)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(capclient); if (iAudioCaptureClient == null) { throw new Exception("COM cast failed to iAudioCaptureClient"); } hnsActualDuration = (double)(REFTIMES_PER_SEC * buffersize / waveformat.nSamplesPerSec); // 8391 smallest possible value recordingthread = new Thread(recordingloop); recordingthread.IsBackground = false; recordingthread.Start(); }