示例#1
0
        private static void AddAndStartPlaying(SafeSoundEffect sound, FadePitchPan fpp, bool loop = false, int queue = -1)
        {
            Debug.Assert(playingSoundCount <= playingSounds.Length);
            if (playingSoundCount == playingSounds.Length)
            {
                Array.Resize(ref playingSounds, playingSounds.Length * 2);
            }

            Debug.Assert(playingSounds[playingSoundCount].sound == null);    // <- got cleared properly
            Debug.Assert(playingSounds[playingSoundCount].instance == null); // <- got cleared properly
            Debug.Assert(playingSounds[playingSoundCount].frameCount == 0);  // <- got cleared properly


            // If we are about to play multiple identical sounds at about the same time, stop them from overlapping:
            float quashFade = 1f;

            for (int i = playingSoundCount - 1; i >= 0; i--)
            {
                if (playingSounds[i].frameCount >= 3)
                {
                    break; // <- Reaching sounds that are too old
                }
                if (ReferenceEquals(playingSounds[i].sound, sound))
                {
                    quashFade -= (1f - ((float)playingSounds[i].frameCount / 3f));
                }
            }
            // TODO: The following is ugly, because it kills sequential sounds (but odds are they would be killed anyway - and because we just use `fpp.fade`, below, they'd get killed anyway)
            // If a sound would be quashed completely, just don't play it -- this is required because otherwise the quashed sounds would be taking up simulated channels
            if (quashFade < 0.1f)
            {
                while (queue != -1) // Don't leak the queue, if any
                {
                    queue = FreeQueuedSound(queue);
                }
                return;
            }
            // TODO: This is ugly because sequential sounds will inherit this fade level
            fpp.fade *= MathHelper.Clamp(quashFade, 0f, 1f);



            if (loop)
            {
                playingSounds[playingSoundCount].instance = sound.CreateInstance();
            }
            else
            {
                playingSounds[playingSoundCount].instance = sound.SoundEffectManager_GetInstance();
            }

            if (playingSounds[playingSoundCount].instance == null)
            {
                while (queue != -1) // Don't leak the queue, if any
                {
                    queue = FreeQueuedSound(queue);
                }
                return; // Failed to create sound instance... oh well.
            }

            Debug.Assert(playingSounds[playingSoundCount].instance.IsLooped == false); // <- instance was properly cleared
            if (loop)                                                                  // <- Cannot set on used instances (even to the same value)
            {
                playingSounds[playingSoundCount].instance.IsLooped = true;
            }

            playingSounds[playingSoundCount].sound      = sound;
            playingSounds[playingSoundCount].fpp        = fpp;
            playingSounds[playingSoundCount].queue      = queue;
            playingSounds[playingSoundCount].linkToNext = true; // <- all sounds on a given frame get linked!
            playingSounds[playingSoundCount].fade       = 1f;   // <- NOTE: assumed by channel ducking code
            playingSounds[playingSoundCount].frameCount = 0;

            fpp.ApplyTo(playingSounds[playingSoundCount].instance, SafeSoundEffect.SoundEffectVolume);
            playingSounds[playingSoundCount].instance.Play();

            playingSoundCount++;
        }