예제 #1
0
 public void Play()
 {
     _instance.Stop();
     _instance.Play();
     _instance.Volume = _volume;
     _iSaidStop       = false;
 }
예제 #2
0
        public virtual void Tick(long cycles = 0)
        {
            currentPeriod += (int)cycles;
            if (Restart && !ChannelThree)
            {
                //Stopping clears the buffer.
                Channel_Out.Stop();
                Channel_Out.Play();
            }

            //if looping and the buffer is empty, or starting a new sound.
            if (Play() && !ChannelThree)
            {
                Channel_Out.SubmitBuffer(CreateTone());
                Restart = false;
            }
            else if (Restart && ChannelThree && currentPeriod > period)
            {
                if (pendingSamples.Count >= 32)
                {
                    TriggerWavePlay();
                }
            }
            else if (Play() && ChannelThree)
            {
                //while(Channel_Out.PendingBufferCount < 50)
                //{
                //    Channel_Out.SubmitBuffer(bBuffer);
                //}
            }
        }
예제 #3
0
 public override void Stop()
 {
     if (mSong != null && !mSong.IsDisposed)
     {
         mSong.Stop();
     }
 }
예제 #4
0
        public void Playback_Exceptions()
        {
            var instance = new DynamicSoundEffectInstance(16000, AudioChannels.Mono);

            instance.Dispose();
            Assert.Throws <ObjectDisposedException>(() => { instance.Play(); });
            Assert.Throws <ObjectDisposedException>(() => { instance.Pause(); });
            Assert.Throws <ObjectDisposedException>(() => { instance.Resume(); });
            Assert.Throws <ObjectDisposedException>(() => { instance.Stop(); });
            Assert.Throws <ObjectDisposedException>(() => { instance.Stop(false); });
            Assert.Throws <ObjectDisposedException>(() => { instance.SubmitBuffer(new byte[0]); });
        }
예제 #5
0
        private void StateButton_Click(object sender, RoutedEventArgs e)
        {
            if (state == STATE.INIT)
            {
                StateButton.Content = "Stop";
                state = STATE.RECORD;

                if (microphone.State == MicrophoneState.Stopped)
                {
                    bufferCollection.Clear();
                    playback.Stop();
                    microphone.Start();
                }
            }
            else if (state == STATE.RECORD)
            {
                if (microphone.State == MicrophoneState.Started)
                {
                    StopRecording();
                }
            }
            else if (state == STATE.RECORDED)
            {
                StateButton.Content = "Stop";
                state = STATE.PLAY;

                playback.Stop();
                using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream stream = storage.OpenFile(FILE_NAME, FileMode.Open, FileAccess.Read))
                    {
                        byte[] buffer = new byte[stream.Length];
                        stream.Read(buffer, 0, buffer.Length);
                        playback.SubmitBuffer(buffer);
                    }
                }

                playback.Play();
            }
            else if (state == STATE.PLAY)
            {
                StopPlaying();
            }
            else
            {
                throw new ArgumentException("invalid state");
            }
        }
예제 #6
0
 /// <summary>
 /// Stops playback.
 /// </summary>
 public void StopPlayback()
 {
     if (playback.State == SoundState.Playing)
     {
         playback.Stop();
     }
 }
예제 #7
0
 public void Stop()
 {
     if (dynamicSound != null)
     {
         dynamicSound.Stop();
     }
 }
        private void UpdateCurrentTone()
        {
            if (_currentToneMillisecondsLeft > 0)
            {
                _currentToneMillisecondsLeft -= _dispatcherTimer.Interval.Milliseconds;
                return;
            }

            if (_dynamicSound != null)
            {
                _dynamicSound.Stop();                        // otherwise, buffer (1sec) is played out
            }
            if (_toneQueue.Count == 0)
            {
                _dispatcherTimer.Stop();
                return;
            }

            var newTone = _toneQueue.Dequeue();

            _currentToneMillisecondsLeft = newTone.DurationInMilliSeconds - _dispatcherTimer.Interval.Milliseconds;

            if (newTone.Mute)
            {
                return;
            }

            _currentToneFrequency = newTone.Frequency;

            _dynamicSound = new DynamicSoundEffectInstance(48000, AudioChannels.Stereo);
            _dynamicSound.BufferNeeded += GetSoundBuffer;

            _dynamicSound.Play();
        }
예제 #9
0
        protected override void Update(GameTime gameTime)
        {
            var keyboardState = Keyboard.GetState();

            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            if (previousKeyboardState != keyboardState)
            {
                if (keyboardState.IsKeyDown(Keys.A))
                {
                    dynamicSound.Play();
                }
                if (keyboardState.IsKeyDown(Keys.B))
                {
                    dynamicSound.Stop();
                }
                if (keyboardState.IsKeyDown(Keys.Space))
                {
                    streamingWave.Looped = !streamingWave.Looped;
                }

                previousKeyboardState = keyboardState;
            }

            base.Update(gameTime);
        }
예제 #10
0
        private static void PlaybackSpeech()
        {
            // trace the operation
            TraceHelper.AddMessage("About to playback speech");

            // create a sound effect instance
            DynamicSoundEffectInstance effect = new DynamicSoundEffectInstance(mic.SampleRate, AudioChannels.Mono);

            // submit all the buffers to the instance
            foreach (var buf in speechBufferList)
            {
                if (buf.Length > 0)
                {
                    effect.SubmitBuffer(buf);
                }
            }
            speechBufferList.Clear();

            // create an event handler to stop playback when all the buffers have been consumed
            effect.BufferNeeded += delegate
            {
                if (effect.PendingBufferCount == 0)
                {
                    effect.Stop();
                    TraceHelper.AddMessage("Finished playing back speech");
                }
            };

            // play the speech
            FrameworkDispatcher.Update();
            effect.Play();
        }
예제 #11
0
 public void Stop()
 {
     lock (ControlLock)
     {
         _State = SoundState.Stopped;
         Inst?.Stop();
     }
 }
예제 #12
0
        public void Play(string fileName)
        {
            // If another one is playing, stop it
            _playback.Stop();

            // Fetch the waveform data from isolated storage and play it
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream stream = storage.OpenFile(fileName, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, buffer.Length);
                    _playback.SubmitBuffer(buffer);
                }
            }
            _playback.Play();
        }
예제 #13
0
        public void TestPendingBufferCount()
        {
            mono8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            var dispInstance = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_16Bits);

            dispInstance.Dispose();

            var pendingCount = 0;

            ///////////////////////////////////////////////////////////////////////////
            // 1. Test that it throws ObjectDisposedException with disposed instance
            Assert.Throws <ObjectDisposedException>(() => pendingCount = dispInstance.PendingBufferCount, "PendingBufferCount did not throw ObjectDisposedException");

            //////////////////////////////////
            // 2. Test that it does not crash
            Assert.DoesNotThrow(() => pendingCount = mono8Bits.PendingBufferCount, "PendingBufferCount crashed with valid instance");

            ////////////////////////////
            // 3. Test the default value
            mono8Bits.Stop();
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount default value is not 0");

            //////////////////////////////////////////////////
            // 4. Check the value after adding some buffers
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            Assert.AreEqual(3, mono8Bits.PendingBufferCount, "PendingBufferCount value is not 3 after adding buffers");

            //////////////////////////////////
            // 5. Check the value after stop
            mono8Bits.Stop();
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount default value is not 0");

            //////////////////////////////////
            // 6 Check the value after play
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 1000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 1000));
            mono8Bits.Play();
            Utilities.Sleep(1000);
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount value is not 0 after play");
            mono8Bits.Stop();

            mono8Bits.Dispose();
        }
예제 #14
0
 /// <summary>
 /// Used to stop the currently playing song.
 /// </summary>
 public override void stopSong()
 {
     if (dynamicSound != null)
     {
         dynamicSound.Stop();
         dynamicSound     = null;
         this.currentSong = null;
     }
 }
예제 #15
0
 public void Dispose()
 {
     if (_instance != null)
     {
         _instance.Stop(true);
         _instance.Dispose();
         _instance = null;
     }
 }
예제 #16
0
파일: XNAMP3.cs 프로젝트: samuliy/MP3Sharp
 public void Stop()
 {
     if (_Playing)
     {
         _Playing = false;
         _Instance.Stop();
         _Instance.BufferNeeded -= InstanceBufferNeeded;
     }
 }
예제 #17
0
        public void Stop()
        {
            if (m_Playing)
            {
                m_Playing = false;

                m_Instance.Stop();
                m_Instance.BufferNeeded -= instance_BufferNeeded;
            }
        }
예제 #18
0
파일: Song.cs 프로젝트: sethbattin/FNA
        internal void Stop()
        {
            PlayCount = 0;

#if !NO_STREAM_THREAD
            exitThread = true;
            if (songThread != null && Thread.CurrentThread != songThread)
            {
                songThread.Join();
            }
#endif

            timer.Stop();
            timer.Reset();

            soundStream.Stop();
            soundStream.BufferNeeded -= QueueBuffer;
            Vorbisfile.ov_time_seek(vorbisFile, 0.0);
        }
예제 #19
0
        /// <summary>
        /// DynamicSoundEffectInstance.BufferNeeded イベントの発生で呼び出されます。
        /// 必要に応じて Wave データを読み込み、DynamicSoundEffectInstance に設定します。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnDynamicSoundBufferNeeded(object sender, EventArgs e)
        {
            if (!Looped && totalDataCount == dataChunkHeader.Size)
            {
                // 再生を完全に終わらせるように処理します。
                if (dynamicSound.PendingBufferCount == 0)
                {
                    // 停止寸前であるため状態をリセットします。
                    // これにより、停止後に再生を開始した時に Wave データの先頭から再生できます。
                    Reset();

                    // 停止状態に設定します。
                    dynamicSound.Stop();
                }
                return;
            }

            if (asyncResult == null)
            {
                // 再生直後はここに入ります。
                // ここでは同期的に Wave データを読み込みます。
                ReadData();
            }
            else
            {
                // 非同期に Wave データを読み込んでいるので、その完了を待機します。
                asyncResult.AsyncWaitHandle.WaitOne();
            }

            if (dataCount == bufferSize)
            {
                // 最大サイズをフルに使用している場合は分割して設定します。
                var halfSize = bufferSize / 2;
                dynamicSound.SubmitBuffer(buffer, 0, halfSize);
                dynamicSound.SubmitBuffer(buffer, halfSize, halfSize);
            }
            else if (dataCount != 0)
            {
                // 最大サイズに足りていない場合はそのまま設定します。
                dynamicSound.SubmitBuffer(buffer, 0, dataCount);
            }

            dataCount = 0;

            if (!Looped && totalDataCount == dataChunkHeader.Size)
            {
                // ループ OFF で末尾に到達しているならば、ここで設定したバッファで再生を終えます。
                // なお、DynamicSoundEffectInstance は、Stop() および Stop(bool) メソッドを呼び出しても、
                // PendingBufferCount = 0 になるまで停止しない点に注意が必要です。
                return;
            }

            // 非同期に次の Wave データを読み込み、次の BufferNeeded イベント受信に備えます。
            asyncResult = readDataAsyncCaller.BeginInvoke(null, null);
        }
예제 #20
0
 /// <summary>
 /// Used to stop the currently playing song.
 /// </summary>
 public void stop()
 {
     if (dynamicSound != null)
     {
         dynamicSound.Stop(true);
         dynamicSound.BufferNeeded -= new EventHandler <EventArgs>(DynamicSound_BufferNeeded);
         position  = 0;
         count     = 0;
         byteArray = new byte[0];
     }
 }
예제 #21
0
        public void Play()
        {
            lock (this)
            {
                if (MediaState == MediaState.Playing)
                {
                    return;
                }

                MediaState = MediaState.Playing;

                if (enumerator == null)
                {
                    enumerator = decoder.GetEnumerator();
                }

                bufferCount = -1;
                effect.Stop();
                effect.Play();
            }
        }
예제 #22
0
        public override void Stop(AudioStopOptions options)
        {
            instance.Stop();

            instance.Dispose();
            instance = null;

            stream.Dispose();
            stream = null;

            buffer = null;
        }
예제 #23
0
 public void Dispose()
 {
     if (m_ThisInstance != null)
     {
         if (!m_ThisInstance.IsDisposed)
         {
             m_ThisInstance.Stop();
             m_ThisInstance.Dispose();
         }
         m_ThisInstance = null;
     }
 }
예제 #24
0
파일: XnaSound.cs 프로젝트: zxmak/ZXMAK2
 public void Dispose()
 {
     if (m_isDisposed)
     {
         return;
     }
     m_isDisposed = true;
     m_soundEffect.Stop();
     CancelWait();
     m_soundEffect.Dispose();
     m_waitEvent.Dispose();
     m_frameEvent.Dispose();
 }
예제 #25
0
 public void Dispose()
 {
     if (_thisInstance != null)
     {
         _thisInstance.BufferNeeded -= OnBufferNeeded;
         if (!_thisInstance.IsDisposed)
         {
             _thisInstance.Stop();
             _thisInstance.Dispose();
         }
         _thisInstance = null;
     }
 }
예제 #26
0
 public void Dispose()
 {
     if (m_ThisInstance != null)
     {
         m_ThisInstance.BufferNeeded -= OnBufferNeeded;
         if (!m_ThisInstance.IsDisposed)
         {
             m_ThisInstance.Stop();
             m_ThisInstance.Dispose();
         }
         m_ThisInstance = null;
     }
 }
예제 #27
0
        internal void Stop()
        {
#if !NO_STREAM_THREAD
            exitThread = true;
            if (songThread != null && Thread.CurrentThread != songThread)
            {
                songThread.Join();
            }
#endif

            soundStream.Stop();
            soundStream.BufferNeeded -= QueueBuffer;
            PlayCount = 0;
        }
 public override void Dispose()
 {
     mDisposed = true;
     try
     {
         mSong?.Stop();
         //Closing the source will lock the processing thread and then properly dispose of the song.
         mSource.Close();
     }
     catch
     {
         /* This is just to catch any B.S. errors that MonoGame shouldn't be throwing to us. */
     }
 }
예제 #29
0
        public void Stop_False()
        {
            // Calling Stop(false) has no effect

            using (var instance = new DynamicSoundEffectInstance(12000, AudioChannels.Mono))
            {
                instance.Play();
                Assert.AreEqual(SoundState.Playing, instance.State);

                instance.Stop(false);
                SleepWhileDispatching(20);
                Assert.AreEqual(SoundState.Playing, instance.State);
            }
        }
예제 #30
0
        public void Stop_RemovesBuffers()
        {
            using (var instance = new DynamicSoundEffectInstance(12000, AudioChannels.Mono))
            {
                instance.SubmitBuffer(GenerateSineWave(440, 12000, 1, 0.1f));
                instance.SubmitBuffer(GenerateSineWave(440, 12000, 1, 0.1f));
                instance.SubmitBuffer(GenerateSineWave(440, 12000, 1, 0.1f));
                Assert.AreEqual(3, instance.PendingBufferCount);

                instance.Stop();
                SleepWhileDispatching(20);
                Assert.AreEqual(0, instance.PendingBufferCount);
            }
        }
        public void TestBufferNeeded()
        {
            mono8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);

            mono8Bits.BufferNeeded += SetBufferNeededHasBeenCalledToTrue;

            var sizeOfOneSubBuffer = 44100 * 200 / 1000;

#if SILICONSTUDIO_PLATFORM_ANDROID
            sizeOfOneSubBuffer = mono8Bits.SubBufferSize;
#endif

            ////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 1. Check that BufferNeeded is thrown when the user call plays with insufficient number of audio data
            mono8Bits.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called when the user played without any buffers");
            bufferNeededHasBeenCalled = false;
            mono8Bits.Stop();
            
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 1000));
            Utilities.Sleep(50);
            bufferNeededHasBeenCalled = false;
            mono8Bits.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called when the user played wit one buffers");
            bufferNeededHasBeenCalled = false;
            mono8Bits.Stop();
            
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 2. Check that BufferNeeded is thrown when the user call SubmitBuffer with insufficient number of audio data
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, sizeOfOneSubBuffer));
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called when the user submit the first buffer");
            bufferNeededHasBeenCalled = false;

            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, sizeOfOneSubBuffer));
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called when the user submit the second buffer");
            bufferNeededHasBeenCalled = false;
            mono8Bits.Stop();
            
            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // 3. Check that BufferNeeded is thrown when the number of buffers falls from 3 to 2, 2 to 1, 1 to 0
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, sizeOfOneSubBuffer));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, sizeOfOneSubBuffer));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, sizeOfOneSubBuffer));
            Utilities.Sleep(50);
            bufferNeededHasBeenCalled = false;
            mono8Bits.Play();
            var lastBufferCount = mono8Bits.PendingBufferCount;
            var loopCount = 0;
            while (true)
            {
                Utilities.Sleep(10);

                if (lastBufferCount != mono8Bits.PendingBufferCount)
                {
                    lastBufferCount = mono8Bits.PendingBufferCount;
                    Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called when number of buffer pass from "+(lastBufferCount+1)+" to "+lastBufferCount);
                    bufferNeededHasBeenCalled = false;
                }
                if (lastBufferCount == 0)
                    break;

                ++loopCount;

                if(loopCount>100)
                    Assert.Fail("The test process is block in the loop.");
            }
            mono8Bits.Stop();

            ///////////////////////////////////////////////////////////////////////////
            // 4. Check that invocation of BufferNeeded does not block audio playback
            mono8Bits.BufferNeeded -= SetBufferNeededHasBeenCalledToTrue;
            mono8Bits.BufferNeeded += GenerateNextDataAndBlockThead;

            mono8Bits.Play();
            Utilities.Sleep(2000);
            mono8Bits.Stop();

            mono8Bits.BufferNeeded -= GenerateNextDataAndBlockThead;
            mono8Bits.Dispose();
        }
        public void TestPlayableInterface()
        {
            WaveFormat dataFormat;
            using (var stream = AssetManager.FileProvider.OpenStream("EffectFishLamp", VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                var memoryStream = new MemoryStream((int)stream.Length);
                stream.CopyTo(memoryStream);
                memoryStream.Position = 0;

                var waveStreamReader = new SoundStream(memoryStream);
                dataFormat = waveStreamReader.Format;
                bufferData = new byte[waveStreamReader.Length];

                if (waveStreamReader.Read(bufferData, 0, (int)waveStreamReader.Length) != waveStreamReader.Length)
                    throw new AudioSystemInternalException("The data length read in wave soundStream does not correspond to the stream's length.");
            }
            dynSEInstance = new DynamicSoundEffectInstance(defaultEngine, dataFormat.SampleRate, (AudioChannels)dataFormat.Channels, (AudioDataEncoding)dataFormat.BitsPerSample);
            dynSEInstance.BufferNeeded += SubmitBuffer;

            //////////////////
            // 1. Test play
            dynSEInstance.Play();
            Utilities.Sleep(2000);
            Assert.AreEqual(SoundPlayState.Playing, dynSEInstance.PlayState, "Music is not playing");

            //////////////////
            // 2. Test Pause
            dynSEInstance.Pause();
            Utilities.Sleep(600);
            Assert.AreEqual(SoundPlayState.Paused, dynSEInstance.PlayState, "Music is not Paused");
            dynSEInstance.Play();
            Utilities.Sleep(1000);

            //////////////////
            // 2. Test Stop
            dynSEInstance.Stop();
            bufferCount = 0;
            Utilities.Sleep(600);
            Assert.AreEqual(SoundPlayState.Stopped, dynSEInstance.PlayState, "Music is not Stopped");
            dynSEInstance.Play();
            Utilities.Sleep(9000);

            ///////////////////
            // 3. Test ExitLoop
            Assert.DoesNotThrow(dynSEInstance.ExitLoop, "ExitLoop crached");

            ///////////////
            // 4. Volume
            var value = 1f;
            var sign = -1f;
            while (value <= 1f)
            {
                dynSEInstance.Volume = value;

                value += sign * 0.01f;
                Utilities.Sleep(30);

                if (value < -0.2)
                    sign = 1f;
            }
            Utilities.Sleep(2000);

            //////////////////
            // 5.Pan
            value = 0;
            sign = -1f;
            while (value <= 1f)
            {
                dynSEInstance.Pan = value;

                value += sign * 0.01f;
                Utilities.Sleep(30);

                if (value < -1.2)
                    sign = 1f;
            }
            dynSEInstance.Pan = 0;
            Utilities.Sleep(2000);
            
            ////////////////////////////////////////////////////////////////////////////
            // 7. Wait until the end of the stream to check that there are not crashes
            Utilities.Sleep(50000);

            dynSEInstance.Dispose();
        }
        public void TestImplementationSpecific()
        {
            bufferNeededHasBeenCalled = false;

            ////////////////////////////////////////////////////////////////////////////////////////////////
            // 1. Check that worker process buffer needed requests with the first instance of dynamic sound.
            var instance1 = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            instance1.BufferNeeded += SetBufferNeededHasBeenCalledToTrue; 
            instance1.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called with a first single instance.");
            bufferNeededHasBeenCalled = false;
            instance1.Stop();

            ////////////////////////////////////////////////////////////////////////////////////////////////
            // 2. Check that worker process buffer needed requests with the second instance of dynamic sound.
            var instance2 = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            instance2.BufferNeeded += SetBufferNeededHasBeenCalledToTrue; 
            instance2.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called with a second instance.");
            bufferNeededHasBeenCalled = false;
            instance2.Stop();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 3. Check that worker process buffer needed requests of the second instance when the first is disposed.
            instance1.Dispose();
            instance2.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called with a second single instance.");
            bufferNeededHasBeenCalled = false;
            instance2.Stop();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////
            // 4. Check that the worker is correctly recreated when the number of dynamic instances have reached 0
            instance2.Dispose();
            instance1 = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            instance1.BufferNeeded += SetBufferNeededHasBeenCalledToTrue; 
            instance1.Play();
            Utilities.Sleep(50);
            Assert.IsTrue(bufferNeededHasBeenCalled, "Buffer Needed has not been called with a single instance after destruct of all instances.");
            bufferNeededHasBeenCalled = false;
            instance1.Stop();

            ///////////////////////////////////////////////////////////////////////////////////////////////////
            // 5. Play several dynamic at the same time to check that there is not problem with a single worker

            dynGenSound = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            dynGenSound.BufferNeeded += SubmitDynGenSound;

            GCHandle pinnedDataWave1;
            GCHandle pinnedDataStereo;
            GCHandle pinnedDataSayuriPart;

            LoadWaveFileIntoBuffers(out pinnedDataWave1, out wave1, "EffectBip");
            LoadWaveFileIntoBuffers(out pinnedDataStereo, out stereo, "EffectStereo");
            LoadWaveFileIntoBuffers(out pinnedDataSayuriPart, out sayuriPart, "EffectFishLamp");

            wave1.Instance.BufferNeeded += SubmitWave1;
            stereo.Instance.BufferNeeded += SubmitStereo;
            sayuriPart.Instance.BufferNeeded += SubmitSayuriPart;

            // plays all the instances together to see
            wave1.Instance.Play();
            stereo.Instance.Play();
            sayuriPart.Instance.Play();
            dynGenSound.Play();

            Utilities.Sleep(5000);

            wave1.Instance.Stop();
            stereo.Instance.Stop();
            sayuriPart.Instance.Stop();
            dynGenSound.Stop();

            Utilities.Sleep(100); // avoid crash due to ObjectDisposedException

            dynGenSound.Dispose();
            wave1.Instance.Dispose();
            stereo.Instance.Dispose();
            sayuriPart.Instance.Dispose();

            pinnedDataWave1.Free();
            pinnedDataStereo.Free();
            pinnedDataSayuriPart.Free();
        }
        public void TestPendingBufferCount()
        {
            mono8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            var dispInstance = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_16Bits);
            dispInstance.Dispose();

            var pendingCount = 0;
            ///////////////////////////////////////////////////////////////////////////
            // 1. Test that it throws ObjectDisposedException with disposed instance
            Assert.Throws<ObjectDisposedException>(() => pendingCount = dispInstance.PendingBufferCount, "PendingBufferCount did not throw ObjectDisposedException");

            //////////////////////////////////
            // 2. Test that it does not crash
            Assert.DoesNotThrow(() => pendingCount = mono8Bits.PendingBufferCount, "PendingBufferCount crashed with valid instance");

            ////////////////////////////
            // 3. Test the default value
            mono8Bits.Stop();
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount default value is not 0");

            //////////////////////////////////////////////////
            // 4. Check the value after adding some buffers
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 10000));
            Assert.AreEqual(3, mono8Bits.PendingBufferCount, "PendingBufferCount value is not 3 after adding buffers");

            //////////////////////////////////
            // 5. Check the value after stop
            mono8Bits.Stop();
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount default value is not 0");

            //////////////////////////////////
            // 6 Check the value after play
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 1000));
            mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 0f }, 1, 1000));
            mono8Bits.Play();
            Utilities.Sleep(1000);
            Assert.AreEqual(0, mono8Bits.PendingBufferCount, "PendingBufferCount value is not 0 after play");
            mono8Bits.Stop();

            mono8Bits.Dispose();
        }