예제 #1
0
        public void Dispose()
        {
            // Stop the VideoPlayer. This gets almost everything...
            Stop();

            // Destroy the other GL bits.
            GL_dispose();

            // Dispose the DynamicSoundEffectInstance
            if (audioStream != null)
            {
                audioStream.Dispose();
                audioStream = null;
            }

            // Dispose the Texture.
            videoTexture[0].RenderTarget.Dispose();

            // Free the YUV buffer
            if (yuvData != IntPtr.Zero)
            {
                free(yuvData);
                yuvData = IntPtr.Zero;
            }

            // Okay, we out.
            IsDisposed = true;
        }
예제 #2
0
        public void GetSampleDuration()
        {
            var monoInstance   = new DynamicSoundEffectInstance(8000, AudioChannels.Mono);
            var stereoInstance = new DynamicSoundEffectInstance(24000, AudioChannels.Stereo);

            // Zero length
            Assert.AreEqual(0, (int)monoInstance.GetSampleDuration(0).TotalMilliseconds / 10);
            Assert.AreEqual(0, (int)stereoInstance.GetSampleDuration(0).TotalMilliseconds / 10);

            // Nonzero length
            Assert.AreNotEqual(0, monoInstance.GetSampleDuration(16000).Ticks);
            Assert.AreNotEqual(0, stereoInstance.GetSampleDuration(96000).Ticks);

            // Length not aligned with format
            Assert.AreEqual(1, (int)stereoInstance.GetSampleDuration(97).TotalMilliseconds);

            // Negative length
            Assert.Throws <ArgumentException>(() => { monoInstance.GetSampleDuration(-1); });

            // Disposed
            monoInstance.Dispose();
            Assert.Throws <ObjectDisposedException>(() => { monoInstance.GetSampleDuration(0); });

            stereoInstance.Dispose();
        }
예제 #3
0
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            this.Content.Unload();

            _audioInstance.Dispose();
            _audioContext.Dispose();
        }
예제 #4
0
        public void Ctor()
        {
            // Valid sample rates
            var instance = new DynamicSoundEffectInstance(48000, AudioChannels.Stereo);

            instance.Dispose();
            instance = new DynamicSoundEffectInstance(8000, AudioChannels.Stereo);
            instance.Dispose();

            // Invalid sample rates
            Assert.Throws <ArgumentOutOfRangeException>(() => { instance = new DynamicSoundEffectInstance(7999, AudioChannels.Stereo); });
            if (instance != null)
            {
                instance.Dispose();
            }
            Assert.Throws <ArgumentOutOfRangeException>(() => { instance = new DynamicSoundEffectInstance(48001, AudioChannels.Stereo); });
            if (instance != null)
            {
                instance.Dispose();
            }

            // Valid channel counts
            instance = new DynamicSoundEffectInstance(44100, AudioChannels.Mono);
            instance.Dispose();

            instance = new DynamicSoundEffectInstance(44100, AudioChannels.Stereo);
            instance.Dispose();

            // Invalid channel count
            Assert.Throws <ArgumentOutOfRangeException>(() => { instance = new DynamicSoundEffectInstance(44100, (AudioChannels)123); });
            if (instance != null)
            {
                instance.Dispose();
            }
        }
예제 #5
0
        public void GetSampleDuration()
        {
            var monoInstance   = new DynamicSoundEffectInstance(8000, AudioChannels.Mono);
            var stereoInstance = new DynamicSoundEffectInstance(24000, AudioChannels.Stereo);

            // Zero length
            Assert.AreEqual(TimeSpan.Zero, monoInstance.GetSampleDuration(0));
            Assert.AreEqual(TimeSpan.Zero, stereoInstance.GetSampleDuration(0));

            // Nonzero length
            Assert.AreEqual(TimeSpan.FromSeconds(1), monoInstance.GetSampleDuration(16000));
            Assert.AreEqual(TimeSpan.FromSeconds(1), stereoInstance.GetSampleDuration(96000));

            // Length not aligned with format
            Assert.AreEqual(TimeSpan.FromMilliseconds(1), stereoInstance.GetSampleDuration(97));

            // Negative length
            Assert.Throws <ArgumentException>(() => { monoInstance.GetSampleDuration(-1); });

            // Disposed
            monoInstance.Dispose();
            Assert.Throws <ObjectDisposedException>(() => { monoInstance.GetSampleDuration(0); });

            stereoInstance.Dispose();
        }
예제 #6
0
파일: OggSong.cs 프로젝트: jeffdt/BlueSun
 protected void Dispose(bool isDisposing)
 {
     threadRunHandle.Set();
     if (sound != null)
     {
         sound.Dispose();
     }
 }
예제 #7
0
 public void Dispose()
 {
     if (source != null)
     {
         source.Dispose();
     }
     source      = null;
     musicStream = null;
 }
예제 #8
0
 public void Dispose()
 {
     if (_instance != null)
     {
         _instance.Stop(true);
         _instance.Dispose();
         _instance = null;
     }
 }
예제 #9
0
        public void TestDispose()
        {
            var crossDisposedEngine = AudioEngineFactory.NewAudioEngine(); 
            var engine = AudioEngineFactory.NewAudioEngine();
            crossDisposedEngine.Dispose(); // Check there no Dispose problems with sereval cross-disposed instances. 

            // Create some SoundEffects
            SoundEffect soundEffect;
            using (var wavStream = AssetManager.FileProvider.OpenStream("EffectBip", VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                soundEffect = SoundEffect.Load(engine, wavStream);
            }
            SoundEffect dispSoundEffect;
            using (var wavStream = AssetManager.FileProvider.OpenStream("EffectBip", VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                dispSoundEffect = SoundEffect.Load(engine, wavStream);
            }
            dispSoundEffect.Dispose();

            var soundEffectInstance = soundEffect.CreateInstance();
            var dispInstance = soundEffect.CreateInstance();
            dispInstance.Dispose();

            // Create some SoundMusics.
            var soundMusic1 = SoundMusic.Load(engine, AssetManager.FileProvider.OpenStream("MusicBip", VirtualFileMode.Open, VirtualFileAccess.Read));
            var soundMusic2 = SoundMusic.Load(engine, AssetManager.FileProvider.OpenStream("MusicToneA", VirtualFileMode.Open, VirtualFileAccess.Read));
            soundMusic2.Dispose();

            // Create some dynamicSounds.
            var generator = new SoundGenerator();
            var dynSound1 = new DynamicSoundEffectInstance(engine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            var dynSound2 = new DynamicSoundEffectInstance(engine, 20000, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            dynSound1.Play();
            dynSound1.SubmitBuffer(generator.Generate(44100, new[]{ 1000f }, 1, 120000));
            dynSound2.Dispose();

            // Start playing some
            soundEffectInstance.Play();
            soundMusic1.Play();

            for (int i = 0; i < 10; i++)
            {
                engine.Update();
                Utilities.Sleep(5);
            }

            Assert.DoesNotThrow(engine.Dispose, "AudioEngine crashed during disposal.");
            Assert.IsTrue(soundEffect.IsDisposed, "SoundEffect is not disposed.");
            Assert.Throws<InvalidOperationException>(engine.Dispose, "AudioEngine did not threw invalid operation exception.");
            Assert.AreEqual(SoundPlayState.Stopped, soundEffectInstance.PlayState, "SoundEffectInstance has not been stopped properly.");
            Assert.IsTrue(soundEffectInstance.IsDisposed, "SoundEffectInstance has not been disposed properly.");
            Assert.AreEqual(SoundPlayState.Stopped, soundMusic1.PlayState, "soundMusic1 has not been stopped properly.");
            Assert.IsTrue(soundMusic1.IsDisposed, "soundMusic1 has not been disposed properly.");
            //Assert.AreEqual(SoundPlayState.Stopped, dynSound1.PlayState, "The dynamic sound 1 has not been stopped correctly.");
            //Assert.IsTrue(dynSound1.IsDisposed, "The dynamic sound 1 has not been disposed correctly.");
        }
예제 #10
0
        public void Dispose()
        {
            if (mSoundEffectInstance != null)
            {
                mSoundEffectInstance.Dispose();
            }

            mOnBufferNeededCallback = null;
            mSoundEffectInstance    = null;
        }
예제 #11
0
 public void Dispose()
 {
     lock (this)
     {
         Inst.Dispose();
         Stream.Dispose();
         DecoderThread.Abort();
         EndOfStream = true;
     }
 }
예제 #12
0
파일: MP3Player.cs 프로젝트: jwofles/ForkSO
 public void Dispose()
 {
     lock (ControlLock)
     {
         Disposed = true;
         Inst?.Dispose();
         Stream?.Dispose();
         DecoderThread?.Abort();
         EndOfStream = true;
     }
 }
예제 #13
0
 void Dispose(bool disposing)
 {
     if (disposing)
     {
         Stop();
         soundStream.Dispose();
         soundStream = null;
         Vorbisfile.ov_clear(ref vorbisFile);
     }
     IsDisposed = true;
 }
예제 #14
0
파일: XNAMP3.cs 프로젝트: samuliy/MP3Sharp
 public void Dispose()
 {
     if (_Playing)
     {
         Stop();
     }
     _Instance.Dispose();
     _Instance = null;
     _Stream.Close();
     _Stream = null;
 }
예제 #15
0
 public void Dispose()
 {
     if (m_ThisInstance != null)
     {
         if (!m_ThisInstance.IsDisposed)
         {
             m_ThisInstance.Stop();
             m_ThisInstance.Dispose();
         }
         m_ThisInstance = null;
     }
 }
예제 #16
0
        public override void Stop(AudioStopOptions options)
        {
            instance.Stop();

            instance.Dispose();
            instance = null;

            stream.Dispose();
            stream = null;

            buffer = null;
        }
예제 #17
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]); });
        }
예제 #18
0
        public void IsLooped()
        {
            var instance = new DynamicSoundEffectInstance(24000, AudioChannels.Mono);

            // Always returns false and cannot be set true
            Assert.IsFalse(instance.IsLooped);
            instance.IsLooped = false; // Setting it to false does not throw, however
            Assert.Throws <InvalidOperationException>(() => { instance.IsLooped = true; });

            instance.Dispose();
            Assert.Throws <ObjectDisposedException>(() => { instance.IsLooped = false; });
        }
예제 #19
0
        public void Dispose()
        {
            if (instance.State == SoundState.Playing)
            {
                instance.Stop();
            }

            instance.Dispose();
            instance = null;

            stream.Close();
            stream = null;
        }
예제 #20
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;
     }
 }
예제 #21
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();
 }
예제 #22
0
        public void Dispose()
        {
            if (m_Playing)
            {
                Stop();
            }

            m_Instance.Dispose();
            m_Instance = null;

            m_Stream.Close();
            m_Stream = null;
        }
예제 #23
0
 public void Dispose()
 {
     if (_thisInstance != null)
     {
         _thisInstance.BufferNeeded -= OnBufferNeeded;
         if (!_thisInstance.IsDisposed)
         {
             _thisInstance.Stop();
             _thisInstance.Dispose();
         }
         _thisInstance = null;
     }
 }
예제 #24
0
파일: VideoPlayer.cs 프로젝트: zwcloud/FNA
        public void Dispose()
        {
            // Stop the VideoPlayer. This gets almost everything...
            Stop();

#if VIDEOPLAYER_OPENGL
            // Destroy the OpenGL bits.
            GL_dispose();
#endif

            // Dispose the DynamicSoundEffectInstance
            if (audioStream != null)
            {
                audioStream.Dispose();
                audioStream = null;
            }

            // Dispose the Texture.
            videoTexture.Dispose();

            // Okay, we out.
            IsDisposed = true;
        }
예제 #25
0
 /// <summary>
 /// Disposes of the resources used by this ActiveSound instance.
 /// <param name="CleanUpNativeAndManagedResources">Should both native and managed resources be cleaned?</param>
 /// </summary>
 protected virtual void Dispose(bool CleanUpNativeAndManagedResources)
 {
     if (CleanUpNativeAndManagedResources)
     {
         if (Instance != null)
         {
             Instance.Dispose();
         }
         if (DynInstance != null)
         {
             DynInstance.Dispose();
         }
     }
 }
예제 #26
0
        public void Dispose()
        {
            lock (ControlLock)
            {
                Disposed = true;
                Inst?.Dispose();
                Stream?.Dispose();

                Active = false;
                DecodeNext.Set(); //end the mp3 thread immediately

                EndOfStream = true;
            }
        }
예제 #27
0
        public void Close()
        {
            if (instance != null)
            {
                instance.BufferNeeded -= FillBuffer;
                instance.Dispose();
                instance = null;
            }

            if (vorbis != IntPtr.Zero)
            {
                FAudio.stb_vorbis_close(vorbis);
            }
            vorbis = IntPtr.Zero;
        }
예제 #28
0
 public void Dispose()
 {
     aread?.Dispose();
     sfx?.Dispose();
     aread    = null;
     sfx      = null;
     labels   = null;
     samps    = null;
     buf      = null;
     disposed = true;
     data     = null;
     bufUsed.Set();
     readthread.Join();
     bufSent?.Dispose();
     bufUsed?.Dispose();
 }
예제 #29
0
        public void InstanceNotDisposedWhenGameDisposed()
        {
            var game = new Game();

            var se = new SoundEffect(new byte[16000], 8000, AudioChannels.Mono);
            var s  = se.CreateInstance();
            var d  = new DynamicSoundEffectInstance(44100, AudioChannels.Stereo);

            game.Dispose();

            Assert.IsFalse(s.IsDisposed);
            Assert.IsFalse(d.IsDisposed);

            s.Dispose();
            d.Dispose();
        }
예제 #30
0
        protected void Dispose(bool isDisposing)
        {
            // They might be null if the constructor threw an exception

            if (threadRunHandle != null)
            {
                threadRunHandle.Set();
            }

            if (effect != null)
            {
                lock ( effect )
                {
                    effect.Dispose();
                }
            }
        }
예제 #31
0
        public void PendingBufferCount()
        {
            var instance = new DynamicSoundEffectInstance(44100, AudioChannels.Stereo);

            Assert.AreEqual(0, instance.PendingBufferCount);

            instance.SubmitBuffer(GenerateSineWave(440, 44100, 2, 1.0f));
            Assert.AreEqual(1, instance.PendingBufferCount);

            instance.Play();
            SleepWhileDispatching(1050); // Give it time to finish
            Assert.AreEqual(0, instance.PendingBufferCount);

            // Throws ObjectDisposedException
            instance.Dispose();
            Assert.Throws <ObjectDisposedException>(() => { var a = instance.PendingBufferCount; });
        }
        public void TestIsLooped()
        {
            mono8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            var dispInstance = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_16Bits);
            dispInstance.Dispose();

            bool looped;
            /////////////////////////////////////////////////////////////////////////////////////////////
            // 1. Check that get and set IsLooped for an Disposed instance throw the 'ObjectDisposedException'
            Assert.Throws<ObjectDisposedException>(() => looped = dispInstance.IsLooped, "DynamicSoundEffectInstance.IsLooped { get } did not throw the 'ObjectDisposedException' when called from a disposed object.");
            Assert.Throws<ObjectDisposedException>(() => dispInstance.IsLooped = false, "DynamicSoundEffectInstance.IsLooped { set } did not throw the 'ObjectDisposedException' when called from a disposed object.");

            //////////////////////////////////////////////////////////////////
            // 2. Check that IsLooped = true throws InvalidOperationException
            Assert.Throws<InvalidOperationException>(() => mono8Bits.IsLooped = true, "DynamicSoundEffectInstance.IsLooped { set } did not throw the 'InvalidOperationException' when called with 'true'.");

            ////////////////////////////////////////////////
            // 3. Check that the value of IsLooped is false
            Assert.IsFalse(mono8Bits.IsLooped, "DynamicSoundEffectInstance.IsLooped { get } did not return 'false'.");

            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 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 TestSubmitBuffer()
        {
            mono8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_8Bits);
            var mono16Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Mono, AudioDataEncoding.PCM_16Bits);
            var stereo8Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_8Bits);
            var stereo16Bits = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_16Bits);
            var dispInstance = new DynamicSoundEffectInstance(defaultEngine, 44100, AudioChannels.Stereo, AudioDataEncoding.PCM_16Bits);
            dispInstance.Dispose();

            ///////////////////////////////////////////////////////////////////////
            // 1. Test that it throws ObjectDisposedException with disposed instance
            Assert.Throws<ObjectDisposedException>(() => dispInstance.SubmitBuffer(new byte[16]), "SubmitBuffer did not throw ObjectDisposedException");

            ///////////////////////////////////////////////////////////
            // 2. Test that ArgumentNullException is correctly thrown
            Assert.Throws<ArgumentNullException>(() => mono8Bits.SubmitBuffer(null), "SubmitBuffer did not throw ArgumentNullException");

            /////////////////////////////////////////////////////////////////////////////
            // 3. Test that ArgumentException is correctly thrown when buffer length is 0
            Assert.Throws<ArgumentException>(() => mono8Bits.SubmitBuffer(new byte[0]), "SubmitBuffer did not throw ArgumentException with 0 length buffer");

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 4. Test that ArgumentException is correctly thrown when buffer length do not respect alignment restrictions
            Assert.Throws<ArgumentException>(() => mono16Bits.SubmitBuffer(new byte[3]), "SubmitBuffer did not throw ArgumentException with 3 length buffer");

            ///////////////////////////////////////////////////////////////////////////
            // 5. Test that ArgumentOutOfRangeException is thrown with negative offset
            Assert.Throws<ArgumentOutOfRangeException>(() => mono8Bits.SubmitBuffer(new byte[16], -1, 3), "SubmitBuffer did not throw ArgumentOutOfRangeException with -1 offset");

            //////////////////////////////////////////////////////////////////////////////////////////////
            // 6. Test that ArgumentOutOfRangeException is thrown with offset greater than buffer length
            Assert.Throws<ArgumentOutOfRangeException>(() => mono8Bits.SubmitBuffer(new byte[16], 16, 3), "SubmitBuffer did not throw ArgumentOutOfRangeException with 16 offset");

            //////////////////////////////////////////////////////////////////////////////////
            // 7. Test that ArgumentOutOfRangeException is thrown with byteCount is negative
            Assert.Throws<ArgumentOutOfRangeException>(() => mono8Bits.SubmitBuffer(new byte[16], 16, -1), "SubmitBuffer did not throw ArgumentOutOfRangeException with -1 bytecount");

            ////////////////////////////////////////////////////////////////////////////////////////////
            // 8. Test that ArgumentOutOfRangeException is thrown with offset+byteCount is more buffer length
            Assert.Throws<ArgumentOutOfRangeException>(() => mono8Bits.SubmitBuffer(new byte[16], 10, 7), "SubmitBuffer did not throw ArgumentOutOfRangeException with offset+bytecount greater than buffer length.");

            /////////////////////////////////////////////////////////////////////////////////////////
            // 9. Check that submitting mono-8bits signals does not crash and has the good behaviour
            Assert.DoesNotThrow(()=>mono8Bits.SubmitBuffer(generator.Generate(44100, new[] { 40000f }, 1, 88200 )), "SubmitBuffer on mono8Bits crached.");
            mono8Bits.Play();
            Utilities.Sleep(2500);
            
            /////////////////////////////////////////////////////////////////////////////////////////
            // 10. Check that submitting mono-16bits signals does not crash and has the good behaviour
            Assert.DoesNotThrow(() => mono16Bits.SubmitBuffer(generator.Generate(44100, new[] { 40000f }, 2, 176400)), "SubmitBuffer on mono16Bits crached.");
            mono16Bits.Play();
            Utilities.Sleep(2500);
            
            ///////////////////////////////////////////////////////////////////////////////////////////
            // 11. Check that submitting stereo-8bits signals does not crash and has the good behaviour
            Assert.DoesNotThrow(() => stereo8Bits.SubmitBuffer(generator.Generate(44100, new[] { 40000f, 20000f }, 1, 176400)), "SubmitBuffer on stereo8Bits crached.");
            stereo8Bits.Play();
            Utilities.Sleep(2500);
            
            ///////////////////////////////////////////////////////////////////////////////////////////
            // 12 Check that submitting stereo-16bits signals does not crash and has the good behaviour
            Assert.DoesNotThrow(() => stereo16Bits.SubmitBuffer(generator.Generate(44100, new[] { 40000f, 10000f }, 2, 352800)), "SubmitBuffer on stereo16Bits crached.");
            stereo16Bits.Play();
            Utilities.Sleep(2500);

            /////////////////////////////////////////////////////////////////////
            // 13. Check that offset and byte count works in SubmitBuffer method
            var buffer1 = generator.Generate(44100, new[] { 10000f }, 1, 44100);
            var buffer2 = generator.Generate(44100, new[] { 40000f }, 1, 44100);
            var buffer3 = generator.Generate(44100, new[] { 80000f }, 1, 44100);
            var totalBuffer = new byte[132300];
            Array.Copy(buffer1, totalBuffer, 44100);
            Array.Copy(buffer2, 0, totalBuffer, 44100, 44100);
            Array.Copy(buffer3, 0, totalBuffer, 88200, 44100);

            Assert.DoesNotThrow(() => mono8Bits.SubmitBuffer(totalBuffer, 44100, 44100), "SubmitBuffer with offset and bytecount crached.");
            mono8Bits.Play();
            Utilities.Sleep(1500);

            mono8Bits.Dispose();
            mono16Bits.Dispose();
            stereo8Bits.Dispose();
            stereo16Bits.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();
        }