Example #1
0
        public void Resume()
        {
            if (AL.GetSourceState(alSourceId) != ALSourceState.Paused)
            {
                return;
            }

            AudioDevice.Instance.AddStream(this);
            AL.SourcePlay(alSourceId);
            ALHelper.Check();
        }
Example #2
0
        public void Pause()
        {
            if (AL.GetSourceState(alSourceId) != ALSourceState.Playing)
            {
                return;
            }

            AudioDevice.Instance.RemoveStream(this);
            AL.SourcePause(alSourceId);
            ALHelper.Check();
        }
Example #3
0
        public bool FillBuffer(Sound stream, int bufferId)
        {
            int readSamples;

            lock (readMutex)
            {
                readSamples = stream.Reader.ReadSamples(readSampleBuffer, 0, BufferSize);
                CastBuffer(readSampleBuffer, castBuffer, readSamples);
            }
            AL.BufferData(bufferId, stream.Reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, castBuffer,
                          readSamples * sizeof(short), stream.Reader.SampleRate);
            ALHelper.Check();

            return(readSamples != BufferSize);
        }
Example #4
0
        internal void Open(bool precache = false)
        {
            underlyingStream.Seek(0, SeekOrigin.Begin);
            Reader = new VorbisReader(underlyingStream, false);

            if (precache)
            {
                // Fill first buffer synchronously
                AudioDevice.Instance.FillBuffer(this, alBufferIds[0]);
                AL.SourceQueueBuffer(alSourceId, alBufferIds[0]);
                ALHelper.Check();

                // Schedule the others asynchronously
                AudioDevice.Instance.AddStream(this);
            }

            Ready = true;
        }
Example #5
0
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    var state = AL.GetSourceState(alSourceId);
                    if (state == ALSourceState.Playing || state == ALSourceState.Paused)
                    {
                        StopPlayback();
                    }

                    lock (prepareMutex)
                    {
                        AudioDevice.Instance.RemoveStream(this);

                        if (state != ALSourceState.Initial)
                        {
                            Empty();
                        }

                        Close();

                        underlyingStream.Dispose();
                    }

                    AL.DeleteSource(alSourceId);
                    AL.DeleteBuffers(alBufferIds);

                    if (ALHelper.Efx.IsInitialized)
                    {
                        ALHelper.Efx.DeleteFilter(alFilterId);
                    }

                    ALHelper.Check();
                }

                // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
                // TODO: set large fields to null.

                disposedValue = true;
            }
        }
Example #6
0
        public void Play()
        {
            var state = AL.GetSourceState(alSourceId);

            switch (state)
            {
            case ALSourceState.Playing: return;

            case ALSourceState.Paused:
                Resume();
                return;
            }

            Prepare();

            AL.SourcePlay(alSourceId);
            ALHelper.Check();

            Preparing = false;

            AudioDevice.Instance.AddStream(this);
        }
Example #7
0
 void StopPlayback()
 {
     AL.SourceStop(alSourceId);
     ALHelper.Check();
 }
Example #8
0
        public void EnsureBuffersFilled()
        {
            do
            {
                threadLocalStreams.Clear();
                lock (iterationMutex) threadLocalStreams.AddRange(streams);

                foreach (var stream in threadLocalStreams)
                {
                    lock (stream.prepareMutex)
                    {
                        lock (iterationMutex)
                            if (!streams.Contains(stream))
                            {
                                continue;
                            }

                        bool finished = false;

                        int queued;
                        AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersQueued, out queued);
                        ALHelper.Check();
                        int processed;
                        AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersProcessed, out processed);
                        ALHelper.Check();

                        if (processed == 0 && queued == stream.BufferCount)
                        {
                            continue;
                        }

                        int[] tempBuffers;
                        if (processed > 0)
                        {
                            tempBuffers = AL.SourceUnqueueBuffers(stream.alSourceId, processed);
                        }
                        else
                        {
                            tempBuffers = stream.alBufferIds.Skip(queued).ToArray();
                        }

                        int bufIdx = 0;
                        for (; bufIdx < tempBuffers.Length; bufIdx++)
                        {
                            finished |= FillBuffer(stream, tempBuffers[bufIdx]);

                            if (finished)
                            {
                                if (stream.IsLooped)
                                {
                                    stream.Reader.DecodedTime = TimeSpan.Zero;
                                    if (bufIdx == 0)
                                    {
                                        // we didn't have any buffers left over, so let's start from the beginning on the next cycle...
                                        continue;
                                    }
                                }
                                else
                                {
                                    lock (stream.stopMutex)
                                    {
                                        stream.NotifyFinished();
                                    }
                                    streams.Remove(stream);
                                    break;
                                }
                            }
                        }

                        AL.SourceQueueBuffers(stream.alSourceId, bufIdx, tempBuffers);
                        ALHelper.Check();

                        if (finished && !stream.IsLooped)
                        {
                            continue;
                        }
                    }

                    lock (stream.stopMutex)
                    {
                        if (stream.Preparing)
                        {
                            continue;
                        }

                        lock (iterationMutex)
                            if (!streams.Contains(stream))
                            {
                                continue;
                            }

                        var state = AL.GetSourceState(stream.alSourceId);
                        if (state == ALSourceState.Stopped)
                        {
                            AL.SourcePlay(stream.alSourceId);
                            ALHelper.Check();
                        }
                    }
                }

                if (UpdateRate > 0)
                {
                    Thread.Sleep((int)(1000 / UpdateRate));
                }
            }while (underlyingThread != null && !cancelled);
        }