示例#1
0
        public void ResumeSource(IALSource source)
        {
            AL10.alSourcePlay((source as OpenALSource).Handle);
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif
        }
示例#2
0
 public void Resume()
 {
     if (INTERNAL_delayMS > 0)
     {
         INTERNAL_timer.Start();
     }
     if (INTERNAL_alSource != 0 && State == SoundState.Paused)
     {
         AL10.alSourcePlay(INTERNAL_alSource);
     }
 }
示例#3
0
        private void alSourcePlay()
        {
            int state = AL10.alGetSourcei(alSource, AL10.AL_SOURCE_STATE);

            if (state != AL10.AL_PLAYING)
            {
                if (minimumNumberBuffers <= 0 || WaitingBuffers >= minimumNumberBuffers)
                {
                    AL10.alSourcePlay(alSource);
                }
            }
        }
示例#4
0
        public OpenAlSound(uint source, uint buffer, bool looping, bool relative, WPos pos, float volume)
        {
            Source = source;
            Volume = volume;

            AL10.alSourcef(source, AL10.AL_PITCH, 1f);
            AL10.alSource3f(source, AL10.AL_POSITION, pos.X, pos.Y, pos.Z);
            AL10.alSource3f(source, AL10.AL_VELOCITY, 0f, 0f, 0f);
            AL10.alSourcei(source, AL10.AL_BUFFER, (int)buffer);
            AL10.alSourcei(source, AL10.AL_LOOPING, looping ? 1 : 0);
            AL10.alSourcei(source, AL10.AL_SOURCE_RELATIVE, relative ? 1 : 0);

            AL10.alSourcef(source, AL10.AL_REFERENCE_DISTANCE, 6826);
            AL10.alSourcef(source, AL10.AL_MAX_DISTANCE, 136533);
            AL10.alSourcePlay(source);
        }
示例#5
0
 public void SetAllSoundsPaused(bool paused)
 {
     foreach (var key in sourcePool.Keys)
     {
         int state;
         AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state);
         if (state == AL10.AL_PLAYING && paused)
         {
             AL10.alSourcePause(key);
         }
         else if (state == AL10.AL_PAUSED && !paused)
         {
             AL10.alSourcePlay(key);
         }
     }
 }
示例#6
0
        public void PauseSound(ISound sound, bool paused)
        {
            if (sound == null)
            {
                return;
            }

            var key = ((OpenAlSound)sound).Source;
            int state;

            AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state);
            if (state == AL10.AL_PLAYING && paused)
            {
                AL10.alSourcePause(key);
            }
            else if (state == AL10.AL_PAUSED && !paused)
            {
                AL10.alSourcePlay(key);
            }
        }
示例#7
0
 void PauseSound(uint source, bool paused)
 {
     AL10.alGetSourcei(source, AL10.AL_SOURCE_STATE, out var state);
     if (paused)
     {
         if (state == AL10.AL_PLAYING)
         {
             AL10.alSourcePause(source);
         }
         else if (state == AL10.AL_INITIAL)
         {
             // If a sound hasn't started yet,
             // we indicate it should not play be transitioning it to the stopped state.
             AL10.alSourcePlay(source);
             AL10.alSourceStop(source);
         }
     }
     else if (!paused && state != AL10.AL_PLAYING)
     {
         AL10.alSourcePlay(source);
     }
 }
示例#8
0
        public override void Play()
        {
            if (State != SoundState.Stopped)
            {
                return;                 // No-op if we're already playing.
            }

            if (INTERNAL_alSource != 0)
            {
                // The sound has stopped, but hasn't cleaned up yet...
                AL10.alSourceStop(INTERNAL_alSource);
                AL10.alDeleteSources((IntPtr)1, ref INTERNAL_alSource);
                INTERNAL_alSource = 0;
            }
            while (queuedBuffers.Count > 0)
            {
                availableBuffers.Enqueue(queuedBuffers.Dequeue());
            }

            AL10.alGenSources((IntPtr)1, out INTERNAL_alSource);
            if (INTERNAL_alSource == 0)
            {
                System.Console.WriteLine("WARNING: AL SOURCE WAS NOT AVAILABLE. SKIPPING.");
                return;
            }

            // Queue the buffers to this source
            while (buffersToQueue.Count > 0)
            {
                uint nextBuf = buffersToQueue.Dequeue();
                queuedBuffers.Enqueue(nextBuf);
                AL10.alSourceQueueBuffers(
                    INTERNAL_alSource,
                    (IntPtr)1,
                    ref nextBuf
                    );
            }

            // Apply Pan/Position
            if (INTERNAL_positionalAudio)
            {
                INTERNAL_positionalAudio = false;
                AL10.alSource3f(
                    INTERNAL_alSource,
                    AL10.AL_POSITION,
                    position.X,
                    position.Y,
                    position.Z
                    );
            }
            else
            {
                Pan = Pan;
            }

            // Reassign Properties, in case the AL properties need to be applied.
            Volume   = Volume;
            IsLooped = IsLooped;
            Pitch    = Pitch;

            // Finally.
            AL10.alSourcePlay(INTERNAL_alSource);
            OpenALDevice.Instance.dynamicInstancePool.Add(this);

            // ... but wait! What if we need moar buffers?
            if (PendingBufferCount <= 2 && BufferNeeded != null)
            {
                BufferNeeded(this, null);
            }
        }
示例#9
0
        public virtual void Play()
        {
            if (State != SoundState.Stopped && INTERNAL_alSource != 0)             // FIXME: alSource check part of timer hack!
            {
                // FIXME: Is this XNA4 behavior?
                Stop();
            }

            if (INTERNAL_delayMS != 0 && !INTERNAL_timer.IsRunning)
            {
                INTERNAL_timer.Start();
            }
            if (INTERNAL_timer.ElapsedMilliseconds < INTERNAL_delayMS)
            {
                return;                 // We'll be back...
            }
            INTERNAL_timer.Stop();
            INTERNAL_timer.Reset();

            if (INTERNAL_alSource != 0)
            {
                // The sound has stopped, but hasn't cleaned up yet...
                AL10.alSourceStop(INTERNAL_alSource);
                AL10.alDeleteSources((IntPtr)1, ref INTERNAL_alSource);
                INTERNAL_alSource = 0;
            }

            AL10.alGenSources((IntPtr)1, out INTERNAL_alSource);
            if (INTERNAL_alSource == 0)
            {
                System.Console.WriteLine("WARNING: AL SOURCE WAS NOT AVAILABLE. SKIPPING.");
                return;
            }

            // Attach the buffer to this source
            AL10.alSourcei(
                INTERNAL_alSource,
                AL10.AL_BUFFER,
                (int)INTERNAL_parentEffect.INTERNAL_buffer
                );

            // Apply Pan/Position
            if (INTERNAL_positionalAudio)
            {
                INTERNAL_positionalAudio = false;
                AL10.alSource3f(
                    INTERNAL_alSource,
                    AL10.AL_POSITION,
                    position.X,
                    position.Y,
                    position.Z
                    );
            }
            else
            {
                Pan = Pan;
            }

            // Reassign Properties, in case the AL properties need to be applied.
            Volume   = Volume;
            IsLooped = IsLooped;
            Pitch    = Pitch;

            // Apply EFX
            if (INTERNAL_alEffectSlot != 0)
            {
                AL10.alSource3i(
                    INTERNAL_alSource,
                    EFX.AL_AUXILIARY_SEND_FILTER,
                    (int)INTERNAL_alEffectSlot,
                    0,
                    0
                    );
            }

            AL10.alSourcePlay(INTERNAL_alSource);
        }
示例#10
0
        public OpenAlAsyncLoadSound(uint source, bool looping, bool relative, WPos pos, float volume, int channels, int sampleBits, int sampleRate, Stream stream)
            : base(source, looping, relative, pos, volume, sampleRate)
        {
            // Load a silent buffer into the source. Without this,
            // attempting to change the state (i.e. play/pause) the source fails on some systems.
            var silentSource = new OpenAlSoundSource(SilentData, SilentData.Length, channels, sampleBits, sampleRate);

            AL10.alSourcei(source, AL10.AL_BUFFER, (int)silentSource.Buffer);

            playTask = Task.Run(async() =>
            {
                MemoryStream memoryStream;
                using (stream)
                {
                    try
                    {
                        memoryStream = new MemoryStream((int)stream.Length);
                    }
                    catch (NotSupportedException)
                    {
                        // Fallback for stream types that don't support Length.
                        memoryStream = new MemoryStream();
                    }

                    try
                    {
                        await stream.CopyToAsync(memoryStream, 81920, cts.Token);
                    }
                    catch (TaskCanceledException)
                    {
                        // Sound was stopped early, cleanup the unused buffer and exit.
                        AL10.alSourceStop(source);
                        AL10.alSourcei(source, AL10.AL_BUFFER, 0);
                        silentSource.Dispose();
                        return;
                    }
                }

                var data           = memoryStream.GetBuffer();
                var dataLength     = (int)memoryStream.Length;
                var bytesPerSample = sampleBits / 8f;
                var lengthInSecs   = dataLength / (channels * bytesPerSample * sampleRate);
                using (var soundSource = new OpenAlSoundSource(data, dataLength, channels, sampleBits, sampleRate))
                {
                    // Need to stop the source, before attaching the real input and deleting the silent one.
                    AL10.alSourceStop(source);
                    AL10.alSourcei(source, AL10.AL_BUFFER, (int)soundSource.Buffer);
                    silentSource.Dispose();

                    lock (cts)
                    {
                        if (!cts.IsCancellationRequested)
                        {
                            // TODO: A race condition can happen between the state check and playing/rewinding if a
                            // user pauses/resumes at the right moment. The window of opportunity is small and the
                            // consequences are minor, so for now we'll ignore it.
                            int state;
                            AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out state);
                            if (state != AL10.AL_STOPPED)
                            {
                                AL10.alSourcePlay(source);
                            }
                            else
                            {
                                // A stopped sound indicates it was paused before we finishing loaded.
                                // We don't want to start playing it right away.
                                // We rewind the source so when it is started, it plays from the beginning.
                                AL10.alSourceRewind(source);
                            }
                        }
                    }

                    while (!cts.IsCancellationRequested)
                    {
                        // Need to check seek before state. Otherwise, the music can stop after our state check at
                        // which point the seek will be zero, meaning we'll wait the full track length before seeing it
                        // has stopped.
                        var currentSeek = SeekPosition;

                        int state;
                        AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out state);
                        if (state == AL10.AL_STOPPED)
                        {
                            break;
                        }

                        try
                        {
                            // Wait until the track is due to complete, and at most 60 times a second to prevent a
                            // busy-wait.
                            var delaySecs = Math.Max(lengthInSecs - currentSeek, 1 / 60f);
                            await Task.Delay(TimeSpan.FromSeconds(delaySecs), cts.Token);
                        }
                        catch (TaskCanceledException)
                        {
                            // Sound was stopped early, allow normal cleanup to occur.
                        }
                    }

                    AL10.alSourcei(Source, AL10.AL_BUFFER, 0);
                }
            });
        }
示例#11
0
 public OpenAlSound(uint source, bool looping, bool relative, WPos pos, float volume, int sampleRate, uint buffer)
     : this(source, looping, relative, pos, volume, sampleRate)
 {
     AL10.alSourcei(source, AL10.AL_BUFFER, (int)buffer);
     AL10.alSourcePlay(source);
 }
示例#12
0
 public virtual void Play()
 {
     AL10.alSourcePlay(Source); Check();
 }
示例#13
0
 public void ResumeSource(IALSource source)
 {
     AL10.alSourcePlay((source as OpenALSource).Handle);
 }
示例#14
0
 public void Play()
 {
     AL10.alSourcePlay(_handle);
 }
示例#15
0
 /// <summary>
 /// Play this source.
 /// </summary>
 public void Play()
 {
     CheckDisposed();
     Context.MakeCurrent();
     AL10.alSourcePlay(Name);
 }