Exemple #1
0
        private void Run()
        {
            try
            {
                App.DebugLog("Started streaming custom audio @ {0}Hz", m_sampleRate);

                // Get number of channels and sample rate
                var channels   = m_channels;
                var format     = (channels == 2) ? ALFormat.Stereo16 : ALFormat.Mono16;
                var sampleRate = m_sampleRate;

                // Start reading
                int nextBufferIndex = 0;
                var shortBuffer     = new short[SAMPLES_PER_BUFFER * channels];

                // Loop until the we stop
                while (true)
                {
                    // Get the queue state
                    int queued, processed;
                    lock (m_lock)
                    {
                        if (m_stopped)
                        {
                            break;
                        }

                        AL.GetSource(m_source, ALGetSourcei.BuffersQueued, out queued);
                        AL.GetSource(m_source, ALGetSourcei.BuffersProcessed, out processed);
                        App.CheckOpenALError(true);

                        // Dequeued processed buffers
                        if (processed > 0)
                        {
                            AL.SourceUnqueueBuffers((int)m_source, processed);
                            App.CheckOpenALError(true);
                            queued   -= processed;
                            processed = 0;
                        }
                    }

                    // Queue some samples
                    while (queued < m_buffers.Length)
                    {
                        // Generate the samples
                        m_audioSource.GenerateSamples(this, shortBuffer, 0, SAMPLES_PER_BUFFER);

                        // Pick an OpenAL buffer to put the samples in
                        var alBuffer = m_buffers[nextBufferIndex];
                        nextBufferIndex = (nextBufferIndex + 1) % m_buffers.Length;

                        lock (m_lock)
                        {
                            if (m_stopped)
                            {
                                break;
                            }

                            // Put the samples into the OpenAL buffer
                            AL.BufferData((int)alBuffer, format, shortBuffer, SAMPLES_PER_BUFFER * channels * sizeof(short), sampleRate);
                            App.CheckOpenALError(true);

                            // Add the buffer to the source's queue
                            AL.SourceQueueBuffer((int)m_source, (int)alBuffer);
                            App.CheckOpenALError(true);
                        }

                        queued++;
                    }

                    // Play the source if it's not playing already
                    lock (m_lock)
                    {
                        if (m_stopped)
                        {
                            break;
                        }

                        var state = AL.GetSourceState(m_source);
                        if (state != ALSourceState.Playing)
                        {
                            if (state != ALSourceState.Initial)
                            {
                                App.Log("Error: Buffer overrun detected. Resuming custom audio");
                            }
                            AL.SourcePlay(m_source);
                            App.CheckOpenALError(true);
                        }
                    }

                    // Sleep
                    Thread.Sleep(UPDATE_INTERVAL_MILLIS);
                }
                App.DebugLog("Stopped streaming custom audio");
            }
            catch (Exception e)
            {
                App.Log("Error streaming custom audio: Threw {0}: {1}", e.GetType().FullName, e.Message);
                App.Log(e.StackTrace);
            }
            finally
            {
                if (!m_stopped)
                {
                    // Wait for complete
                    while (true)
                    {
                        lock (m_lock)
                        {
                            if (m_stopped)
                            {
                                break;
                            }

                            var state = AL.GetSourceState(m_source);
                            if (state != ALSourceState.Playing)
                            {
                                break;
                            }
                        }
                        Thread.Sleep(UPDATE_INTERVAL_MILLIS);
                    }

                    // Stop
                    Stop();
                }
            }
        }