Skip to content
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
702 changes: 257 additions & 445 deletions src/AudioToolbox/AudioConverter.cs

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions src/AudioToolbox/AudioFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,89 @@ public AudioFileError WritePackets (bool useCache, int numBytes, AudioStreamPack
}
}

[SupportedOSPlatform ("ios26.0")]
[SupportedOSPlatform ("tvos26.0")]
[SupportedOSPlatform ("maccatalyst26.0")]
[SupportedOSPlatform ("macos26.0")]
[DllImport (Constants.AudioToolboxLibrary)]
unsafe extern static /* OSStatus */ AudioFileError AudioFileWritePacketsWithDependencies (
AudioFileID inAudioFile,
byte /* Boolean */ inUseCache,
uint /* UInt32 */ inNumBytes,
AudioStreamPacketDescription* /* const AudioStreamPacketDescription * __nullable */ inPacketDescriptions,
AudioStreamPacketDependencyDescription* /* const AudioStreamPacketDependencyDescription * */ inPacketDependencies,
long /* SInt64 */ inStartingPacket,
uint* /* UInt32 * */ ioNumPackets,
IntPtr /* const void * */inBuffer);

/// <summary>Writes audio packets to the file.</summary>
/// <param name="useCache">Whether the data should be kept in the cache.</param>
/// <param name="packetDescriptions">An array of packet descriptions that describe the content of the buffer.</param>
/// <param name="packetDependencies">An array of packet dependencies for the audio data.</param>
/// <param name="startingPacket">The index the first packet in the buffer to write.</param>
/// <param name="numPackets">The number of packets to write replaced with the number of packets actually written.</param>
/// <param name="buffer">The buffer containing the audio data to write.</param>
/// <param name="numBytes">The number of bytes to write.</param>
/// <returns><see cref="AudioFileError.Success" /> if successful, otherwise a status error code.</returns>
[SupportedOSPlatform ("ios26.0")]
[SupportedOSPlatform ("tvos26.0")]
[SupportedOSPlatform ("maccatalyst26.0")]
[SupportedOSPlatform ("macos26.0")]
public AudioFileError WritePackets (bool useCache, AudioStreamPacketDescription []? packetDescriptions, AudioStreamPacketDependencyDescription [] packetDependencies, long startingPacket, ref int numPackets, IntPtr buffer, int numBytes)
{
if (buffer == IntPtr.Zero)
throw new ArgumentException (nameof (buffer));

if (packetDependencies is null)
ThrowHelper.ThrowArgumentNullException (nameof (packetDependencies));

unsafe {
fixed (AudioStreamPacketDescription* packetDescriptionsPtr = packetDescriptions) {
fixed (AudioStreamPacketDependencyDescription* packetDependenciesPtr = packetDependencies) {
return AudioFileWritePacketsWithDependencies (
GetCheckedHandle (),
useCache.AsByte (),
(uint) numBytes,
packetDescriptionsPtr,
packetDependenciesPtr,
startingPacket,
(uint*) Unsafe.AsPointer<int> (ref numPackets),
buffer);
}
}
}
}

/// <summary>Writes audio packets to the file.</summary>
/// <param name="useCache">Whether the data should be kept in the cache.</param>
/// <param name="numBytes">The number of bytes to write.</param>
/// <param name="packetDescriptions">An array of packet descriptions that describe the content of the buffer.</param>
/// <param name="packetDependencies">An array of packet dependencies for the audio data.</param>
/// <param name="startingPacket">The index the first packet in the buffer to write.</param>
/// <param name="numPackets">The number of packets to write replaced with the number of packets actually written.</param>
/// <param name="buffer">The buffer containing the audio data to write.</param>
/// <param name="offset">An offset into <see paramref="buffer" /> where the audio data to write starts.</param>
/// <returns><see cref="AudioFileError.Success" /> if successful, otherwise a status error code.</returns>
[SupportedOSPlatform ("ios26.0")]
[SupportedOSPlatform ("tvos26.0")]
[SupportedOSPlatform ("maccatalyst26.0")]
[SupportedOSPlatform ("macos26.0")]
public AudioFileError WritePackets (bool useCache, AudioStreamPacketDescription []? packetDescriptions, AudioStreamPacketDependencyDescription [] packetDependencies, long startingPacket, ref int numPackets, byte [] buffer, int offset, int numBytes)
{
if (buffer is null)
ThrowHelper.ThrowArgumentNullException (nameof (buffer));
if (offset < 0)
throw new ArgumentOutOfRangeException (nameof (offset), "< 0");
if (numBytes < 0)
throw new ArgumentOutOfRangeException (nameof (numBytes), "< 0");
if (offset > buffer.Length - numBytes)
throw new ArgumentException ("Reading would overrun buffer");
unsafe {
fixed (byte* bufferPtr = &buffer [offset])
return WritePackets (useCache, packetDescriptions, packetDependencies, startingPacket, ref numPackets, (IntPtr) bufferPtr, numBytes);
}
}

[DllImport (Constants.AudioToolboxLibrary)]
unsafe extern static OSStatus AudioFileCountUserData (AudioFileID handle, uint userData, int* count);

Expand Down
6 changes: 3 additions & 3 deletions src/AudioToolbox/AudioFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ public enum AudioFormatError : int // Implictly cast to OSType
UnsupportedDataFormat = 0x666d743f, // 'fmt?'
/// <summary>To be added.</summary>
UnknownFormat = 0x21666d74, // '!fmt'

// TODO: Not documented
// '!dat'
/// <summary>The format is unsupported.</summary>
UnsupportedFormat = 0x21646174, // '!dat'
}

/// <summary>A struct that holds minimum and maximum float values, indicating a range.</summary>
Expand Down Expand Up @@ -441,6 +440,7 @@ enum AudioFormatProperty : uint // UInt32 AudioFormatPropertyID
FirstPlayableFormatFromList = 0x6670666c, // 'fpfl'
FormatIsVBR = 0x66766272, // 'fvbr'
FormatIsExternallyFramed = 0x66657866, // 'fexf'
FormatEmploysDependentPackets = 0x66646570, // 'fdep'
FormatIsEncrypted = 0x63727970, // 'cryp'
Encoders = 0x6176656e, // 'aven'
Decoders = 0x61766465, // 'avde'
Expand Down
58 changes: 58 additions & 0 deletions src/AudioToolbox/AudioType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,21 @@ public unsafe bool IsVariableBitrate {
}
}

/// <summary>Whether this format is able to combining independently decodable packets with dependent packets.</summary>
public unsafe bool EmploysDependentPackets {
get {
uint data;
var size = sizeof (uint);

fixed (AudioStreamBasicDescription* self = &this) {
if (AudioFormatPropertyNative.AudioFormatGetProperty (AudioFormatProperty.FormatEmploysDependentPackets, sizeof (AudioStreamBasicDescription), self, &size, &data) != 0)
return false;
}

return data != 0;
}
}

/// <summary>Renders a debugging-friendly description of the contents of the AudioStreamBasicDescription.</summary>
/// <returns>
/// </returns>
Expand Down Expand Up @@ -556,6 +571,49 @@ public override string ToString ()
}
}

/// <summary>A structure that describes dependencies between audio packets.</summary>
[SupportedOSPlatform ("ios26.0")]
[SupportedOSPlatform ("maccatalyst26.0")]
[SupportedOSPlatform ("macos26.0")]
[SupportedOSPlatform ("tvos26.0")]
public struct AudioStreamPacketDependencyDescription {
uint isIndependentlyDecodable;
uint preRollCount;
uint flags;
uint reserved;

/// <summary>Specifies whether an audio packet is independency decodable, or if more audio packets are required to reset the decoder.</summary>
public bool IsIndependentlyDecodable {
get => isIndependentlyDecodable != 0;
set => isIndependentlyDecodable = value ? (uint) 1 : (uint) 0;
}

/// <summary>Specifies how many additional audio packets are required to reset the decoder for audio packets that aren't independenly decodable.</summary>
/// <remarks>Ignored for independenly decodable audio packets.</remarks>
public uint PreRollCount {
get => preRollCount;
set => preRollCount = value;
}

/// <summary>Currently unused.</summary>
public uint Flags {
get => flags;
set => flags = value;
}

/// <summary>Currently unused.</summary>
public uint Reserved {
get => reserved;
set => reserved = value;
}

/// <summary>Provides a string representation of the packet dependency description.</summary>
public override string ToString ()
{
return $"AudioStreamPacketDependencyDescription[IsIndependentlyDecodable={IsIndependentlyDecodable};PreRollCount={PreRollCount};Flags={Flags}]";
}
}

/// <summary>Flags for the <see cref="AudioToolbox.AudioChannelDescription.Flags" /> property.</summary>
/// <remarks>To be added.</remarks>
[Flags]
Expand Down
130 changes: 130 additions & 0 deletions src/AudioToolbox/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,134 @@ public enum AUVoiceIOOtherAudioDuckingLevel : uint {
Mid = 20,
Max = 30,
}

/// <summary>This enum specifies properties for <see cref="AudioUnitSubType.AUAudioMix" /> audio units.</summary>
[Mac (26, 0), iOS (26, 0), MacCatalyst (26, 0), NoTV]
public enum AUAudioMixProperty {
/// <summary>Remix the data from the file asset.</summary>
/// <remarks>This is a read-write <see cref="NSData" /> property.</remarks>
SpatialAudioMixMetadata = 5000,
/// <summary>If spatialization is enabled or not.</summary>
/// <remarks>This is a read-write <see langword="uint" /> property, with two possible values: 0 or 1.</remarks>
EnableSpatialization = 5001,
}

/// <summary>This enum specifies parameters for <see cref="AudioUnitSubType.AUAudioMix" /> audio units.</summary>
public enum AUAudioMixParameter {
/// <summary>Get or set the style of the audio mixing.</summary>
/// <remarks>This property is an enum of type <see cref="AUAudioMixRenderingStyle" />.</remarks>
[Mac (26, 0), iOS (26, 0), MacCatalyst (26, 0), NoTV]
Style = 0,
/// <summary>The remix amount.</summary>
/// <remarks>This property is a <see langword="float" />, with valid values ranging from 0.0f to 1.0f. The default value is 0.5f.</remarks>
[Mac (26, 0), iOS (26, 0), MacCatalyst (26, 0), NoTV]
RemixAmount = 1,
}

/// <summary>This enum provides the possible values for the <see cref="AUAudioMixParameter.Style" /> parameter.</summary>
[Mac (26, 0), iOS (26, 0), MacCatalyst (26, 0), NoTV]
public enum AUAudioMixRenderingStyle : uint {
/// <summary>Render with a cinematic style. This is the default value.</summary>
Cinematic = 0,
/// <summary>Render with a studio style.</summary>
Studio = 1,
/// <summary>Render with an in-frame style.</summary>
InFrame = 2,
/// <summary>Render the background only with a cinematic style.</summary>
CinematicBackgroundStem = 3,
/// <summary>Render the foreground only with a cinematic style.</summary>
CinematicForegroundStem = 4,
/// <summary>Render the foreground only with a stydio style.</summary>
StudioForegroundStem = 5,
/// <summary>Render the foreground only with an in-frame style.</summary>
InFrameForegroundStem = 6,
/// <summary>Render with a standard style.</summary>
Standard = 7,
/// <summary>Render the background only with a studio style.</summary>
StudioBackgroundStem = 8,
/// <summary>Render the background only with an in-frame style.</summary>
InFrameBackgroundStem = 9,
}

public enum AudioCodecPropertyId : uint {
InputBufferSize = 0x74627566, // 'tbuf'
PacketFrameSize = 0x70616b66, // 'pakf'
HasVariablePacketByteSizes = 0x76706b3f, // 'vpk?'
EmploysDependentPackets = 0x64706b3f, // 'dpk?'
MaximumPacketByteSize = 0x70616b62, // 'pakb'
PacketSizeLimitForVbr = 0x70616b6c, // 'pakl'
CurrentInputFormat = 0x69666d74, // 'ifmt'
CurrentOutputFormat = 0x6f666d74, // 'ofmt'
MagicCookie = 0x6b756b69, // 'kuki'
UsedInputBufferSize = 0x75627566, // 'ubuf'
IsInitialized = 0x696e6974, // 'init'
CurrentTargetBitRate = 0x62726174, // 'brat'
CurrentInputSampleRate = 0x63697372, // 'cisr'
CurrentOutputSampleRate = 0x636f7372, // 'cosr'
QualitySetting = 0x73726371, // 'srcq'
ApplicableBitRateRange = 0x62727461, // 'brta'
RecommendedBitRateRange = 0x62727472, // 'brtr'
ApplicableInputSampleRates = 0x69737261, // 'isra'
ApplicableOutputSampleRates = 0x6f737261, // 'osra'
PaddedZeros = 0x70616430, // 'pad0'
PrimeMethod = 0x70726d6d, // 'prmm'
PrimeInfo = 0x7072696d, // 'prim'
CurrentInputChannelLayout = 0x69636c20, // 'icl '
CurrentOutputChannelLayout = 0x6f636c20, // 'ocl '
Settings = 0x61637320, // 'acs '
FormatList = 0x6163666c, // 'acfl'
BitRateControlMode = 0x61636266, // 'acbf'
SoundQualityForVbr = 0x76627271, // 'vbrq'
BitRateForVbr = 0x76627262, // 'vbrb'
DelayMode = 0x646d6f64, // 'dmod'
AdjustLocalQuality = 0x5e71616c, // '^qal'
DynamicRangeControlMode = 0x6d647263, // 'mdrc'
AdjustCompressionProfile = 0x5e70726f, // '^pro'
ProgramTargetLevelConstant = 0x70746c63, // 'ptlc'
AdjustTargetLevelConstant = 0x5e746c63, // '^tlc'
ProgramTargetLevel = 0x7070746c, // 'pptl'
AdjustTargetLevel = 0x5e70746c, // '^ptl'
[iOS (26, 0), TV (26, 0), Mac (26, 0), MacCatalyst (26, 0)]
DynamicRangeControlConfiguration = 0x63647263, // 'cdrc'
[iOS (26, 0), TV (26, 0), Mac (26, 0), MacCatalyst (26, 0)]
ContentSource = 0x63737263, // 'csrc'
[iOS (26, 0), TV (26, 0), Mac (26, 0), MacCatalyst (26, 0)]
AspFrequency = 0x61737066, // 'aspf'
}

[iOS (26, 0), TV (26, 0), Mac (26, 0), MacCatalyst (26, 0)]
public enum AudioCodecDynamicRangeControlConfiguration : uint {
None = 0,
Music = 1,
Speech = 2,
Movie = 3,
Capture = 4,
}

[iOS (26, 0), TV (26, 0), Mac (26, 0), MacCatalyst (26, 0)]
public enum AudioCodecContentSource : int {
Unspecified = -1,
Reserved = 0,
AppleCaptureTraditional = 1,
AppleCaptureSpatial = 2,
AppleCaptureSpatialEnhanced = 3,
AppleMusicTraditional = 4,
AppleMusicSpatial = 5,
AppleAVTraditionalOffline = 6,
AppleAVSpatialOffline = 7,
AppleAVTraditionalLive = 8,
AppleAVSpatialLive = 9,
ApplePassthrough = 10,

CaptureTraditional = 33,
CaptureSpatial = 34,
CaptureSpatialEnhanced = 35,
MusicTraditional = 36,
MusicSpatial = 37,
AVTraditionalOffline = 38,
AVSpatialOffline = 39,
AVTraditionalLive = 40,
AVSpatialLive = 41,
Passthrough = 42,
}
}
12 changes: 11 additions & 1 deletion src/AudioUnit/AUEnums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,17 @@ public enum AudioUnitSubType : uint {
ScheduledSoundPlayer = 0x7373706C, // 'sspl'
/// <summary>To be added.</summary>
AudioFilePlayer = 0x6166706C, // 'afpl'

/// <summary>A light reverb.</summary>
/// <remarks>The FourCC value for 'rvb2', for the native constant kAudioUnitSubType_Reverb2.</remarks>
Revert2 = 0x72766232, // 'rvb2'

Choose a reason for hiding this comment

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

Typo? "Revert2" -> "Reverb2"

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yes, fix in progress: #23414

/// <summary>An audio unit that can be used to isolate a sound type.</summary>
/// <remarks>The FourCC value for 'vois', for the native constant kAudioUnitSubType_AUSoundIsolation.</remarks>
[iOS (16, 0), Mac (13, 0), MacCatalyst (16, 0), NoTV]
AUSoundIsolation = 0x766f6973, // 'vois'
/// <summary>An audio unit that supports AudioMix separate-and-remix.</summary>
/// <remarks>The FourCC value for 'amix', for the native constant kAudioUnitSubType_AUAudioMix.</remarks>
[iOS (26, 0), Mac (26, 0), MacCatalyst (26, 0), NoTV]
AUAudioMix = 0x616d6978, // 'amix'
#if MONOMAC
/// <summary>To be added.</summary>
HALOutput = 0x6168616C, // 'ahal'
Expand Down
Loading
Loading