Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AudioToolbox] Add support for xcode 14 beta6. #15877

Merged
merged 6 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/AudioToolbox/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,18 @@ public enum AUSpatialMixerSourceMode : uint
AmbienceBed = 3,
}

[NoWatch]
[TV (16, 0)]
[Mac (13, 0)]
[iOS (16, 0)]
public enum AUSpatialMixerPersonalizedHrtfMode : uint
{
[NoiOS, NoTV]
Off = 0,
[NoiOS, NoTV]
On = 1,
[NoiOS, NoTV]
Auto = 2,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm why add tv and ios support if none of the enums support it?


}
10 changes: 10 additions & 0 deletions src/AudioUnit/AUEnums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,16 @@ public enum AUVoiceIOSpeechActivityEvent : uint
Ended = 1,
}

[iOS (16,0), TV (16,0), Mac (13,0), MacCatalyst (16,0)]
public enum AudioUnitEventType : uint
{
ParameterValueChange = 0,
BeginParameterChangeGesture = 1,
EndParameterChangeGesture = 2,
PropertyChange = 3,
}


public enum AudioUnitSubType : uint
{
AUConverter = 0x636F6E76, // 'conv'
Expand Down
178 changes: 177 additions & 1 deletion src/AudioUnit/AudioComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,181 @@ public double LastActiveTime {
#endif

#if IOS || MONOMAC

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
[DllImport (Constants.AudioUnitLibrary)]
static extern int AudioComponentCopyConfigurationInfo (IntPtr /* AudioComponent */ inComponent, out /* CFDictionaryRef** */ IntPtr outConfigurationInfo);

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
public NSDictionary? GetConfigurationInfo (out int resultCode) {
resultCode = AudioComponentCopyConfigurationInfo (GetCheckedHandle (), out var dictPtr);
if (resultCode == 0) {
return Runtime.GetNSObject<NSDictionary> (dictPtr, owns: true);
}
return null;
}

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
public NSDictionary? GetConfigurationInfo () => GetConfigurationInfo (out var _);

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
[MacCatalyst (16,0)]
#endif
[DllImport (Constants.AudioUnitLibrary)]
static extern int AudioComponentValidate (IntPtr /* AudioComponent* */ inComponent, IntPtr /* CFDictionaryRef* */ inValidationParameters,
out AudioComponentValidationResult outValidationResult);

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
[MacCatalyst (16,0)]
#endif
public AudioComponentValidationResult Validate (NSDictionary? validationParameters, out int resultCode) {
resultCode = AudioComponentValidate (GetCheckedHandle (), validationParameters.GetHandle (), out var result);
if (resultCode == 0)
return result;
return AudioComponentValidationResult.Unknown;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your managed bindings have one thing in common: they don't expose the returned OSStatus from the native functions. This return value can be valuable when trying to diagnose why calls to these methods fail, so we often provide another overload that users can use to get this value. In this particular case that could be something like:

public AudioComponentValidationResult Validate (NSDictionary validationParameters, out int resultCode)
{
    ...
}

This goes for all the new API.

}

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
[MacCatalyst (16,0)]
#endif
public AudioComponentValidationResult Validate (NSDictionary? validationParameters = null) => Validate (validationParameters, out var _);

delegate void TrampolineCallback (IntPtr blockPtr, AudioComponentValidationResult result, IntPtr dictionary);

static unsafe readonly TrampolineCallback static_action = TrampolineAction;

[MonoPInvokeCallback (typeof (TrampolineCallback))]
static void TrampolineAction (IntPtr blockPtr, AudioComponentValidationResult result, IntPtr dictionary)
{
var del = BlockLiteral.GetTarget<Action<AudioComponentValidationResult, NSDictionary?>> (blockPtr);
if (del is not null)
del (result, Runtime.GetNSObject<NSDictionary>(dictionary));
}

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
[DllImport (Constants.AudioUnitLibrary)]
static extern int AudioComponentValidateWithResults (IntPtr /* AudioComponent* */ inComponent, IntPtr /* CFDictionaryRef* */ inValidationParameters, ref BlockLiteral inCompletionHandler);

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
[BindingImpl (BindingImplOptions.Optimizable)]
public void ValidateAsync (NSDictionary? validationParameters,
Action<AudioComponentValidationResult, NSDictionary?> onCompletion, out int resultCode) {
if (onCompletion is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (onCompletion));

var block_handler= new BlockLiteral ();
block_handler.SetupBlockUnsafe (static_action, onCompletion);
try {
resultCode = AudioComponentValidateWithResults (GetCheckedHandle (), validationParameters.GetHandle (), ref block_handler);
} finally {
block_handler.CleanupBlock ();
}
}

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
public void ValidateAsync (NSDictionary? validationParameters,
Action<AudioComponentValidationResult, NSDictionary?> onCompletion) => ValidateAsync (validationParameters, onCompletion, out var _);

#if NET
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[UnsupportedOSPlatform ("tvos")]
#else
[NoWatch]
[NoTV]
[Mac (13,0)]
[iOS (16,0)]
#endif
public void ValidateAsync (Action<AudioComponentValidationResult, NSDictionary?> onCompletion) => ValidateAsync (null, onCompletion, out var _);

#if NET
[SupportedOSPlatform ("macos10.13")]
[SupportedOSPlatform ("ios11.0")]
Expand Down Expand Up @@ -608,7 +783,8 @@ public AudioComponentInfo[]? ComponentList {
}
}
}
#endif

#endif // IOS || MONOMAC

#endif // !COREBUILD
}
Expand Down
75 changes: 75 additions & 0 deletions tests/monotouch-test/AudioToolbox/AudioComponentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Drawing;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using Foundation;
using AudioToolbox;
using AudioUnit;
Expand Down Expand Up @@ -117,6 +118,80 @@ public void TestResourceUsageInfoMachLookUpGlobalName ()
resources.MachLookUpGlobalName = null;
Assert.IsNull (resources.MachLookUpGlobalName, "Value was no set to null.");
}

[Test]
public void TestConfigurationInfo ()
{
TestRuntime.AssertXcodeVersion (14, 0);
var resources = new ResourceUsageInfo ();
resources.IOKitUserClient = new string[] { "CustomUserClient1" };
resources.MachLookUpGlobalName = new string[] { "MachServiceName1" };
resources.NetworkClient = false;
resources.TemporaryExceptionReadWrite = false;

var componentInfo = new AudioComponentInfo ();
componentInfo.Type = AudioTypeOutput.Generic.ToString ();
componentInfo.Subtype = "XMPL";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra space before "XMPL"

componentInfo.Name = "XMPL";
componentInfo.Version = 1;
componentInfo.ResourceUsage = resources;
using var component = AudioComponent.FindComponent (AudioTypeOutput.Generic);
Assert.IsNotNull (component);
// assert the property and break
var configInfo = component.GetConfigurationInfo ();
Assert.IsNotNull (configInfo);
}

[Test]
public void TestValidation ()
{
TestRuntime.AssertXcodeVersion (14, 0);
var resources = new ResourceUsageInfo ();
resources.IOKitUserClient = new string[] { "CustomUserClient1" };
resources.MachLookUpGlobalName = new string[] { "MachServiceName1" };
resources.NetworkClient = false;
resources.TemporaryExceptionReadWrite = false;

var componentInfo = new AudioComponentInfo ();
componentInfo.Type = AudioTypeOutput.Generic.ToString ();
componentInfo.Subtype = "XMPL";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

componentInfo.Name = "XMPL";
componentInfo.Version = 1;
componentInfo.ResourceUsage = resources;
using var component = AudioComponent.FindComponent (AudioTypeOutput.Generic);
Assert.IsNotNull (component);
// validate and break
var validation = component.Validate(null);
Assert.Contains (validation,
new List<AudioComponentValidationResult> () {AudioComponentValidationResult.Unknown, AudioComponentValidationResult.Passed}, "validation");
}

[Test]
public void TestValidationAsync ()
{
TestRuntime.AssertXcodeVersion (14, 0);
var resources = new ResourceUsageInfo ();
resources.IOKitUserClient = new string[] { "CustomUserClient1" };
resources.MachLookUpGlobalName = new string[] { "MachServiceName1" };
resources.NetworkClient = false;
resources.TemporaryExceptionReadWrite = false;

var componentInfo = new AudioComponentInfo ();
componentInfo.Type = AudioTypeOutput.Generic.ToString ();
componentInfo.Subtype = "XMPL";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

componentInfo.Name = "XMPL";
componentInfo.Version = 1;
componentInfo.ResourceUsage = resources;
using var component = AudioComponent.FindComponent (AudioTypeOutput.Generic);
Assert.IsNotNull (component);

var cbEvent = new AutoResetEvent(false);
Action<AudioComponentValidationResult, NSDictionary?> cb = (AudioComponentValidationResult _, NSDictionary? _) => {
cbEvent.Set ();
};
component.ValidateAsync(cb);
Assert.True (cbEvent.WaitOne (20000), "Cb was not called.");
}
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
!missing-selector! AUAudioUnit::scheduleMIDIEventBlock not bound
!missing-selector! AUAudioUnit::setMusicalContextBlock: not bound
!missing-selector! AUAudioUnit::tokenByAddingRenderObserver: not bound
!missing-selector! AUAudioUnit::messageChannelFor: not bound
!missing-selector! AUAudioUnitV2Bridge::audioUnit not bound
!missing-type! AUAudioUnitV2Bridge not bound
!missing-pinvoke! AudioCodecAppendInputBufferList is not bound
!missing-pinvoke! AudioCodecAppendInputData is not bound
Expand All @@ -77,3 +79,22 @@
!missing-selector! AUAudioUnit::AudioUnitMIDIProtocol not bound
!missing-selector! AUAudioUnit::hostMIDIProtocol not bound
!missing-selector! AUAudioUnit::setHostMIDIProtocol: not bound

# ignored in the past on macOS now ignored in every platform.
!missing-pinvoke! AUListenerAddParameter is not bound
!missing-pinvoke! AUListenerRemoveParameter is not bound
!missing-pinvoke! AUListenerCreate is not bound
!missing-pinvoke! AUListenerCreateWithDispatchQueue is not bound
!missing-pinvoke! AUListenerDispose is not bound
!missing-pinvoke! AUEventListenerAddEventType is not bound
!missing-pinvoke! AUEventListenerCreate is not bound
!missing-pinvoke! AUEventListenerCreateWithDispatchQueue is not bound
!missing-pinvoke! AUEventListenerNotify is not bound
!missing-pinvoke! AUEventListenerRemoveEventType is not bound
!missing-pinvoke! AUParameterFormatValue is not bound
!missing-pinvoke! AUParameterListenerNotify is not bound
!missing-pinvoke! AUParameterSet is not bound
!missing-pinvoke! AUParameterValueFromLinear is not bound
!missing-pinvoke! AUParameterValueToLinear is not bound

!missing-protocol! AUMessageChannel not bound
23 changes: 0 additions & 23 deletions tests/xtro-sharpie/api-annotations-dotnet/iOS-AudioToolbox.todo

This file was deleted.

Loading