using Microsoft.Xna.Framework.Audio; using System; namespace AlienAttack.MonoGame.Audio; public sealed class VariantSoundPool { private readonly SoundPool[] _variantPools; private readonly Random _rng; private int _lastIndex = -1; public VariantSoundPool(SoundEffect[] variants, int voicesPerVariant, Random rng) { if (variants == null || variants.Length == 0) throw new ArgumentException("At least one variant is required.", nameof(variants)); ArgumentOutOfRangeException.ThrowIfLessThan(voicesPerVariant, 1); _rng = rng ?? throw new ArgumentNullException(nameof(rng)); _variantPools = new SoundPool[variants.Length]; for (int i = 0; i < variants.Length; i++) _variantPools[i] = new SoundPool(variants[i], voicesPerVariant); } public void Play(float volume = 1f, float pitch = 0f, float pan = 0f, bool avoidImmediateRepeat = true) { int idx = PickVariantIndex(avoidImmediateRepeat); _variantPools[idx].Play(volume, pitch, pan); } private int PickVariantIndex(bool avoidImmediateRepeat) { if (_variantPools.Length == 1) return 0; int idx = _rng.Next(_variantPools.Length); if (!avoidImmediateRepeat) { _lastIndex = idx; return idx; } // Avoid playing the exact same sample twice in a row (nice polish) if (idx == _lastIndex) idx = (idx + 1 + _rng.Next(_variantPools.Length - 1)) % _variantPools.Length; _lastIndex = idx; return idx; } }