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

[AVFoundation] Add missing APIs up to Xcode 16.2. #21878

Merged
merged 6 commits into from
Jan 13, 2025
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
97 changes: 74 additions & 23 deletions src/AVFoundation/AVAudioPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,52 +29,103 @@
#nullable enable

namespace AVFoundation {
#if !WATCH
public partial class AVAudioPlayer {
/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified url and hint for the file type.</summary>
/// <param name="url">The url of a local audio file.</param>
/// <param name="fileTypeHint">The uniform type identifier for the audio format.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromUrl (NSUrl url, NSString? fileTypeHint, out NSError? error)
{
var rv = new AVAudioPlayer (NSObjectFlag.Empty);
rv.InitializeHandle (rv._InitWithContentsOfUrl (url, fileTypeHint, out error), string.Empty, false);
if (rv.Handle == IntPtr.Zero) {
rv.Dispose ();
return null;
}
return rv;
}

[DllImport (Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
unsafe static extern IntPtr objc_msgSend (IntPtr receiver, IntPtr selector, IntPtr arg1, IntPtr* arg2);
/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified url and hint for the file type.</summary>
/// <param name="url">The url of a local audio file.</param>
/// <param name="fileTypeHint">The uniform type identifier for the audio format.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromUrl (NSUrl url, AVFileTypes fileTypeHint, out NSError? error)
{
return FromUrl (url, fileTypeHint.GetConstant (), out error);
}

/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified url.</summary>
/// <param name="url">The url of a local audio file.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromUrl (NSUrl url, out NSError? error)
{
error = null;
IntPtr url__handle__ = url!.GetNonNullHandle (nameof (url));
IntPtr handle = Messaging.IntPtr_objc_msgSend (class_ptr, Selector.GetHandle ("alloc"));
IntPtr errorptr = IntPtr.Zero;
if (handle == IntPtr.Zero)
var rv = new AVAudioPlayer (NSObjectFlag.Empty);
rv.InitializeHandle (rv._InitWithContentsOfUrl (url, out error), string.Empty, false);
if (rv.Handle == IntPtr.Zero) {
rv.Dispose ();
return null;
unsafe {
handle = objc_msgSend (handle, Selector.GetHandle ("initWithContentsOfURL:error:"), url__handle__, &errorptr);
}
error = Runtime.GetNSObject<NSError> (errorptr);
return Runtime.GetNSObject<AVAudioPlayer> (handle, owns: true);
return rv;
}

/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified url.</summary>
/// <param name="url">The url of a local audio file.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromUrl (NSUrl url)
{
return FromUrl (url, out _);
}

public static AVAudioPlayer? FromData (NSData data, out NSError? error)
/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified data and hint for the file type.</summary>
/// <param name="data">The audio data to play.</param>
/// <param name="fileTypeHint">The uniform type identifier for the audio format.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromData (NSData data, AVFileTypes fileTypeHint, out NSError? error)
{
error = null;
IntPtr data__handle__ = data!.GetNonNullHandle (nameof (data));
IntPtr errorptr = IntPtr.Zero;
IntPtr handle = Messaging.IntPtr_objc_msgSend (class_ptr, Selector.GetHandle ("alloc"));
return FromData (data, fileTypeHint.GetConstant (), out error);
}

if (handle == IntPtr.Zero)
/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified data and hint for the file type.</summary>
/// <param name="data">The audio data to play.</param>
/// <param name="fileTypeHint">The uniform type identifier for the audio format.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromData (NSData data, NSString? fileTypeHint, out NSError? error)
{
var rv = new AVAudioPlayer (NSObjectFlag.Empty);
rv.InitializeHandle (rv._InitWithData (data, fileTypeHint, out error), string.Empty, false);
if (rv.Handle == IntPtr.Zero) {
rv.Dispose ();
return null;
}
return rv;
}

/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified data.</summary>
/// <param name="data">The audio data to play.</param>
/// <param name="error">An object describing the error in case an error occurs, null otherwise.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromData (NSData data, out NSError? error)
{
var rv = new AVAudioPlayer (NSObjectFlag.Empty);
rv.InitializeHandle (rv._InitWithData (data, out error), string.Empty, false);
if (rv.Handle == IntPtr.Zero) {
rv.Dispose ();
return null;
unsafe {
handle = objc_msgSend (handle, Selector.GetHandle ("initWithData:error:"), data__handle__, &errorptr);
}
error = Runtime.GetNSObject<NSError> (errorptr);
return Runtime.GetNSObject<AVAudioPlayer> (handle, owns: true);
return rv;
}

/// <summary>Create a new <see cref="AVAudioPlayer" /> from the specified data.</summary>
/// <param name="data">The audio data to play.</param>
/// <returns>A new <see cref="AVAudioPlayer" /> instance if successful, null otherwise.</returns>
public static AVAudioPlayer? FromData (NSData data)
{
return FromData (data, out _);
}
}
#endif // !WATCH
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Runtime.InteropServices;
using ObjCRuntime;

#if !TVOS

namespace AVFoundation {
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("macos14.0")]
[UnsupportedOSPlatform ("tvos")]
[SupportedOSPlatform ("maccatalyst17.0")]
public struct AVAudioVoiceProcessingOtherAudioDuckingConfiguration {
byte enableAdvancedDucking;
#pragma warning disable CS0169 // The field 'AVAudioVoiceProcessingOtherAudioDuckingConfiguration.duckingLevel' is never used
nint duckingLevel;
#pragma warning restore CS0169

public bool EnableAdvancedDucking {
get => enableAdvancedDucking != 0;
set => enableAdvancedDucking = value.AsByte ();
}

#if !COREBUILD
public AVAudioVoiceProcessingOtherAudioDuckingLevel DuckingLevel {
get => (AVAudioVoiceProcessingOtherAudioDuckingLevel) (long) duckingLevel;
set => duckingLevel = (nint) (long) value;
}
#endif
}
}
#endif
25 changes: 25 additions & 0 deletions src/AVFoundation/AVCaptureReactionType.rgen.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma warning disable APL0003
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

using CoreFoundation;
using ObjCRuntime;
using ObjCBindings;

Expand Down Expand Up @@ -39,5 +41,28 @@ public enum AVCaptureReactionType {
[Field<EnumValue> ("AVCaptureReactionTypeLasers")]
Lasers,
}

public static class AVCaptureReactionType_Extensions {
[DllImport (Constants.AVFoundationLibrary)]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
[SupportedOSPlatform ("macos14.0")]
static extern IntPtr AVCaptureReactionSystemImageNameForType (IntPtr reactionType);

/// <summary>Get the name of the system image that is the recommended iconography for the specified reaction type.</summary>
/// <param name="reactionType">The reaction type whose system image should be returned.</param>
/// <returns>The name of the system image that is the recommended iconography for the specified reaction type.</returns>
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
[SupportedOSPlatform ("macos14.0")]
public static string GetSystemImage (this AVCaptureReactionType reactionType)
{
var constant = reactionType.GetConstant ();
var image = AVCaptureReactionSystemImageNameForType (constant.GetHandle ());
return CFString.FromHandle (image, false)!;
}
}
}
#pragma warning restore APL0003
81 changes: 81 additions & 0 deletions src/AVFoundation/AVSpeechSynthesisMarker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Threading.Tasks;

using Foundation;
using ObjCRuntime;

#nullable enable

namespace AVFoundation {
/// <summary>This enum is used to select how to initialize a new <see cref="AVSpeechSynthesisMarker" /> instance.</summary>
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("tvos17.0")]
public enum AVSpeechSynthesisMarkerRangeOption {
/// <summary>The <c>range</c> parameter passed to the constructor is a word range.</summary>
Word,
/// <summary>The <c>range</c> parameter passed to the constructor is a sentence range.</summary>
Sentence,
/// <summary>The <c>range</c> parameter passed to the constructor is a paragraph range.</summary>
Paragraph,
}

/// <summary>This enum is used to select how to initialize a new <see cref="AVSpeechSynthesisMarker" /> instance.</summary>
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("tvos17.0")]
public enum AVSpeechSynthesisMarkerStringOption {
/// <summary>The <c>value</c> parameter passed to the constructor is a phoneme.</summary>
Phoneme,
/// <summary>The <c>value</c> parameter passed to the constructor is a bookmark name.</summary>
Bookmark,
}

public partial class AVSpeechSynthesisMarker {
/// <summary>Create a new <see cref="AVSpeechSynthesisMarker" /> instance for the specified range and byte offset.</summary>
/// <param name="range">The range of the marker.</param>
/// <param name="byteSampleOffset">The byte offset into the audio buffer.</param>
/// <param name="option">Use this option to specify how to interpret the <paramref name="range" /> parameter.</param>
public AVSpeechSynthesisMarker (NSRange range, nint byteSampleOffset, AVSpeechSynthesisMarkerRangeOption option)
: base (NSObjectFlag.Empty)
{
switch (option) {
case AVSpeechSynthesisMarkerRangeOption.Word:
InitializeHandle (_InitWithWordRange (range, byteSampleOffset));
break;
case AVSpeechSynthesisMarkerRangeOption.Sentence:
InitializeHandle (_InitWithSentenceRange (range, byteSampleOffset));
break;
case AVSpeechSynthesisMarkerRangeOption.Paragraph:
InitializeHandle (_InitWithParagraphRange (range, byteSampleOffset));
break;
default:
throw new ArgumentOutOfRangeException (nameof (option), option, "Invalid enum value.");
}
}

/// <summary>Create a new <see cref="AVSpeechSynthesisMarker" /> instance for the specified string value.</summary>
/// <param name="value">The phoneme or bookmark name of the marker.</param>
/// <param name="byteSampleOffset">The byte offset into the audio buffer.</param>
/// <param name="option">Use this option to specify how to interpret the <paramref name="value" /> parameter.</param>
public AVSpeechSynthesisMarker (string value, nint byteSampleOffset, AVSpeechSynthesisMarkerStringOption option)
: base (NSObjectFlag.Empty)
{
switch (option) {
case AVSpeechSynthesisMarkerStringOption.Phoneme:
InitializeHandle (_InitWithPhonemeString (value, byteSampleOffset));
break;
case AVSpeechSynthesisMarkerStringOption.Bookmark:
InitializeHandle (_InitWithBookmarkName (value, byteSampleOffset));
break;
default:
throw new ArgumentOutOfRangeException (nameof (option), option, "Invalid enum value.");
}
}
}
}
31 changes: 31 additions & 0 deletions src/AVFoundation/AVSpeechSynthesisProviderAudioUnit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Threading.Tasks;

using AudioUnit;
using Foundation;
using ObjCRuntime;

#nullable enable

namespace AVFoundation {
public partial class AVSpeechSynthesisProviderAudioUnit {
/// <summary>Create a new <see cref="AVSpeechSynthesisProviderAudioUnit" /> instance.</summary>
/// <param name="componentDescription">A description of the component to create.</param>
/// <param name="options">Any options for the returned audio unit.</param>
/// <param name="error">The error if an error occurred, null otherwise.</param>
/// <returns>A new <see cref="AVSpeechSynthesisProviderAudioUnit" /> instance if successful, null otherwise.</returns>
public static AVSpeechSynthesisProviderAudioUnit? Create (AudioComponentDescription componentDescription, AudioComponentInstantiationOptions options, out NSError? error)
{
var rv = new AVSpeechSynthesisProviderAudioUnit (NSObjectFlag.Empty);
rv.InitializeHandle (rv._InitWithComponentDescription (componentDescription, options, out error), string.Empty, false);
if (rv.Handle == IntPtr.Zero) {
rv.Dispose ();
return null;
}
return rv;
}
}
}
51 changes: 51 additions & 0 deletions src/AVFoundation/AVSpeechUtterance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Threading.Tasks;

using Foundation;
using ObjCRuntime;

#nullable enable

namespace AVFoundation {
/// <summary>This enum is used to select how to initialize a new <see cref="AVSpeechUtterance" /> instance.</summary>
public enum AVSpeechUtteranceInitializationOption {
/// <summary>The <c>string</c> parameter passed to the constructor is a plain text string.</summary>
PlainText,
/// <summary>The <c>string</c> parameter passed to the constructor is an SSML (Speech Synthesis Markup Language) string.</summary>
[SupportedOSPlatform ("ios16.0")]
[SupportedOSPlatform ("maccatalyst16.0")]
[SupportedOSPlatform ("macos13.0")]
[SupportedOSPlatform ("tvos16.0")]
SsmlRepresentation,
}

public partial class AVSpeechUtterance {
/// <summary>Create a new <see cref="AVSpeechUtterance" /> instance for the specified string.</summary>
/// <param name="speechString">The text to speak.</param>
public AVSpeechUtterance (string speechString)
: this (speechString, AVSpeechUtteranceInitializationOption.PlainText)
{
}

/// <summary>Create a new <see cref="AVSpeechUtterance" /> instance for the specified string.</summary>
/// <param name="string">The text to speak.</param>
/// <param name="option">Use this option to specify how to interpret the <paramref name="string" /> parameter.</param>
public AVSpeechUtterance (string @string, AVSpeechUtteranceInitializationOption option)
: base (NSObjectFlag.Empty)
{
switch (option) {
case AVSpeechUtteranceInitializationOption.PlainText:
InitializeHandle (_InitWithString (@string));
break;
case AVSpeechUtteranceInitializationOption.SsmlRepresentation:
InitializeHandle (_InitWithSsmlRepresentation (@string));
break;
default:
throw new ArgumentOutOfRangeException (nameof (option), option, "Invalid enum value.");
}
}
}
}
Loading
Loading