public static void LoadData <T>( this INativeAudioBuffer buffer, int sampleRate, T[] data, int dataLength, AudioDataLayout dataLayout, AudioDataElementType dataElementType) where T : struct { if (dataLength < 0) { throw new ArgumentOutOfRangeException("dataLength", "Data length cannot be negative"); } if (dataLength > data.Length) { throw new ArgumentOutOfRangeException("dataLength", "Data length cannot exceed the specified arrays length."); } int itemSize = Marshal.SizeOf(typeof(T)); using (PinnedArrayHandle pinned = new PinnedArrayHandle(data)) { buffer.LoadData( sampleRate, pinned.Address, itemSize * dataLength, dataLayout, dataElementType); } }
bool IAudioStreamProvider.ReadStream(INativeAudioBuffer targetBuffer) { if (openmpt_module == IntPtr.Zero) { return(false); } int count = openmpt_module_read_interleaved_stereo( openmpt_module, SampleRate, BufferSize >> 1, // Buffer size per channel audioBuffer ); if (count == 0) { return(false); } targetBuffer.LoadData( SampleRate, audioBuffer, count << 1, // Number of samples (left + right) AudioDataLayout.LeftRight, AudioDataElementType.Short ); return(true); }
private void PerformStreamingUpdate() { int num; AL.GetSource(this.handle, ALGetSourcei.BuffersProcessed, out num); while (num > 0) { num--; int unqueuedBufferHandle = AL.SourceUnqueueBuffer(this.handle); INativeAudioBuffer unqueuedBuffer = null; for (int i = 0; i < this.strAlBuffers.Length; i++) { NativeAudioBuffer buffer = this.strAlBuffers[i] as NativeAudioBuffer; if (buffer.Handle == unqueuedBufferHandle) { unqueuedBuffer = buffer; break; } } bool eof = !this.streamProvider.ReadStream(unqueuedBuffer); if (!eof) { AL.SourceQueueBuffer(this.handle, unqueuedBufferHandle); } else { this.strStopReq = StopRequest.EndOfStream; } } }
/// <summary> /// Disposes the AudioDatas native buffer. /// </summary> /// <seealso cref="SetupNativeBuffer"/> private void DisposeNativeBuffer() { if (this.native != null) { this.native.Dispose(); this.native = null; } }
void INativeAudioSource.Play(INativeAudioBuffer buffer) { lock (this.strLock) { if (!this.isInitial) throw new InvalidOperationException("Native audio source already in use. To re-use an audio source, reset it first."); this.isInitial = false; AL.SourceQueueBuffer(this.handle, (buffer as NativeAudioBuffer).Handle); AL.SourcePlay(handle); } }
/// <summary> /// Sets up a new native buffer for this AudioData. This will result in decompressing /// the Ogg Vorbis data and uploading it to OpenAL, unless the AudioData is streamed. /// </summary> private void SetupNativeBuffer() { // No AudioData available if (this.data == null || this.data.Length == 0) { this.DisposeNativeBuffer(); return; } // Streamed Audio if (this.IsStreamed) { this.DisposeNativeBuffer(); this.native = null; } // Non-Streamed Audio else { if (this.native == null) { this.native = DualityApp.AudioBackend.CreateBuffer(); //PcmData pcm = OggVorbis.LoadFromMemory(this.data); //this.native.LoadData( // pcm.SampleRate, // pcm.Data, // pcm.DataLength, // pcm.ChannelCount == 1 ? AudioDataLayout.Mono : AudioDataLayout.LeftRight, // AudioDataElementType.Short); byte[] samples; int sampleRate; AudioDataLayout layout; AudioDataElementType type; WavStreamHandle.Parse(this.data, out samples, out sampleRate, out layout, out type); int dataLength = (type == AudioDataElementType.Short ? samples.Length / 2 : samples.Length); this.native.LoadData( sampleRate, samples, dataLength, layout, type); } else { // Buffer already there? Do nothing. } } }
void INativeAudioSource.Play(INativeAudioBuffer buffer) { lock (this.strLock) { if (!this.isInitial) { throw new InvalidOperationException("Native audio source already in use. To re-use an audio source, reset it first."); } this.isInitial = false; AL.SourceQueueBuffer(this.handle, (buffer as NativeAudioBuffer).Handle); AL.SourcePlay(handle); } }
bool IAudioStreamProvider.ReadStream(INativeAudioBuffer targetBuffer) { /*if (!OggVorbis.IsStreamValid(this.strOvStr)) * return false; * * AudioData audioDataRes = this.audioData.Res; * PcmData pcm; * bool eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); * if (eof) * { * OggVorbis.EndStream(ref this.strOvStr); * if (this.looped) * { * OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr); * if (pcm.DataLength == 0) * eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); * else * eof = false; * } * } * * if (pcm.DataLength > 0) * { * targetBuffer.LoadData( * pcm.SampleRate, * pcm.Data, * pcm.DataLength, * pcm.ChannelCount == 1 ? AudioDataLayout.Mono : AudioDataLayout.LeftRight, * AudioDataElementType.Short); * } * * return pcm.DataLength != 0 && !eof;*/ /*byte[] buffer; * int sampleRate; * AudioDataLayout layout; * AudioDataElementType type; * strOvStr.StreamChunk(out buffer, out sampleRate, out layout, out type); * * if (buffer.Length > 0) { * targetBuffer.LoadData( * sampleRate, * buffer, * buffer.Length, * layout, * type); * }*/ return(false); }
void INativeAudioSource.Play(INativeAudioBuffer buffer) { if (!this.isInitial) { throw new InvalidOperationException( "Native audio source already in use. To re-use an audio source, reset it first."); } this.isInitial = false; IsStopped = false; this.strStopReq = StopRequest.None; // All samples are available now (buffer is completed) NativeAudioBuffer newBuffer = buffer as NativeAudioBuffer; AvailableBuffers = new[] { newBuffer }; QueuedBuffersPos = new[] { 0 }; QueuedBuffers.Enqueue(0); AudioBackend.ActiveInstance.EnqueueForStreaming(this); }
bool IAudioStreamProvider.ReadStream(INativeAudioBuffer targetBuffer) { if (!OggVorbis.IsStreamValid(this.strOvStr)) { return(false); } AudioData audioDataRes = this.audioData.Res; PcmData pcm; bool eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); if (eof) { OggVorbis.EndStream(ref this.strOvStr); if (this.looped) { OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr); if (pcm.DataLength == 0) { eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); } else { eof = false; } } } if (pcm.DataLength > 0) { targetBuffer.LoadData( pcm.SampleRate, pcm.Data, pcm.DataLength, pcm.ChannelCount == 1 ? AudioDataLayout.Mono : AudioDataLayout.LeftRight, AudioDataElementType.Short); } return(pcm.DataLength != 0 && !eof); }
/// <summary> /// Sets up a new native buffer for this AudioData. This will result in decompressing /// the Ogg Vorbis data and uploading it to OpenAL, unless the AudioData is streamed. /// </summary> private void SetupNativeBuffer() { // No AudioData available if (this.data == null || this.data.Length == 0) { this.DisposeNativeBuffer(); return; } // Streamed Audio if (this.IsStreamed) { this.DisposeNativeBuffer(); this.native = null; } // Non-Streamed Audio else { if (this.native == null) { this.native = DualityApp.AudioBackend.CreateBuffer(); PcmData pcm = OggVorbis.LoadFromMemory(this.data); this.native.LoadData( pcm.SampleRate, pcm.Data, pcm.DataLength, pcm.ChannelCount == 1 ? AudioDataLayout.Mono : AudioDataLayout.LeftRight, AudioDataElementType.Short); } else { // Buffer already there? Do nothing. } } }
bool IAudioStreamProvider.ReadStream(INativeAudioBuffer targetBuffer) { if (!OggVorbis.IsStreamValid(this.strOvStr)) return false; AudioData audioDataRes = this.audioData.Res; PcmData pcm; bool eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); if (eof) { OggVorbis.EndStream(ref this.strOvStr); if (this.looped) { OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr); if (pcm.DataLength == 0) eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm); else eof = false; } } if (pcm.DataLength > 0) { targetBuffer.LoadData( pcm.SampleRate, pcm.Data, pcm.DataLength, pcm.ChannelCount == 1 ? AudioDataLayout.Mono : AudioDataLayout.LeftRight, AudioDataElementType.Short); } return pcm.DataLength != 0 && !eof; }
void INativeAudioSource.Play(INativeAudioBuffer buffer) { this.initial = false; }