예제 #1
0
        private void GetAudioRenderClient()
        {
            object result;
            var    IID_AUDIO_RENDER_CLIENT = typeof(IAudioRenderClient).GUID;

            Marshal.ThrowExceptionForHR(_realAudioClient.GetService(IID_AUDIO_RENDER_CLIENT, out result));
            _AudioRenderClient = new AudioRenderClient(result as IAudioRenderClient);
        }
예제 #2
0
        private static IAudioCaptureClient CreateRenderClient(IAudioClient audioClient)
        {
            object client;

            audioClient.GetService(typeof(IAudioCaptureClient).GUID, out client);
            return(client as IAudioCaptureClient);
        }
예제 #3
0
        private void InitializeAudio(AudioDataFlow audioFlow, IMMDeviceEnumerator deviceEnumerator)
        {
            //Get Audio Device
            COMResult result = deviceEnumerator.GetDefaultAudioEndpoint(audioFlow, EndPointRole.eMultimedia, out _audioDevice);

            //Register End point notification
            _notifyClient = new MMNotificationClient();
            result        = deviceEnumerator.RegisterEndpointNotificationCallback(_notifyClient);
            //Get Audio Client from device
            result       = _audioDevice.Activate(typeof(IAudioClient).GUID, 0, IntPtr.Zero, out object obj);
            _audioClient = (IAudioClient)obj;
            //Get Audio Meter from device
            result      = _audioDevice.Activate(typeof(IAudioMeterInformation).GUID, 0, IntPtr.Zero, out obj);
            _audioMeter = (IAudioMeterInformation)obj;
            //Initialize Audio Client.
            _sessionGuid = new Guid();
            result       = _audioClient.GetMixFormat(out waveFormat);
            AudioClientStreamFlags streamFlag = AudioClientStreamFlags.None;

            if (audioFlow == AudioDataFlow.eRender)
            {
                streamFlag = AudioClientStreamFlags.Loopback;
            }
            result = _audioClient.Initialize(AudioClientMode.Shared, streamFlag, 10000000, 0, waveFormat, ref _sessionGuid);
            //Get Capture Client.
            result = _audioClient.GetService(typeof(IAudioCaptureClient).GUID, out obj);
            Marshal.ThrowExceptionForHR((int)result);
            _audioCaptureClient = (IAudioCaptureClient)obj;
            result = _audioClient.Start();
            //Change wave format here
            SetupWaveFormat(waveFormat);
        }
예제 #4
0
파일: AudioClient.cs 프로젝트: tihilv/Vkm
        private void GetAudioCaptureClient()
        {
            object result;
            int    hr = _RealClient.GetService(ref IID_IAudioCaptureClient, out result);

            Marshal.ThrowExceptionForHR(hr);
            _audioCaptureClient = new AudioCaptureClient(this, result as IAudioCaptureClient);
        }
예제 #5
0
 internal PlaybackClient_WindowsCoreApi(IAudioClient IAudioClient, System.IO.Stream Stream, int NumChannel, int FrameSize, uint SamplesRate, Type DataFormat)
 {
     _IAudioClient = IAudioClient;
     _IAudioClient.GetService(ref IID_IAudioRenderClient, out _IAudioRenderClient);
     _IAudioClient.GetBufferSize(out _BufferFrameCount);
     _Stream         = Stream;
     _FrameSize      = FrameSize;
     _BufferDuration = _BufferFrameCount / (SamplesRate / 1000);
     _FullBuffer     = new byte[_FrameSize * _BufferFrameCount];
     _Thread         = new System.Threading.Thread(Loop);
     _ChannelCount   = NumChannel;
     _SampleRate     = SamplesRate;
     _Format         = DataFormat;
 }
예제 #6
0
        protected T GetService <T>(Guid guid) where T : class
        {
            object obj; int hr = audioClient.GetService(guid, out obj);

            if (hr != 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }
            T service = obj as T;

            if (service == null)
            {
                throw new NotSupportedException();
            }
            return(service);
        }
예제 #7
0
        private void StartSilenceGeneration()
        {
            IntPtr mixFormatPtr = IntPtr.Zero;

            try
            {
                Checked(_endpoint.Activate(ref IAudioClientId, ClsCtxEnum.All, IntPtr.Zero, out var obj), "Silence.Activate");
                _audioClientForRendering = (IAudioClient)obj;

                Checked(_audioClientForRendering.GetMixFormat(out mixFormatPtr), "Silence.GetMixFormat");
                WaveFormatEx format = (WaveFormatEx)Marshal.PtrToStructure(mixFormatPtr, typeof(WaveFormatEx));

                CheckFormat(format);

                Checked(_audioClientForRendering.Initialize(AudioClientShareModeEnum.Shared, AudioClientStreamFlagsEnum.None, 10_000_000 * 5, 0, mixFormatPtr, Guid.Empty), "Silence.Initialize");
                Checked(_audioClientForRendering.GetBufferSize(out var bufferSize), "Silence.GetBufferSize");
                Checked(_audioClientForRendering.GetService(IAudioRenderClientId, out var renderObj), "Silence.GetService");

                _audioRenderClient = (IAudioRenderClient)renderObj;

                Checked(_audioClientForRendering.Start(), "Silence.Start");

                _silenceThread      = new Thread(() => SilenceGenerationRoutine(bufferSize, format));
                _silenceThread.Name = "Silence generator";
                _silenceThread.Start();
            }
            catch (Exception e)
            {
                ReleaseComObject(ref _audioClientForRendering);
                ReleaseComObject(ref _audioRenderClient);
                Core.LogError(e, "Faied to StartSilenceGeneration");
            }
            finally
            {
                if (mixFormatPtr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(mixFormatPtr);
                }
            }
        }
예제 #8
0
        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();
        }
예제 #9
0
        public WaveFormatEx Open()
        {
            StopSilenceThread();

            Log.Information("Opening DesktopAudio");
            IMMDeviceEnumerator deviceEnumerator = null;
            IntPtr mixFormatPtr = IntPtr.Zero;

            try
            {
                bool render = true;
                deviceEnumerator = Activator.CreateInstance(typeof(MMDeviceEnumerator)) as IMMDeviceEnumerator;
                var res = deviceEnumerator.GetDefaultAudioEndpoint(
                    render ? DataFlowEnum.Render : DataFlowEnum.Capture,
                    render ? RoleEnum.Console : RoleEnum.Communications,
                    out _endpoint);

                if (render)
                {
                    StartSilenceGeneration();
                }

                Checked(_endpoint.Activate(ref IAudioClientId, ClsCtxEnum.All, IntPtr.Zero, out var obj), "Activate");
                _audioClient = (IAudioClient)obj;

                Checked(_audioClient.GetMixFormat(out mixFormatPtr), "GetMixFormat");
                WaveFormatEx outputFormat = (WaveFormatEx)Marshal.PtrToStructure(mixFormatPtr, typeof(WaveFormatEx));

                if (!render) // for render it is checked in the StartSilenceGeneration();
                {
                    CheckFormat(outputFormat);
                }

                _bytesPerFrame = outputFormat.BlockAlign;

                var flags = AudioClientStreamFlagsEnum.StreamFlagsEventCallback | (render ? AudioClientStreamFlagsEnum.StreamFlagsLoopback : AudioClientStreamFlagsEnum.None);
                Checked(_audioClient.Initialize(AudioClientShareModeEnum.Shared, flags, 10_000_000 * 5, 0, mixFormatPtr, Guid.Empty), "Initialize");

                Checked(_audioClient.GetService(IAudioCaptureClientId, out var captureObj), "GetService");
                _audioCaptureClient = (IAudioCaptureClient)captureObj;

#pragma warning disable CS0618 // Type or member is obsolete
                Checked(_audioClient.SetEventHandle(_dataAvailable.Handle), "SetEventHandle");
#pragma warning restore CS0618 // Type or member is obsolete
                Checked(_audioClient.Start(), "Start");

                return(outputFormat);
            }
            catch (Exception e)
            {
                Core.LogError(e, "Open desktop audio failed");
                StopSilenceThread();

                ReleaseComFields();
                throw;
            }
            finally
            {
                if (mixFormatPtr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(mixFormatPtr);
                }

                ReleaseComObject(ref deviceEnumerator);
            }
        }