public override void Update(Microsoft.Xna.Framework.GameTime gameTime) { while (_dsi.PendingBufferCount < 3) { var buf = _master.RequestBuffer(_config.BufferLengthSamples); _dsi.SubmitFloatBufferEXT(buf); } base.Update(gameTime); }
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); }
private unsafe void FillBuffer(object sender, EventArgs e) { int totalSamples = 0; if (vorbis != IntPtr.Zero) { fixed(float *audioBufferPinned = audioBuffer) { int previousSamples = -1; // <- Just silence if we cannot read anything even after seeking do { int samples = stb_vorbis_get_samples_float_interleaved(vorbis, channels, audioBufferPinned + totalSamples * channels, audioBuffer.Length - totalSamples * channels); Debug.Assert(samples >= 0); // <- stb_vorbis should never return negative samples! totalSamples += samples; if (samples == 0) { if (IsLooped && previousSamples != 0) { if (loopStart == 0) { FAudio.stb_vorbis_seek_start(vorbis); } else { FAudio.stb_vorbis_seek(vorbis, (uint)loopStart); } } else { break; } } previousSamples = samples; }while(totalSamples < bufferSamples); } } Debug.Assert(totalSamples <= bufferSamples); if (totalSamples < bufferSamples) { Array.Clear(audioBuffer, totalSamples * channels, audioBuffer.Length - totalSamples * channels); totalSamples = bufferSamples; } instance.SubmitFloatBufferEXT(audioBuffer, 0, totalSamples * channels); }
private bool StreamAudio() { // The size of our abstracted buffer. const int BUFFER_SIZE = 4096 * 2; // Store our abstracted buffer into here. List <float> data = new List <float>(); // We'll store this here, so alBufferData can use it too. TheoraPlay.THEORAPLAY_AudioPacket currentAudio; // There might be an initial period of silence, so forcibly push through. while (audioStream.State == SoundState.Stopped && TheoraPlay.THEORAPLAY_availableAudio(Video.theoraDecoder) == 0) { ; } // Add to the buffer from the decoder until it's large enough. while (data.Count < BUFFER_SIZE) { IntPtr audioPtr = TheoraPlay.THEORAPLAY_getAudio(Video.theoraDecoder); if (audioPtr == IntPtr.Zero) { // FIXME: THEORAPLAY_availableAudio has rounding issues! -flibit break; } currentAudio = TheoraPlay.getAudioPacket(audioPtr); data.AddRange( TheoraPlay.getSamples( currentAudio.samples, currentAudio.frames * currentAudio.channels ) ); TheoraPlay.THEORAPLAY_freeAudio(audioPtr); } // If we actually got data, queue it! if (data.Count > 0) { audioStream.SubmitFloatBufferEXT(data.ToArray()); } else if (TheoraPlay.THEORAPLAY_isDecoding(Video.theoraDecoder) == 0) { // Okay, we ran out. No need for this! audioStream.BufferNeeded -= OnBufferRequest; return(false); } return(true); }
public static int PlaySound(string fileName, float volume = 1.0f) { if (volume * seBalance <= 0f) { return(0); } //don't play more than X sound effects in one frame if (soundIndex == playedSounds.Length) { return(0); } //don't play more than one instance of the same sound in one frame for (int ii = 0; ii < soundIndex; ii++) { if (fileName == playedSounds[ii]) { return(0); } } playedSounds[soundIndex] = fileName; soundIndex++; IntPtr stbVorbisData = FAudio.stb_vorbis_open_filename(fileName, out int error, IntPtr.Zero); FAudio.stb_vorbis_info fileInfo = FAudio.stb_vorbis_get_info(stbVorbisData); long total_samples = FAudio.stb_vorbis_stream_length_in_samples(stbVorbisData); long total_frames = total_samples * 60 / fileInfo.sample_rate; float[] chunk = new float[fileInfo.channels * total_samples]; int framesRead = FAudio.stb_vorbis_get_samples_float_interleaved(stbVorbisData, fileInfo.channels, chunk, fileInfo.channels * (int)total_samples); FAudio.stb_vorbis_close(stbVorbisData); DynamicSoundEffectInstance soundStream = new DynamicSoundEffectInstance( (int)fileInfo.sample_rate, (fileInfo.channels == 1) ? AudioChannels.Mono : AudioChannels.Stereo ); soundStream.Volume = volume * seBalance; soundStream.SubmitFloatBufferEXT(chunk, 0, framesRead * fileInfo.channels); soundStream.Play(); return((int)total_frames); }
private bool StreamAudio() { // The size of our abstracted buffer. const int BUFFER_SIZE = 4096 * 2; // Store our abstracted buffer into here. List <float> data = new List <float>(); // We'll store this here, so alBufferData can use it too. TheoraPlay.THEORAPLAY_AudioPacket currentAudio; currentAudio.channels = 0; currentAudio.freq = 0; // There might be an initial period of silence, so forcibly push through. while (audioStream.State == SoundState.Stopped && TheoraPlay.THEORAPLAY_availableAudio(Video.theoraDecoder) == 0) { ; } // Add to the buffer from the decoder until it's large enough. while (data.Count < BUFFER_SIZE && TheoraPlay.THEORAPLAY_availableAudio(Video.theoraDecoder) > 0) { IntPtr audioPtr = TheoraPlay.THEORAPLAY_getAudio(Video.theoraDecoder); currentAudio = TheoraPlay.getAudioPacket(audioPtr); data.AddRange( TheoraPlay.getSamples( currentAudio.samples, currentAudio.frames * currentAudio.channels ) ); TheoraPlay.THEORAPLAY_freeAudio(audioPtr); } // If we actually got data, buffer it into OpenAL. if (data.Count > 0) { audioStream.SubmitFloatBufferEXT(data.ToArray()); return(true); } return(false); }
private void queueBuffer() { int framesRead = FAudio.stb_vorbis_get_samples_float_interleaved(stbVorbisData, Channels, chunk, chunkSize); framesRead = (int)Math.Min(framesRead, loopEnd - pcmPosition); if (framesRead != 0) { soundStream.SubmitFloatBufferEXT(chunk, 0, framesRead * Channels); pcmPosition += framesRead; } if (loopEnd == pcmPosition) { FAudio.stb_vorbis_seek_frame(stbVorbisData, (uint)loopStart); pcmPosition = loopStart; queueBuffer(); } }
private void OnBufferRequest(object sender, EventArgs args) { int samples = Theorafile.tf_readaudio( Video.theora, audioDataPtr, AUDIO_BUFFER_SIZE ); if (samples > 0) { audioStream.SubmitFloatBufferEXT( audioData, 0, samples ); } else if (Theorafile.tf_eos(Video.theora) == 1) { // Okay, we ran out. No need for this! audioStream.BufferNeeded -= OnBufferRequest; } }