/// <summary>
        /// Stop recording audio and save it to destination WAV-file
        /// </summary>
        /// <param name="destination">Output WAV file containing recorderd sound</param>
        public void StopRecording(string destination)
        {
            var mciCommand = "stop capture";

            Mci.SendString(mciCommand, null, 0, 0);

            mciCommand = string.Format("save capture {0}", destination);
            Mci.SendString(mciCommand, null, 0, 0);

            mciCommand = "close capture";
            Mci.SendString(mciCommand, null, 0, 0);
        }
        /// <summary>
        /// Pause audio playback
        /// </summary>
        public void Pause()
        {
            if (_alias == null)
            {
                return;
            }

            var mciCommand = string.Format("pause {0}", _alias);

            Mci.SendString(mciCommand, null, 0, 0);

            _pauseTime = DateTime.Now;
            _isPaused  = true;
        }
        /// <summary>
        /// Resume playing audio
        /// </summary>
        public void Resume()
        {
            if (_alias == null || !_isPaused)
            {
                return;
            }

            var mciCommand = string.Format("resume {0}", _alias);

            Mci.SendString(mciCommand, null, 0, 0);

            var pause = DateTime.Now - _pauseTime;

            _pauseDuration += pause.Duration().Seconds * 1000 + pause.Duration().Milliseconds;
            _isPaused       = false;
        }
예제 #4
0
        /// <summary>
        /// Pauses playing audio.
        /// </summary>
        public void Pause()
        {
            if (_alias is null)
            {
                return;
            }

            var mciCommand = string.Format("pause {0}", _alias);

            Mci.SendString(mciCommand, null, 0, 0);

            // If the playback was paused, the player memorizes how many milliseconds
            // it was "idle" and then adds this time to the total awaiting time.

            _pauseTime = DateTime.Now;
            _isPaused  = true;
        }
        /// <summary>
        /// Stop playing audio and close MCI device
        /// </summary>
        public void Stop()
        {
            if (_alias == null)
            {
                return;
            }

            if (_isPaused)
            {
                Resume();
            }

            var mciCommand = string.Format("stop {0}", _alias);

            Mci.SendString(mciCommand, null, 0, 0);

            mciCommand = string.Format("close {0}", _alias);
            Mci.SendString(mciCommand, null, 0, 0);

            _alias = null;
        }
        /// <summary>
        /// Start recording audio with specific settings
        /// </summary>
        /// <param name="samplingRate">Sampling rate</param>
        /// <param name="channelCount">Number of channels (1=mono, 2=stereo)</param>
        /// <param name="bitsPerSample">Number of bits per sample (8, 16, 24 or 32)</param>
        public void StartRecording(int samplingRate = 44100, short channelCount = 1, short bitsPerSample = 16)
        {
            var mciCommand = "open new type waveaudio alias capture";
            var result     = Mci.SendString(mciCommand, null, 0, 0);

            if (result != 0)
            {
                throw new System.InvalidOperationException("Could not open device for recording!");
            }

            mciCommand = string.Format("set capture alignment {0} bitspersample {1} samplespersec {2} " +
                                       "channels {3} bytespersec {4} time format samples format tag pcm",
                                       channelCount * bitsPerSample / 8,
                                       bitsPerSample,
                                       samplingRate,
                                       channelCount,
                                       samplingRate * channelCount * bitsPerSample / 8);
            Mci.SendString(mciCommand, null, 0, 0);

            mciCommand = "record capture";
            Mci.SendString(mciCommand, null, 0, 0);
        }
        /// <summary>
        /// Play audio contained in WAV file asynchronously
        /// </summary>
        /// <param name="source">WAV file to play</param>
        /// <param name="startPos">Number of the first sample to play</param>
        /// <param name="endPos">Number of the last sample to play</param>
        public async Task PlayAsync(string source, int startPos = 0, int endPos = -1)
        {
            if (_isPaused)
            {
                Resume();
                return;
            }

            Stop();

            _alias = Guid.NewGuid().ToString();

            var mciCommand = string.Format("open \"{0}\" type waveaudio alias {1}", source, _alias);

            Mci.SendString(mciCommand, null, 0, 0);

            mciCommand = string.Format("set {0} time format samples", _alias);
            Mci.SendString(mciCommand, null, 0, 0);

            var durationBuffer = new StringBuilder(255);

            mciCommand = string.Format("status {0} length", _alias);
            Mci.SendString(mciCommand, durationBuffer, 255, 0);
            var duration = int.Parse(durationBuffer.ToString());

            var samplingRateBuffer = new StringBuilder(255);

            mciCommand = string.Format("status {0} samplespersec", _alias);
            Mci.SendString(mciCommand, samplingRateBuffer, 255, 0);
            var samplingRate = int.Parse(samplingRateBuffer.ToString());

            mciCommand = string.Format("play {2} from {0} to {1} notify", startPos, endPos, _alias);
            mciCommand = mciCommand.Replace(" to -1", "");
            Mci.SendString(mciCommand, null, 0, 0);

            // ======= here's how we do asynchrony with old technology from 90's )) ========

            var currentAlias = _alias;

            await Task.Delay((int)(duration * 1000.0 / samplingRate));

            // During this time someone could Pause player.
            // In this case we add pause duration to awaiting time.

            while (_isPaused || _pauseDuration > 0)
            {
                // first, we check if the pause is right now
                if (_isPaused)
                {
                    // then just await one second more
                    // (the stupidest wait spin I wrote in years ))))
                    await Task.Delay(1000);
                }

                if (_pauseDuration > 0)
                {
                    await Task.Delay(_pauseDuration);

                    _pauseDuration = 0;
                }
            }

            // During this time someone could stop and run player again, so _alias is already different.
            // In this case we don't stop player here because it was stopped some time before.

            if (currentAlias == _alias)
            {
                Stop();
            }
            // =============================================================================
        }