Exemplo n.º 1
0
        public Task Play(SoundboxContext context, SoundPlayback sound)
        {
            if (Finished)
            {
                return(Task.FromResult(false));
            }

            this.Sound     = sound;
            this.WavPlayer = new System.Media.SoundPlayer(context.GetAbsoluteFileName(sound.Sound));

            new System.Threading.Thread(() =>
            {
                WavPlayer.PlaySync();
                lock (this)
                {
                    if (Finished)
                    {
                        return;
                    }
                    Finished = true;

                    PlaybackFinished?.Invoke(this, new ISoundPlaybackService.PlaybackEventArgs(
                                                 sound: sound,
                                                 fromStop: false
                                                 ));
                }
            }).Start();

            return(Task.FromResult(true));
        }
        public void Play(SoundboxContext context, SoundPlaybackRequest sounds)
        {
            if (sounds.Sounds.Count == 0)
            {
                PlaybackChanged?.Invoke(this, new ISoundChainPlaybackService.PlaybackEventArgs(
                                            soundsPlaying: new List <SoundPlayback>(),
                                            finished: true,
                                            fromStop: false,
                                            fromStopGlobal: false
                                            ));
                return;
            }

            Play(context, sounds, 0);
        }
        /// <summary>
        /// Plays the sound at the given index and recursively calls <see cref="Play(SoundboxContext, SoundPlaybackRequest, int)"/> again
        /// to play the next sound as well as required.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sounds"></param>
        /// <param name="index"></param>
        protected void Play(SoundboxContext context, SoundPlaybackRequest sounds, int index)
        {
            if (Finished)
            {
                //aborted
                return;
            }

            var sound = sounds.Sounds[index];
            //whether to play the next sound when we're done here (i.e. this is not the last track of the chain)
            bool continueNextSound = index < (sounds.Sounds.Count - 1);
            //whether to use SoundService's callback to start the next sound (more accurate) or to use start a timer on our own to play the next sound in the chain
            bool continueInCallback = continueNextSound && (sound.Options.ChainDelayMs == 0 || !sound.Sound.MetaData.HasLength);

            var player = GetSoundService();

            player.PlaybackFinished += (sender, args) =>
            {
                if (args.FromStop)
                {
                    //nothing to do. handled in Stop() already
                    return;
                }

                bool finished = false;
                ICollection <SoundPlayback> soundsPlaying;

                lock (this)
                {
                    SoundsPlaying.Remove(sound);
                    PlayersPlaying.Remove(player);

                    if (++SoundsFinished == sounds.Sounds.Count)
                    {
                        //this was the last sound. we're all done now
                        finished = true;
                    }

                    if (!this.Finished)
                    {
                        this.Finished = finished;

                        if (!continueInCallback)
                        {
                            //don't fire the STOPPED event if we would send the START event right away anyway
                            soundsPlaying = new List <SoundPlayback>(this.SoundsPlaying);

                            //update our listeners
                            PlaybackChanged?.Invoke(this, new ISoundChainPlaybackService.PlaybackEventArgs(
                                                        soundsPlaying: soundsPlaying,
                                                        finished: finished,
                                                        fromStop: false,
                                                        fromStopGlobal: false
                                                        ));
                        }
                    }
                }

                if (continueInCallback)
                {
                    //TODO use a timer here for ChainDelayMs > 0
                    //next sound
                    Play(context, sounds, index + 1);
                }
            };
            lock (this)
            {
                //TODO async
                player.Play(context, sound);
                this.SoundsPlaying.Add(sound);
                this.PlayersPlaying.Add(player);

                //update our listeners
                ICollection <SoundPlayback> soundsPlaying = new List <SoundPlayback>(this.SoundsPlaying);

                PlaybackChanged?.Invoke(this, new ISoundChainPlaybackService.PlaybackEventArgs(
                                            soundsPlaying: soundsPlaying,
                                            finished: false,
                                            fromStop: false,
                                            fromStopGlobal: false
                                            ));
            }

            if (continueNextSound && !continueInCallback)
            {
                //start a timer to trigger the next sound.
                var timer = new System.Timers.Timer(Math.Max(0, sound.GetActualLength() + sound.Options.ChainDelayMs));
                timer.AutoReset = false;
                timer.Elapsed  += (tSender, tArgs) =>
                {
                    //cleanup
                    timer.Stop();
                    timer.Dispose();

                    //clip the current sound if required
                    if (sound.Options.ChainDelayMs < 0 && sound.Options.ChainDelayClip)
                    {
                        player.Stop();
                    }

                    //start the next sound
                    Play(context, sounds, index + 1);
                };
                timer.Start();
            }
        }