public XnaBytePusherIODriver(GraphicsDevice gd) { this.gd = gd; // start audio device soundEffect = new DynamicSoundEffectInstance(15360, AudioChannels.Mono); soundEffect.Play(); }
public void Play() { lock (ControlLock) { _State = SoundState.Playing; Inst?.Play(); } }
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."); }
public void BufferNeeded_Play_NoDispatcherCalled() { // No event is raised if FrameworkDispatcher.Update() is not called. using (var instance = new DynamicSoundEffectInstance(8000, AudioChannels.Mono)) { instance.BufferNeeded += BufferNeededEventHandler; var previousEventCount = _bufferNeededEventCount; instance.Play(); Thread.Sleep(20); Assert.AreEqual(0, _bufferNeededEventCount - previousEventCount); } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) { Exit(); } // TODO: Add your update logic here if (!_startedPlaying) { _effect.Play(); _startedPlaying = true; } base.Update(gameTime); }
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(); }
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 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(); }
public void Playback() { using (var instance = new DynamicSoundEffectInstance(48000, AudioChannels.Mono)) { // Initially, the playback is stopped Assert.AreEqual(SoundState.Stopped, instance.State); // Submitting a buffer will not change the state instance.SubmitBuffer(GenerateSineWave(440, 48000, 1, 0.5f)); Assert.AreEqual(SoundState.Stopped, instance.State); // Start playing instance.Play(); Assert.AreEqual(SoundState.Playing, instance.State); // While still playing, pause the playback SleepWhileDispatching(300); instance.Pause(); Assert.AreEqual(SoundState.Paused, instance.State); // Let it continue and run out of buffers instance.Resume(); SleepWhileDispatching(300); Assert.AreEqual(0, instance.PendingBufferCount); Assert.AreEqual(SoundState.Playing, instance.State); // Submit a buffer and the playback should continue instance.SubmitBuffer(GenerateSineWave(466, 48000, 1, 1.0f)); Assert.AreEqual(SoundState.Playing, instance.State); SleepWhileDispatching(500); // Stop immediately Assert.AreEqual(SoundState.Playing, instance.State); instance.Stop(); SleepWhileDispatching(10); // XNA does not stop it until FrameworkDispatcher.Update is called Assert.AreEqual(SoundState.Stopped, instance.State); // And then resume instance.Resume(); Assert.AreEqual(SoundState.Playing, instance.State); } }
/// <summary> /// Plays the effect. /// </summary> /// <param name="asEffect">Set to false for music, true for sound effects.</param> public void Play(bool asEffect, AudioEffects effect = AudioEffects.None, float volume = 1.0f, bool spamCheck = false) { double now = UltimaGame.TotalMS; CullExpiredEffects(now); if (spamCheck && (LastPlayed + MinimumDelay > DateTime.Now)) { return; } m_ThisInstance = GetNewInstance(asEffect); if (m_ThisInstance == null) { Dispose(); return; } switch (effect) { case AudioEffects.PitchVariation: float pitch = Utility.RandomValue(-5, 5) * .025f; m_ThisInstance.Pitch = pitch; break; } BeforePlay(); LastPlayed = DateTime.Now; byte[] buffer = GetBuffer(); if (buffer != null && buffer.Length > 0) { m_ThisInstance.BufferNeeded += OnBufferNeeded; m_ThisInstance.SubmitBuffer(buffer); m_ThisInstance.Volume = volume; m_ThisInstance.Play(); List <Tuple <DynamicSoundEffectInstance, double> > list = (asEffect) ? m_EffectInstances : m_MusicInstances; double ms = m_ThisInstance.GetSampleDuration(buffer.Length).TotalMilliseconds; list.Add(new Tuple <DynamicSoundEffectInstance, double>(m_ThisInstance, now + ms)); } }
public void BufferNeeded_MoreThanThree() { // No events are raised when a buffer is consumed and there are more than 3 buffers submitted. using (var instance = new DynamicSoundEffectInstance(8000, AudioChannels.Mono)) { instance.BufferNeeded += BufferNeededEventHandler; instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.25f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.25f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.05f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.05f)); var previousEventCount = _bufferNeededEventCount; instance.Play(); SleepWhileDispatching(300); Assert.AreEqual(0, _bufferNeededEventCount - previousEventCount); } }
public void BufferNeeded_MultipleConsumed() { // Both buffers should be consumed by the time the event routine is called by XNA. // This test verifies that each consumed buffer raises its own event. using (var instance = new DynamicSoundEffectInstance(8000, AudioChannels.Mono)) { instance.BufferNeeded += BufferNeededEventHandler; instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.05f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.05f)); var previousEventCount = _bufferNeededEventCount; instance.Play(); Thread.Sleep(125); SleepWhileDispatching(10); Assert.AreEqual(3, _bufferNeededEventCount - previousEventCount); } }
public void BufferNeeded_DuringPlayback() { // XNA raises the event every time a buffer is consumed and there are less than two left. using (var instance = new DynamicSoundEffectInstance(8000, AudioChannels.Mono)) { instance.BufferNeeded += BufferNeededEventHandler; instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.1f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.1f)); instance.SubmitBuffer(GenerateSineWave(880, 8000, 1, 0.1f)); var previousEventCount = _bufferNeededEventCount; instance.Play(); SleepWhileDispatching(350); Assert.AreEqual(3, _bufferNeededEventCount - previousEventCount); // The event is raised on the same thread as FrameworkDispatcher.Update() is called. Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, _bufferNeededEventThread); } }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); logo = this.Content.Load <Texture2D>("afx logo"); blackSquare = new Texture2D(GraphicsDevice, 1, 1); blackSquare.SetData(new Color[] { Color.DarkBlue }); // audio stuff _instance = new DynamicSoundEffectInstance(SampleRate, (ChannelsCount == 2) ? AudioChannels.Stereo : AudioChannels.Mono); _workingBuffer = new float[ChannelsCount, SamplesPerBuffer]; const int bytesPerSample = 2; _xnaBuffer = new byte[ChannelsCount * SamplesPerBuffer * bytesPerSample]; _instance.Play(); }
protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) { this.Exit(); } bytesRead += Microphone.Default.GetData(buffer, bytesRead, (buffer.Length - bytesRead)); if (gameTime.TotalGameTime.Seconds >= 2) { if (DSEI.PendingBufferCount == 0) { //for (int i = 0; i < buffer.Length; i++) //{ // buffer[i] = 55; //} DSEI.SubmitBuffer(buffer); } else { DSEI.Play(); } if (!isMicrophoneRecording) { } else { if (Microphone.Default.State != MicrophoneState.Stopped) { Microphone.Default.Stop(); isMicrophoneRecording = !isMicrophoneRecording; } } } base.Update(gameTime); }
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(); } }
public Synth() { // Create DynamicSoundEffectInstance object and start it _instance = new DynamicSoundEffectInstance(SampleRate, Channels == 2 ? AudioChannels.Stereo : AudioChannels.Mono); _instance.Play(); // Create buffers const int bytesPerSample = 2; _xnaBuffer = new byte[Channels * SamplesPerBuffer * bytesPerSample]; _workingBuffer = new float[Channels, SamplesPerBuffer]; // Create voice structures _voicePool = new Voice[Polyphony]; for (int i = 0; i < Polyphony; ++i) { _voicePool[i] = new Voice(this); } _freeVoices = new Stack <Voice>(_voicePool); _activeVoices = new List <Voice>(); _keyRegistry = new Dictionary <int, Voice>(); }
public void Play() { lock (DynamicSoundSync) { if (_dynamicSound == null) { IsPlaying = true; Time = 0; CurrentFillBufferIndex = 0; CurrentPlayBufferIndex = 0; _dynamicSound = new DynamicSoundEffectInstance(SampleRate, (ChannelCount == 1) ? AudioChannels.Mono : AudioChannels.Stereo); _dynamicSound.BufferNeeded += BufferNeeded; FillBuffer(); BufferHitCount = 0; SubmitBuffer(); _dynamicSound.Play(); } } }
public void Play() { float now = (float)UltimaEngine.TotalMS; // Check to see if any existing instances of this sound effect have stopped playing. If // they have, remove the reference to them so the garbage collector can collect them. for (int i = 0; i < m_instances.Count; i++) { if (m_instances[i].Item2 < now) { m_instances.RemoveAt(i); i--; } } DynamicSoundEffectInstance instance = new DynamicSoundEffectInstance(22050, AudioChannels.Mono); instance.BufferNeeded += new EventHandler <EventArgs>(instance_BufferNeeded); instance.SubmitBuffer(m_waveBuffer); instance.Play(); m_instances.Add(new Tuple <DynamicSoundEffectInstance, float>(instance, now + (instance.GetSampleDuration(m_waveBuffer.Length).Milliseconds))); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { base.Initialize(); // Init game config _cfg = new GameConfig(null); // Init graphics _viewport = _graphics.GraphicsDevice.Viewport; _spriteBatch = new SpriteBatch(GraphicsDevice); // TODO Resizing! _drawBuffer = new UInt32[_viewport.Width * _viewport.Height]; _backBuffer = new Texture2D(_graphics.GraphicsDevice, _viewport.Width, _viewport.Height); // Init audio _audioContext = new AudioContext(); _audioBuffer = new byte[_cfg.AudioBufferLenBytes]; _audioInstance = new DynamicSoundEffectInstance(_cfg.SampleRate, Microsoft.Xna.Framework.Audio.AudioChannels.Stereo); _audioInstance = new DynamicSoundEffectInstance(48000, Microsoft.Xna.Framework.Audio.AudioChannels.Stereo); _audioInstance.Play(); _logStrings = new List <string>(); }
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 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 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 Play() { instance.Play(); }
/// <summary> /// Plays the audio using DynamicSoundEffectInstance /// so we can monitor the playback status. /// </summary> private void playSoundEffect() { playback.Play(); }
public Texture2D GetTexture() { checkDisposed(); // Be sure we can even get something from TheoraPlay... if (State == MediaState.Stopped || Video.theoraDecoder == IntPtr.Zero || TheoraPlay.THEORAPLAY_isInitialized(Video.theoraDecoder) == 0 || TheoraPlay.THEORAPLAY_hasVideoStream(Video.theoraDecoder) == 0) { return(videoTexture); // Screw it, give them the old one. } // Get the latest video frames. bool missedFrame = false; while (nextVideo.playms <= timer.ElapsedMilliseconds && !missedFrame) { currentVideo = nextVideo; IntPtr nextFrame = TheoraPlay.THEORAPLAY_getVideo(Video.theoraDecoder); if (nextFrame != IntPtr.Zero) { TheoraPlay.THEORAPLAY_freeVideo(previousFrame); previousFrame = Video.videoStream; Video.videoStream = nextFrame; nextVideo = TheoraPlay.getVideoFrame(Video.videoStream); missedFrame = false; } else { // Don't mind me, just ignoring that complete failure above! missedFrame = true; } if (TheoraPlay.THEORAPLAY_isDecoding(Video.theoraDecoder) == 0) { // FIXME: This is part of the Duration hack! Video.Duration = new TimeSpan(0, 0, 0, 0, (int)currentVideo.playms); // Stop and reset the timer. If we're looping, the loop will start it again. timer.Stop(); timer.Reset(); // If looping, go back to the start. Otherwise, we'll be exiting. if (IsLooped && State == MediaState.Playing) { // Kill the audio, no matter what. if (audioStream != null) { audioStream.Stop(); audioStream.Dispose(); audioStream = null; } // Free everything and start over. TheoraPlay.THEORAPLAY_freeVideo(previousFrame); previousFrame = IntPtr.Zero; Video.AttachedToPlayer = false; Video.Dispose(); Video.AttachedToPlayer = true; Video.Initialize(); // Grab the initial audio again. if (TheoraPlay.THEORAPLAY_hasAudioStream(Video.theoraDecoder) != 0) { InitAudioStream(); } // Grab the initial video again. if (TheoraPlay.THEORAPLAY_hasVideoStream(Video.theoraDecoder) != 0) { currentVideo = TheoraPlay.getVideoFrame(Video.videoStream); previousFrame = Video.videoStream; do { // The decoder miiight not be ready yet. Video.videoStream = TheoraPlay.THEORAPLAY_getVideo(Video.theoraDecoder); } while (Video.videoStream == IntPtr.Zero); nextVideo = TheoraPlay.getVideoFrame(Video.videoStream); } // Start! Again! timer.Start(); if (audioStream != null) { audioStream.Play(); } } else { // Stop everything, clean up. We out. State = MediaState.Stopped; if (audioStream != null) { audioStream.Stop(); audioStream.Dispose(); audioStream = null; } TheoraPlay.THEORAPLAY_freeVideo(previousFrame); Video.AttachedToPlayer = false; Video.Dispose(); // We're done, so give them the last frame. return(videoTexture); } } } #if VIDEOPLAYER_OPENGL // Set up an environment to muck about in. GL_pushState(); // Bind our shader program. currentDevice.GLDevice.glUseProgram(shaderProgram); // We're using client-side arrays like CAVEMEN currentDevice.GLDevice.BindVertexBuffer(OpenGLDevice.OpenGLVertexBuffer.NullBuffer); // Set up the vertex pointers/arrays. currentDevice.GLDevice.AttributeEnabled[0] = true; currentDevice.GLDevice.AttributeEnabled[1] = true; for (int i = 2; i < currentDevice.GLDevice.AttributeEnabled.Length; i += 1) { currentDevice.GLDevice.AttributeEnabled[i] = false; } currentDevice.GLDevice.FlushGLVertexAttributes(); currentDevice.GLDevice.VertexAttribPointer( 0, 2, VertexElementFormat.Single, false, 2 * sizeof(float), vertPosPtr ); currentDevice.GLDevice.VertexAttribPointer( 1, 2, VertexElementFormat.Single, false, 2 * sizeof(float), vertTexPtr ); // Bind our target framebuffer. currentDevice.GLDevice.BindDrawFramebuffer(rgbaFramebuffer); // Prepare YUV GL textures with our current frame data currentDevice.GLDevice.glActiveTexture( OpenGLDevice.GLenum.GL_TEXTURE0 ); currentDevice.GLDevice.glBindTexture( OpenGLDevice.GLenum.GL_TEXTURE_2D, yuvTextures[0] ); currentDevice.GLDevice.glTexSubImage2D( OpenGLDevice.GLenum.GL_TEXTURE_2D, 0, 0, 0, (int)currentVideo.width, (int)currentVideo.height, OpenGLDevice.GLenum.GL_LUMINANCE, OpenGLDevice.GLenum.GL_UNSIGNED_BYTE, currentVideo.pixels ); currentDevice.GLDevice.glActiveTexture( OpenGLDevice.GLenum.GL_TEXTURE0 + 1 ); currentDevice.GLDevice.glBindTexture( OpenGLDevice.GLenum.GL_TEXTURE_2D, yuvTextures[1] ); currentDevice.GLDevice.glTexSubImage2D( OpenGLDevice.GLenum.GL_TEXTURE_2D, 0, 0, 0, (int)(currentVideo.width / 2), (int)(currentVideo.height / 2), OpenGLDevice.GLenum.GL_LUMINANCE, OpenGLDevice.GLenum.GL_UNSIGNED_BYTE, new IntPtr( currentVideo.pixels.ToInt64() + (currentVideo.width * currentVideo.height) ) ); currentDevice.GLDevice.glActiveTexture( OpenGLDevice.GLenum.GL_TEXTURE0 + 2 ); currentDevice.GLDevice.glBindTexture( OpenGLDevice.GLenum.GL_TEXTURE_2D, yuvTextures[2] ); currentDevice.GLDevice.glTexSubImage2D( OpenGLDevice.GLenum.GL_TEXTURE_2D, 0, 0, 0, (int)(currentVideo.width / 2), (int)(currentVideo.height / 2), OpenGLDevice.GLenum.GL_LUMINANCE, OpenGLDevice.GLenum.GL_UNSIGNED_BYTE, new IntPtr( currentVideo.pixels.ToInt64() + (currentVideo.width * currentVideo.height) + (currentVideo.width / 2 * currentVideo.height / 2) ) ); // Flip the viewport, because loldirectx currentDevice.GLDevice.glViewport( 0, 0, (int)currentVideo.width, (int)currentVideo.height ); // Draw the YUV textures to the framebuffer with our shader. currentDevice.GLDevice.glDrawArrays( OpenGLDevice.GLenum.GL_TRIANGLE_STRIP, 0, 4 ); // Clean up after ourselves. GL_popState(); #else // Just copy it to an array, since it's RGBA anyway. try { byte[] theoraPixels = TheoraPlay.getPixels( currentVideo.pixels, (int)currentVideo.width * (int)currentVideo.height * 4 ); // TexImage2D. videoTexture.SetData <byte>(theoraPixels); } catch (Exception e) { // I hope we've still got something in videoTexture! System.Console.WriteLine( "WARNING: THEORA FRAME COPY FAILED: " + e.Message ); } #endif return(videoTexture); }
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(); }
public Audio() { m_sfx = new DynamicSoundEffectInstance(SAMPLE_RATE, AudioChannels.Stereo); m_sfx.Play(); }
public void Reset() { m_sfx.Stop(); m_sfx.Play(); }
public void Start() { Stream = new Mp3Stream(Path); Stream.DecodeFrames(1); var freq = Stream.Frequency; lock (ControlLock) { if (Disposed) { return; } Inst = new DynamicSoundEffectInstance(freq, AudioChannels.Stereo); Inst.IsLooped = false; Inst.BufferNeeded += SubmitBufferAsync; if (_State == SoundState.Playing) { Inst.Play(); } else if (_State == SoundState.Paused) { Inst.Play(); Inst.Pause(); } Inst.Volume = _Volume; Inst.Pan = _Pan; Requests = 2; } //SubmitBuffer(null, null); //SubmitBuffer(null, null); DecoderThread = new Thread(() => { try { while (Active && MainThread.IsAlive) { DecodeNext.WaitOne(128); bool go; lock (this) go = Requests > 0; while (go) { var buf = new byte[262144];// 524288]; var read = Stream.Read(buf, 0, buf.Length); lock (this) { Requests--; NextBuffers.Add(buf); NextSizes.Add(read); if (read == 0) { EndOfStream = true; BufferDone.Set(); return; } BufferDone.Set(); } lock (this) go = Requests > 0; } } } catch (Exception e) { } }); DecoderThread.Start(); DecodeNext.Set(); }
public MonoGameAudioBackend() { soundInstance = new DynamicSoundEffectInstance(AudioUnit.SampleRate, AudioChannels.Mono); soundInstance.Play(); }
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 Texture2D GetTexture() { checkDisposed(); if (Video == null) { throw new InvalidOperationException(); } // Be sure we can even get something from Theorafile... if (State == MediaState.Stopped || Video.theora == IntPtr.Zero || Theorafile.tf_hasvideo(Video.theora) == 0) { // Screw it, give them the old one. return(videoTexture[0].RenderTarget as Texture2D); } int thisFrame = (int)(timer.Elapsed.TotalMilliseconds / (1000.0 / Video.fps)); if (thisFrame > currentFrame) { // Only update the textures if we need to! if (Theorafile.tf_readvideo( Video.theora, yuvData, thisFrame - currentFrame ) == 1 || currentFrame == -1) { UpdateTexture(); } currentFrame = thisFrame; } // Check for the end... bool ended = Theorafile.tf_eos(Video.theora) == 1; if (audioStream != null) { ended &= audioStream.PendingBufferCount == 0; } if (ended) { // FIXME: This is part of the Duration hack! if (Video.needsDurationHack) { Video.Duration = timer.Elapsed; // FIXME: Frames * FPS? -flibit } // Stop and reset the timer. If we're looping, the loop will start it again. timer.Stop(); timer.Reset(); // Kill whatever audio/video we've got if (audioStream != null) { audioStream.Stop(); audioStream.Dispose(); audioStream = null; } // Reset the stream no matter what happens next Theorafile.tf_reset(Video.theora); // If looping, go back to the start. Otherwise, we'll be exiting. if (IsLooped) { // Starting over! InitializeTheoraStream(); // Start! Again! timer.Start(); if (audioStream != null) { audioStream.Play(); } } else { // We out State = MediaState.Stopped; } } // Finally. return(videoTexture[0].RenderTarget as Texture2D); }
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 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 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(); }