public void AddCueToActiveList(AudioCue audioCue) { if (!activeCues.Contains(audioCue)) { activeCues.Add(audioCue); } } // end of AddCueToActiveList()
/// <summary> /// If nothing in the list is me (or descendent) already playing, /// Play myself and add myself to the list. /// Returns the new audiocue if it started one, else null. /// </summary> /// <param name="list"></param> public virtual AudioCue Play(GameThing emitter, List <AudioCue> list) { for (int i = 0; i < list.Count; ++i) { AudioCue cue = list[i]; Sound v = cue.Sound; if ((v != null) && v.BelongsTo(this)) { /// Already playing, just bail. return(null); } } /// Start a random child playing Sound leaf = Select(); AudioCue toplay = leaf.Play(emitter); if (emitter != null) { toplay.OnComplete += emitter.OnAudioCueComplete; } /// Add leaf to list list.Add(toplay); return(toplay); }
/// <summary> /// Version of GetCue spatialized with a fixed position. /// </summary> /// <param name="name"></param> /// <param name="position"></param> /// <returns></returns> public AudioCue GetCue(string name, Vector3 position) { AudioCue audioCue = null; if (spareCues.Count > 0) { // Reuse a spare AudioCue instance audioCue = spareCues[0]; spareCues.RemoveAt(0); } else { // No spare AudioCue instances available, so create a new one audioCue = new AudioCue(); } // Initialize the sound cue if (Enabled) { Cue cue = SoundBank.GetCue(name); audioCue.Set(cue, position); // Apply initial 3D audio values audioCue.Apply3D(listener); } else { audioCue.Set(null, position); } // Cue is not added to activeCues list until played. return(audioCue); }
/// <summary> /// Helper for immediately stopping and clearing out an entire list. /// </summary> /// <param name="list"></param> public static void ClearImmediate(List <AudioCue> list) { for (int i = 0; i < list.Count; ++i) { AudioCue cue = list[i]; cue.StopImmediate(); } list.Clear(); }
/// <summary> /// Will actually start playing, but assumes /// accompanying bookkeeping has been done. Use Play(list) instead. /// </summary> internal AudioCue Play(GameThing emitter) { AudioCue cue = BokuGame.Audio.GetCue(cuename, emitter, Spatial); cue.Play(); cue.Sound = this; cues.Add(cue); return(cue); }
} // end of Playing() #endregion #region Internal private void Restart(AudioCue audioCue, GameThing emitter) { audioCue.Reset(); Cue cue = BokuGame.Audio.SoundBank.GetCue(soundName); audioCue.Set(cue, emitter); audioCue.Play(); frame = Time.FrameCounter; lastTime = Time.WallClockTotalSeconds; } // end of Restart()
/// <summary> /// Pass an update to the underlying audio engine, as well as /// cull dead sounds from our active list. Finally, give active /// cues a chance to apply 3d effects. /// </summary> public void Update() { // this.updateTimer.Start(); // Limit audio updates to 60 fps //if (Time.GameTimeTotalSeconds > lastFrameTimeSeconds && // Time.GameTimeTotalSeconds - lastFrameTimeSeconds < 1 / 60.0f) // return; lastFrameTimeSeconds = Time.GameTimeTotalSeconds; if (Enabled) { engine.Update(); if (InGame.inGame != null) { // Update 3D audio listener values from camera state listener.Position = InGame.inGame.Camera.ActualFrom; listener.Up = InGame.inGame.Camera.ViewUp; listener.Forward = InGame.inGame.Camera.ViewDir; listener.Velocity = Vector3.Zero; // Camera doesn't expose a "Velocity" property } } // Loop through active audio cues, updating 3D values and recycling completed cues for (int cueIndex = activeCues.Count - 1; cueIndex >= 0; --cueIndex) { AudioCue cue = activeCues[cueIndex]; if (cue.VirtualDone()) { cue.DetachSound(); } // If cue is done playing, recycle it. Because we create // and destroy AudioCue objects frequently, this helps avoid // unnecessary garbage collector activity. if (cue.IsComplete) { cue.Reset(); spareCues.Add(cue); activeCues.RemoveAt(cueIndex); continue; } // Update cue's 3D audio values if (Enabled) { cue.Apply3D(listener); } } // this.updateTimer.Stop(); }
/// <summary> /// Play sound identified by id (or randomly selected descendent) with /// (possibly null) emitter for 3d effects, and place sound in list cues. /// If I'm already playing a sound in the list, /// do nothing and return null. /// </summary> /// <param name="id"></param> /// <param name="emitter"></param> /// <param name="cues"></param> /// <returns></returns> public AudioCue Play(string id, GameThing emitter, List <AudioCue> cues) { AudioCue cue = null; Voice v = Find(id); if (v != null) { if (v.IsAny) { v = v.Parent; } cue = v.Play(emitter, cues); } return(cue); }
/// <summary> /// Full version of GetCue allows the overriding of whether it is spatialized. /// </summary> /// <param name="name"></param> /// <param name="thing"></param> /// <param name="spatial"></param> /// <returns></returns> public AudioCue GetCue(string name, GameThing thing, bool?spatial) { AudioCue audioCue = null; if (spareCues.Count > 0) { // Reuse a spare AudioCue instance audioCue = spareCues[0]; spareCues.RemoveAt(0); } else { // No spare AudioCue instances available, so create a new one audioCue = new AudioCue(); } // Initialize the sound cue if (Enabled) { try { Cue cue = SoundBank.GetCue(name); audioCue.Set(cue, thing); if (spatial != null) { audioCue.Spatial = spatial.Value; } // Apply initial 3D audio values audioCue.Apply3D(listener); } catch { audioCue.Set(null, thing); } } else { audioCue.Set(null, thing); } // Cue is not added to activeCues list until played. return(audioCue); }
/// <summary> /// True if the emitter is playing a sound through me. /// </summary> /// <param name="emitter"></param> /// <returns></returns> internal override bool IsPlaying(GameThing emitter) { for (int i = 0; i < cues.Count; ++i) { AudioCue cue = cues[i]; if ( (cue.Emitter == emitter) || (!Spatial && (emitter == null)) ) { return(true); } } return(false); }
/// <summary> /// If anything(s) in the list are me (or descendent), /// Stop it and remove it from the list. /// </summary> /// <param name="list"></param> public virtual bool Stop(List <AudioCue> list) { bool stopped = false; for (int i = list.Count - 1; i >= 0; --i) { AudioCue cue = list[i]; Sound v = cue.Sound; if ((v != null) && v.BelongsTo(this)) { /// Stop v from playing cue.StopImmediate(); list.RemoveAt(i); stopped = true; } } return(stopped); }
/// <summary> /// Play a spacialized sound attatched to a GameThing. /// </summary> /// <param name="emitter"></param> public void Play(GameThing emitter) { // Don't allow mute actors to make noise. GameActor actor = emitter as GameActor; if (actor != null && actor.Mute) { return; } // If a singleton and already playing, ignore this call. if (singleton && Playing(emitter)) { return; } if (BokuGame.Audio.Enabled) { // Ensure we haven't already played this sound this frame. if (frame == Time.FrameCounter) { return; } // Make sure enough time has elapsed. double dt = Time.WallClockTotalSeconds - lastTime; if (dt < timeGap) { return; } AudioCue cue = BokuGame.Audio.GetCue(soundName, emitter, true); cue.Play(); frame = Time.FrameCounter; lastTime = Time.WallClockTotalSeconds; } // end if enabled. } // end of Play()
} // end of Play() /// <summary> /// Play a spacialized sound from a fixed position. /// </summary> /// <param name="position">Where the sound is coming from.</param> /// <param name="volume">In range 0..1</param> public void Play(Vector3 position, float volume) { if (BokuGame.Audio.Enabled) { // Ensure we haven't already played this sound this frame. if (frame == Time.FrameCounter) { return; } // Make sure enough time has elapsed. double dt = Time.WallClockTotalSeconds - lastTime; if (dt < timeGap) { return; } AudioCue cue = BokuGame.Audio.GetCue(soundName, position); cue.SetVolume(volume); cue.Play(); frame = Time.FrameCounter; lastTime = Time.WallClockTotalSeconds; } // end if enabled. } // end of Play()
/// <summary> /// Have I played long enough to restart? /// </summary> /// <param name="cue"></param> /// <returns></returns> internal bool Done(AudioCue cue) { return((VirtualLength > 0.0f) && (Time.WallClockTotalSeconds - cue.StartTime >= VirtualLength)); }
/// <summary> /// Break ties with a cue we've spawned. /// </summary> /// <param name="cue"></param> internal void Detach(AudioCue cue) { Debug.Assert(cue.Sound == this, "Someone else's cue detaching from me"); cues.Remove(cue); cue.Sound = null; }