3 #if SILICONSTUDIO_PLATFORM_IOS
6 using MonoTouch.AVFoundation;
7 using MonoTouch.AudioToolbox;
8 using MonoTouch.Foundation;
10 namespace SiliconStudio.
Paradox.Audio
12 public partial class AudioEngine
14 private AVAudioPlayer audioPlayer;
15 private bool currentMusicDataTypeIsUnsupported;
17 private void AudioEngineImpl(AudioDevice device)
19 if (nbOfAudioEngineInstances == 0)
20 ActivateAudioSession();
23 private void ActivateAudioSession()
26 const double preferedAudioLatency = 0.005;
29 var audioSession = AVAudioSession.SharedInstance();
32 error = audioSession.SetCategory(AVAudioSessionCategory.SoloAmbient);
35 Logger.Warning(
"Failed to set the audio category to 'Ambient'. [Error info: {0}]", error.UserInfo);
36 State = AudioEngineState.Invalidated;
41 audioSession.SetPreferredIOBufferDuration(preferedAudioLatency, out error);
43 Logger.Warning(
"Failed to set the audio IO buffer duration to '{1}'. [Error info: {0}]", error.UserInfo,
44 preferedAudioLatency);
47 if (AudioSampleRate != 0)
49 audioSession.SetPreferredSampleRate(AudioSampleRate, out error);
50 Logger.Warning(
"Failed to set the audio session preferred sampling rate to '{1}'. [Error info: {0}]",
51 error.UserInfo, AudioSampleRate);
55 error = audioSession.SetActive(
true);
58 Logger.Warning(
"Failed to activate the audio session. [Error info: {0}]", error.UserInfo);
59 State = AudioEngineState.Invalidated;
63 private void DestroyImpl()
68 private void LoadNewMusic(SoundMusic lastPlayRequestMusicInstance)
70 if(audioPlayer != null)
71 throw new AudioSystemInternalException(
"Tried to create a new AudioPlayer but the current instance was not freed.");
73 currentMusic = lastPlayRequestMusicInstance;
75 currentMusicDataTypeIsUnsupported =
false;
80 currentMusic.Stream.Position = 0;
81 audioPlayer = AVAudioPlayer.FromData(NSData.FromStream(currentMusic.Stream), out loadError);
83 if (loadError != null)
85 if (loadError.Code == (
int) AudioFileError.UnsupportedFileType || loadError.Code == (
int) AudioFileError.UnsupportedDataFormat)
87 currentMusicDataTypeIsUnsupported =
true;
88 musicMediaEvents.Enqueue(
new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
91 throw new AudioSystemInternalException(
"Music loading failed and failure was not handled. [Error="+loadError.LocalizedDescription+
"].");
94 if (audioPlayer == null)
95 throw new AudioSystemInternalException(
"Music loading failed and failure was not handled. [Unspecified Error].");
97 audioPlayer.DecoderError += OnAudioPlayerDecoderError;
98 audioPlayer.FinishedPlaying += OnAudioPlayerFinishedPlaying;
100 if (!audioPlayer.PrepareToPlay())
103 var currentMusicName = currentMusic.Name;
104 currentMusic.SetStateToStopped();
107 Logger.Warning(
"The music '{0}' failed to prepare to play.", currentMusicName);
111 musicMediaEvents.Enqueue(
new SoundMusicEventNotification(SoundMusicEvent.MetaDataLoaded, null));
112 musicMediaEvents.Enqueue(
new SoundMusicEventNotification(SoundMusicEvent.ReadyToBePlayed, null));
116 private void OnAudioPlayerFinishedPlaying(
object sender, AVStatusEventArgs e)
119 throw new AudioSystemInternalException(
"The music play back did not completed successfully.");
121 musicMediaEvents.Enqueue(
new SoundMusicEventNotification(SoundMusicEvent.EndOfTrackReached, e));
124 private void OnAudioPlayerDecoderError(
object sender, AVErrorEventArgs e)
126 musicMediaEvents.Enqueue(
new SoundMusicEventNotification(SoundMusicEvent.ErrorOccurred, e));
129 private void ResetMusicPlayer()
133 if (audioPlayer != null)
135 audioPlayer.Dispose();
140 private void StopCurrentMusic()
142 if(audioPlayer == null)
146 audioPlayer.CurrentTime = 0;
149 private void PauseCurrentMusic()
151 if (audioPlayer == null)
157 private void UpdateMusicVolume()
159 if (audioPlayer == null)
162 audioPlayer.Volume = currentMusic.Volume;
165 private void StartCurrentMusic()
167 if (audioPlayer == null)
170 if (!audioPlayer.Play())
173 var currentMusicName = currentMusic.Name;
174 currentMusic.SetStateToStopped();
177 Logger.Warning(
"The music '{0}' failed to start playing.", currentMusicName);
181 private void RestartCurrentMusic()
187 private void PlatformSpecificProcessMusicReady()
192 private void ProcessMusicError(SoundMusicEventNotification eventNotification)
194 if (eventNotification.Event == SoundMusicEvent.ErrorOccurred)
196 var errorEventArgs = (AVErrorEventArgs) eventNotification.EventData;
197 throw new AudioSystemInternalException(
"An error happened during music play back and was not handled by the AudioSystem. [error:" + errorEventArgs.Error.LocalizedDescription +
"].");
201 private void ProcessMusicMetaData()
203 var errorMsg =
"Try to play a music with other format than PCM or MP3.";
204 var errorInFormat = currentMusicDataTypeIsUnsupported;
206 if (audioPlayer != null)
208 var settings = audioPlayer.Settings;
210 if (settings.NumberChannels > 2)
212 errorInFormat =
true;
213 errorMsg =
"Try to play a music with more than two audio channels.";
219 throw new InvalidOperationException(errorMsg);
223 private void ProcessPlayerClosed()
225 throw new AudioSystemInternalException(
"Should never arrive here. (Used only by windows implementation.");
228 private void PauseAudioPlatformSpecific()
233 private void ResumeAudioPlatformSpecific()
235 ActivateAudioSession();