예제 #1
0
        internal override void LoadMusic(SoundMusic music)
        {
            if (audioPlayer != null)
            {
                throw new AudioSystemInternalException("Tried to create a new AudioPlayer but the current instance was not freed.");
            }

            CurrentMusic = music;

            currentMusicDataTypeIsUnsupported = false;

            NSError loadError;

            // TODO: Avoid allocating twice the music size (i.e. by using NSData.FromBytesNoCopy on CurrentMusic.Stream.GetBuffer())
            CurrentMusic.Stream.Position = 0;
            audioPlayer = AVAudioPlayer.FromData(NSData.FromStream(CurrentMusic.Stream), out loadError);

            if (loadError != null)
            {
                if (loadError.Code == (int)AudioFileError.UnsupportedFileType || loadError.Code == (int)AudioFileError.UnsupportedDataFormat)
                {
                    currentMusicDataTypeIsUnsupported = true;
                    musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
                    return;
                }
                throw new AudioSystemInternalException("Music loading failed and failure was not handled. [Error=" + loadError.LocalizedDescription + "].");
            }

            if (audioPlayer == null) // both audioPlayer and loadError are null (happened before when url was not correct)
            {
                throw new AudioSystemInternalException("Music loading failed and failure was not handled. [Unspecified Error].");
            }

            audioPlayer.DecoderError    += OnAudioPlayerDecoderError;
            audioPlayer.FinishedPlaying += OnAudioPlayerFinishedPlaying;

            if (!audioPlayer.PrepareToPlay())
            {
                // this happens sometimes when we put the application on background when starting to play.
                var currentMusicName = CurrentMusic.Name;
                CurrentMusic.SetStateToStopped();
                ResetMusicPlayer();

                Logger.Warning("The music '{0}' failed to prepare to play.", currentMusicName);
            }
            else
            {
                musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
                musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.ReadyToBePlayed, null));
            }
        }
예제 #2
0
        private void ProcessMusicEnded()
        {
            if (currentMusic == null || currentMusic.IsDisposed) //this event is asynchronous so the music can be disposed by the user meanwhile.
            {
                return;
            }

            // If the music need to be looped, we start it again.
            if (currentMusic.IsLooped && !currentMusic.ShouldExitLoop && currentMusic.PlayState != SoundPlayState.Stopped)
            {
                RestartCurrentMusic(); // restart the sound to simulate looping.
                StartCurrentMusic();
            }
            // otherwise we set the state of currentMusic to "stopped"
            else
            {
                currentMusic.SetStateToStopped();
            }
        }
예제 #3
0
        internal override void PlayImpl()
        {
            AudioEngine.SubmitMusicActionRequest(new SoundMusicActionRequest(this, SoundMusicAction.Play));

            // Actual Playing is happening during the Audio Engine update
            // but we can not wait this long to update the PlayState of the currently playing SoundMusic
            // after this call to Play, PlayState of the previous playing music should directly be set to Stopped
            // this is why we use here the static field PreviousPlayingInstance
            lock (PreviousPlayingInstanceLock) // protection again possible future multithreading.
            {
                if (previousPlayingInstance != this)
                {
                    if (previousPlayingInstance != null)
                    {
                        previousPlayingInstance.SetStateToStopped();
                    }

                    previousPlayingInstance = this;
                }
            }
        }
예제 #4
0
        private void LoadNewMusic(SoundMusic lastPlayRequestMusicInstance)
        {
            if(audioPlayer != null)
                throw new AudioSystemInternalException("Tried to create a new AudioPlayer but the current instance was not freed.");

            currentMusic = lastPlayRequestMusicInstance;

            currentMusicDataTypeIsUnsupported = false;

            NSError loadError;

            // TODO: Avoid allocating twice the music size (i.e. by using NSData.FromBytesNoCopy on currentMusic.Stream.GetBuffer())
            currentMusic.Stream.Position = 0;
            audioPlayer = AVAudioPlayer.FromData(NSData.FromStream(currentMusic.Stream), out loadError);

            if (loadError != null)
            {
                if (loadError.Code == (int) AudioFileError.UnsupportedFileType || loadError.Code == (int) AudioFileError.UnsupportedDataFormat)
                {
                    currentMusicDataTypeIsUnsupported = true;
                    musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
                    return;
                }
                throw new AudioSystemInternalException("Music loading failed and failure was not handled. [Error="+loadError.LocalizedDescription+"].");
            }

            if (audioPlayer == null) // both audioPlayer and loadError are null (happened before when url was not correct) 
                throw new AudioSystemInternalException("Music loading failed and failure was not handled. [Unspecified Error].");

            audioPlayer.DecoderError += OnAudioPlayerDecoderError;
            audioPlayer.FinishedPlaying += OnAudioPlayerFinishedPlaying;

            if (!audioPlayer.PrepareToPlay())
            {
                // this happens sometimes when we put the application on background when starting to play.
                var currentMusicName = currentMusic.Name;
                currentMusic.SetStateToStopped();
                ResetMusicPlayer();

                Logger.Warning("The music '{0}' failed to prepare to play.", currentMusicName);
            }
            else
            {
                musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
                musicMediaEvents.Enqueue(new SoundMusicEventNotification(SoundMusicEvent.ReadyToBePlayed, null));
            }
        }