PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/AudioToolbox/SystemSound.cs

https://github.com/kjpou1/maccore
C# | 247 lines | 175 code | 43 blank | 29 comment | 29 complexity | b0386950922e0501b6497f73a8f1d8d3 MD5 | raw file
Possible License(s): Apache-2.0
  1. //
  2. // SystemSound.cs: AudioServices system sound
  3. //
  4. // Authors: Mono Team
  5. // Marek Safar (marek.safar@gmail.com)
  6. //
  7. // Copyright 2009 Novell, Inc
  8. // Copyright 2012 Xamarin Inc.
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System;
  30. using System.Runtime.InteropServices;
  31. using MonoMac.Foundation;
  32. using MonoMac.CoreFoundation;
  33. using MonoMac.ObjCRuntime;
  34. namespace MonoMac.AudioToolbox {
  35. enum SystemSoundId : uint {
  36. Vibrate = 0x00000FFF,
  37. }
  38. public class SystemSound : INativeObject, IDisposable {
  39. #if MONOMAC
  40. // TODO:
  41. #else
  42. public static readonly SystemSound Vibrate = new SystemSound ((uint) SystemSoundId.Vibrate, false);
  43. #endif
  44. uint soundId;
  45. bool ownsHandle;
  46. Action completionRoutine;
  47. GCHandle gc_handle;
  48. static readonly Action<SystemSoundId, IntPtr> SoundCompletionCallback = SoundCompletionShared;
  49. internal SystemSound (uint soundId, bool ownsHandle)
  50. {
  51. this.soundId = soundId;
  52. this.ownsHandle = ownsHandle;
  53. }
  54. ~SystemSound ()
  55. {
  56. Dispose (false);
  57. }
  58. public IntPtr Handle {
  59. get {
  60. AssertNotDisposed ();
  61. return (IntPtr) soundId;
  62. }
  63. }
  64. public bool IsUISound {
  65. get {
  66. uint out_size = sizeof (uint);
  67. uint data;
  68. var res = AudioServices.AudioServicesGetProperty (AudioServicesPropertyKey.IsUISound, sizeof (AudioServicesPropertyKey), ref soundId, out out_size, out data);
  69. if (res != AudioServicesError.None)
  70. throw new ArgumentException (res.ToString ());
  71. return data == 1;
  72. }
  73. set {
  74. uint data = value ? (uint)1 : 0;
  75. var res = AudioServices.AudioServicesSetProperty (AudioServicesPropertyKey.IsUISound, sizeof (AudioServicesPropertyKey), ref soundId, sizeof (uint), ref data);
  76. if (res != AudioServicesError.None)
  77. throw new ArgumentException (res.ToString ());
  78. }
  79. }
  80. public bool CompletePlaybackIfAppDies {
  81. get {
  82. uint out_size = sizeof (uint);
  83. uint data;
  84. var res = AudioServices.AudioServicesGetProperty (AudioServicesPropertyKey.CompletePlaybackIfAppDies, sizeof (AudioServicesPropertyKey), ref soundId, out out_size, out data);
  85. if (res != AudioServicesError.None)
  86. throw new ArgumentException (res.ToString ());
  87. return data == 1;
  88. }
  89. set {
  90. uint data = value ? (uint)1 : 0;
  91. var res = AudioServices.AudioServicesSetProperty (AudioServicesPropertyKey.CompletePlaybackIfAppDies, sizeof (AudioServicesPropertyKey), ref soundId, sizeof (uint), ref data);
  92. if (res != AudioServicesError.None)
  93. throw new ArgumentException (res.ToString ());
  94. }
  95. }
  96. void AssertNotDisposed ()
  97. {
  98. if (soundId == 0)
  99. throw new ObjectDisposedException ("SystemSound");
  100. }
  101. void IDisposable.Dispose ()
  102. {
  103. Dispose (true);
  104. GC.SuppressFinalize (this);
  105. }
  106. protected virtual void Dispose (bool disposing)
  107. {
  108. Cleanup (false);
  109. }
  110. [DllImport (Constants.AudioToolboxLibrary)]
  111. static extern AudioServicesError AudioServicesDisposeSystemSoundID (uint soundId);
  112. void Cleanup (bool checkForError)
  113. {
  114. if (soundId == 0 || !ownsHandle)
  115. return;
  116. if (gc_handle.IsAllocated) {
  117. gc_handle.Free ();
  118. }
  119. if (completionRoutine != null) {
  120. RemoveSystemSoundCompletion ();
  121. }
  122. var error = AudioServicesDisposeSystemSoundID (soundId);
  123. var oldId = soundId;
  124. soundId = 0;
  125. if (checkForError && error != AudioServicesError.None) {
  126. throw new InvalidOperationException (string.Format ("Error while disposing SystemSound with ID {0}: {1}",
  127. oldId, error.ToString()));
  128. }
  129. }
  130. public void Close ()
  131. {
  132. Cleanup (true);
  133. }
  134. [DllImport (Constants.AudioToolboxLibrary)]
  135. static extern void AudioServicesPlayAlertSound (uint inSystemSoundID);
  136. public void PlayAlertSound ()
  137. {
  138. AssertNotDisposed ();
  139. AudioServicesPlayAlertSound (soundId);
  140. }
  141. [DllImport (Constants.AudioToolboxLibrary)]
  142. static extern void AudioServicesPlaySystemSound(uint inSystemSoundID);
  143. public void PlaySystemSound ()
  144. {
  145. AssertNotDisposed ();
  146. AudioServicesPlaySystemSound (soundId);
  147. }
  148. [DllImport (Constants.AudioToolboxLibrary)]
  149. static extern AudioServicesError AudioServicesCreateSystemSoundID (IntPtr fileUrl, out uint soundId);
  150. public SystemSound (NSUrl fileUrl)
  151. {
  152. var error = AudioServicesCreateSystemSoundID (fileUrl.Handle, out soundId);
  153. if (error != AudioServicesError.None)
  154. throw new InvalidOperationException (string.Format ("Could not create system sound ID for url {0}; error={1}",
  155. fileUrl, error));
  156. ownsHandle = true;
  157. }
  158. public static SystemSound FromFile (NSUrl fileUrl)
  159. {
  160. uint soundId;
  161. var error = AudioServicesCreateSystemSoundID (fileUrl.Handle, out soundId);
  162. if (error != AudioServicesError.None)
  163. return null;
  164. return new SystemSound (soundId, true);
  165. }
  166. public static SystemSound FromFile (string filename)
  167. {
  168. using (var url = new NSUrl (filename)){
  169. uint soundId;
  170. var error = AudioServicesCreateSystemSoundID (url.Handle, out soundId);
  171. if (error != AudioServicesError.None)
  172. return null;
  173. return new SystemSound (soundId, true);
  174. }
  175. }
  176. [DllImport (Constants.AudioToolboxLibrary)]
  177. static extern AudioServicesError AudioServicesAddSystemSoundCompletion (uint soundId, IntPtr runLoop, IntPtr runLoopMode, Action<SystemSoundId, IntPtr> completionRoutine, IntPtr clientData);
  178. [MonoPInvokeCallback (typeof (Action<SystemSoundId, IntPtr>))]
  179. static void SoundCompletionShared (SystemSoundId id, IntPtr clientData)
  180. {
  181. GCHandle gch = GCHandle.FromIntPtr (clientData);
  182. var ss = (SystemSound) gch.Target;
  183. ss.completionRoutine ();
  184. }
  185. public AudioServicesError AddSystemSoundCompletion (Action routine, CFRunLoop runLoop = null)
  186. {
  187. if (gc_handle.IsAllocated)
  188. throw new ArgumentException ("Only single completion routine is supported");
  189. gc_handle = GCHandle.Alloc (this);
  190. completionRoutine = routine;
  191. return AudioServicesAddSystemSoundCompletion (soundId,
  192. runLoop == null ? IntPtr.Zero : runLoop.Handle,
  193. IntPtr.Zero, // runLoopMode should be enum runLoopMode == null ? IntPtr.Zero : runLoopMode.Handle,
  194. SoundCompletionCallback, GCHandle.ToIntPtr (gc_handle));
  195. }
  196. [DllImport (Constants.AudioToolboxLibrary)]
  197. static extern void AudioServicesRemoveSystemSoundCompletion (uint soundId);
  198. public void RemoveSystemSoundCompletion ()
  199. {
  200. completionRoutine = null;
  201. AudioServicesRemoveSystemSoundCompletion (soundId);
  202. }
  203. }
  204. }