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)); } }
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(); } }
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; } } }
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)); } }