From 84bcea0a402a1158287452600439d8be192fbc66 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 27 Aug 2024 13:58:15 +0200 Subject: [PATCH] [AudioToolbox] Implement Xcode 16.0 beta 1-6 changes. (#20856) Note: there were no changes in beta 2, beta 3, beta 4, beta 5 or beta 6. --- src/AudioToolbox/AudioConverter.cs | 126 +++++++++++ src/AudioToolbox/AudioFile.cs | 195 +++++++++++++++++- src/AudioToolbox/Enums.cs | 16 +- src/AudioUnit/AUEnums.cs | 39 ++-- src/audiounit.cs | 4 + .../Documentation.KnownFailures.txt | 13 +- .../AudioToolbox/AudioConverterTest.cs | 51 ++++- .../AudioToolbox/AudioFileTest.cs | 95 +++++++++ .../MacCatalyst-AudioToolbox.ignore | 2 + .../MacCatalyst-AudioToolbox.todo | 9 - .../iOS-AudioToolbox.todo | 7 - .../macOS-AudioToolbox.ignore | 2 + .../macOS-AudioToolbox.todo | 9 - .../tvOS-AudioToolbox.todo | 7 - tests/xtro-sharpie/iOS-AudioToolbox.todo | 7 - tests/xtro-sharpie/macOS-AudioToolbox.todo | 7 - tests/xtro-sharpie/tvOS-AudioToolbox.todo | 7 - 17 files changed, 516 insertions(+), 80 deletions(-) create mode 100644 tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.ignore delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/iOS-AudioToolbox.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.todo delete mode 100644 tests/xtro-sharpie/api-annotations-dotnet/tvOS-AudioToolbox.todo delete mode 100644 tests/xtro-sharpie/iOS-AudioToolbox.todo delete mode 100644 tests/xtro-sharpie/tvOS-AudioToolbox.todo diff --git a/src/AudioToolbox/AudioConverter.cs b/src/AudioToolbox/AudioConverter.cs index e1a0c1bc0fe1..d9a544234dbc 100644 --- a/src/AudioToolbox/AudioConverter.cs +++ b/src/AudioToolbox/AudioConverter.cs @@ -82,6 +82,20 @@ public enum AudioConverterPrimeMethod // typedef UInt32 AudioConverterPropertyID None = 2 } + [Flags] +#if NET + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] +#else + [Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] +#endif + public enum AudioConverterOptions : uint { + None = 0, + Unbuffered = 1 << 16, + } + #if NET [SupportedOSPlatform ("ios")] [SupportedOSPlatform ("maccatalyst")] @@ -441,6 +455,49 @@ public bool CanResumeFromInterruption { return new AudioConverter (ptr, true); } + /// Create a new AudioConverter with the specified options. + /// The format of the source audio to be converted. + /// The format to convert the source audio to. + /// Any to use. + /// In case of failure, will contain the error code for the failure. Otherwise the value will be returned. + /// A new AudioConverter instance, or null in case of failure. +#if NET + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] +#else + [Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] +#endif + public static AudioConverter? Create (AudioStreamBasicDescription sourceFormat, AudioStreamBasicDescription destinationFormat, AudioConverterOptions options, out AudioConverterError error) + { + IntPtr ptr = default (IntPtr); + unsafe { + error = AudioConverterNewWithOptions (&sourceFormat, &destinationFormat, options, &ptr); + } + if (error != AudioConverterError.None) + return null; + return new AudioConverter (ptr, true); + } + + /// Create a new AudioConverter with the specified options. + /// The format of the source audio to be converted. + /// The format to convert the source audio to. + /// Any to use. + /// A new AudioConverter instance, or null in case of failure. +#if NET + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] +#else + [Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] +#endif + public static AudioConverter? Create (AudioStreamBasicDescription sourceFormat, AudioStreamBasicDescription destinationFormat, AudioConverterOptions options) + { + return Create (sourceFormat, destinationFormat, options, out var _); + } + public static AudioFormatType []? DecodeFormats { get { return GetFormats (AudioFormatProperty.DecodeFormatIDs); @@ -641,6 +698,49 @@ static AudioConverterError FillComplexBufferShared (IntPtr inAudioConverter, ref } } +#if NET + public delegate void PrepareCompletionCallback (AudioConverterError status); + + [UnmanagedCallersOnly] + static void PrepareCompletionHandler (IntPtr block, int status) + { + var del = BlockLiteral.GetTarget (block); + if (del is not null) + del ((AudioConverterError) status); + } + + /// Optimizes any subsequent creation of audio converters in this process. + /// Reserved; always pass 0. + /// Reserved; always pass IntPtr.Zero. + /// Optional callback to invoke when the preparation is complete. + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] + [BindingImpl (BindingImplOptions.Optimizable)] + public unsafe static void Prepare (uint flags = 0, IntPtr ioReserved = default (IntPtr), PrepareCompletionCallback? completionCallback = null) + { + if (completionCallback is null) { + AudioConverterPrepare (flags, ioReserved, null); + } else { + delegate* unmanaged trampoline = &PrepareCompletionHandler; + using var block = new BlockLiteral (trampoline, completionCallback, typeof (AudioConverter), nameof (PrepareCompletionHandler)); + AudioConverterPrepare (flags, ioReserved, &block); + } + } + + /// Optimizes any subsequent creation of audio converters in this process. + /// Callback to invoke when the preparation is complete. + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] + public unsafe static void Prepare (PrepareCompletionCallback completionCallback) + { + Prepare (0, IntPtr.Zero, completionCallback); + } +#endif // NET + public AudioConverterError Reset () { return AudioConverterReset (Handle); @@ -743,6 +843,32 @@ void SetProperty (AudioConverterPropertyID propertyID, double value) unsafe static extern AudioConverterError AudioConverterNewSpecific (AudioStreamBasicDescription* inSourceFormat, AudioStreamBasicDescription* inDestinationFormat, int inNumberClassDescriptions, AudioClassDescription* inClassDescriptions, IntPtr* outAudioConverter); +#if NET + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] +#else + [Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] +#endif + [DllImport (Constants.AudioToolboxLibrary)] + unsafe static extern void AudioConverterPrepare (uint inFlags, IntPtr ioReserved, BlockLiteral* block); + +#if NET + [SupportedOSPlatform ("ios18.0")] + [SupportedOSPlatform ("maccatalyst18.0")] + [SupportedOSPlatform ("macos15.0")] + [SupportedOSPlatform ("tvos18.0")] +#else + [Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)] +#endif + [DllImport (Constants.AudioToolboxLibrary)] + unsafe static extern /* OSStatus */ AudioConverterError AudioConverterNewWithOptions ( + /* const AudioStreamBasicDescription * */ AudioStreamBasicDescription* inSourceFormat, + /* const AudioStreamBasicDescription * */ AudioStreamBasicDescription* inDestinationFormat, + /* AudioConverterOptions */ AudioConverterOptions inOptions, + /* AudioConverterRef __nullable * __nonnull */ IntPtr* outAudioConverter); + [DllImport (Constants.AudioToolboxLibrary)] static extern AudioConverterError AudioConverterDispose (IntPtr inAudioConverter); diff --git a/src/AudioToolbox/AudioFile.cs b/src/AudioToolbox/AudioFile.cs index 6c34d1858a33..e9b91260e2b6 100644 --- a/src/AudioToolbox/AudioFile.cs +++ b/src/AudioToolbox/AudioFile.cs @@ -1160,6 +1160,9 @@ public AudioFileError WritePackets (bool useCache, int numBytes, AudioStreamPack [DllImport (Constants.AudioToolboxLibrary)] unsafe extern static OSStatus AudioFileCountUserData (AudioFileID handle, uint userData, int* count); + /// Get the number of user data for the specified chunk type. + /// The fourcc of the ID whose count to retrieve. + /// The number of user udata for the specified ID. public int CountUserData (uint userData) { int count; @@ -1170,29 +1173,219 @@ public int CountUserData (uint userData) return -1; } + /// Get the number of user data for the specified chunk type. + /// The fourcc of the chunk. + /// The number of user data for the specified chunk type. + public int CountUserData (AudioFileChunkType chunkType) + { + return CountUserData ((uint) chunkType); + } + [DllImport (Constants.AudioToolboxLibrary)] unsafe extern static OSStatus AudioFileGetUserDataSize (AudioFileID audioFile, uint userDataID, int index, int* userDataSize); + + /// Get the size of the specified user data. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// Returns the (non-negative) size on success, otherwise -1. public int GetUserDataSize (uint userDataId, int index) { int ds; unsafe { - if (AudioFileGetUserDataSize (Handle, userDataId, index, &ds) == 0) + if (AudioFileGetUserDataSize (Handle, userDataId, index, &ds) != 0) return -1; } return ds; } + /// Get the size of the specified user data. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// Returns the (non-negative) size on success, otherwise -1. + public int GetUserDataSize (AudioFileChunkType chunkType, int index) + { + return GetUserDataSize ((uint) chunkType, index); + } + +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + [DllImport (Constants.AudioToolboxLibrary)] + unsafe extern static OSStatus AudioFileGetUserDataSize64 (AudioFileID audioFile, uint userDataID, int index, ulong* userDataSize); + + /// Get the 64-bit size of the specified user data. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The retrieved 64-bit size of the specified user data. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserDataSize (uint userDataId, int index, out ulong size) + { + size = 0; + unsafe { + return (AudioFileError) AudioFileGetUserDataSize64 (Handle, userDataId, index, (ulong*) Unsafe.AsPointer (ref size)); + } + } + + /// Get the 64-bit size of the specified user data. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The retrieved 64-bit size of the specified user data. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserDataSize (AudioFileChunkType chunkType, int index, out ulong size) + { + return GetUserDataSize ((uint) chunkType, index, out size); + } + [DllImport (Constants.AudioToolboxLibrary)] unsafe extern static OSStatus AudioFileGetUserData (AudioFileID audioFile, int userDataID, int index, int* userDataSize, IntPtr userData); + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// On input the size of the memory points to. On output the number of bytes written. + /// A pointer to memory where the data will be copied. + /// Returns on success, otherwise an error code. +#if XAMCORE_5_0 + public AudioFileError GetUserData (int userDataID, int index, ref int size, IntPtr userData) +#else public int GetUserData (int userDataID, int index, ref int size, IntPtr userData) +#endif { unsafe { return AudioFileGetUserData (Handle, userDataID, index, (int*) Unsafe.AsPointer (ref size), userData); } } + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// On input the size of the memory points to. On output the number of bytes written. + /// A pointer to memory where the data will be copied. + /// Returns on success, otherwise an error code. + public AudioFileError GetUserData (AudioFileChunkType chunkType, int index, ref int size, IntPtr userData) + { + return (AudioFileError) GetUserData ((int) chunkType, index, ref size, userData); + } + +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + [DllImport (Constants.AudioToolboxLibrary)] + unsafe extern static OSStatus AudioFileGetUserDataAtOffset (AudioFileID audioFile, uint userDataID, int index, long inOffset, int* userDataSize, IntPtr userData); + + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The offset from the first byte of the chunk of the data to get. + /// On input the size of the memory points to. On output the number of bytes written. + /// A pointer to memory where the data will be copied. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserData (uint userDataId, int index, long offset, ref int size, IntPtr userData) + { + unsafe { + return (AudioFileError) AudioFileGetUserDataAtOffset (Handle, userDataId, index, offset, (int*) Unsafe.AsPointer (ref size), userData); + } + } + + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The offset from the first byte of the chunk of the data to get. + /// On input the size of the memory points to. On output the number of bytes written. + /// A pointer to memory where the data will be copied. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserData (AudioFileChunkType chunkType, int index, long offset, ref int size, IntPtr userData) + { + return GetUserData ((uint) chunkType, index, offset, ref size, userData); + } + + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The offset from the first byte of the chunk of the data to get. + /// The number of bytes written into the byte array. + /// An array of bytes where the data will be copied. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserData (uint userDataId, int index, long offset, byte [] data, out int size) + { + size = data.Length; + unsafe { + fixed (byte* dataPtr = data) + return GetUserData (userDataId, index, offset, ref size, (IntPtr) dataPtr); + } + } + + /// Get part of the data of a chunk in a file. + /// The fourcc of the chunk. + /// The index of the chunk if there are more than one chunk. + /// The offset from the first byte of the chunk of the data to get. + /// The number of bytes written into the byte array. + /// An array of bytes where the data will be copied. + /// Returns on success, otherwise an error code. +#if NET + [SupportedOSPlatform ("ios17.0")] + [SupportedOSPlatform ("tvos17.0")] + [SupportedOSPlatform ("maccatalyst17.0")] + [SupportedOSPlatform ("macos14.0")] +#else + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] +#endif + public AudioFileError GetUserData (AudioFileChunkType chunkType, int index, long offset, byte [] data, out int size) + { + return GetUserData ((uint) chunkType, index, offset, data, out size); + } + [DllImport (Constants.AudioToolboxLibrary)] extern static OSStatus AudioFileSetUserData (AudioFileID inAudioFile, int userDataID, int index, int userDataSize, IntPtr userData); diff --git a/src/AudioToolbox/Enums.cs b/src/AudioToolbox/Enums.cs index 50c3a7046c9d..8acff9ffcb46 100644 --- a/src/AudioToolbox/Enums.cs +++ b/src/AudioToolbox/Enums.cs @@ -54,15 +54,19 @@ public enum AUSpatialMixerSourceMode : uint { [iOS (16, 0)] [MacCatalyst (16, 0)] public enum AUSpatialMixerPersonalizedHrtfMode : uint { - [NoiOS, NoTV] - [NoMacCatalyst] + [iOS (18, 0), TV (18, 0), MacCatalyst (18, 0)] Off = 0, - [NoiOS, NoTV] - [NoMacCatalyst] + [iOS (18, 0), TV (18, 0), MacCatalyst (18, 0)] On = 1, - [NoiOS, NoTV] - [NoMacCatalyst] + [iOS (18, 0), TV (18, 0), MacCatalyst (18, 0)] Auto = 2, } + [iOS (17, 0), TV (17, 0), MacCatalyst (17, 0), Mac (14, 0)] + public enum AUVoiceIOOtherAudioDuckingLevel : uint { + Default = 0, + Min = 10, + Mid = 20, + Max = 30, + } } diff --git a/src/AudioUnit/AUEnums.cs b/src/AudioUnit/AUEnums.cs index c452b90febc9..c53428feb853 100644 --- a/src/AudioUnit/AUEnums.cs +++ b/src/AudioUnit/AUEnums.cs @@ -31,6 +31,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel; using System.Text; using System.Runtime.InteropServices; using System.Threading; @@ -418,21 +419,29 @@ enum AudioUnitPropertyIDType { // UInt32 AudioUnitPropertyID ReverbRoomType = 10, UsesInternalReverb = 1005, SpatializationAlgorithm = 3000, - [Deprecated (PlatformName.iOS, 9, 0)] - [Deprecated (PlatformName.TvOS, 9, 0)] - [Deprecated (PlatformName.MacCatalyst, 13, 1)] - [Deprecated (PlatformName.MacOSX, 10, 11)] - DistanceParams = 3010, - [Deprecated (PlatformName.iOS, 9, 0)] - [Deprecated (PlatformName.TvOS, 9, 0)] - [Deprecated (PlatformName.MacCatalyst, 13, 1)] - [Deprecated (PlatformName.MacOSX, 10, 11)] - AttenuationCurve = 3013, - [Deprecated (PlatformName.iOS, 9, 0)] - [Deprecated (PlatformName.TvOS, 9, 0)] - [Deprecated (PlatformName.MacCatalyst, 13, 1)] - [Deprecated (PlatformName.MacOSX, 10, 11)] - RenderingFlags = 3003, + SpatialMixerRenderingFlags = 3003, + SpatialMixerSourceMode = 3005, + SpatialMixerDistanceParams = 3010, +#if !XAMCORE_5_0 + [Obsolete ("Use 'SpatialMixerDistanceParams' instead.")] + [EditorBrowsable (EditorBrowsableState.Never)] + DistanceParams = SpatialMixerDistanceParams, + [Obsolete ("Use 'SpatialMixerAttenuationCurve' instead.")] + [EditorBrowsable (EditorBrowsableState.Never)] + AttenuationCurve = SpatialMixerAttenuationCurve, + [Obsolete ("Use 'SpatialMixerRenderingFlags' instead.")] + [EditorBrowsable (EditorBrowsableState.Never)] + RenderingFlags = SpatialMixerRenderingFlags, +#endif + SpatialMixerAttenuationCurve = 3013, + SpatialMixerOutputType = 3100, + SpatialMixerPointSourceInHeadMode = 3103, + [Mac (12, 3), iOS (18, 0), TV (18, 0), MacCatalyst (18, 0), NoWatch] + SpatialMixerEnableHeadTracking = 3111, + [Mac (13, 0), iOS (18, 0), TV (18, 0), MacCatalyst (18, 0), NoWatch] + SpatialMixerPersonalizedHrtfMode = 3113, + [Mac (14, 0), iOS (18, 0), TV (18, 0), MacCatalyst (18, 0), NoWatch] + SpatialMixerAnyInputIsUsingPersonalizedHrtf = 3116, // AUScheduledSoundPlayer ScheduleAudioSlice = 3300, diff --git a/src/audiounit.cs b/src/audiounit.cs index 341c2cdcad6f..0ff8d321a68a 100644 --- a/src/audiounit.cs +++ b/src/audiounit.cs @@ -388,6 +388,10 @@ AUParameterTree ParameterTree { [NoWatch, NoTV, NoiOS] [Export ("isLoadedInProcess")] bool IsLoadedInProcess { get; } + + [Watch (9, 0), TV (16, 0), Mac (13, 0), iOS (16, 0), MacCatalyst (16, 0)] + [Export ("migrateFromPlugin")] + NSData [] MigrateFromPlugin { get; } } // kept separate from AUAudioUnit, quote: diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt index 1d3e8ef93039..a8215195ae6e 100644 --- a/tests/cecil-tests/Documentation.KnownFailures.txt +++ b/tests/cecil-tests/Documentation.KnownFailures.txt @@ -3517,6 +3517,8 @@ F:AudioToolbox.AudioConverterError.OutputSampleRateOutOfRange F:AudioToolbox.AudioConverterError.PropertyNotSupported F:AudioToolbox.AudioConverterError.RequiresPacketDescriptionsError F:AudioToolbox.AudioConverterError.UnspecifiedError +F:AudioToolbox.AudioConverterOptions.None +F:AudioToolbox.AudioConverterOptions.Unbuffered F:AudioToolbox.AudioConverterPrimeInfo.LeadingFrames F:AudioToolbox.AudioConverterPrimeInfo.TrailingFrames F:AudioToolbox.AudioConverterPrimeMethod.None @@ -4007,6 +4009,10 @@ F:AudioToolbox.AUSpatialMixerSourceMode.AmbienceBed F:AudioToolbox.AUSpatialMixerSourceMode.Bypass F:AudioToolbox.AUSpatialMixerSourceMode.PointSource F:AudioToolbox.AUSpatialMixerSourceMode.SpatializeIfMono +F:AudioToolbox.AUVoiceIOOtherAudioDuckingLevel.Default +F:AudioToolbox.AUVoiceIOOtherAudioDuckingLevel.Max +F:AudioToolbox.AUVoiceIOOtherAudioDuckingLevel.Mid +F:AudioToolbox.AUVoiceIOOtherAudioDuckingLevel.Min F:AudioToolbox.CABarBeatTime.Bar F:AudioToolbox.CABarBeatTime.Beat F:AudioToolbox.CABarBeatTime.Reserved @@ -25831,7 +25837,6 @@ M:AudioToolbox.AudioConverter.FillComplexBuffer(System.Int32@,AudioToolbox.Audio M:AudioToolbox.AudioConverter.remove_InputData(AudioToolbox.AudioConverterComplexInputData) M:AudioToolbox.AudioConverter.Reset M:AudioToolbox.AudioFile.ByteToPacket(System.Int64,System.Int32@,System.Boolean@) -M:AudioToolbox.AudioFile.CountUserData(System.UInt32) M:AudioToolbox.AudioFile.Create(CoreFoundation.CFUrl,AudioToolbox.AudioFileType,AudioToolbox.AudioStreamBasicDescription,AudioToolbox.AudioFileFlags) M:AudioToolbox.AudioFile.Create(Foundation.NSUrl,AudioToolbox.AudioFileType,AudioToolbox.AudioStreamBasicDescription,AudioToolbox.AudioFileFlags) M:AudioToolbox.AudioFile.Create(System.String,AudioToolbox.AudioFileType,AudioToolbox.AudioStreamBasicDescription,AudioToolbox.AudioFileFlags) @@ -25840,8 +25845,6 @@ M:AudioToolbox.AudioFile.FrameToPacket(System.Int64,System.Int32@) M:AudioToolbox.AudioFile.GetProperty(AudioToolbox.AudioFileProperty,System.Int32@,System.IntPtr) M:AudioToolbox.AudioFile.GetProperty(AudioToolbox.AudioFileProperty,System.Int32@) M:AudioToolbox.AudioFile.GetPropertyInfo(AudioToolbox.AudioFileProperty,System.Int32@,System.Int32@) -M:AudioToolbox.AudioFile.GetUserData(System.Int32,System.Int32,System.Int32@,System.IntPtr) -M:AudioToolbox.AudioFile.GetUserDataSize(System.UInt32,System.Int32) M:AudioToolbox.AudioFile.IsPropertyWritable(AudioToolbox.AudioFileProperty) M:AudioToolbox.AudioFile.Open(CoreFoundation.CFUrl,AudioToolbox.AudioFilePermission,AudioToolbox.AudioFileError@,AudioToolbox.AudioFileType) M:AudioToolbox.AudioFile.Open(CoreFoundation.CFUrl,AudioToolbox.AudioFilePermission,AudioToolbox.AudioFileType) @@ -56747,6 +56750,7 @@ P:AudioUnit.AUAudioUnit.MaximumFramesToRender P:AudioUnit.AUAudioUnit.MidiOutputBufferSizeHint P:AudioUnit.AUAudioUnit.MidiOutputEventBlock P:AudioUnit.AUAudioUnit.MidiOutputNames +P:AudioUnit.AUAudioUnit.MigrateFromPlugin P:AudioUnit.AUAudioUnit.MusicDeviceOrEffect P:AudioUnit.AUAudioUnit.OutputBusses P:AudioUnit.AUAudioUnit.ParameterTree @@ -79125,8 +79129,10 @@ T:AudioToolbox.AudioChannelLayoutTagExtensions T:AudioToolbox.AudioClassDescription T:AudioToolbox.AudioCodecComponentType T:AudioToolbox.AudioConverter +T:AudioToolbox.AudioConverter.PrepareCompletionCallback T:AudioToolbox.AudioConverterComplexInputData T:AudioToolbox.AudioConverterError +T:AudioToolbox.AudioConverterOptions T:AudioToolbox.AudioConverterPrimeInfo T:AudioToolbox.AudioConverterPrimeMethod T:AudioToolbox.AudioConverterQuality @@ -79192,6 +79198,7 @@ T:AudioToolbox.AUSpatialMixerOutputType T:AudioToolbox.AUSpatialMixerPersonalizedHrtfMode T:AudioToolbox.AUSpatialMixerPointSourceInHeadMode T:AudioToolbox.AUSpatialMixerSourceMode +T:AudioToolbox.AUVoiceIOOtherAudioDuckingLevel T:AudioToolbox.BufferCompletedEventArgs T:AudioToolbox.CABarBeatTime T:AudioToolbox.ExtendedNoteOnEvent diff --git a/tests/monotouch-test/AudioToolbox/AudioConverterTest.cs b/tests/monotouch-test/AudioToolbox/AudioConverterTest.cs index ccd5e92c328c..a8603ec09734 100644 --- a/tests/monotouch-test/AudioToolbox/AudioConverterTest.cs +++ b/tests/monotouch-test/AudioToolbox/AudioConverterTest.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Threading.Tasks; using AudioToolbox; using AudioUnit; @@ -34,6 +35,49 @@ public void Formats () Assert.That (encodeFormats.Length, Is.GreaterThan (10), "Encode Length #1"); } +#if NET + [Test] + public void Prepare () + { + TestRuntime.AssertXcodeVersion (16, 0); + + AudioConverter.Prepare (); + } + + [Test] + public void PrepareWithCallback () + { + TestRuntime.AssertXcodeVersion (16, 0); + + var tcs = new TaskCompletionSource (); + AudioConverter.Prepare ((status) => tcs.SetResult (status)); + var timeout = TimeSpan.FromSeconds (5); + if (!tcs.Task.Wait (timeout)) { + // Preparation might take a long time, so don't assert on the bots. + // We might have to bump the timeout for local test runs as well. + if (!TestRuntime.IsInCI) + Assert.Fail ($"Callback wasn't called within {timeout.TotalSeconds} s"); + } + } +#endif + + [Test] + public void CreateWithOptions () + { + TestRuntime.AssertXcodeVersion (16, 0); + + var sourcePath = Path.Combine (NSBundle.MainBundle.ResourcePath, "Hand.wav"); + var paths = NSSearchPath.GetDirectories (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User); + + // Convert once + var output1 = Path.Combine (paths [0], "outputOptions1.caf"); + Convert (sourcePath, output1, AudioFormatType.AppleLossless, options: AudioConverterOptions.None); + + // Convert converted output + var output2 = Path.Combine (paths [0], "outputOptions2.wav"); + Convert (output1, output2, AudioFormatType.LinearPCM, options: AudioConverterOptions.None); + } + [Test] public void Convert () { @@ -51,7 +95,7 @@ public void Convert () Convert (output1, output2, AudioFormatType.LinearPCM); } - void Convert (string sourceFilePath, string destinationFilePath, AudioFormatType outputFormatType, int? sampleRate = null) + void Convert (string sourceFilePath, string destinationFilePath, AudioFormatType outputFormatType, int? sampleRate = null, AudioConverterOptions? options = null) { var destinationUrl = NSUrl.FromFilename (destinationFilePath); var sourceUrl = NSUrl.FromFilename (sourceFilePath); @@ -84,7 +128,10 @@ void Convert (string sourceFilePath, string destinationFilePath, AudioFormatType } // create the AudioConverter - using var converter = AudioConverter.Create (srcFormat, dstFormat, out var ce); + AudioConverterError ce; + using AudioConverter? converter = options.HasValue ? + AudioConverter.Create (srcFormat, dstFormat, options.Value, out ce) : + AudioConverter.Create (srcFormat, dstFormat, out ce); Assert.AreEqual (AudioConverterError.None, ce, $"AudioConverterCreate: {name}"); // set up source buffers and data proc info struct diff --git a/tests/monotouch-test/AudioToolbox/AudioFileTest.cs b/tests/monotouch-test/AudioToolbox/AudioFileTest.cs index 6745e79d7d10..991690e5246a 100644 --- a/tests/monotouch-test/AudioToolbox/AudioFileTest.cs +++ b/tests/monotouch-test/AudioToolbox/AudioFileTest.cs @@ -2,7 +2,10 @@ #if !__WATCHOS__ +using System; using System.IO; +using System.Runtime.InteropServices; + using Foundation; using AudioToolbox; using CoreFoundation; @@ -32,6 +35,98 @@ public void ReadTest () int header = 4096; Assert.That (header + current == full_len, "#1"); } + + [Test] + public void ApiTest () + { + TestRuntime.AssertXcodeVersion (15, 0); + + var path = NSBundle.MainBundle.PathForResource ("1", "caf", "AudioToolbox"); + using var af = AudioFile.Open (CFUrl.FromFile (path), AudioFilePermission.Read, AudioFileType.CAF); + var chunkIds = af.ChunkIDs; + Assert.That (chunkIds.Length, Is.GreaterThan (0), "ChunkIDs"); + + var memorySize = 1024; + IntPtr memory = Marshal.AllocHGlobal (memorySize); ; + int size = 0; + int offset; + byte [] buffer; + var expectedData = new byte [] { 0x40, 0xc5, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x6d, 0x61, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; + + try { + var chunkType = AudioFileChunkType.CAFStreamDescription; + Assert.Multiple (() => { + Assert.AreEqual (1, af.CountUserData (chunkType), "CountUserData #1"); + Assert.AreEqual (1, af.CountUserData ((uint) chunkType), "CountUserData #2"); + + Assert.AreEqual (32, af.GetUserDataSize (chunkType, 0), "GetUserDataSize #1"); + Assert.AreEqual (32, af.GetUserDataSize ((uint) chunkType, 0), "GetUserDataSize #2"); + + Assert.AreEqual (AudioFileError.Success, af.GetUserDataSize (chunkType, 0, out var userDataSize64), "GetUserDataSize64 #1"); + Assert.AreEqual (32, userDataSize64, "GetUserDataSize64 #2"); + + Assert.AreEqual (AudioFileError.Success, af.GetUserDataSize ((uint) chunkType, 0, out userDataSize64), "GetUserDataSize64 #3"); + Assert.AreEqual (32, userDataSize64, "GetUserDataSize64 #4"); + + size = memorySize; + Assert.AreEqual (AudioFileError.Success, af.GetUserData (chunkType, 0, ref size, memory), "GetUserData #1"); + Assert.AreEqual (32, size, "GetUserData #2"); + Assert.AreEqual (size, expectedData.Length, "GetUserData #3"); + for (var i = 0; i < expectedData.Length; i++) { + Assert.AreEqual (expectedData [i], Marshal.ReadByte (memory, i), $"GetUserData #4[{i}]"); + Marshal.WriteByte (memory, i, 0); + } + + size = memorySize; + Assert.AreEqual (0, af.GetUserData ((int) chunkType, 0, ref size, memory), "GetUserData/B #1"); + Assert.AreEqual (32, size, "GetUserData/B #2"); + Assert.AreEqual (size, expectedData.Length, "GetUserData/B #3"); + for (var i = 0; i < expectedData.Length; i++) { + Assert.AreEqual (expectedData [i], Marshal.ReadByte (memory, i), $"GetUserData/B #4[{i}]"); + Marshal.WriteByte (memory, i, 0); + } + + size = memorySize; + offset = 16; + Assert.AreEqual (AudioFileError.Success, af.GetUserData (chunkType, 0, offset, ref size, memory), "GetUserDataAtOffset/A #1"); + Assert.AreEqual (32 - offset, size, "GetUserDataAtOffset/A #2"); + Assert.AreEqual (size, expectedData.Length - offset, "GetUserDataAtOffset/A #3"); + for (var i = offset; i < expectedData.Length; i++) { + Assert.AreEqual (expectedData [i], Marshal.ReadByte (memory, i - offset), $"GetUserDataAtOffset/A #4[{i}]"); + Marshal.WriteByte (memory, i - offset, 0); + } + + size = memorySize; + offset = 12; + Assert.AreEqual (AudioFileError.Success, af.GetUserData ((uint) chunkType, 0, offset, ref size, memory), "GetUserDataAtOffset/B #1"); + Assert.AreEqual (32 - offset, size, "GetUserDataAtOffset/B #2"); + Assert.AreEqual (size, expectedData.Length - offset, "GetUserDataAtOffset/B #3"); + for (var i = offset; i < expectedData.Length; i++) { + Assert.AreEqual (expectedData [i], Marshal.ReadByte (memory, i - offset), $"GetUserDataAtOffset/B #4[{i}]"); + Marshal.WriteByte (memory, i - offset, 0); + } + + size = memorySize; + offset = 24; + buffer = new byte [memorySize]; + Assert.AreEqual (AudioFileError.Success, af.GetUserData (chunkType, 0, offset, buffer, out size), "GetUserDataAtOffset/C #1"); + Assert.AreEqual (32 - offset, size, "GetUserDataAtOffset/C #2"); + Assert.AreEqual (size, expectedData.Length - offset, "GetUserDataAtOffset/C #3"); + for (var i = offset; i < expectedData.Length; i++) + Assert.AreEqual (expectedData [i], buffer [i - offset], $"GetUserDataAtOffset/C #4[{i}]"); + + size = memorySize; + offset = 8; + Assert.AreEqual (AudioFileError.Success, af.GetUserData ((uint) chunkType, 0, offset, buffer, out size), "GetUserDataAtOffset/D #1"); + Assert.AreEqual (32 - offset, size, "GetUserDataAtOffset/D #2"); + Assert.AreEqual (size, expectedData.Length - offset, "GetUserDataAtOffset/D #3"); + for (var i = offset; i < expectedData.Length; i++) + Assert.AreEqual (expectedData [i], buffer [i - offset], $"GetUserDataAtOffset/D #4[{i}]"); + }); + } finally { + Marshal.FreeHGlobal (memory); + } + } } } diff --git a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.ignore b/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.ignore new file mode 100644 index 000000000000..9268424ba42d --- /dev/null +++ b/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.ignore @@ -0,0 +1,2 @@ +!missing-selector! AUAudioUnit::messageChannelFor: not bound +!missing-protocol! AUMessageChannel not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.todo b/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.todo deleted file mode 100644 index 586c0a19467e..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-AudioToolbox.todo +++ /dev/null @@ -1,9 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-protocol! AUMessageChannel not bound -!missing-selector! AUAudioUnit::messageChannelFor: not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/iOS-AudioToolbox.todo b/tests/xtro-sharpie/api-annotations-dotnet/iOS-AudioToolbox.todo deleted file mode 100644 index 18d4bb0c9c0e..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/iOS-AudioToolbox.todo +++ /dev/null @@ -1,7 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.ignore b/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.ignore index 09b9c684f548..a110502de4f9 100644 --- a/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.ignore +++ b/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.ignore @@ -14,7 +14,9 @@ !missing-pinvoke! AudioFileComponentGetProperty is not bound !missing-pinvoke! AudioFileComponentGetPropertyInfo is not bound !missing-pinvoke! AudioFileComponentGetUserData is not bound +!missing-pinvoke! AudioFileComponentGetUserDataAtOffset is not bound !missing-pinvoke! AudioFileComponentGetUserDataSize is not bound +!missing-pinvoke! AudioFileComponentGetUserDataSize64 is not bound !missing-pinvoke! AudioFileComponentInitializeWithCallbacks is not bound !missing-pinvoke! AudioFileComponentOpenURL is not bound !missing-pinvoke! AudioFileComponentOpenWithCallbacks is not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.todo b/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.todo deleted file mode 100644 index d203c85a92dc..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/macOS-AudioToolbox.todo +++ /dev/null @@ -1,9 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileComponentGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileComponentGetUserDataSize64 is not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/api-annotations-dotnet/tvOS-AudioToolbox.todo b/tests/xtro-sharpie/api-annotations-dotnet/tvOS-AudioToolbox.todo deleted file mode 100644 index 18d4bb0c9c0e..000000000000 --- a/tests/xtro-sharpie/api-annotations-dotnet/tvOS-AudioToolbox.todo +++ /dev/null @@ -1,7 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/iOS-AudioToolbox.todo b/tests/xtro-sharpie/iOS-AudioToolbox.todo deleted file mode 100644 index 18d4bb0c9c0e..000000000000 --- a/tests/xtro-sharpie/iOS-AudioToolbox.todo +++ /dev/null @@ -1,7 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/macOS-AudioToolbox.todo b/tests/xtro-sharpie/macOS-AudioToolbox.todo index d203c85a92dc..cc1c76415427 100644 --- a/tests/xtro-sharpie/macOS-AudioToolbox.todo +++ b/tests/xtro-sharpie/macOS-AudioToolbox.todo @@ -1,9 +1,2 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound !missing-pinvoke! AudioFileComponentGetUserDataAtOffset is not bound !missing-pinvoke! AudioFileComponentGetUserDataSize64 is not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound diff --git a/tests/xtro-sharpie/tvOS-AudioToolbox.todo b/tests/xtro-sharpie/tvOS-AudioToolbox.todo deleted file mode 100644 index 18d4bb0c9c0e..000000000000 --- a/tests/xtro-sharpie/tvOS-AudioToolbox.todo +++ /dev/null @@ -1,7 +0,0 @@ -!missing-enum! AUVoiceIOOtherAudioDuckingLevel not bound -!missing-pinvoke! AudioFileGetUserDataAtOffset is not bound -!missing-pinvoke! AudioFileGetUserDataSize64 is not bound -!missing-enum! AudioConverterOptions not bound -!missing-pinvoke! AudioConverterNewWithOptions is not bound -!missing-pinvoke! AudioConverterPrepare is not bound -!missing-selector! AUAudioUnit::migrateFromPlugin not bound