Esempio n. 1
0
        private void InitializeInternal()
        {
            const int reftimesPerMillisecond = 10000;

            _audioClient = AudioClient.FromMMDevice(Device);
            _outputFormat = SetupWaveFormat(_source, _audioClient);

            long latency = _latency * reftimesPerMillisecond;
            AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED_TRY_AGAIN:
            try
            {

                if (!_eventSync)
                    _audioClient.Initialize(_shareMode, AudioClientStreamFlags.None, latency, 0, _outputFormat,
                        Guid.Empty);
                else //event sync
                {
                    if (_shareMode == AudioClientShareMode.Exclusive) //exclusive
                    {
                        _audioClient.Initialize(_shareMode, AudioClientStreamFlags.StreamFlagsEventCallback, latency,
                            latency, _outputFormat, Guid.Empty);
                    }
                    else //shared
                    {
                        _audioClient.Initialize(_shareMode, AudioClientStreamFlags.StreamFlagsEventCallback, 0, 0,
                            _outputFormat, Guid.Empty);
                        //latency = (int)(_audioClient.StreamLatency / reftimesPerMillisecond);
                    }
                }
            }
            catch (CoreAudioAPIException exception)
            {
                if (exception.ErrorCode == unchecked((int)0x88890019)) //AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED
                {
                    const long reftimesPerSec = 10000000;
                    int framesInBuffer = _audioClient.GetBufferSize();
                    // ReSharper disable once PossibleLossOfFraction
                    latency = (int)(reftimesPerSec * framesInBuffer / _outputFormat.SampleRate + 0.5);
                    goto AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED_TRY_AGAIN;
                }
                throw;
            }

            if (_audioClient.StreamLatency != 0) //windows 10 returns zero, got no idea why => https://github.com/filoe/cscore/issues/11
            {
                Latency = (int)(_audioClient.StreamLatency / reftimesPerMillisecond);
            }

            if (_eventSync)
            {
                _eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
                _audioClient.SetEventHandle(_eventWaitHandle.SafeWaitHandle.DangerousGetHandle());
            }

            _renderClient = AudioRenderClient.FromAudioClient(_audioClient);
        }
Esempio n. 2
0
        private bool FeedBuffer(AudioRenderClient renderClient, byte[] buffer, int numFramesCount, int frameSize)
        {
            //calculate the number of bytes to "feed"
            int count = numFramesCount * frameSize;
            count -= (count % _source.WaveFormat.BlockAlign);
            //if the driver did not request enough data, return true to continue playback
            if (count <= 0)
                return true;

            //get the requested data
            int read = _source.Read(buffer, 0, count);
            //if the source did not provide enough data, we abort the playback by returning false
            if (read <= 0)
                return false;

            //calculate the number of FRAMES to request
            int actualNumFramesCount = read / frameSize;

            //again there are some special requirements for exclusive mode AND eventsync
            if (_shareMode == AudioClientShareMode.Exclusive && _eventSync &&
                read < count)
            {
                /* The caller can request a packet size that is less than or equal to the amount
                 * of available space in the buffer (except in the case of an exclusive-mode stream
                 * that uses event-driven buffering; for more information, see IAudioClient::Initialize).
                 * see https://msdn.microsoft.com/en-us/library/windows/desktop/dd368243%28v=vs.85%29.aspx - remarks*/

                //since we have to provide exactly the requested number of frames, we clear the rest of the array
                Array.Clear(buffer, read, count - read);
                //set the number of frames to request memory for, to the number of requested frames
                actualNumFramesCount = numFramesCount;
            }

            IntPtr ptr = renderClient.GetBuffer(actualNumFramesCount);

            //we may should introduce a try-finally statement here, but the Marshal.Copy method should not
            //throw any relevant exceptions ... so we should be able to always release the packet
            Marshal.Copy(buffer, 0, ptr, read);
            renderClient.ReleaseBuffer(actualNumFramesCount, AudioClientBufferFlags.None);

            return true;
        }
Esempio n. 3
0
        private void InitializeInternal()
        {
            _audioClient = AudioClient.FromMMDevice(Device);
            _outputFormat = SetupWaveFormat(_source.WaveFormat, _audioClient);

            long latency = _latency * 10000;

            if (!_eventSync)
            {
                _audioClient.Initialize(_shareMode, AudioClientStreamFlags.None, latency, 0, _outputFormat, Guid.Empty);
            }
            else //event sync
            {
                if (_shareMode == AudioClientShareMode.Exclusive) //exclusive
                {
                    _audioClient.Initialize(_shareMode, AudioClientStreamFlags.StreamFlags_EventCallback, latency, latency, _outputFormat, Guid.Empty);
                }
                else //shared
                {
                    _audioClient.Initialize(_shareMode, AudioClientStreamFlags.StreamFlags_EventCallback, 0, 0, _outputFormat, Guid.Empty);
                    _latency = (int)(_audioClient.StreamLatency / 10000);
                }

                _eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
                _audioClient.SetEventHandle(_eventWaitHandle.SafeWaitHandle.DangerousGetHandle());
            }

            _renderClient = AudioRenderClient.FromAudioClient(_audioClient);
            _simpleAudioVolume = SimpleAudioVolume.FromAudioClient(_audioClient);
            _simpleAudioVolume.MasterVolume = 1f;
        }
Esempio n. 4
0
        private void CleanupResources()
        {
            if (_createdResampler && _source is DmoResampler)
            {
                ((DmoResampler)_source).DisposeResamplerOnly();
                _source = null;
            }

            if (_renderClient != null)
            {
                _renderClient.Dispose();
                _renderClient = null;
            }
            if (_audioClient != null && _audioClient.BasePtr != IntPtr.Zero)
            {
                try
                {
                    _audioClient.StopNative();
                    _audioClient.Reset();
                }
                catch (CoreAudioAPIException ex)
                {
                    if (ex.ErrorCode != unchecked((int)0x88890001)) //AUDCLNT_E_NOT_INITIALIZED
                        throw;
                }
                _audioClient.Dispose();
                _audioClient = null;
            }
            if (_eventWaitHandle != null)
            {
                _eventWaitHandle.Close();
                _eventWaitHandle = null;
            }

            _isInitialized = false;
        }
Esempio n. 5
0
        private bool FeedBuffer(AudioRenderClient renderClient, byte[] buffer, int numFramesCount, int frameSize)
        {
            int count = numFramesCount * frameSize;
            count -= (count % _source.WaveFormat.BlockAlign);
            if (count <= 0)
                return true;

            int read = _source.Read(buffer, 0, count);

            var ptr = renderClient.GetBuffer(numFramesCount);
            Marshal.Copy(buffer, 0, ptr, read);
            renderClient.ReleaseBuffer((int)(read / frameSize), AudioClientBufferFlags.None);

            return read > 0;
        }