public MTAudioProcessingTap(MTAudioProcessingTapCallbacks callbacks, MTAudioProcessingTapCreationFlags flags) { if (callbacks == null) { throw new ArgumentNullException("callbacks"); } const MTAudioProcessingTapCreationFlags all_flags = MTAudioProcessingTapCreationFlags.PreEffects | MTAudioProcessingTapCreationFlags.PostEffects; if ((flags & all_flags) == all_flags) { throw new ArgumentException("Only one effect type can be set"); } this.callbacks = callbacks; var c = new Callbacks(); unsafe { if (callbacks.Initialize != null) { c.init = InitializeProxy; } if (callbacks.Finalize != null) { c.finalize = FinalizeProxy; } if (callbacks.Prepare != null) { c.prepare = PrepareProxy; } if (callbacks.Unprepare != null) { c.unprepare = UnprepareProxy; } c.process = ProcessProxy; } // a GCHandle is needed because we do not have an handle before calling MTAudioProcessingTapCreate // and that will call the InitializeProxy. So using this (short-lived) GCHandle allow us to find back the // original managed instance gch = GCHandle.Alloc(this); c.clientInfo = (IntPtr)gch; var res = MTAudioProcessingTapCreate(IntPtr.Zero, ref c, flags, out handle); // we won't need the GCHandle after the Create call gch.Free(); if (res != 0) { throw new ArgumentException(res.ToString()); } lock (handles) handles [handle] = this; }
public MTAudioProcessingTap (MTAudioProcessingTapCallbacks callbacks, MTAudioProcessingTapCreationFlags flags) { if (callbacks == null) throw new ArgumentNullException ("callbacks"); const MTAudioProcessingTapCreationFlags all_flags = MTAudioProcessingTapCreationFlags.PreEffects | MTAudioProcessingTapCreationFlags.PostEffects; if ((flags & all_flags) == all_flags) throw new ArgumentException ("Only one effect type can be set"); this.callbacks = callbacks; var c = new Callbacks (); unsafe { if (callbacks.Initialize != null) c.init = InitializeProxy; if (callbacks.Finalize != null) c.finalize = FinalizeProxy; if (callbacks.Prepare != null) c.prepare = PrepareProxy; if (callbacks.Unprepare != null) c.unprepare = UnprepareProxy; c.process = ProcessProxy; } // a GCHandle is needed because we do not have an handle before calling MTAudioProcessingTapCreate // and that will call the InitializeProxy. So using this (short-lived) GCHandle allow us to find back the // original managed instance gch = GCHandle.Alloc (this); c.clientInfo = (IntPtr)gch; var res = MTAudioProcessingTapCreate (IntPtr.Zero, ref c, flags, out handle); // we won't need the GCHandle after the Create call gch.Free (); if (res != 0) throw new ArgumentException (res.ToString ()); lock (handles) handles [handle] = this; }