From 6d8ef62705e10ff2f971ba110d4e86aa59fbfff8 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 8 Oct 2021 07:52:40 +0200 Subject: [PATCH] [AVFoundation] Fix a few issues with AudioUnit. (#12954) * Add an (IntPtr, bool) constructor so that AudioUnit works with Runtime.GetINativeObject. * Keep track of ownership, so that AudioUnit doesn't free the native resources when it doesn't own them. * Update a test to verify that calling 'AVAudioIONode.AudioUnit' multiple times and disposing the result between them works (this fails if AudioUnit doesn't keep track of ownership). --- src/AudioUnit/AudioUnit.cs | 18 ++++++++++++++---- .../AVFoundation/AVAudioIONode.cs | 14 ++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/AudioUnit/AudioUnit.cs b/src/AudioUnit/AudioUnit.cs index d089dfa11a..db4b49ad4a 100644 --- a/src/AudioUnit/AudioUnit.cs +++ b/src/AudioUnit/AudioUnit.cs @@ -298,7 +298,7 @@ namespace AudioUnit public class AudioUnit : IDisposable, ObjCRuntime.INativeObject { #pragma warning disable 649 // Field 'AudioUnit.handle' is never assigned to, and will always have its default value - internal IntPtr handle; + IntPtr handle; #pragma warning restore 649 public IntPtr Handle { get { @@ -314,14 +314,21 @@ namespace AudioUnit GCHandle gcHandle; bool _isPlaying; + bool owns; Dictionary renderer; Dictionary inputs; internal AudioUnit (IntPtr ptr) + : this (ptr, false) + { + } + + internal AudioUnit (IntPtr ptr, bool owns) { handle = ptr; gcHandle = GCHandle.Alloc(this); + this.owns = owns; } public AudioUnit (AudioComponent component) @@ -336,6 +343,7 @@ namespace AudioUnit throw new AudioUnitException (err); gcHandle = GCHandle.Alloc(this); + owns = true; } public AudioComponent Component { @@ -795,9 +803,11 @@ namespace AudioUnit protected virtual void Dispose (bool disposing) { if (handle != IntPtr.Zero){ - Stop (); - AudioUnitUninitialize (handle); - AudioComponentInstanceDispose (handle); + if (owns) { + Stop (); + AudioUnitUninitialize (handle); + AudioComponentInstanceDispose (handle); + } gcHandle.Free(); handle = IntPtr.Zero; } diff --git a/tests/monotouch-test/AVFoundation/AVAudioIONode.cs b/tests/monotouch-test/AVFoundation/AVAudioIONode.cs index faede9c114..8a97088153 100644 --- a/tests/monotouch-test/AVFoundation/AVAudioIONode.cs +++ b/tests/monotouch-test/AVFoundation/AVAudioIONode.cs @@ -21,10 +21,16 @@ namespace Xamarin.Mac.Tests Asserts.EnsureYosemite (); - AVAudioEngine eng = new AVAudioEngine(); - AVAudioIONode node = eng.OutputNode; - AUUnit unit = node.AudioUnit; - unit.GetElementCount (AudioUnitScopeType.Global); + using (AVAudioEngine eng = new AVAudioEngine ()) { + using (AVAudioIONode node = eng.OutputNode) { + using (AUUnit unit = node.AudioUnit) + unit.GetElementCount (AudioUnitScopeType.Global); + using (AUUnit unit = node.AudioUnit) + unit.GetElementCount (AudioUnitScopeType.Global); + using (AUUnit unit = node.AudioUnit) + unit.GetElementCount (AudioUnitScopeType.Global); + } + } // Make sure this doens't crash. } }