public void SubmitBuffer_ParameterValidation_ComplexOverload() { using (var instance = new DynamicSoundEffectInstance(16000, AudioChannels.Stereo)) { // Null or empty buffer - with different null behavior to the other overload Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(null, 0, 4); }); Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(new byte[0], 0, 4); }); var buffer = GenerateSineWave(440, 16000, 2, 0.5f); // Correct alignment instance.SubmitBuffer(buffer, 0, 4); // One sample per channel instance.SubmitBuffer(buffer, 1000, 1000); // 250 samples // Invalid alignment Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, 0, 3); }); Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, 1, 4); }); // Unaligned start position also throws // Invalid size Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, 0, 0); }); Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, 0, -1); }); Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, 0, buffer.Length + 1); }); Assert.Throws <ArgumentException>(() => { instance.SubmitBuffer(buffer, buffer.Length - 4, 8); }); } }
private void StreamThread() { while (!sound.IsDisposed) { // sleep until we need a buffer while (!sound.IsDisposed && !threadRunHandle.WaitOne(0) && !needBufferHandle.WaitOne(0)) { Thread.Sleep(50); } // if the thread is waiting to exit, leave if (threadRunHandle.WaitOne(0)) { break; } lock (sound) { // ensure the effect isn't disposed if (sound.IsDisposed) { break; } } // read the next chunk of data int samplesRead = reader.ReadSamples(nvBuffer, 0, nvBuffer.Length); // out of data and looping? reset the reader and read again if (samplesRead == 0 && IsLooped) { reader.DecodedTime = TimeSpan.Zero; samplesRead = reader.ReadSamples(nvBuffer, 0, nvBuffer.Length); } if (samplesRead > 0) { for (int i = 0; i < samplesRead; i++) { short sValue = (short)Math.Max(Math.Min(short.MaxValue * nvBuffer[i], short.MaxValue), short.MinValue); buffer[i * 2] = (byte)(sValue & 0xff); buffer[i * 2 + 1] = (byte)((sValue >> 8) & 0xff); } // submit our buffers lock (sound) { // ensure the effect isn't disposed if (sound.IsDisposed) { break; } sound.SubmitBuffer(buffer, 0, samplesRead); sound.SubmitBuffer(buffer, samplesRead, samplesRead); } } // reset our handle needBufferHandle.Reset(); } }
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); //} } }
public void SubmitBuffer(byte[] buf, int offset, int length) { System.Buffer.BlockCopy(buf, offset, mBuffer, 0, length); int halfLen = length / 2; mSoundEffectInstance.SubmitBuffer(mBuffer, 0, halfLen); mSoundEffectInstance.SubmitBuffer(mBuffer, halfLen, halfLen); }
/// <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); }
bool SubmitSamples() { // read the next chunk of data int samplesRead = reader.ReadSamples(nvBuffer, 0, nvBuffer.Length); // out of data and looping? reset the reader and read again if (samplesRead == 0) { if (IsLooped) { reader.DecodedTime = TimeSpan.Zero; samplesRead = reader.ReadSamples(nvBuffer, 0, nvBuffer.Length); } else { // Song is over, stop thread thread = null; return(false); } } if (samplesRead > 0) { // Submit our buffers #if !FNA for (int i = 0; i < samplesRead; i++) { short sValue = (short)Math.Max(Math.Min(short.MaxValue * nvBuffer[i], short.MaxValue), short.MinValue); buffer[i * 2] = (byte)(sValue & 0xff); buffer[i * 2 + 1] = (byte)((sValue >> 8) & 0xff); } #endif lock ( effect ) { // Ensure the effect isn't disposed if (effect.IsDisposed) { return(false); } // Ensure the number of samples read is block-aligned samplesRead += samplesRead % (reader.Channels * 2); #if !FNA effect.SubmitBuffer(buffer, 0, samplesRead); effect.SubmitBuffer(buffer, samplesRead, samplesRead); #else effect.SubmitFloatBufferEXT(nvBuffer); #endif } } return(true); }
void DynamicSound_BufferNeeded(object sender, EventArgs e) { dynamicSound.SubmitBuffer(byteArray, position, count / 2); dynamicSound.SubmitBuffer(byteArray, position + count / 2, count / 2); position += count; if (position + count > byteArray.Length) { position = 0; } }
public MainPage() { InitializeComponent(); mixer = new Mixer(); emptyBuffer = new byte[1024]; sound = new DynamicSoundEffectInstance(48000, AudioChannels.Stereo); sound.SubmitBuffer(emptyBuffer); sound.SubmitBuffer(emptyBuffer); sound.BufferNeeded += new EventHandler <EventArgs>(sound_BufferNeeded); sound.Play(); }
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); } }
private void SubmitBuffer(object sender, EventArgs e) { byte[] buffer = new byte[524288]; lock (this) { var read = Stream.Read(buffer, 0, buffer.Length); LastChunkSize = read; if (read == 0) { return; } Inst.SubmitBuffer(buffer, 0, read); } }
void _dsei_BufferNeeded(object sender, EventArgs e) { if (Player != null) { for (int i = 0; i < 3; i++) { this.Player.GetBytes(buf, 8192); _dsei.SubmitBuffer(buf); } } else { _dsei.SubmitBuffer(buf); } }
private void SubmitBuffer() { _bufferPos = 0; ConvertBuffer(_workingBuffer, _monoBuffer); _instance.SubmitBuffer(_monoBuffer); }
void FillBuffer() { /* * int WriteBuffer = * WaitAtLeastBuffer(4); * for (int n = 0; n < 4; n++) * { * var Segment = Buffer.Dequeue(); * //Debug.WriteLine("BUFFER: {0}, {1} : {2}:{3}", Buffer.Count, DynamicSoundEffect.PendingBufferCount, Segment.Offset, Segment.Count); * //DynamicSoundEffect.SubmitBuffer(Segment.Array, Segment.Offset, Segment.Count); * DynamicSoundEffect.SubmitBuffer(Segment); * } */ int BufferCount = 2; do { WaitAtLeastBuffer(BufferCount); for (int n = 0; n < BufferCount; n++) { var Segment = ReadBuffer(); if (Segment == null) { Ended = true; return; } else { EmittedBytes += Segment.Length; DynamicSoundEffect.SubmitBuffer(Segment); } } } while (DynamicSoundEffect.PendingBufferCount < BufferCount * 2); //DynamicSoundEffect.pen }
private void OnBufferNeeded(object sender, EventArgs e) { Array.Clear(_buffer, 0, _buffer.Length); var available = _audioSampleProvider != null?_audioSampleProvider.Read(_buffer, _buffer.Length) : 0; _dsei.SubmitBuffer(_buffer, available); }
private void QueueBuffer(object source, EventArgs ea) { // The original method refers to Int64 Vorbisfile.ov_read(IntPtr, IntPtr, Int32, Int32, Int32, Int32, Int32 ByRef), // which has been changed in newer FNA releases. The last parameter is now out, not ref. int pos = 0; int read; do { int current_section; read = (int)Vorbisfile.ov_read(vorbisFile, bufferPtr + pos, 4096, 0, 2, 1, out current_section); pos += read; }while (read > 0 && pos < 187904); if (pos != 0) { soundEffect.SubmitBuffer(vorbisBuffer, 0, pos); return; } if (IsLooped) { Vorbisfile.ov_time_seek(vorbisFile, 0.0); QueueBuffer(source, ea); return; } hitEof = true; soundEffect.BufferNeeded -= OnBufferNeeded; }
private void FillBuffers(int buffers = 3, int samples = 44100) { float[] sampleBuffer = null; while (mInstance.PendingBufferCount < buffers && mReader != null) { if (sampleBuffer == null) { sampleBuffer = new float[samples]; } var read = mReader.ReadSamples(sampleBuffer, 0, sampleBuffer.Length); if (read == 0) { mReader.DecodedPosition = 0; continue; } var dataBuffer = new byte[read << 1]; for (var sampleIndex = 0; sampleIndex < read; ++sampleIndex) { var sample = (short)MathHelper.Clamp(sampleBuffer[sampleIndex] * 32767f, short.MinValue, short.MaxValue); var sampleData = BitConverter.GetBytes(sample); for (var sampleByteIndex = 0; sampleByteIndex < sampleData.Length; ++sampleByteIndex) { dataBuffer[(sampleIndex << 1) + sampleByteIndex] = sampleData[sampleByteIndex]; } } mInstance.SubmitBuffer(dataBuffer, 0, read << 1); } }
private void SubmitBuffer() { _vorbis.SubmitBuffer(); if (_vorbis.Decoded == 0) { // Restart _vorbis.Restart(); _vorbis.SubmitBuffer(); } var audioShort = _vorbis.SongBuffer; byte[] audioData = new byte[_vorbis.Decoded * _vorbis.Channels * 2]; for (var i = 0; i < _vorbis.Decoded * _vorbis.Channels; ++i) { if (i * 2 >= audioData.Length) { break; } var b1 = (byte)(audioShort[i] >> 8); var b2 = (byte)(audioShort[i] & 256); audioData[i * 2 + 0] = b2; audioData[i * 2 + 1] = b1; } _effect.SubmitBuffer(audioData); }
/// <summary> /// Plays the effect. /// </summary> /// <param name="asEffect">Set to false for music, true for sound effects.</param> public void Play(bool asEffect = true) { double now = UltimaGame.TotalMS; CullExpiredEffects(now); m_ThisInstance = GetNewInstance(asEffect); if (m_ThisInstance == null) { this.Dispose(); return; } BeforePlay(); byte[] buffer = GetBuffer(); if (buffer != null && buffer.Length > 0) { m_ThisInstance.BufferNeeded += new EventHandler <EventArgs>(OnBufferNeeded); m_ThisInstance.SubmitBuffer(buffer); m_ThisInstance.Play(); List <Tuple <DynamicSoundEffectInstance, double> > list = (asEffect) ? m_EffectInstances : m_MusicInstances; list.Add(new Tuple <DynamicSoundEffectInstance, double>(m_ThisInstance, now + (m_ThisInstance.GetSampleDuration(buffer.Length).Milliseconds))); } }
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(); }
internal void QueueBuffer(object sender, EventArgs args) { int bs; int cur = 0; int total = 0; do { cur = (int)Vorbisfile.ov_read( vorbisFile, bufferPtr + total, 4096, 0, 2, 1, out bs ); total += cur; } while (cur > 0 && total < (MAX_SAMPLES - 4096)); // If we're at the end of the file, stop! if (total == 0) { eof = true; soundStream.BufferNeeded -= QueueBuffer; return; } // Send the filled buffer to the stream. soundStream.SubmitBuffer( vorbisBuffer, 0, total ); }
public override void Update() { while (soundInstance.PendingBufferCount < 3) { var p8Buffer = Emulator.Audio.RequestBuffer(); var samplesPerBuffer = p8Buffer.Length; var audioBuffer = new byte[samplesPerBuffer * 2]; for (var i = 0; i < samplesPerBuffer; i += 1) { var floatSample = p8Buffer[i]; var shortSample = (short)(floatSample >= 0.0f ? floatSample * short.MaxValue : floatSample * short.MinValue * -1); if (!BitConverter.IsLittleEndian) { audioBuffer[i * 2] = (byte)(shortSample >> 8); audioBuffer[i * 2 + 1] = (byte)shortSample; } else { audioBuffer[i * 2] = (byte)shortSample; audioBuffer[i * 2 + 1] = (byte)(shortSample >> 8); } } soundInstance.SubmitBuffer(audioBuffer); } }
private void HandleAudio() { //If enough has been gathered to submit, do so if (emu.APU.GetAudioBufferReady()) { float[] buffer = emu.APU.GetAudioBuffer(); for (int i = 0; i < APU.BufferSize; i++) { float sample = MathHelper.Clamp(buffer[i], 0, 1); short signedSample = (short)(sample * (short.MaxValue - short.MinValue) + short.MinValue); int index = i * 2; if (!BitConverter.IsLittleEndian) { audioBuffer[index] = (byte)(signedSample >> 8); audioBuffer[index + 1] = (byte)signedSample; } else { audioBuffer[index] = (byte)signedSample; audioBuffer[index + 1] = (byte)(signedSample >> 8); } } sound.SubmitBuffer(audioBuffer); } }
// Private Methods private void SubmitBuffer() { ClearWorkingBuffer(); FillWorkingBuffer(); SoundHelper.ConvertBuffer(_workingBuffer, _xnaBuffer); _instance.SubmitBuffer(_xnaBuffer); }
public void PlaySound(int samplingRate, byte[] pcmData) { DynamicSoundEffectInstance playback = new DynamicSoundEffectInstance(samplingRate, AudioChannels.Mono); playback.SubmitBuffer(pcmData); playback.Play(); }
void submitBuffer() { // clear the buffer before filling it Array.Clear(_workingBuffer, 0, channels * samplesPerBuffer); fillWorkingBuffer(); SoundHelper.convertBuffer(_workingBuffer, _xnaBuffer); _instance.SubmitBuffer(_xnaBuffer); }
private void UnlockBuffer(byte[] buffer) { lock (m_soundEffect) { m_soundEffect.SubmitBuffer(buffer); m_playQueue.Enqueue(buffer); } }
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(); }
/// <summary> /// Gives samples to the DynamicSoundEffectInstance to play. /// Updates the position of the playback in the buffer. /// </summary> /// <param name="sender">DynamicSoundEffectInstance.</param> /// <param name="e">Event arguments.</param> private void GetSamples(object sender, EventArgs e) { // -44 for taking wav header into account while (playback.PendingBufferCount < 2 && position < byteArray.Length - 44) { playback.SubmitBuffer(byteArray, position, sampleSize); position += sampleSize; } }
void sound_BufferNeeded(object sender, EventArgs e) { if (!isPlaying) { sound.SubmitBuffer(emptyBuffer); } else { short[] data = mixer.MixToStream(); byte[] buffer = new byte[data.Length * sizeof(short)]; for (int i = 0; i < data.Length; i++) { BitConverter.GetBytes(data[i]).CopyTo(buffer, i * 2); } sound.SubmitBuffer(buffer); } }
private void SubmitBuffer(int count = 1) { while (count > 0) { ReadFromStream(); m_Instance.SubmitBuffer(m_WaveBuffer); count--; } }
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 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 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 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(); }