/// <summary>
        ///   Plays a sound that fades in and/or out from a file.
        /// </summary>
        /// <param name="fileName">The name of the file to play.</param>
        /// <param name="additionalOnPlaybackEndedHandler">
        ///   An event handler raised when the playback ends.
        /// </param>
        /// <param name="beginFadeInAction">
        ///   An action called when the fade-in begins.
        /// </param>
        /// <param name="beginFadeOutAction">
        ///   An action called when the fade-out begins.
        /// </param>
        public void PlayFadeableSound(string fileName, EventHandler additionalOnPlaybackEndedHandler, out Action<double> beginFadeInAction, out Action<double> beginFadeOutAction)
        {
            if (!playingSoundFileNames.Contains(fileName))
            {
                var input = new AudioFileReader(fileName);
                var reader = new AutoDisposeFileReader(input);
                reader.PlaybackEndedEvent += (sender, e) => playingSoundFileNames.Remove(fileName);
                reader.PlaybackEndedEvent += additionalOnPlaybackEndedHandler;

                FadeInFadeOutSampleProvider fadeSampleProvider = new FadeInFadeOutSampleProvider(reader);
                beginFadeInAction = fadeSampleProvider.BeginFadeIn;
                beginFadeOutAction = fadeSampleProvider.BeginFadeOut;

                AddMixerInput(fadeSampleProvider);
                playingSoundFileNames.Add(fileName);
            }
            else
            {
                // If the sound's already playing, we don't need to do anything,
                // but beginFadeInAction and beginFadeOutAction both need to be
                // assigned, so we give them both an empty lambda.
                beginFadeInAction = beginFadeOutAction = (value) => { };
            }
        }
        /// <summary>
        ///   Plays a <see cref="CachedSound" /> instance that fades in and/or out.
        /// </summary>
        /// <param name="sound">The sound to play.</param>
        /// <param name="additionalOnPlaybackEndedHandler">
        ///   An event handler raised when the playback ends.
        /// </param>
        /// <param name="beginFadeInAction">
        ///   An action called when the fade-in begins.
        /// </param>
        /// <param name="beginFadeOutAction">
        ///   An action called when the fade-out begins.
        /// </param>
        public void PlayFadeableSound(CachedSound sound, EventHandler additionalOnPlaybackEndedHandler, out Action<double> beginFadeInAction, out Action<double> beginFadeOutAction)
        {
            if (!playingSoundFileNames.Contains(sound.Name))
            {
                CachedSoundSampleProvider provider = new CachedSoundSampleProvider(sound);
                playingSoundFileNames.Add(sound.Name);
                provider.PlaybackEndedEvent += (sender, e) => playingSoundFileNames.Remove(sound.Name);
                provider.PlaybackEndedEvent += additionalOnPlaybackEndedHandler;

                FadeInFadeOutSampleProvider fadeSampleProvider = new FadeInFadeOutSampleProvider(provider);
                beginFadeInAction = fadeSampleProvider.BeginFadeIn;
                beginFadeOutAction = fadeSampleProvider.BeginFadeOut;

                AddMixerInput(fadeSampleProvider);
            }
            else
            {
                beginFadeInAction = beginFadeOutAction = (value) => { };
            }
        }