Пример #1
0
        private void PerformStreamingUpdate(AudioData audioDataRes)
        {
            int num;

            AL.GetSource(this.alSource, ALGetSourcei.BuffersProcessed, out num);
            while (num > 0)
            {
                num--;

                int unqueued;
                unqueued = AL.SourceUnqueueBuffer(this.alSource);

                if (OggVorbis.IsStreamValid(this.strOvStr))
                {
                    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)
                    {
                        AL.BufferData(
                            unqueued,
                            pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                            pcm.data,
                            pcm.dataLength * PcmData.SizeOfDataElement,
                            pcm.sampleRate);
                        AL.SourceQueueBuffer(this.alSource, unqueued);
                    }
                    if (pcm.dataLength == 0 || eof)
                    {
                        this.strStopReq = StopRequest.EndOfStream;
                        break;
                    }
                }
            }
        }
Пример #2
0
        private void PerformStreamingBegin(AudioData audioDataRes)
        {
            // Generate streaming buffers
            this.strAlBuffers = new int[3];
            for (int i = 0; i < this.strAlBuffers.Length; ++i)
            {
                AL.GenBuffers(1, out this.strAlBuffers[i]);
            }

            // Begin streaming
            OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr);

            // Initially, completely fill all buffers
            for (int i = 0; i < this.strAlBuffers.Length; ++i)
            {
                PcmData pcm;
                bool    eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm);
                if (pcm.dataLength > 0)
                {
                    AL.BufferData(
                        this.strAlBuffers[i],
                        pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                        pcm.data,
                        pcm.dataLength * PcmData.SizeOfDataElement,
                        pcm.sampleRate);
                    AL.SourceQueueBuffer(this.alSource, this.strAlBuffers[i]);
                    if (eof)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }
Пример #3
0
        private static void ThreadStreamFunc(object param)
        {
            SoundInstance sndInst = (SoundInstance)param;

            while (true)
            {
                lock (sndInst.strLock)
                {
                    if (sndInst.Disposed)
                    {
                        return;
                    }
                    if (!DualityApp.Sound.IsAvailable)
                    {
                        return;
                    }

                    ALSourceState stateTemp = ALSourceState.Stopped;
                    if (sndInst.alSource > AlSource_NotAvailable)
                    {
                        stateTemp = AL.GetSourceState(sndInst.alSource);
                    }

                    if (stateTemp == ALSourceState.Stopped && sndInst.strStopReq != StopRequest.None)
                    {
                        // Stopped due to regular EOF. If strStopReq is NOT set,
                        // the source stopped playing because it reached the end of the buffer
                        // but in fact only because we were too slow inserting new data.
                        return;
                    }
                    else if (sndInst.strStopReq == StopRequest.Immediately)
                    {
                        // Stopped intentionally due to Stop()
                        if (sndInst.alSource > AlSource_NotAvailable)
                        {
                            AL.SourceStop(sndInst.alSource);
                        }
                        return;
                    }

                    Sound     soundRes     = sndInst.sound.Res;
                    AudioData audioDataRes = sndInst.audioData.Res;
                    if (soundRes == null || audioDataRes == null)
                    {
                        sndInst.Dispose();
                        return;
                    }
                    if (stateTemp == ALSourceState.Initial)
                    {
                        // Generate streaming buffers
                        sndInst.strAlBuffers = new int[3];
                        for (int i = 0; i < sndInst.strAlBuffers.Length; ++i)
                        {
                            AL.GenBuffers(1, out sndInst.strAlBuffers[i]);
                        }

                        // Begin streaming
                        OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out sndInst.strOvStr);

                        // Initially, completely fill all buffers
                        for (int i = 0; i < sndInst.strAlBuffers.Length; ++i)
                        {
                            PcmData pcm;
                            bool    eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                            if (pcm.dataLength > 0)
                            {
                                AL.BufferData(
                                    sndInst.strAlBuffers[i],
                                    pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                                    pcm.data,
                                    pcm.dataLength * PcmData.SizeOfDataElement,
                                    pcm.sampleRate);
                                AL.SourceQueueBuffer(sndInst.alSource, sndInst.strAlBuffers[i]);
                                if (eof)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }

                        // Initially play source
                        AL.SourcePlay(sndInst.alSource);
                        stateTemp = AL.GetSourceState(sndInst.alSource);
                    }
                    else
                    {
                        int num;
                        AL.GetSource(sndInst.alSource, ALGetSourcei.BuffersProcessed, out num);
                        while (num > 0)
                        {
                            num--;

                            int unqueued;
                            unqueued = AL.SourceUnqueueBuffer(sndInst.alSource);

                            if (OggVorbis.IsStreamValid(sndInst.strOvStr))
                            {
                                PcmData pcm;
                                bool    eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                                if (eof)
                                {
                                    OggVorbis.EndStream(ref sndInst.strOvStr);
                                    if (sndInst.looped)
                                    {
                                        OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out sndInst.strOvStr);
                                        if (pcm.dataLength == 0)
                                        {
                                            eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                                        }
                                    }
                                }
                                if (pcm.dataLength > 0)
                                {
                                    AL.BufferData(
                                        unqueued,
                                        pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                                        pcm.data,
                                        pcm.dataLength * PcmData.SizeOfDataElement,
                                        pcm.sampleRate);
                                    AL.SourceQueueBuffer(sndInst.alSource, unqueued);
                                }
                                if (pcm.dataLength == 0 || eof)
                                {
                                    sndInst.strStopReq = StopRequest.EndOfStream;
                                    break;
                                }
                            }
                        }
                    }

                    if (stateTemp == ALSourceState.Stopped && sndInst.strStopReq == StopRequest.None)
                    {
                        // If the source stopped unintentionally, restart it. (See above)
                        AL.SourcePlay(sndInst.alSource);
                    }
                }
                Thread.Sleep(16);
            }
        }