public void Dispose() { if (this.IsDisposed) { return; } this.IsDisposed = true; ALSourceState sourceState = AL.GetSourceState(this.alSourceId); if (sourceState == ALSourceState.Playing || sourceState == ALSourceState.Paused) { this.StopPlayback(); } lock (this.prepareMutex) { if (OggStreamer.HasInstance) { OggStreamer.Instance.RemoveStream(this); } if (sourceState != ALSourceState.Initial) { this.Empty(false); } this.Close(); this.underlyingStream.Dispose(); } if (OpenALSoundController.Instance != null) { OpenALSoundController.Instance.ReturnSource(this.alSourceId); OpenALSoundController.Instance.ReturnBuffers(this.alBufferIds); } ALHelper.Check(); }
public void Prepare(bool asynchronous = false) { ALSourceState sourceState = AL.GetSourceState(this.alSourceId); lock (this.stopMutex) { switch (sourceState) { case ALSourceState.Playing: break; case ALSourceState.Paused: break; default: lock (this.prepareMutex) { if (this.Reader == null) { this.Open(); } if (!this.Precaching) { this.Precaching = true; this.Precache(asynchronous); break; } else { break; } } } } }
public void Prepare(bool asynchronous = false) { ALSourceState sourceState = AL.GetSourceState(this.alSourceId); this.StoppingLock.EnterReadLock(); switch (sourceState) { case ALSourceState.Playing: case ALSourceState.Paused: this.StoppingLock.ExitReadLock(); break; default: this.PreparationLock.EnterWriteLock(); if (this.Reader == null) { this.Open(); } if (!this.Precaching) { this.Precaching = true; this.Precache(asynchronous); } this.PreparationLock.ExitWriteLock(); this.StoppingLock.ExitReadLock(); break; } }
public void Play(int Source) { Stop(); this.Source = Source; AL.Source(Source, ALSourcei.Buffer, Buffer); AL.SourcePlay(Source); SourceState = AL.GetSourceState(Source); }
public async Task Play() { AL.SourcePlay(_source); do { await Task.Delay(100); State = AL.GetSourceState(_source); } while (State == ALSourceState.Playing); AL.SourceStop(_source); }
private void StartPlaybackIfNeeded(Track Td) { AL.GetSource(Td.SourceId, ALGetSourcei.SourceState, out int StateInt); ALSourceState State = (ALSourceState)StateInt; if (State != ALSourceState.Playing && Td.State == PlaybackState.Playing) { AL.SourcePlay(Td.SourceId); } }
private void StartIfNotPlaying() { AL.GetSource(_sourceId, ALGetSourcei.SourceState, out int stateInt); ALSourceState State = (ALSourceState)stateInt; if (State != ALSourceState.Playing) { AL.SourcePlay(_sourceId); } }
private void StartPlaybackIfNeeded(OpenALAudioTrack track) { AL.GetSource(track.SourceId, ALGetSourcei.SourceState, out int stateInt); ALSourceState State = (ALSourceState)stateInt; if (State != ALSourceState.Playing && track.State == PlaybackState.Playing) { AL.SourcePlay(track.SourceId); } }
private void Play() { AL.GetSource(Source, ALGetSourcei.SourceState, out int state); ALSourceState actualState = (ALSourceState)state; if (actualState != ALSourceState.Playing) { AL.SourcePlay(Source); } }
void INativeAudioSource.ApplyState(ref AudioSourceState state) { lock (this.strLock) { ALSourceState nativeState = AL.GetSourceState(this.handle); bool looped = state.Looped && !this.isStreamed; if (this.isFirstUpdate || this.lastState.RelativeToListener != state.RelativeToListener) { AL.Source(handle, ALSourceb.SourceRelative, state.RelativeToListener); } if (this.isFirstUpdate || this.lastState.Position != state.Position) { AL.Source(handle, ALSource3f.Position, state.Position.X, -state.Position.Y, -state.Position.Z * 0.5f); } if (this.isFirstUpdate || this.lastState.Velocity != state.Velocity) { AL.Source(handle, ALSource3f.Velocity, state.Velocity.X, -state.Velocity.Y, -state.Velocity.Z); } if (this.isFirstUpdate || this.lastState.MaxDistance != state.MaxDistance) { AL.Source(handle, ALSourcef.MaxDistance, state.MaxDistance); } if (this.isFirstUpdate || this.lastState.MinDistance != state.MinDistance) { AL.Source(handle, ALSourcef.ReferenceDistance, state.MinDistance); } if (this.isFirstUpdate || this.lastState.Looped != looped) { AL.Source(handle, ALSourceb.Looping, looped); } if (this.isFirstUpdate || this.lastState.Volume != state.Volume) { AL.Source(handle, ALSourcef.Gain, state.Volume); } if (this.isFirstUpdate || this.lastState.Pitch != state.Pitch) { AL.Source(handle, ALSourcef.Pitch, state.Pitch); } if (state.Paused && nativeState == ALSourceState.Playing) { AL.SourcePause(handle); } else if (!state.Paused && nativeState == ALSourceState.Paused) { AL.SourcePlay(handle); } this.lastState = state; this.lastState.Looped = looped; this.isFirstUpdate = false; } }
internal int GetAvailableSource() { for (int i = 0; i < _sources.Length; i++) { bool isValidSource = AL.IsSource(_sources[i]); ALChecker.CheckError(); if (isValidSource) { // Some sources are probably used by another sounds // Return the one that not in use // Identify source state ALSourceState state = AL.GetSourceState(_sources[i]); ALChecker.CheckError(); // Do not use un-deferred source if (_unDeferredSources.Contains(_sources[i]) && state == ALSourceState.Initial) { continue; } else if (_unDeferredSources.Contains(_sources[i]) && state == ALSourceState.Stopped) { _unDeferredSources.Remove(_sources[i]); } // No sounds using it or no longer in use, use it if (state == ALSourceState.Initial || (state == ALSourceState.Stopped)) { return(_sources[i]); } // Source is in use by a sound, find another one else if (state == ALSourceState.Paused || state == ALSourceState.Playing) { continue; } } else { // Not a source (anymore..?) // Generate and use it _sources[i] = AL.GenSource(); // Since it's newly generated, it must be unused source return(_sources[i]); } } // All sources are used at the moment... // Return invalid source return(-1); }
private static ChannelState ALSourceStateToChannelState(ALSourceState alSourceState) { switch (alSourceState) { case ALSourceState.Playing: return(ChannelState.Playing); case ALSourceState.Paused: return(ChannelState.Paused); default: return(ChannelState.Stopped); } }
internal bool PerformStreaming() { lock (this.strLock) { if (this.handle == 0) { return(false); } ALSourceState stateTemp = AL.GetSourceState(this.handle); if ((stateTemp == ALSourceState.Stopped || stateTemp == ALSourceState.Initial) && this.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. // When stream is empty, source is still in initial state but strStopReq // is already set to EndOfStream. return(false); } else if (this.strStopReq == StopRequest.Immediately) { // Stopped intentionally due to Stop() AL.SourceStop(handle); return(false); } if (stateTemp == ALSourceState.Initial) { // Initialize streaming PerformStreamingBegin(); // Initially play source AL.SourcePlay(handle); } else { // Stream new data PerformStreamingUpdate(); // If the source stopped unintentionally, restart it. (See above) if (stateTemp == ALSourceState.Stopped && this.strStopReq == StopRequest.None) { AL.SourcePlay(handle); } } } return(true); }
public void Stop() { ALSourceState sourceState = AL.GetSourceState(this.alSourceId); if (sourceState == ALSourceState.Playing || sourceState == ALSourceState.Paused) { this.StopPlayback(); } lock (this.stopMutex) { if (!OggStreamer.HasInstance) { return; } OggStreamer.Instance.RemoveStream(this); } }
private void StartPlaybackIfNeeded(OpenALAudioTrack track) { AL.GetSource(track.SourceId, ALGetSourcei.SourceState, out int stateInt); ALSourceState State = (ALSourceState)stateInt; if (State != ALSourceState.Playing && track.State == PlaybackState.Playing) { if (_volumeChanged) { AL.Source(track.SourceId, ALSourcef.Gain, _volume); _volumeChanged = false; } AL.SourcePlay(track.SourceId); } }
public int CalculateSamplesNeeded() { int currentSamplesPlayed = GetSource(ALGetSourcei.SampleOffset); ALSourceState sourceState = AL.GetSourceState(_sourceID); bool isInitializing = sourceState == ALSourceState.Initial; bool detectedUnderrun = sourceState == ALSourceState.Stopped; if (detectedUnderrun) { // SampleOffset should reset to 0 when stopped; update the queued sample count to match UnqueueProcessedBuffers(); currentSamplesPlayed = 0; } int samplesAwaitingPlayback = _currentSamplesQueued - currentSamplesPlayed; int samplesNeeded = Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0); if (isInitializing || detectedUnderrun) { _sound.HandleInitializationOrUnderrun(detectedUnderrun, ref samplesNeeded); } return(samplesNeeded); }
public void Pause () { _userState = ALSourceState.Paused; while (AL.GetSourceState(_source) != ALSourceState.Paused) Thread.Sleep(1); }
public void Stop () { _userState = ALSourceState.Stopped; while (AL.GetSourceState(_source) != ALSourceState.Stopped && AL.GetSourceState(_source) != ALSourceState.Initial) Thread.Sleep(1); }
public void Update(double time) { updateTime += time; if (updateTime >= .25) { State = AL.GetSourceState(SourceID); } if (Looping && State == ALSourceState.Stopped) { Stop(); Play(); } }
internal bool PerformStreaming() { lock (this.strLock) { if (this.Disposed) { return(false); } if (!DualityApp.Sound.IsAvailable) { return(false); } ALSourceState stateTemp = ALSourceState.Stopped; bool sourceAvailable = this.alSource > AlSource_NotAvailable; if (sourceAvailable) { stateTemp = AL.GetSourceState(this.alSource); } if (stateTemp == ALSourceState.Stopped && this.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(false); } else if (this.strStopReq == StopRequest.Immediately) { // Stopped intentionally due to Stop() if (this.alSource > AlSource_NotAvailable) { AL.SourceStop(this.alSource); } return(false); } AudioData audioDataRes = this.audioData.Res; if (!this.sound.IsAvailable || audioDataRes == null) { this.Dispose(); return(false); } if (sourceAvailable) { if (stateTemp == ALSourceState.Initial) { // Initialize streaming PerformStreamingBegin(audioDataRes); // Initially play source AL.SourcePlay(this.alSource); stateTemp = AL.GetSourceState(this.alSource); } else { // Stream new data PerformStreamingUpdate(audioDataRes); // If the source stopped unintentionally, restart it. (See above) if (stateTemp == ALSourceState.Stopped && this.strStopReq == StopRequest.None) { AL.SourcePlay(this.alSource); } } } } return(true); }
public bool IsPaused() { ALSourceState state = AL.GetSourceState(mySource); return(state == ALSourceState.Paused); }
void INativeAudioSource.ApplyState(ref AudioSourceState state) { lock (this.strLock) { ALSourceState nativeState = AL.GetSourceState(this.handle); bool looped = state.Looped && !this.isStreamed; if (this.isFirstUpdate || this.lastState.RelativeToListener != state.RelativeToListener) { AL.Source(handle, ALSourceb.SourceRelative, state.RelativeToListener); } if (this.isFirstUpdate || this.lastState.Position != state.Position) { AL.Source(handle, ALSource3f.Position, state.Position.X, -state.Position.Y, -state.Position.Z * 0.5f); } if (this.isFirstUpdate || this.lastState.Velocity != state.Velocity) { AL.Source(handle, ALSource3f.Velocity, state.Velocity.X, -state.Velocity.Y, -state.Velocity.Z); } if (this.isFirstUpdate || this.lastState.MaxDistance != state.MaxDistance) { AL.Source(handle, ALSourcef.MaxDistance, state.MaxDistance); } if (this.isFirstUpdate || this.lastState.MinDistance != state.MinDistance) { AL.Source(handle, ALSourcef.ReferenceDistance, state.MinDistance); } if (this.isFirstUpdate || this.lastState.Looped != looped) { AL.Source(handle, ALSourceb.Looping, looped); } if (this.isFirstUpdate || this.lastState.Volume != state.Volume) { AL.Source(handle, ALSourcef.Gain, state.Volume); } if (this.isFirstUpdate || this.lastState.Pitch != state.Pitch) { AL.Source(handle, ALSourcef.Pitch, state.Pitch); } // Update lowpass settings requires Effects extension if (this.isFirstUpdate || this.lastState.Lowpass != state.Lowpass) { var fx = AudioBackend.ActiveInstance.EffectsExtension; if (fx != null) { // If there is no filter, create one when required. if (this.filterHandle == 0 && state.Lowpass < 1.0f) { this.filterHandle = fx.GenFilter(); fx.Filter(this.filterHandle, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass); fx.Filter(this.filterHandle, EfxFilterf.LowpassGain, 1); } // If there is a filter, keep it up-to-date if (this.filterHandle != 0) { fx.Filter(this.filterHandle, EfxFilterf.LowpassGainHF, MathF.Clamp(state.Lowpass, 0.0f, 1.0f)); fx.BindFilterToSource(this.handle, this.filterHandle); } } } if (state.Paused && nativeState == ALSourceState.Playing) { AL.SourcePause(handle); } else if (!state.Paused && nativeState == ALSourceState.Paused) { AL.SourcePlay(handle); } this.lastState = state; this.lastState.Looped = looped; this.isFirstUpdate = false; } }
public Audio(int source, int buffer) { _source = source; _buffer = buffer; State = ALSourceState.Initial; }
public void Playing_ShouldBeFalse_OnNonPlayingStates(ALSourceState state) { adapter.Setup(a => a.GetSourceState(sound.SourceHandle)) .Returns(state); sound.Playing.ShouldBeFalse(); }
public void Stopped_ReturnsFalse_OnNonStoppedStates(ALSourceState state) { adapter.Setup(a => a.GetSourceState(sound.SourceHandle)) .Returns(state); sound.Stopped.ShouldBeFalse(); }
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 (sndInst.strStopReq) { // Stopped intentionally due to Stop() or 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. if (stateTemp != ALSourceState.Stopped) { sndInst.Stop(); } return; } Sound res = sndInst.snd.Res; if (res == 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 OV.BeginStreamFromMemory(res.Data.Res.OggVorbisData, out sndInst.strOvStr); // Initially, completely fill all buffers for (int i = 0; i < sndInst.strAlBuffers.Length; ++i) { PcmData pcm; bool eof = !OV.StreamChunk(sndInst.strOvStr, out pcm); if (pcm.data.Length > 0) { AL.BufferData( sndInst.strAlBuffers[i], pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, pcm.data, pcm.data.Length, 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 (sndInst.strOvStr != IntPtr.Zero) { PcmData pcm; bool eof = !OV.StreamChunk(sndInst.strOvStr, out pcm); if (pcm.data.Length > 0) { AL.BufferData( unqueued, pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, pcm.data, pcm.data.Length, pcm.sampleRate); } AL.SourceQueueBuffer(sndInst.alSource, unqueued); if (eof && pcm.data.Length == 0) { OV.EndStream(ref sndInst.strOvStr); if (sndInst.looped) { OV.BeginStreamFromMemory(res.Data.Res.OggVorbisData, out sndInst.strOvStr); } else { sndInst.strStopReq = true; break; } } } } } if (stateTemp == ALSourceState.Stopped && !sndInst.strStopReq) { // If the source stopped unintentionally, restart it. (See above) AL.SourcePlay(sndInst.alSource); } } Thread.Sleep(8); } }
public void Pause() { AL.SourcePause(Source); SourceState = AL.GetSourceState(Source); }
public bool IsStopped() { ALSourceState state = AL.GetSourceState(mySource); return(state == ALSourceState.Stopped); }
public bool Play () { if (_music == null) return false; if (!EnqueueBuffers()) return false; _userState = ALSourceState.Playing; while (AL.GetSourceState(_source) != ALSourceState.Playing) Thread.Sleep(1); return true; }
public void Stop() { AL.SourceStop(Source); SourceState = AL.GetSourceState(Source); }
private static ChannelState ALSourceStateToChannelState(ALSourceState alSourceState) { switch (alSourceState) { case ALSourceState.Playing: return ChannelState.Playing; case ALSourceState.Paused: return ChannelState.Paused; default: return ChannelState.Stopped; } }
/// <summary> /// Updates the SoundInstance /// </summary> public void Update() { if (!DualityApp.Sound.IsAvailable) { return; } lock (this.strLock) { // Check existence of attachTo object if (this.attachedTo != null && this.attachedTo.Disposed) { this.attachedTo = null; } // Retrieve sound resource values Sound soundRes = this.sound.Res; AudioData audioDataRes = this.audioData.Res; if (soundRes == null || audioDataRes == null) { this.Dispose(); return; } float optVolFactor = this.GetTypeVolFactor(); float minDistTemp = soundRes.MinDist; float maxDistTemp = soundRes.MaxDist; float volTemp = optVolFactor * soundRes.VolumeFactor * this.vol * this.curFade * this.pauseFade; float pitchTemp = soundRes.PitchFactor * this.pitch; float priorityTemp = 1000.0f; priorityTemp *= volTemp; // Calculate 3D source values, distance and priority Vector3 posAbs = this.pos; Vector3 velAbs = this.vel; if (this.is3D) { Components.Transform attachTransform = this.attachedTo != null ? this.attachedTo.Transform : null; // Attach to object if (this.attachedTo != null && this.attachedTo != DualityApp.Sound.Listener) { MathF.TransformCoord(ref posAbs.X, ref posAbs.Y, attachTransform.Angle); MathF.TransformCoord(ref velAbs.X, ref velAbs.Y, attachTransform.Angle); posAbs += attachTransform.Pos; velAbs += attachTransform.Vel; } // Distance check Vector3 listenerPos = DualityApp.Sound.ListenerPos; float dist; if (this.attachedTo != DualityApp.Sound.Listener) { dist = MathF.Sqrt( (posAbs.X - listenerPos.X) * (posAbs.X - listenerPos.X) + (posAbs.Y - listenerPos.Y) * (posAbs.Y - listenerPos.Y) + (posAbs.Z - listenerPos.Z) * (posAbs.Z - listenerPos.Z) * 0.25f); } else { dist = MathF.Sqrt( posAbs.X * posAbs.X + posAbs.Y * posAbs.Y + posAbs.Z * posAbs.Z * 0.25f); } if (dist > maxDistTemp) { this.Dispose(); return; } else { priorityTemp *= Math.Max(0.0f, 1.0f - (dist - minDistTemp) / (maxDistTemp - minDistTemp)); } } // Grab an OpenAL source, if not yet assigned if (this.alSource == AlSource_NotYetAssigned) { if (this.GrabAlSource()) { this.RegisterPlaying(); } else { this.Dispose(); return; } } // Determine source state, if available ALSourceState stateTemp = ALSourceState.Stopped; bool sourceAvailable = this.alSource > AlSource_NotAvailable; if (sourceAvailable) { stateTemp = AL.GetSourceState(this.alSource); } // If the source is stopped / finished, dispose and return if (stateTemp == ALSourceState.Stopped && (!audioDataRes.IsStreamed || this.strStopReq != StopRequest.None)) { this.Dispose(); return; } else if (stateTemp == ALSourceState.Initial && this.strStopReq == StopRequest.Immediately) { this.Dispose(); return; } // Fading in and out bool fadeOut = this.fadeTarget <= 0.0f; if (!this.paused) { if (this.fadeTarget != this.curFade) { float fadeTemp = Time.TimeMult * Time.SPFMult / Math.Max(0.05f, this.fadeTimeSec); if (this.fadeTarget > this.curFade) { this.curFade += fadeTemp; } else { this.curFade -= fadeTemp; } if (Math.Abs(this.curFade - this.fadeTarget) < fadeTemp * 2.0f) { this.curFade = this.fadeTarget; } this.dirtyState |= DirtyFlag.Vol; } } // Special paused-fading if (this.paused && this.pauseFade > 0.0f) { this.pauseFade = MathF.Max(0.0f, this.pauseFade - Time.TimeMult * Time.SPFMult * 5.0f); this.dirtyState |= DirtyFlag.Paused | DirtyFlag.Vol; } else if (!this.paused && this.pauseFade < 1.0f) { this.pauseFade = MathF.Min(1.0f, this.pauseFade + Time.TimeMult * Time.SPFMult * 5.0f); this.dirtyState |= DirtyFlag.Paused | DirtyFlag.Vol; } // SlowMotion //if (this.type == SoundType.EffectWorld) //{ // pitchTemp *= (float)Math.Max(0.5d, SteApp.Current.SlowMotion); // volTemp *= 2.0f * (float)Math.Min(0.5d, SteApp.Current.SlowMotion); // // Hack: Pitch always dirty // this.dirtyState |= DirtyFlag.Pitch; //} //else if (this.type == SoundType.Speech) //{ // volTemp *= (float)Math.Sqrt(SteApp.Current.SlowMotion); //} // Hack: Volume always dirty - just to be sure this.dirtyState |= DirtyFlag.Vol; if (sourceAvailable) { if (this.is3D) { // Hack: Relative always dirty to support switching listeners without establishing a notifier-event this.dirtyState |= DirtyFlag.Relative; if (this.attachedTo != null) { this.dirtyState |= DirtyFlag.AttachedTo; } if ((this.dirtyState & DirtyFlag.Relative) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.SourceRelative, this.attachedTo == DualityApp.Sound.Listener); } if ((this.dirtyState & DirtyFlag.Pos) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Position, posAbs.X, -posAbs.Y, -posAbs.Z * 0.5f); } if ((this.dirtyState & DirtyFlag.Vel) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Velocity, velAbs.X, -velAbs.Y, -velAbs.Z); } } else { if ((this.dirtyState & DirtyFlag.Relative) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.SourceRelative, true); } if ((this.dirtyState & DirtyFlag.Pos) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Position, 0.0f, 0.0f, 0.0f); } if ((this.dirtyState & DirtyFlag.Vel) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Velocity, 0.0f, 0.0f, 0.0f); } } if ((this.dirtyState & DirtyFlag.MaxDist) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.MaxDistance, maxDistTemp); } if ((this.dirtyState & DirtyFlag.RefDist) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.ReferenceDistance, minDistTemp); } if ((this.dirtyState & DirtyFlag.Loop) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.Looping, (this.looped && !audioDataRes.IsStreamed)); } if ((this.dirtyState & DirtyFlag.Vol) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.Gain, volTemp); } if ((this.dirtyState & DirtyFlag.Pitch) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.Pitch, pitchTemp); } if ((this.dirtyState & DirtyFlag.Paused) != DirtyFlag.None) { if (this.paused && this.pauseFade == 0.0f && stateTemp == ALSourceState.Playing) { AL.SourcePause(this.alSource); } else if ((!this.paused || this.pauseFade > 0.0f) && stateTemp == ALSourceState.Paused) { AL.SourcePlay(this.alSource); } } } this.dirtyState = DirtyFlag.None; // Update play time if (!this.paused) { this.playTime += MathF.Max(0.5f, pitchTemp) * Time.TimeMult * Time.SPFMult; if (this.sound.Res.FadeOutAt > 0.0f && this.playTime >= this.sound.Res.FadeOutAt) { this.FadeOut(this.sound.Res.FadeOutTime); } } // Finish priority calculation this.curPriority = (int)Math.Round(priorityTemp / Math.Sqrt(DualityApp.Sound.GetNumPlaying(this.sound))); // Initially play the source if (stateTemp == ALSourceState.Initial && !this.paused) { if (audioDataRes.IsStreamed) { this.isStreamed = true; DualityApp.Sound.EnqueueForStreaming(this); } else { AL.SourceQueueBuffer(this.alSource, audioDataRes.AlBuffer); AL.SourcePlay(this.alSource); } } // Remove faded out sources if (fadeOut && volTemp <= 0.0f) { this.fadeWaitEnd += Time.TimeMult * Time.MsPFMult; // After fading out entirely, wait 50 ms before actually stopping the source to prevent unpleasant audio tick / glitch noises if (this.fadeWaitEnd > 50.0f) { this.Dispose(); return; } } else { this.fadeWaitEnd = 0.0f; } } }
public bool IsPlaying() { ALSourceState state = AL.GetSourceState(mySource); return(state == ALSourceState.Playing); }