From a832718429a84df7df1a9b716c585309561d9c70 Mon Sep 17 00:00:00 2001 From: olegoid Date: Thu, 12 May 2016 16:50:05 -0300 Subject: [PATCH 1/4] [AudioToolbox] Add missing MusicSequence.SetUserCallback method --- src/AudioToolbox/MusicSequence.cs | 40 ++++++++++++++++++++++++++++--- src/AudioToolbox/MusicTrack.cs | 14 +++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/AudioToolbox/MusicSequence.cs b/src/AudioToolbox/MusicSequence.cs index 59053c379c9f..0c3815f9c3d2 100644 --- a/src/AudioToolbox/MusicSequence.cs +++ b/src/AudioToolbox/MusicSequence.cs @@ -6,9 +6,6 @@ // // Copyright 2012-2014 Xamarin Inc. // -// MISSING: -// MusicSequenceSetUserCallback -// #if IOS || TVOS @@ -30,6 +27,12 @@ namespace XamCore.AudioToolbox { +#if !COREBUILD + public delegate void MusicSequenceUserCallback (MusicTrack track, double inEventTime, MusicEventUserData inEventData, double inStartSliceBeat, double inEndSliceBeat); + + delegate void MusicSequenceUserCallbackProxy (/* void * */ IntPtr inClientData, /* MusicSequence* */ IntPtr inSequence, /* MusicTrack* */ IntPtr inTrack, /* MusicTimeStamp */ double inEventTime, /* MusicEventUserData* */ IntPtr inEventData, /* MusicTimeStamp */ double inStartSliceBeat, /* MusicTimeStamp */ double inEndSliceBeat); +#endif + // MusicPlayer.h public class MusicSequence : INativeObject #if !COREBUILD @@ -73,6 +76,10 @@ public IntPtr Handle { protected virtual void Dispose (bool disposing) { if (handle != IntPtr.Zero){ + + // Remove native user callback + MusicSequenceSetUserCallback (handle, null, IntPtr.Zero); + DisposeMusicSequence (handle); lock (sequenceMap){ sequenceMap.Remove (handle); @@ -274,6 +281,33 @@ public double GetBeatsForSeconds (double seconds) return beats; return 0; } + + [DllImport (Constants.AudioToolboxLibrary)] + extern static /* OSStatus */ MusicPlayerStatus MusicSequenceSetUserCallback (/* MusicSequence */ IntPtr inSequence, MusicSequenceUserCallbackProxy inCallback, /* void * */ IntPtr inClientData); + + MusicSequenceUserCallback userCallback; + + public void SetUserCallback (MusicSequenceUserCallback callback) + { + if (MusicSequenceSetUserCallback (handle, UserCallbackProxy, IntPtr.Zero) == MusicPlayerStatus.Success) + userCallback = callback; + } + +#if !MONOMAC + [MonoPInvokeCallback (typeof (MusicSequenceUserCallbackProxy))] +#endif + static void UserCallbackProxy (IntPtr inClientData, IntPtr inSequence, IntPtr inTrack, double inEventTime, IntPtr inEventData, double inStartSliceBeat, double inEndSliceBeat) + { + var musicSequence = MusicSequence.Lookup (inSequence); + var callback = musicSequence.userCallback; + + if (callback != null) { + var userEventData = new MusicEventUserData (inEventData); + var musicTrack = new MusicTrack (musicSequence, inTrack, false); + + callback (musicTrack, inEventTime, userEventData, inStartSliceBeat, inEndSliceBeat); + } + } [DllImport (Constants.AudioToolboxLibrary)] extern static /* OSStatus */ MusicPlayerStatus MusicSequenceBeatsToBarBeatTime (/* MusicSequence */ IntPtr inSequence, /* MusicTimeStamp */ double inBeats, /* UInt32 */ int inSubbeatDivisor, out CABarBeatTime outBarBeatTime); diff --git a/src/AudioToolbox/MusicTrack.cs b/src/AudioToolbox/MusicTrack.cs index d4dbb5fb744b..8805a0f3d17b 100644 --- a/src/AudioToolbox/MusicTrack.cs +++ b/src/AudioToolbox/MusicTrack.cs @@ -129,6 +129,20 @@ internal override IntPtr ToUnmanaged () public class MusicEventUserData : MidiRawData { public MusicEventUserData () {} + + internal MusicEventUserData (IntPtr handle) + { + var buffer = new byte[sizeof(int)]; + Marshal.Copy (handle, buffer, 0, sizeof(int)); + int length = BitConverter.ToInt32 (buffer, 0); + + var dataPtr = IntPtr.Add (handle, sizeof (int)); + buffer = new byte[length]; + Marshal.Copy (dataPtr, buffer, 0, length); + + len = length; + data = buffer; + } } // From c2da1731633e55cbaa34c74cf2a9c35f648036dd Mon Sep 17 00:00:00 2001 From: olegoid Date: Tue, 17 May 2016 00:40:37 -0300 Subject: [PATCH 2/4] [AudioToolbox] MusicEventUserData internal .ctor refactoring --- src/AudioToolbox/MusicTrack.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AudioToolbox/MusicTrack.cs b/src/AudioToolbox/MusicTrack.cs index 8805a0f3d17b..945fb77b2c3e 100644 --- a/src/AudioToolbox/MusicTrack.cs +++ b/src/AudioToolbox/MusicTrack.cs @@ -132,13 +132,13 @@ public MusicEventUserData () {} internal MusicEventUserData (IntPtr handle) { - var buffer = new byte[sizeof(int)]; - Marshal.Copy (handle, buffer, 0, sizeof(int)); - int length = BitConverter.ToInt32 (buffer, 0); + if (handle == IntPtr.Zero) + throw new ArgumentNullException (nameof(handle)); - var dataPtr = IntPtr.Add (handle, sizeof (int)); - buffer = new byte[length]; - Marshal.Copy (dataPtr, buffer, 0, length); + int length = Marshal.ReadInt32 (handle); + + var buffer = new byte[length]; + Marshal.Copy (handle + 4, buffer, 0, length); len = length; data = buffer; From aa775e7329be7ecb6907e5bb489b6144db817cb9 Mon Sep 17 00:00:00 2001 From: olegoid Date: Tue, 17 May 2016 21:43:38 -0300 Subject: [PATCH 3/4] [AudioToolbox] Correct callbacks storage --- src/AudioToolbox/MusicSequence.cs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/AudioToolbox/MusicSequence.cs b/src/AudioToolbox/MusicSequence.cs index 0c3815f9c3d2..eac2fa439c27 100644 --- a/src/AudioToolbox/MusicSequence.cs +++ b/src/AudioToolbox/MusicSequence.cs @@ -45,6 +45,10 @@ internal MusicSequence (IntPtr handle) { this.handle = handle; } + static Dictionary userCallbackHandles = new Dictionary (); + + static MusicSequenceUserCallbackProxy userCallbackProxy = new MusicSequenceUserCallbackProxy (UserCallbackProxy); + [DllImport (Constants.AudioToolboxLibrary)] extern static /* OSStatus */ MusicPlayerStatus NewMusicSequence (/* MusicSequence* */ out IntPtr outSequence); @@ -77,6 +81,9 @@ protected virtual void Dispose (bool disposing) { if (handle != IntPtr.Zero){ + lock (userCallbackHandles) + userCallbackHandles.Remove (handle); + // Remove native user callback MusicSequenceSetUserCallback (handle, null, IntPtr.Zero); @@ -285,12 +292,16 @@ public double GetBeatsForSeconds (double seconds) [DllImport (Constants.AudioToolboxLibrary)] extern static /* OSStatus */ MusicPlayerStatus MusicSequenceSetUserCallback (/* MusicSequence */ IntPtr inSequence, MusicSequenceUserCallbackProxy inCallback, /* void * */ IntPtr inClientData); - MusicSequenceUserCallback userCallback; - public void SetUserCallback (MusicSequenceUserCallback callback) { - if (MusicSequenceSetUserCallback (handle, UserCallbackProxy, IntPtr.Zero) == MusicPlayerStatus.Success) - userCallback = callback; + lock (userCallbackHandles) { + if (userCallbackHandles.ContainsKey (handle)) + userCallbackHandles[handle] = callback; + else + userCallbackHandles.Add (handle, callback); + } + + MusicSequenceSetUserCallback (handle, userCallbackProxy, IntPtr.Zero); } #if !MONOMAC @@ -298,14 +309,16 @@ public void SetUserCallback (MusicSequenceUserCallback callback) #endif static void UserCallbackProxy (IntPtr inClientData, IntPtr inSequence, IntPtr inTrack, double inEventTime, IntPtr inEventData, double inStartSliceBeat, double inEndSliceBeat) { - var musicSequence = MusicSequence.Lookup (inSequence); - var callback = musicSequence.userCallback; + MusicSequenceUserCallback userCallback; + lock (userCallbackHandles) + userCallbackHandles.TryGetValue (inSequence, out userCallback); - if (callback != null) { + if (userCallback != null) { var userEventData = new MusicEventUserData (inEventData); + var musicSequence = MusicSequence.Lookup (inSequence); var musicTrack = new MusicTrack (musicSequence, inTrack, false); - callback (musicTrack, inEventTime, userEventData, inStartSliceBeat, inEndSliceBeat); + userCallback (musicTrack, inEventTime, userEventData, inStartSliceBeat, inEndSliceBeat); } } From 8b393b320e0b024d9807b19df1556e1ccdd5df18 Mon Sep 17 00:00:00 2001 From: olegoid Date: Fri, 20 May 2016 16:59:46 -0300 Subject: [PATCH 4/4] [AudioToolbox] Remove deprecated checks and fix code style issues --- src/AudioToolbox/MusicSequence.cs | 8 ++------ src/AudioToolbox/MusicTrack.cs | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/AudioToolbox/MusicSequence.cs b/src/AudioToolbox/MusicSequence.cs index eac2fa439c27..d35e1219711d 100644 --- a/src/AudioToolbox/MusicSequence.cs +++ b/src/AudioToolbox/MusicSequence.cs @@ -294,12 +294,8 @@ public double GetBeatsForSeconds (double seconds) public void SetUserCallback (MusicSequenceUserCallback callback) { - lock (userCallbackHandles) { - if (userCallbackHandles.ContainsKey (handle)) - userCallbackHandles[handle] = callback; - else - userCallbackHandles.Add (handle, callback); - } + lock (userCallbackHandles) + userCallbackHandles [handle] = callback; MusicSequenceSetUserCallback (handle, userCallbackProxy, IntPtr.Zero); } diff --git a/src/AudioToolbox/MusicTrack.cs b/src/AudioToolbox/MusicTrack.cs index 945fb77b2c3e..abae2a14180a 100644 --- a/src/AudioToolbox/MusicTrack.cs +++ b/src/AudioToolbox/MusicTrack.cs @@ -133,11 +133,11 @@ public MusicEventUserData () {} internal MusicEventUserData (IntPtr handle) { if (handle == IntPtr.Zero) - throw new ArgumentNullException (nameof(handle)); + throw new ArgumentNullException (nameof (handle)); int length = Marshal.ReadInt32 (handle); - var buffer = new byte[length]; + var buffer = new byte [length]; Marshal.Copy (handle + 4, buffer, 0, length); len = length;