Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #8
0
        /// <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();
        }