示例#1
0
        /// <summary>
        /// Disposes the object.
        /// </summary>
        /// <param name="disposing">The disposing state.</param>
        protected virtual void Dispose(bool disposing)
        {
            _beginDispose = true;
            if (PlaybackState != PlaybackState.Stopped)
            {
                lock (_locker)
                {
                    OpenAL.alSourceStop(_source.SourceId);
                    PlaybackState = PlaybackState.Stopped;
                    RaisePlaybackChanged();
                }
            }

            if (_source.SourceId != 0)
            {
                lock (_locker)
                {
                    var queuedBuffers = new uint[3];
                    OpenAL.alSourceUnqueueBuffers(_source.SourceId, 3, queuedBuffers);
                    OpenAL.alDeleteBuffers(3, queuedBuffers);
                }
                Owner.SourcePool.FreeSource(_source);
                Owner.DestroyAudioBuffer(this);
            }

            if (disposing)
            {
            }
        }
示例#2
0
 /// <summary>
 /// Resumes the playback.
 /// </summary>
 public void Resume()
 {
     lock (_locker)
     {
         Owner.Context.MakeCurrent();
         OpenAL.alSourcePlay(_source.SourceId);
         PlaybackState = PlaybackState.Playing;
         RaisePlaybackChanged();
     }
 }
示例#3
0
 /// <summary>
 /// Stops the playback.
 /// </summary>
 public void Stop()
 {
     lock (_locker)
     {
         Owner.Context.MakeCurrent();
         OpenAL.alSourceStop(_source.SourceId);
         PlaybackState = PlaybackState.Stopped;
         RaisePlaybackChanged();
     }
 }
示例#4
0
        /// <summary>
        /// Requests a Source from the source pool.
        /// </summary>
        /// <returns>OpenALSource.</returns>
        public OpenALSource RequestSource()
        {
            _context.MakeCurrent();
            var sources = new uint[1];

            OpenAL.alGenSources(1, sources);

            var source = new OpenALSource(sources[0]);

            _sources.Add(source);
            return(source);
        }
示例#5
0
        /// <summary>
        /// Initializes the device.
        /// </summary>
        private void InitializeDevice()
        {
            if (_deviceHandle != IntPtr.Zero)
            {
                return;
            }

            _disposing    = false;
            _deviceHandle = OpenAL.alcOpenDevice(Name);
            Context       = OpenALContext.CreateContext(_deviceHandle);
            SourcePool    = new OpenALSourcePool(Context);
        }
示例#6
0
 /// <summary>
 /// Frees a source.
 /// </summary>
 /// <param name="source">The OpenALSource.</param>
 public void FreeSource(OpenALSource source)
 {
     if (_sources.Contains(source))
     {
         _sources.Remove(source);
         if (source.SourceId != 0)
         {
             _context.MakeCurrent();
             var sources = new uint[1];
             sources[0] = source.SourceId;
             OpenAL.alDeleteSources(1, sources);
             source.Reset();
         }
     }
 }
示例#7
0
        /// <summary>
        /// Disposes the object.
        /// </summary>
        /// <param name="disposing">The disposing state.</param>
        public virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                SourcePool.Dispose();
            }

            if (_deviceHandle == IntPtr.Zero)
            {
                return;
            }

            _disposing = true;

            Context.Destroy();
            OpenAL.alcCloseDevice(_deviceHandle);
            _deviceHandle = IntPtr.Zero;
            Context       = null;
        }
示例#8
0
        /// <summary>
        /// Initializes the OpenALAudioBuffer class.
        /// </summary>
        /// <param name="audioData">The Buffer.</param>
        /// <param name="format">The WaveFormat.</param>
        /// <param name="latency">The Latency.</param>
        public void Initialize(byte[] audioData, WaveFormat format, int latency)
        {
            lock (_locker)
            {
                Owner.Context.MakeCurrent();

                OpenAL.alListener3f(SourceProperty.Position, 0, 0, 1);
                OpenAL.alListener3f(SourceProperty.Velocity, 0, 0, 0);
                OpenAL.alListenerfv(SourceProperty.Orientation, new float[] { 0, 0, 1, 0, 1, 0 });
                OpenAL.alSourcef(_source.SourceId, SourceProperty.Gain, _audioMixer.Volume);
                OpenAL.alSourcefv(_source.SourceId, SourceProperty.Position, new[] { _audioMixer.Pan, 0, 0 });
            }

            SampleRate      = (uint)format.SamplesPerSec;
            Latency         = latency;
            _audioData      = audioData;
            WaveFormat      = format;
            Length          = audioData.Length / format.AvgBytesPerSec * 1000;
            _bufferSize     = format.AvgBytesPerSec / 1000 * latency;
            _processedBytes = 0;
        }
示例#9
0
        /// <summary>
        /// Disposes the object.
        /// </summary>
        /// <param name="disposing">The disposing state.</param>
        protected virtual void Dispose(bool disposing)
        {
            _context.MakeCurrent();

            foreach (var source in _sources)
            {
                if (source != null && source.SourceId != 0)
                {
                    var sources = new uint[1];
                    sources[0] = source.SourceId;
                    OpenAL.alDeleteSources(1, sources);
                    source.Reset();
                }
#if DEBUG
                _logger.Info("Source automatically disposed.");
#endif
            }

            if (disposing)
            {
                _sources.Clear();
            }
        }
示例#10
0
 /// <summary>
 /// Fills the buffer.
 /// </summary>
 /// <param name="target">The OpenALDataBuffer.</param>
 private void FillBuffer(OpenALDataBuffer target)
 {
     lock (_locker)
     {
         var unqueueBuffer = new uint[1];
         OpenAL.alSourceUnqueueBuffers(_source.SourceId, 1, unqueueBuffer);
         var data       = new byte[_bufferSize];
         var datalength = _bufferSize;
         if (_bufferSize > _audioData.Length - _processedBytes)
         {
             Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _audioData.Length - _processedBytes);
             datalength       = _audioData.Length - _processedBytes;
             _processedBytes += datalength;
         }
         else
         {
             Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _bufferSize);
             _processedBytes += _bufferSize;
         }
         _audioMixer.ApplyEffects(data, WaveFormat);
         OpenAL.alBufferData(target.Id, Format, data, datalength, SampleRate);
         OpenAL.alSourceQueueBuffers(_source.SourceId, 1, new[] { target.Id });
     }
 }
示例#11
0
        /// <summary>
        /// Starts the playback.
        /// </summary>
        private void StartPlayback()
        {
            if (PlaybackState == PlaybackState.Stopped)
            {
                PlaybackState = PlaybackState.Playing;
                RaisePlaybackChanged();

                _processedBytes = 0;

                _playbackThread = new Task(() =>
                {
                    OpenALDataBuffer buffer1;
                    OpenALDataBuffer buffer2;
                    OpenALDataBuffer buffer3;

                    lock (_locker)
                    {
                        Owner.Context.MakeCurrent();
                        buffer1 = OpenALDataBuffer.CreateBuffer();
                        buffer2 = OpenALDataBuffer.CreateBuffer();
                        buffer3 = OpenALDataBuffer.CreateBuffer();
                    }

                    buffer1.Next = buffer2;
                    buffer2.Next = buffer3;
                    buffer3.Next = buffer1;

                    OpenALDataBuffer currentBuffer = buffer1;
                    FillBuffer(currentBuffer);
                    currentBuffer = currentBuffer.Next;
                    FillBuffer(currentBuffer);
                    currentBuffer = currentBuffer.Next;
                    FillBuffer(currentBuffer);

                    lock (_locker)
                    {
                        OpenAL.alSourcePlay(_source.SourceId);
                    }

                    while (_processedBytes < _audioData.Length)
                    {
                        if (_beginDispose)
                        {
                            return;
                        }
                        switch (PlaybackState)
                        {
                        case PlaybackState.Paused:
                            _playbackThread.Wait(Latency);
                            continue;

                        case PlaybackState.Stopped:
                            return;
                        }

                        int finishedBuffers;
                        lock (_locker)
                        {
                            OpenAL.alGetSourcei(_source.SourceId, SourceProperty.AllBuffersProcessed,
                                                out finishedBuffers);
                        }

                        if (finishedBuffers == 0)
                        {
                            _playbackThread.Wait(Latency);
                        }

                        while (finishedBuffers > 0)
                        {
                            finishedBuffers--;
                            currentBuffer = currentBuffer.Next;
                            FillBuffer(currentBuffer);
                        }

                        Position = _processedBytes / WaveFormat.AvgBytesPerSec * 1000;

                        //if the audio stops where it should not, restart playback
                        lock (_locker)
                        {
                            int sourceState;
                            OpenAL.alGetSourcei(_source.SourceId, SourceProperty.SourceState, out sourceState);
                            if ((SourceState)sourceState == SourceState.Stopped)
                            {
                                OpenAL.alSourcePlay(_source.SourceId);
                            }
                        }
                    }

                    PlaybackState     = PlaybackState.Stopped;
                    var queuedBuffers = new uint[3];
                    RaisePlaybackChanged();

                    lock (_locker)
                    {
                        OpenAL.alSourceUnqueueBuffers(_source.SourceId, 3, queuedBuffers);
                        OpenAL.alDeleteBuffers(3, queuedBuffers);
                    }
                });
                _playbackThread.Start();
            }
        }
示例#12
0
 /// <summary>
 /// Creates a new OpenALContext on the specified OpenALDevice.
 /// </summary>
 /// <param name="openALDeviceHandle">The OpenALDevice.</param>
 public static OpenALContext CreateContext(IntPtr openALDeviceHandle)
 {
     return(new OpenALContext(OpenAL.alcCreateContext(openALDeviceHandle, IntPtr.Zero)));
 }
示例#13
0
 /// <summary>
 /// Destroys the Context.
 /// </summary>
 public void Destroy()
 {
     OpenAL.alcDestroyContext(_handle);
 }
示例#14
0
 /// <summary>
 /// Makes the context the current Context.
 /// </summary>
 public void MakeCurrent()
 {
     OpenAL.alcMakeContextCurrent(_handle);
 }