/// <summary> /// Play a sound (simple internal option). /// </summary> /// <param name="sfx">The effect.</param> /// <param name="loop">Whether to loop.</param> /// <returns>The sound played.</returns> public ActiveSound PlaySimpleInternal(SoundEffect sfx, bool loop) { ActiveSound playSound() { ActiveSound actsfx = new ActiveSound(sfx) { Engine = this, Position = Location.NaN, Pitch = 1.0f, Gain = 1.0f, Loop = loop }; actsfx.Create(); actsfx.Play(); return(actsfx); } lock (sfx) { if (sfx.Internal == -1) { return(null); // TODO: Enforce load-NOW? } } return(playSound()); }
/// <summary> /// Try to clean things. Return whether anything was cleaned. /// </summary> /// <returns>Whether successful.</returns> public bool CanClean() { bool cleaned = false; for (int i = 0; i < PlayingNow.Count; i++) { ActiveSound sound = PlayingNow[i]; if (sound.Gain < 0.05 || (sound.Position.DistanceSquared(CPosition) > 30 * 30)) { sound.Destroy(); PlayingNow.RemoveAt(i); i--; cleaned = true; } } return(cleaned); }
/// <summary> /// Plays a sound effect. /// NOTE: *NOT* guaranteed to play a sound effect immediately, regardless of input! Some sound effects will be delayed! If too many audible sounds are already playing, this will refuse to play. /// </summary> /// <param name="sfx">The sound effect.</param> /// <param name="loop">Whether to loop.</param> /// <param name="pos">The position.</param> /// <param name="pitch">The pitch.</param> /// <param name="volume">The volume.</param> /// <param name="seek">The seek location.</param> /// <param name="callback">The callback upon playing start.</param> public void Play(SoundEffect sfx, bool loop, Location pos, float pitch = 1, float volume = 1, float seek = 0, Action <ActiveSound> callback = null) { if (sfx == null) { //SysConsole.Output(OutputType.DEBUG, "Audio / null"); return; } if (PlayingNow.Count > 200 && AudioInternal == null) { if (!CanClean()) { //SysConsole.Output(OutputType.DEBUG, "Audio / count"); return; } } if (sfx.Internal == -2) { Play(GetSound(sfx.Name), loop, pos, pitch, volume, seek, callback); return; } if (pitch <= 0 || pitch > 2) { throw new ArgumentException("Must be between 0 and 2", "pitch"); } if (volume == 0) { SysConsole.Output(OutputType.DEBUG, "Audio / volume"); return; } if (volume <= 0 || volume > 1) { throw new ArgumentException("Must be between 0 and 1", "volume"); } void playSound() { if (sfx.Clip == null && sfx.Internal < 0) { //SysConsole.Output(OutputType.DEBUG, "Audio / clip"); return; } ActiveSound actsfx = new ActiveSound(sfx) { Engine = this, Position = pos, Pitch = pitch * GlobalPitch, Gain = volume, Loop = loop }; actsfx.Create(); if (actsfx.AudioInternal == null && actsfx.Src < 0) { //SysConsole.Output(OutputType.DEBUG, "Audio / src"); return; } CheckError("Create:" + sfx.Name); /*if (TimeDeaf > 0.0) * { * actsfx.IsDeafened = true; * if (AudioInternal == null) * { * AL.Source(actsfx.Src, ALSourcef.Gain, 0.0001f); * } * else * { * actsfx.AudioInternal.Gain = 0.0001f; * } * }*/ if (seek != 0) { actsfx.Seek(seek); } CheckError("Preconfig:" + sfx.Name); actsfx.Play(); CheckError("Play:" + sfx.Name); //SysConsole.Output(OutputType.DEBUG, "Audio / sucess"); PlayingNow.Add(actsfx); callback?.Invoke(actsfx); } lock (sfx) { if (sfx.Clip == null && sfx.Internal == -1) { //SysConsole.Output(OutputType.DEBUG, "Audio / delay"); sfx.Loaded += (o, e) => { playSound(); }; return; } } playSound(); }