Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into selector-intrinsic

  • Loading branch information...
commit 7e1d59c6b7c349121b30fd0c6b83112dc2440a22 2 parents ced4e03 + 4125235
@rolfbjarne rolfbjarne authored
Showing with 2,758 additions and 205 deletions.
  1. +4 −4 src/AVFoundation/Events.cs
  2. +729 −0 src/AudioToolbox/AudioConverter.cs
  3. +56 −16 src/AudioToolbox/AudioFile.cs
  4. +6 −2 src/AudioToolbox/AudioFormat.cs
  5. +1 −0  src/AudioToolbox/AudioFormatAvailability.cs
  6. +185 −73 src/AudioToolbox/AudioSession.cs
  7. +2 −2 src/AudioToolbox/AudioSessions.cs
  8. +2 −2 src/AudioToolbox/AudioType.cs
  9. +8 −2 src/AudioUnit/AudioComponentDescription.cs
  10. +22 −8 src/AudioUnit/ExtAudioFile.cs
  11. +1 −0  src/AudioUnit/_AudioConverter.cs
  12. +1 −0  src/AudioUnit/_AudioConverterEventArgs.cs
  13. +4 −0 src/Foundation/Enum.cs
  14. +0 −6 src/Foundation/NSInputStream.cs
  15. +297 −12 src/Foundation/NSObject2.cs
  16. +44 −0 src/Foundation/NSSearchPath.cs
  17. +2 −2 src/Security/Certificate.cs
  18. +9 −7 src/avfoundation.cs
  19. +1 −0  src/error.cs
  20. +183 −21 src/foundation.cs
  21. +160 −48 src/generator.cs
  22. +66 −0 tests/bindings/ApiBaseTest.cs
  23. +146 −0 tests/bindings/ApiCtorInitTest.cs
  24. +125 −0 tests/bindings/ApiFieldTest.cs
  25. +230 −0 tests/bindings/ApiSelectorTest.cs
  26. +473 −0 tests/bindings/ApiSignatureTest.cs
  27. +1 −0  tests/bindings/README
View
8 src/AVFoundation/Events.cs
@@ -73,7 +73,7 @@ public override void DecoderError (AVAudioPlayer player, NSError error)
if (cbDecoderError != null)
cbDecoderError (player, new AVErrorEventArgs (error));
}
-
+#if !MONOMAC
[Preserve (Conditional = true)]
public override void BeginInterruption (AVAudioPlayer player)
{
@@ -87,7 +87,7 @@ public override void EndInterruption (AVAudioPlayer player)
if (cbEndInterruption != null)
cbEndInterruption (player, EventArgs.Empty);
}
-
+#endif
}
#pragma warning restore 672
@@ -161,7 +161,7 @@ public override void EncoderError (AVAudioRecorder recorder, NSError error)
if (cbEncoderError != null)
cbEncoderError (recorder, new AVErrorEventArgs (error));
}
-
+#if !MONOMAC
[Preserve (Conditional = true)]
public override void BeginInterruption (AVAudioRecorder recorder)
{
@@ -176,7 +176,7 @@ public override void EndInterruption (AVAudioRecorder recorder)
if (cbEndInterruption != null)
cbEndInterruption (recorder, EventArgs.Empty);
}
-
+#endif
}
public partial class AVAudioRecorder {
View
729 src/AudioToolbox/AudioConverter.cs
@@ -0,0 +1,729 @@
+//
+// AudioConverter.cs: AudioConverter wrapper class
+//
+// Authors:
+// Marek Safar (marek.safar@gmail.com)
+//
+// Copyright 2013 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+
+namespace MonoMac.AudioToolbox
+{
+ public enum AudioConverterError
+ {
+ None = 0,
+ FormatNotSupported = 0x666d743f, // 'fmt?'
+ OperationNotSupported = 0x6f703f3f, // 'op??'
+ PropertyNotSupported = 0x70726f70, // 'prop'
+ InvalidInputSize = 0x696e737a, // 'insz'
+ InvalidOutputSize = 0x6f74737a, // 'otsz'
+ UnspecifiedError = 0x77686174, // 'what'
+ BadPropertySizeError = 0x2173697a, // '!siz'
+ RequiresPacketDescriptionsError = 0x21706b64, // '!pkd'
+ InputSampleRateOutOfRange = 0x21697372, // '!isr'
+ OutputSampleRateOutOfRange = 0x216f7372, // '!osr'
+ HardwareInUse = 0x68776975, // 'hwiu'
+ NoHardwarePermission = 0x7065726d, // 'perm'
+
+ // TODO: Not documented
+ // '!dat'
+ }
+
+ public enum AudioConverterSampleRateConverterComplexity
+ {
+ Linear = 0x6c696e65, // 'line'
+ Normal = 0x6e6f726d, // 'norm'
+ Mastering = 0x62617473, // 'bats'
+ }
+
+ public enum AudioConverterQuality
+ {
+ Max = 0x7F,
+ High = 0x60,
+ Medium = 0x40,
+ Low = 0x20,
+ Min = 0
+ }
+
+ public enum AudioConverterPrimeMethod
+ {
+ Pre = 0,
+ Normal = 1,
+ None = 2
+ }
+
+ public struct AudioConverterPrimeInfo
+ {
+ public int LeadingFrames;
+ public int TrailingFrames;
+ }
+
+ public delegate AudioConverterError AudioConverterComplexInputData (ref int numberDataPackets, AudioBuffers data,
+ ref AudioStreamPacketDescription[] dataPacketDescription);
+
+ public class AudioConverter : IDisposable
+ {
+ delegate AudioConverterError AudioConverterComplexInputDataShared (IntPtr inAudioConverter, ref int ioNumberDataPackets, IntPtr ioData,
+ IntPtr outDataPacketDescription, IntPtr inUserData);
+
+ IntPtr handle;
+ readonly bool owns;
+ static readonly AudioConverterComplexInputDataShared ComplexInputDataShared = FillComplexBufferShared;
+
+ public event AudioConverterComplexInputData InputData;
+
+ private AudioConverter (IntPtr handle)
+ : this (handle, false)
+ {
+ }
+
+ internal AudioConverter (IntPtr handle, bool owns)
+ {
+ if (handle == IntPtr.Zero)
+ throw new ArgumentException ("address");
+
+ this.handle = handle;
+ this.owns = owns;
+ }
+
+ public uint MinimumInputBufferSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.MinimumInputBufferSize);
+ }
+ }
+
+ public uint MinimumOutputBufferSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.MinimumOutputBufferSize);
+ }
+ }
+
+ public uint MaximumInputPacketSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.MaximumInputPacketSize);
+ }
+ }
+
+ public uint MaximumOutputPacketSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.MaximumOutputPacketSize);
+ }
+ }
+
+ public uint CalculateInputBufferSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.CalculateInputBufferSize);
+ }
+ }
+
+ public uint CalculateOutputBufferSize {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.CalculateOutputBufferSize);
+ }
+ }
+
+ public double SampleRateConverterInitialPhase {
+ get {
+ return GetDoubleProperty (AudioConverterPropertyID.SampleRateConverterInitialPhase);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.SampleRateConverterInitialPhase, value);
+ }
+ }
+
+ public AudioConverterSampleRateConverterComplexity SampleRateConverterComplexity {
+ get {
+ return (AudioConverterSampleRateConverterComplexity) GetUIntProperty (AudioConverterPropertyID.SampleRateConverterComplexity);
+ }
+ }
+
+ public AudioConverterQuality SampleRateConverterQuality {
+ get {
+ return (AudioConverterQuality) GetUIntProperty (AudioConverterPropertyID.SampleRateConverterQuality);
+ }
+ }
+
+ public AudioConverterQuality CodecQuality {
+ get {
+ return (AudioConverterQuality) GetUIntProperty (AudioConverterPropertyID.CodecQuality);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.CodecQuality, (uint) value);
+ }
+ }
+
+ public AudioConverterPrimeMethod PrimeMethod {
+ get {
+ return (AudioConverterPrimeMethod) GetUIntProperty (AudioConverterPropertyID.PrimeMethod);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.PrimeMethod, (uint) value);
+ }
+ }
+
+ public AudioConverterPrimeInfo PrimeInfo {
+ get {
+ AudioConverterPrimeInfo value;
+ var size = Marshal.SizeOf (typeof (AudioConverterPrimeInfo));
+ var res = AudioConverterGetProperty (handle, AudioConverterPropertyID.PrimeInfo, ref size, out value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ return value;
+ }
+ }
+
+ public int[] ChannelMap {
+ get {
+ return GetArray<int> (AudioConverterPropertyID.ChannelMap, sizeof (int));
+ }
+ }
+
+ public byte[] CompressionMagicCookie {
+ get {
+ int size;
+ bool writable;
+ if (AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.CompressionMagicCookie, out size, out writable) != AudioConverterError.None)
+ return null;
+
+ var cookie = new byte [size];
+ if (AudioConverterGetProperty (handle, AudioConverterPropertyID.CompressionMagicCookie, ref size, cookie) != AudioConverterError.None)
+ return null;
+
+ return cookie;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ var res = AudioConverterSetProperty (handle, AudioConverterPropertyID.CompressionMagicCookie, value.Length, value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+ }
+ }
+
+ public byte[] DecompressionMagicCookie {
+ get {
+ int size;
+ bool writable;
+ if (AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.DecompressionMagicCookie, out size, out writable) != AudioConverterError.None)
+ return null;
+
+ var cookie = new byte [size];
+ if (AudioConverterGetProperty (handle, AudioConverterPropertyID.DecompressionMagicCookie, ref size, cookie) != AudioConverterError.None)
+ return null;
+
+ return cookie;
+ }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ var res = AudioConverterSetProperty (handle, AudioConverterPropertyID.DecompressionMagicCookie, value.Length, value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+ }
+ }
+
+ public uint EncodeBitRate {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.EncodeBitRate);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.EncodeBitRate, value);
+ }
+ }
+
+ public double EncodeAdjustableSampleRate {
+ get {
+ return GetDoubleProperty (AudioConverterPropertyID.EncodeAdjustableSampleRate);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.EncodeAdjustableSampleRate, value);
+ }
+ }
+
+ public AudioChannelLayout InputChannelLayout {
+ get {
+ int size;
+ bool writable;
+ if (AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.InputChannelLayout, out size, out writable) != AudioConverterError.None)
+ return null;
+
+ IntPtr ptr = Marshal.AllocHGlobal (size);
+ var res = AudioConverterGetProperty (handle, AudioConverterPropertyID.InputChannelLayout, ref size, ptr);
+ var layout = res == AudioConverterError.None ? new AudioChannelLayout (ptr) : null;
+ Marshal.FreeHGlobal (ptr);
+ return layout;
+ }
+ }
+
+ public AudioChannelLayout OutputChannelLayout {
+ get {
+ int size;
+ bool writable;
+ if (AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.OutputChannelLayout, out size, out writable) != AudioConverterError.None)
+ return null;
+
+ IntPtr ptr = Marshal.AllocHGlobal (size);
+ var res = AudioConverterGetProperty (handle, AudioConverterPropertyID.OutputChannelLayout, ref size, ptr);
+ var layout = res == AudioConverterError.None ? new AudioChannelLayout (ptr) : null;
+ Marshal.FreeHGlobal (ptr);
+ return layout;
+ }
+ }
+
+ public AudioValueRange[] ApplicableEncodeBitRates {
+ get {
+ return GetAudioValueRange (AudioConverterPropertyID.ApplicableEncodeBitRates);
+ }
+ }
+
+ public AudioValueRange[] AvailableEncodeBitRates {
+ get {
+ return GetAudioValueRange (AudioConverterPropertyID.AvailableEncodeBitRates);
+ }
+ }
+
+ public AudioValueRange[] ApplicableEncodeSampleRates {
+ get {
+ return GetAudioValueRange (AudioConverterPropertyID.ApplicableEncodeSampleRates);
+ }
+ }
+
+ public AudioValueRange[] AvailableEncodeSampleRates {
+ get {
+ return GetAudioValueRange (AudioConverterPropertyID.AvailableEncodeSampleRates);
+ }
+ }
+
+ public AudioChannelLayoutTag[] AvailableEncodeChannelLayoutTags {
+ get {
+ return GetArray<AudioChannelLayoutTag> (AudioConverterPropertyID.AvailableEncodeChannelLayoutTags, sizeof (AudioChannelLayoutTag));
+ }
+ }
+
+ public AudioStreamBasicDescription CurrentOutputStreamDescription {
+ get {
+ int size;
+ bool writable;
+ var res = AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.CurrentOutputStreamDescription, out size, out writable);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ IntPtr ptr = Marshal.AllocHGlobal (size);
+ res = AudioConverterGetProperty (handle, AudioConverterPropertyID.CurrentOutputStreamDescription, ref size, ptr);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ var asbd = (AudioStreamBasicDescription) Marshal.PtrToStructure (ptr, typeof (AudioStreamBasicDescription));
+ Marshal.FreeHGlobal (ptr);
+ return asbd;
+ }
+ }
+
+ public AudioStreamBasicDescription CurrentInputStreamDescription {
+ get {
+ int size;
+ bool writable;
+ var res = AudioConverterGetPropertyInfo (handle, AudioConverterPropertyID.CurrentInputStreamDescription, out size, out writable);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ IntPtr ptr = Marshal.AllocHGlobal (size);
+ res = AudioConverterGetProperty (handle, AudioConverterPropertyID.CurrentInputStreamDescription, ref size, ptr);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ var asbd = (AudioStreamBasicDescription) Marshal.PtrToStructure (ptr, typeof (AudioStreamBasicDescription));
+ Marshal.FreeHGlobal (ptr);
+ return asbd;
+ }
+ }
+
+ public int BitDepthHint {
+ get {
+ return (int) GetUIntProperty (AudioConverterPropertyID.PropertyBitDepthHint);
+ }
+ set {
+ SetProperty (AudioConverterPropertyID.PropertyBitDepthHint, value);
+ }
+ }
+
+ public AudioFormat[] FormatList {
+ get {
+ return GetArray<AudioFormat> (AudioConverterPropertyID.PropertyFormatList, Marshal.SizeOf (typeof (AudioFormat)));
+ }
+ }
+
+#if !MONOMAC
+ public bool CanResumeFromInterruption {
+ get {
+ return GetUIntProperty (AudioConverterPropertyID.CanResumeFromInterruption) != 0;
+ }
+ }
+#endif
+
+ public static AudioConverter Create (AudioStreamBasicDescription sourceFormat, AudioStreamBasicDescription destinationFormat)
+ {
+ AudioConverterError res;
+ return Create (sourceFormat, destinationFormat, out res);
+ }
+
+ public static AudioConverter Create (AudioStreamBasicDescription sourceFormat, AudioStreamBasicDescription destinationFormat, out AudioConverterError error)
+ {
+ IntPtr ptr = new IntPtr ();
+ error = AudioConverterNew (ref sourceFormat, ref destinationFormat, ref ptr);
+ if (error != AudioConverterError.None)
+ return null;
+
+ return new AudioConverter (ptr, true);
+ }
+
+ public static AudioConverter Create (AudioStreamBasicDescription sourceFormat, AudioStreamBasicDescription destinationFormat, AudioClassDescription[] descriptions)
+ {
+ if (descriptions == null)
+ throw new ArgumentNullException ("descriptions");
+
+ IntPtr ptr = new IntPtr ();
+ var res = AudioConverterNewSpecific (ref sourceFormat, ref destinationFormat, descriptions.Length, ref descriptions, ref ptr);
+ if (res != AudioConverterError.None)
+ return null;
+
+ return new AudioConverter (ptr, true);
+ }
+
+ public static AudioFormatType[] DecodeFormats {
+ get {
+ return GetFormats (AudioFormatProperty.DecodeFormatIDs);
+ }
+ }
+
+ public static AudioFormatType[] EncodeFormats {
+ get {
+ return GetFormats (AudioFormatProperty.EncodeFormatIDs);
+ }
+ }
+
+ ~AudioConverter ()
+ {
+ Dispose (false);
+ GC.SuppressFinalize (this);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (handle != IntPtr.Zero) {
+ if (owns)
+ AudioConverterDispose (handle);
+
+ handle = IntPtr.Zero;
+ }
+ }
+
+ public AudioConverterError ConvertBuffer (byte[] input, byte[] output)
+ {
+ if (input == null)
+ throw new ArgumentNullException ("input");
+ if (output == null)
+ throw new ArgumentNullException ("output");
+
+ int outSize = output.Length;
+ return AudioConverterConvertBuffer (handle, input.Length, input, ref outSize, output);
+ }
+
+ [Since (5,0)]
+ public AudioConverterError ConvertComplexBuffer (int numberPCMFrames, AudioBuffers inputData, AudioBuffers outputData)
+ {
+ if (inputData == null)
+ throw new ArgumentNullException ("inputData");
+ if (outputData == null)
+ throw new ArgumentNullException ("outputData");
+
+ return AudioConverterConvertComplexBuffer (handle, numberPCMFrames, (IntPtr) inputData, (IntPtr) outputData);
+ }
+
+ public AudioConverterError FillComplexBuffer (ref int outputDataPacketSize,
+ AudioBuffers outputData, AudioStreamPacketDescription[] packetDescription)
+ {
+ AudioConverterError res;
+
+ var this_handle = GCHandle.Alloc (this);
+ var this_ptr = GCHandle.ToIntPtr (this_handle);
+
+ if (packetDescription == null) {
+ res = AudioConverterFillComplexBuffer (handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr) outputData, IntPtr.Zero);
+ } else {
+ unsafe {
+ fixed (AudioStreamPacketDescription* pdesc = &packetDescription [0]) {
+ res = AudioConverterFillComplexBuffer (handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr) outputData, (IntPtr) pdesc);
+ }
+ }
+ }
+
+ return res;
+ }
+
+ [MonoPInvokeCallback (typeof (AudioConverterComplexInputDataShared))]
+ static AudioConverterError FillComplexBufferShared (IntPtr inAudioConverter, ref int ioNumberDataPackets, IntPtr ioData,
+ IntPtr outDataPacketDescription, IntPtr inUserData)
+ {
+ AudioStreamPacketDescription[] data;
+ if (outDataPacketDescription == IntPtr.Zero) {
+ data = null;
+ } else {
+ // TODO: AudioStreamPacketDescription
+ data = null;
+ }
+
+ var handler = GCHandle.FromIntPtr (inUserData);
+ var inst = (AudioConverter) handler.Target;
+
+ // evoke event handler with an argument
+ if (inst.InputData == null)
+ throw new ArgumentNullException ("InputData");
+
+ var res = inst.InputData (ref ioNumberDataPackets, new AudioBuffers (ioData), ref data);
+ if (data == null) {
+ outDataPacketDescription = IntPtr.Zero;
+ } else {
+ // TODO: AudioStreamPacketDescription
+ throw new NotImplementedException ("outDataPacketDescription is not null");
+ }
+ return res;
+ }
+
+ public AudioConverterError Reset ()
+ {
+ return AudioConverterReset (handle);
+ }
+
+ unsafe static AudioFormatType[] GetFormats (AudioFormatProperty prop)
+ {
+ int size;
+ if (AudioFormatPropertyNative.AudioFormatGetPropertyInfo (prop, 0, IntPtr.Zero, out size) != 0)
+ return null;
+
+ var elementSize = sizeof (AudioFormatType);
+ var data = new AudioFormatType[size / elementSize];
+ fixed (AudioFormatType* ptr = data) {
+ var res = AudioFormatPropertyNative.AudioFormatGetProperty (prop, 0, IntPtr.Zero, ref size, (IntPtr)ptr);
+ if (res != 0)
+ return null;
+
+ Array.Resize (ref data, elementSize);
+ return data;
+ }
+ }
+
+ uint GetUIntProperty (AudioConverterPropertyID propertyID)
+ {
+ uint value;
+ var size = sizeof (uint);
+ var res = AudioConverterGetProperty (handle, propertyID, ref size, out value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ return value;
+ }
+
+ double GetDoubleProperty (AudioConverterPropertyID propertyID)
+ {
+ double value;
+ var size = sizeof (double);
+ var res = AudioConverterGetProperty (handle, propertyID, ref size, out value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+
+ return value;
+ }
+
+ AudioValueRange[] GetAudioValueRange (AudioConverterPropertyID prop)
+ {
+ return GetArray<AudioValueRange> (prop, Marshal.SizeOf (typeof (AudioValueRange)));
+ }
+
+ unsafe T[] GetArray<T> (AudioConverterPropertyID prop, int elementSize) where T : struct
+ {
+ int size;
+ bool writable;
+ if (AudioConverterGetPropertyInfo (handle, prop, out size, out writable) != AudioConverterError.None)
+ return null;
+
+ var data = new T[size / elementSize];
+ fixed (T* ptr = &data[0]) {
+ var res = AudioConverterGetProperty (handle, prop, ref size, (IntPtr)ptr);
+ if (res != 0)
+ return null;
+
+ Array.Resize (ref data, size / elementSize);
+ return data;
+ }
+ }
+
+ void SetProperty (AudioConverterPropertyID propertyID, uint value)
+ {
+ var res = AudioConverterSetProperty (handle, propertyID, sizeof (uint), ref value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+ }
+
+ void SetProperty (AudioConverterPropertyID propertyID, int value)
+ {
+ var res = AudioConverterSetProperty (handle, propertyID, sizeof (int), ref value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+ }
+
+ void SetProperty (AudioConverterPropertyID propertyID, double value)
+ {
+ var res = AudioConverterSetProperty (handle, propertyID, sizeof (double), ref value);
+ if (res != AudioConverterError.None)
+ throw new ArgumentException (res.ToString ());
+ }
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterNew (ref AudioStreamBasicDescription inSourceFormat, ref AudioStreamBasicDescription inDestinationFormat, ref IntPtr outAudioConverter);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterNewSpecific (ref AudioStreamBasicDescription inSourceFormat, ref AudioStreamBasicDescription inDestinationFormat,
+ int inNumberClassDescriptions, ref AudioClassDescription[] inClassDescriptions, ref IntPtr outAudioConverter);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterDispose (IntPtr inAudioConverter);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterReset (IntPtr inAudioConverter);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterConvertComplexBuffer (IntPtr inAudioConverter, int inNumberPCMFrames,
+ IntPtr inInputData, IntPtr outOutputData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, out uint outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, out int outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, out double outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, byte[] outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, out AudioConverterPrimeInfo outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ ref int ioPropertyDataSize, IntPtr outPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterGetPropertyInfo (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ out int outSize, out bool outWritable);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterSetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ int inPropertyDataSize, ref uint inPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterSetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ int inPropertyDataSize, ref int inPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterSetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ int inPropertyDataSize, ref double inPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterSetProperty (IntPtr inAudioConverter, AudioConverterPropertyID inPropertyID,
+ int inPropertyDataSize, byte[] inPropertyData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterConvertBuffer (IntPtr inAudioConverter, int inInputDataSize, byte[] inInputData,
+ ref int ioOutputDataSize, byte[] outOutputData);
+
+ [DllImport (MonoMac.Constants.AudioToolboxLibrary)]
+ static extern AudioConverterError AudioConverterFillComplexBuffer (IntPtr inAudioConverter,
+ AudioConverterComplexInputDataShared inInputDataProc, IntPtr inInputDataProcUserData,
+ ref int ioOutputDataPacketSize, IntPtr outOutputData,
+ IntPtr outPacketDescription);
+ }
+
+ enum AudioConverterPropertyID
+ {
+ MinimumInputBufferSize = 0x6d696273, // 'mibs'
+ MinimumOutputBufferSize = 0x6d6f6273, // 'mobs'
+ // Deprecated
+ // MaximumInputBufferSize = 0x78696273, // 'xibs'
+ MaximumInputPacketSize = 0x78697073, // 'xips'
+ MaximumOutputPacketSize = 0x786f7073, // 'xops'
+ CalculateInputBufferSize = 0x63696273, // 'cibs'
+ CalculateOutputBufferSize = 0x636f6273, // 'cobs'
+
+ // TODO: Format specific
+ // InputCodecParameters = 'icdp'
+ // OutputCodecParameters = 'ocdp'
+
+ // Deprecated
+ // SampleRateConverterAlgorithm = 'srci'
+ SampleRateConverterComplexity = 0x73726361, // 'srca'
+ SampleRateConverterQuality = 0x73726371, // 'srcq'
+ SampleRateConverterInitialPhase = 0x73726370, // 'srcp'
+ CodecQuality = 0x63647175, // 'cdqu'
+ PrimeMethod = 0x70726d6d, // 'prmm'
+ PrimeInfo = 0x7072696d, // 'prim'
+ ChannelMap = 0x63686d70, // 'chmp'
+ DecompressionMagicCookie = 0x646d6763, // 'dmgc'
+ CompressionMagicCookie = 0x636d6763, // 'cmgc'
+ EncodeBitRate = 0x62726174, // 'brat'
+ EncodeAdjustableSampleRate = 0x616a7372, // 'ajsr'
+ InputChannelLayout = 0x69636c20, // 'icl '
+ OutputChannelLayout = 0x6f636c20, // 'ocl '
+ ApplicableEncodeBitRates = 0x61656272, // 'aebr'
+ AvailableEncodeBitRates = 0x76656272, // 'vebr'
+ ApplicableEncodeSampleRates = 0x61657372, // 'aesr'
+ AvailableEncodeSampleRates = 0x76657372, // 'vesr'
+ AvailableEncodeChannelLayoutTags = 0x6165636c, // 'aecl'
+ CurrentOutputStreamDescription = 0x61636f64, // 'acod'
+ CurrentInputStreamDescription = 0x61636964, // 'acid'
+ PropertySettings = 0x61637073, // 'acps' // TODO
+ PropertyBitDepthHint = 0x61636264, // 'acbd'
+ PropertyFormatList = 0x666c7374, // 'flst'
+ CanResumeFromInterruption = 0x63726669, // 'crfi'
+ }
+}
View
72 src/AudioToolbox/AudioFile.cs
@@ -60,7 +60,7 @@ public enum AudioFileType {
AMR = 0x616d7266, // amrf
}
- enum AudioFileError {
+ public enum AudioFileError {
Unspecified = 0x7768743f, // wht?
UnsupportedFileType = 0x7479703f, // typ?
UnsupportedDataFormat = 0x666d743f, // fmt?
@@ -693,6 +693,19 @@ public int Write (long startingByte, byte [] buffer, int offset, int count, bool
return ReadPacketData (useCache, inStartingPacket, ref nPackets, buffer, offset, ref count);
}
+ [DllImport (Constants.AudioToolboxLibrary)]
+ extern static AudioFileError AudioFileReadPackets (IntPtr inAudioFile, bool inUseCache, out int numBytes,
+ [MarshalAs (UnmanagedType.LPArray)] AudioStreamPacketDescription[] packetDescriptions, long startingPacket, ref int numPackets, IntPtr buffer);
+
+ public AudioFileError ReadPackets (bool useCache, out int numBytes,
+ AudioStreamPacketDescription[] packetDescriptions, long startingPacket, ref int numPackets, IntPtr buffer)
+ {
+ if (buffer == IntPtr.Zero)
+ throw new ArgumentException ("buffer");
+
+ return AudioFileReadPackets (handle, useCache, out numBytes, packetDescriptions, startingPacket, ref numPackets, buffer);
+ }
+
static internal AudioStreamPacketDescription [] PacketDescriptionFrom (int nPackets, IntPtr b)
{
if (b == IntPtr.Zero)
@@ -798,29 +811,29 @@ public int Write (long startingByte, byte [] buffer, int offset, int count, bool
}
[DllImport (Constants.AudioToolboxLibrary)]
- extern static OSStatus AudioFileWritePackets (
+ extern static AudioFileError AudioFileWritePackets (
AudioFileID audioFile, bool useCache, int inNumBytes, AudioStreamPacketDescription [] inPacketDescriptions,
long inStartingPacket, ref int numPackets, IntPtr buffer);
- public int WritePackets (bool useCache, long inStartingPacket, int numPackets, IntPtr buffer, int count)
+ public int WritePackets (bool useCache, long startingPacket, int numPackets, IntPtr buffer, int count)
{
if (buffer == IntPtr.Zero)
throw new ArgumentNullException ("buffer");
- if (AudioFileWritePackets (handle, useCache, count, null, inStartingPacket, ref numPackets, buffer) == 0)
+ if (AudioFileWritePackets (handle, useCache, count, null, startingPacket, ref numPackets, buffer) == 0)
return numPackets;
return -1;
}
- unsafe public int WritePackets (bool useCache, long inStartingPacket, AudioStreamPacketDescription [] inPacketDescriptions, IntPtr buffer, int count)
+ public int WritePackets (bool useCache, long startingPacket, AudioStreamPacketDescription [] packetDescriptions, IntPtr buffer, int count)
{
- if (inPacketDescriptions == null)
- throw new ArgumentNullException ("inPacketDescriptions");
+ if (packetDescriptions == null)
+ throw new ArgumentNullException ("packetDescriptions");
if (buffer == IntPtr.Zero)
throw new ArgumentNullException ("buffer");
- int nPackets = inPacketDescriptions.Length;
- if (AudioFileWritePackets (handle, useCache, count, inPacketDescriptions, inStartingPacket, ref nPackets, buffer) == 0)
+ int nPackets = packetDescriptions.Length;
+ if (AudioFileWritePackets (handle, useCache, count, packetDescriptions, startingPacket, ref nPackets, buffer) == 0)
return nPackets;
return -1;
}
@@ -846,15 +859,15 @@ unsafe public int WritePackets (bool useCache, long startingPacket, AudioStreamP
}
}
- unsafe public int WritePackets (bool useCache, long inStartingPacket, AudioStreamPacketDescription [] inPacketDescriptions, IntPtr buffer, int count, out int errorCode)
+ public int WritePackets (bool useCache, long startingPacket, AudioStreamPacketDescription [] packetDescriptions, IntPtr buffer, int count, out int errorCode)
{
- if (inPacketDescriptions == null)
- throw new ArgumentNullException ("inPacketDescriptions");
+ if (packetDescriptions == null)
+ throw new ArgumentNullException ("packetDescriptions");
if (buffer == IntPtr.Zero)
- throw new ArgumentNullException ("buffer");
- int nPackets = inPacketDescriptions.Length;
+ throw new ArgumentException ("buffer");
+ int nPackets = packetDescriptions.Length;
- errorCode = AudioFileWritePackets (handle, useCache, count, inPacketDescriptions, inStartingPacket, ref nPackets, buffer);
+ errorCode = (int) AudioFileWritePackets (handle, useCache, count, packetDescriptions, startingPacket, ref nPackets, buffer);
if (errorCode == 0)
return nPackets;
return -1;
@@ -875,13 +888,21 @@ unsafe public int WritePackets (bool useCache, long startingPacket, AudioStreamP
int nPackets = packetDescriptions.Length;
fixed (byte *bop = &buffer [offset]){
- errorCode = AudioFileWritePackets (handle, useCache, count, packetDescriptions, startingPacket, ref nPackets, (IntPtr) bop);
+ errorCode = (int) AudioFileWritePackets (handle, useCache, count, packetDescriptions, startingPacket, ref nPackets, (IntPtr) bop);
if (errorCode == 0)
return nPackets;
return -1;
}
}
+ public AudioFileError WritePackets (bool useCache, int numBytes, AudioStreamPacketDescription[] packetDescriptions, long startingPacket, ref int numPackets, IntPtr buffer)
+ {
+ if (buffer == IntPtr.Zero)
+ throw new ArgumentException ("buffer");
+
+ return AudioFileWritePackets (handle, useCache, numBytes, packetDescriptions, startingPacket, ref numPackets, buffer);
+ }
+
[DllImport (Constants.AudioToolboxLibrary)]
extern static OSStatus AudioFileCountUserData (AudioFileID handle, uint userData, out int count);
@@ -935,6 +956,13 @@ public bool GetPropertyInfo (AudioFileProperty property, out int size, out int w
{
return AudioFileGetPropertyInfo (handle, property, out size, out writable) == 0;
}
+
+ public bool IsPropertyWritable (AudioFileProperty property)
+ {
+ int writable;
+ int size;
+ return AudioFileGetPropertyInfo (handle, property, out size, out writable) == 0 && writable != 0;
+ }
[DllImport (Constants.AudioToolboxLibrary)]
extern static OSStatus AudioFileGetProperty (AudioFileID audioFile, AudioFileProperty property, ref int dataSize, IntPtr outdata);
@@ -1030,6 +1058,9 @@ long GetLong (AudioFileProperty property)
[DllImport (Constants.AudioToolboxLibrary)]
extern static AudioFileError AudioFileSetProperty (AudioFileID audioFile, AudioFileProperty property, int dataSize, IntPtr propertyData);
+ [DllImport (Constants.AudioToolboxLibrary)]
+ extern static AudioFileError AudioFileSetProperty (AudioFileID audioFile, AudioFileProperty property, int dataSize, ref AudioFilePacketTableInfo propertyData);
+
public bool SetProperty (AudioFileProperty property, int dataSize, IntPtr propertyData)
{
return AudioFileSetProperty (handle, property, dataSize, propertyData) == 0;
@@ -1231,6 +1262,15 @@ unsafe AudioFileError SetDouble (AudioFileProperty property, double value)
get {
return GetProperty<AudioFilePacketTableInfo> (AudioFileProperty.PacketTableInfo);
}
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ AudioFilePacketTableInfo afpti = value.Value;
+ var res = AudioFileSetProperty (handle, AudioFileProperty.PacketTableInfo, Marshal.SizeOf (typeof (AudioFilePacketTableInfo)), ref afpti);
+ if (res != 0)
+ throw new ArgumentException (res.ToString ());
+ }
}
public unsafe AudioFileChunkType[] ChunkIDs {
View
8 src/AudioToolbox/AudioFormat.cs
@@ -270,6 +270,10 @@ static partial class AudioFormatPropertyNative
[DllImport (Constants.AudioToolboxLibrary)]
public unsafe extern static AudioFormatError AudioFormatGetProperty (AudioFormatProperty propertyID, int inSpecifierSize, IntPtr inSpecifier,
+ ref int ioDataSize, IntPtr outPropertyData);
+
+ [DllImport (Constants.AudioToolboxLibrary)]
+ public unsafe extern static AudioFormatError AudioFormatGetProperty (AudioFormatProperty propertyID, int inSpecifierSize, IntPtr inSpecifier,
ref int ioDataSize, out IntPtr outPropertyData);
[DllImport (Constants.AudioToolboxLibrary)]
@@ -330,8 +334,8 @@ enum AudioFormatProperty
{
FormatInfo = 0x666d7469, // 'fmti'
FormatName = 0x666e616d, // 'fnam'
- EncodeFormatIDs = 0x61636f66, // 'acof' // TODO: Add to Converter
- DecodeFormatIDs = 0x61636966, // 'acif' // TODO: Add to Converter
+ EncodeFormatIDs = 0x61636f66, // 'acof'
+ DecodeFormatIDs = 0x61636966, // 'acif'
FormatList = 0x666c7374, // 'flst'
ASBDFromESDS = 0x65737364, // 'essd' // TODO: FromElementaryStreamDescriptor
ChannelLayoutFromESDS = 0x6573636c, // 'escl' // TODO:
View
1  src/AudioToolbox/AudioFormatAvailability.cs
@@ -67,6 +67,7 @@ public static AudioClassDescription[] GetEncoders (AudioFormatType format)
if (res != 0)
return null;
+ Array.Resize (ref data, (int) size / Marshal.SizeOf (typeof (T)));
return data;
}
}
View
258 src/AudioToolbox/AudioSession.cs
@@ -73,7 +73,7 @@ static string Lookup (int k)
return "This operation requries AudioSession.Category to be explicitly set";
}
- return String.Format ("Unknown error code: 0x{0:x}", k);
+ return String.Format ("Unknown error code: {0}", k);
}
internal AudioSessionException (int k) : base (Lookup (k))
@@ -107,15 +107,89 @@ public AudioSessionPropertyEventArgs (AudioSessionProperty prop, int size, IntPt
public int Size { get; set; }
public IntPtr Data { get; set; }
}
+
+ public class AudioSessionRouteChangeEventArgs : EventArgs {
+ static IntPtr route_change_key, previous_route_key, current_route_key;
+
+ static AudioSessionRouteChangeEventArgs ()
+ {
+ var lib = Dlfcn.dlopen (Constants.AudioToolboxLibrary, 0);
+ route_change_key = Dlfcn.GetIntPtr (lib, "kAudioSession_RouteChangeKey_Reason");
+ previous_route_key = Dlfcn.GetIntPtr (lib, "kAudioSession_AudioRouteChangeKey_PreviousRouteDescription");
+ current_route_key = Dlfcn.GetIntPtr (lib, "kAudioSession_AudioRouteChangeKey_CurrentRouteDescription");
+
+ Dlfcn.dlclose (lib);
+ }
+
+ public NSDictionary Dictionary { get; private set; }
+
+ public AudioSessionRouteChangeEventArgs (IntPtr dictHandle)
+ {
+ Dictionary = new NSDictionary (dictHandle);
+ }
+
+ public AudioSessionRouteChangeReason Reason {
+ get {
+ using (var num = new NSNumber (Dictionary.LowlevelObjectForKey (route_change_key))){
+ return (AudioSessionRouteChangeReason) num.Int32Value;
+ }
+ }
+ }
+
+ NSArray Extract (IntPtr key, NSString secondKey)
+ {
+ var dictH = Dictionary.LowlevelObjectForKey (key);
+ if (dictH == IntPtr.Zero)
+ return null;
+
+// Console.WriteLine ("Extracting from {2} {0} and getting {1}", new NSString (key), new NSDictionary (dictH).Description, Dictionary.Description);
+ // Description dictionary, indexed by the second key, the result is an array
+ using (var descDict = new NSDictionary (dictH)){
+ var sdict = descDict.LowlevelObjectForKey (secondKey.Handle);
+ if (sdict == IntPtr.Zero)
+ return null;
+
+ return new NSArray (sdict);
+ }
+ }
+
+ public AudioSessionInputRouteKind PreviousInputRoute {
+ get {
+ using (var array = Extract (previous_route_key, AudioSession.AudioRouteKey_Inputs))
+ return AudioSession.GetInputRoute (array);
+ }
+ }
+
+ public AudioSessionOutputRouteKind [] PreviousOutputRoutes {
+ get {
+ using (var array = Extract (previous_route_key, AudioSession.AudioRouteKey_Outputs))
+ return AudioSession.GetOutputRoutes (array);
+ }
+ }
+
+ public AudioSessionInputRouteKind CurrentInputRoute {
+ get {
+ using (var array = Extract (current_route_key, AudioSession.AudioRouteKey_Inputs))
+ return AudioSession.GetInputRoute (array);
+ }
+ }
+
+ public AudioSessionOutputRouteKind [] CurrentOutputRoutes {
+ get {
+ using (var array = Extract (current_route_key, AudioSession.AudioRouteKey_Outputs))
+ return AudioSession.GetOutputRoutes (array);
+ }
+ }
+ }
public static class AudioSession {
static bool initialized;
public static event EventHandler Interrupted;
public static event EventHandler Resumed;
- static NSString AudioRouteKey_Type;
- static NSString AudioRouteKey_Inputs;
- static NSString AudioRouteKey_Outputs;
+ internal static NSString AudioRouteKey_Type;
+ internal static NSString AudioRouteKey_Inputs;
+ internal static NSString AudioRouteKey_Outputs;
static NSString InputRoute_LineIn;
static NSString InputRoute_BuiltInMic;
@@ -278,7 +352,7 @@ static void SetDouble (AudioSessionProperty property, double val)
static void SetInt (AudioSessionProperty property, int val)
{
unsafe {
- int k = AudioSessionSetProperty (property, 4, (IntPtr) (&val));
+ int k = AudioSessionSetProperty (property, sizeof (int), (IntPtr) (&val));
if (k != 0)
throw new AudioSessionException (k);
}
@@ -393,88 +467,91 @@ static void SetFloat (AudioSessionProperty property, float val)
}
*/
-
- // TODO: Wrong can return more than 1 value
- [Since (5,0)]
- static public AudioSessionInputRouteKind InputRoute {
- get {
- var arr = (NSArray) AudioRouteDescription [AudioRouteKey_Inputs];
-
- if (arr == null || arr.Count == 0)
- return AudioSessionInputRouteKind.None;
+
+ static internal AudioSessionInputRouteKind GetInputRoute (NSArray arr)
+ {
+ if (arr == null || arr.Count == 0)
+ return AudioSessionInputRouteKind.None;
+
+ var dict = new NSDictionary (arr.ValueAt (0));
+
+ if (dict == null || dict.Count == 0)
+ return AudioSessionInputRouteKind.None;
+
+ var val = (NSString) dict [AudioRouteKey_Type];
+
+ if (val == null)
+ return AudioSessionInputRouteKind.None;
+
+ if (val == InputRoute_LineIn) {
+ return AudioSessionInputRouteKind.LineIn;
+ } else if (val == InputRoute_BuiltInMic) {
+ return AudioSessionInputRouteKind.BuiltInMic;
+ } else if (val == InputRoute_HeadsetMic) {
+ return AudioSessionInputRouteKind.HeadsetMic;
+ } else if (val == InputRoute_BluetoothHFP) {
+ return AudioSessionInputRouteKind.BluetoothHFP;
+ } else if (val == InputRoute_USBAudio) {
+ return AudioSessionInputRouteKind.USBAudio;
+ } else {
+ return (AudioSessionInputRouteKind) val.Handle;
+ }
+ }
+
+ static internal AudioSessionOutputRouteKind [] GetOutputRoutes (NSArray arr)
+ {
+ if (arr == null || arr.Count == 0)
+ return null;
+
+ var result = new AudioSessionOutputRouteKind [arr.Count];
+ for (uint i = 0; i < arr.Count; i++) {
+ var dict = new NSDictionary ((IntPtr) arr.ValueAt (i));
- var dict = new NSDictionary (arr.ValueAt (0));
+ result [i] = AudioSessionOutputRouteKind.None;
if (dict == null || dict.Count == 0)
- return AudioSessionInputRouteKind.None;
+ continue;
var val = (NSString) dict [AudioRouteKey_Type];
if (val == null)
- return AudioSessionInputRouteKind.None;
+ continue;
- if (val == InputRoute_LineIn) {
- return AudioSessionInputRouteKind.LineIn;
- } else if (val == InputRoute_BuiltInMic) {
- return AudioSessionInputRouteKind.BuiltInMic;
- } else if (val == InputRoute_HeadsetMic) {
- return AudioSessionInputRouteKind.HeadsetMic;
- } else if (val == InputRoute_BluetoothHFP) {
- return AudioSessionInputRouteKind.BluetoothHFP;
- } else if (val == InputRoute_USBAudio) {
- return AudioSessionInputRouteKind.USBAudio;
- } else {
- // now what?
- throw new Exception (); // return AudioSessionInputRouteKind.None;
- }
+ if (val == OutputRoute_LineOut) {
+ result [i] = AudioSessionOutputRouteKind.LineOut;
+ } else if (val == OutputRoute_Headphones) {
+ result [i] = AudioSessionOutputRouteKind.Headphones;
+ } else if (val == OutputRoute_BluetoothHFP) {
+ result [i] = AudioSessionOutputRouteKind.BluetoothHFP;
+ } else if (val == OutputRoute_BluetoothA2DP) {
+ result [i] = AudioSessionOutputRouteKind.BluetoothA2DP;
+ } else if (val == OutputRoute_BuiltInReceiver) {
+ result [i] = AudioSessionOutputRouteKind.BuiltInReceiver;
+ } else if (val == OutputRoute_BuiltInSpeaker) {
+ result [i] = AudioSessionOutputRouteKind.BuiltInSpeaker;
+ } else if (val == OutputRoute_USBAudio) {
+ result [i] = AudioSessionOutputRouteKind.USBAudio;
+ } else if (val == OutputRoute_HDMI) {
+ result [i] = AudioSessionOutputRouteKind.HDMI;
+ } else if (val == OutputRoute_AirPlay) {
+ result [i] = AudioSessionOutputRouteKind.AirPlay;
+ } else
+ result [i] = (AudioSessionOutputRouteKind) val.Handle;
+ }
+ return result;
+ }
+
+ [Since (5,0)]
+ static public AudioSessionInputRouteKind InputRoute {
+ get {
+ return GetInputRoute ((NSArray) AudioRouteDescription [AudioRouteKey_Inputs]);
}
}
[Since (5,0)]
static public AudioSessionOutputRouteKind [] OutputRoutes {
get {
- var arr = (NSArray) AudioRouteDescription [AudioRouteKey_Outputs];
-
- if (arr == null || arr.Count == 0)
- return null;
-
- var result = new AudioSessionOutputRouteKind [arr.Count];
- for (uint i = 0; i < arr.Count; i++) {
- var dict = new NSDictionary ((IntPtr) arr.ValueAt (i));
-
- result [i] = AudioSessionOutputRouteKind.None;
-
- if (dict == null || dict.Count == 0)
- continue;
-
- var val = (NSString) dict [AudioRouteKey_Type];
-
- if (val == null)
- continue;
-
- if (val == OutputRoute_LineOut) {
- result [i] = AudioSessionOutputRouteKind.LineOut;
- } else if (val == OutputRoute_Headphones) {
- result [i] = AudioSessionOutputRouteKind.Headphones;
- } else if (val == OutputRoute_BluetoothHFP) {
- result [i] = AudioSessionOutputRouteKind.BluetoothHFP;
- } else if (val == OutputRoute_BluetoothA2DP) {
- result [i] = AudioSessionOutputRouteKind.BluetoothA2DP;
- } else if (val == OutputRoute_BuiltInReceiver) {
- result [i] = AudioSessionOutputRouteKind.BuiltInReceiver;
- } else if (val == OutputRoute_BuiltInSpeaker) {
- result [i] = AudioSessionOutputRouteKind.BuiltInSpeaker;
- } else if (val == OutputRoute_USBAudio) {
- result [i] = AudioSessionOutputRouteKind.USBAudio;
- } else if (val == OutputRoute_HDMI) {
- result [i] = AudioSessionOutputRouteKind.HDMI;
- } else if (val == OutputRoute_AirPlay) {
- result [i] = AudioSessionOutputRouteKind.AirPlay;
-
- }
- }
-
- return result;
+ return GetOutputRoutes ((NSArray) AudioRouteDescription [AudioRouteKey_Outputs]);
}
}
@@ -664,5 +741,40 @@ public static void RemoveListener (AudioSessionProperty property, PropertyListen
listeners [property] = null;
}
+ class RouteChangeListener {
+ public EventHandler<AudioSessionRouteChangeEventArgs> cback;
+
+ public RouteChangeListener (EventHandler<AudioSessionRouteChangeEventArgs> cback)
+ {
+ this.cback = cback;
+ }
+
+ public void Listener (AudioSessionProperty prop, int size, IntPtr data)
+ {
+ cback (null, new AudioSessionRouteChangeEventArgs (data));
+ }
+ }
+
+ static Hashtable strongListenerHash;
+
+ public static event EventHandler<AudioSessionRouteChangeEventArgs> AudioRouteChanged {
+ add {
+ if (strongListenerHash == null)
+ strongListenerHash = new Hashtable ();
+ var routeChangeListener = new RouteChangeListener (value);
+ strongListenerHash [value] = routeChangeListener;
+ AddListener (AudioSessionProperty.AudioRouteChange, routeChangeListener.Listener);
+ }
+
+ remove {
+ if (strongListenerHash == null)
+ return;
+ var k = strongListenerHash [value] as RouteChangeListener;
+ if (k != null){
+ RemoveListener (AudioSessionProperty.AudioRouteChange, k.Listener);
+ strongListenerHash.Remove (value);
+ }
+ }
+ }
}
}
View
4 src/AudioToolbox/AudioSessions.cs
@@ -85,7 +85,7 @@ public enum AudioSessionInterruptionType {
public enum AudioSessionProperty {
PreferredHardwareSampleRate = 0x68777372,
PreferredHardwareIOBufferDuration = 0x696f6264,
- AudioCategory = 0x61636174,
+ AudioCategory = 0x61636174, // 'acat'
[Obsolete ("Deprecated in iOS 5.0")]
AudioRoute = 0x726f7574,
AudioRouteChange = 0x726f6368,
@@ -104,7 +104,7 @@ public enum AudioSessionProperty {
OverrideCategoryMixWithOthers = 0x636d6978,
OverrideCategoryDefaultToSpeaker = 0x6373706b, //'cspk'
OverrideCategoryEnableBluetoothInput = 0x63626c75, //'cblu'
- InterruptionType = 0x2172736d,
+ InterruptionType = 0x74797065, // 'type'
Mode = 0x6d6f6465,
InputSources = 0x73726373, // 'srcs'
OutputDestinations = 0x64737473, // 'dsts'
View
4 src/AudioToolbox/AudioType.cs
@@ -483,7 +483,7 @@ public override string ToString ()
}
}
- public enum AudioChannelLayoutTag {
+ public enum AudioChannelLayoutTag : uint {
UseChannelDescriptions = (0<<16) | 0,
UseChannelBitmap = (1<<16) | 0,
@@ -628,7 +628,7 @@ public enum AudioChannelLayoutTag {
DTS_6_1_D = (182<<16) | 7,
DiscreteInOrder = (147<<16) | 0, // needs to be ORed with the actual number of channels
- Unknown = unchecked ((int)(0xFFFF0000)) // needs to be ORed with the actual number of channels
+ Unknown = 0xFFFF0000 // needs to be ORed with the actual number of channels
}
public static class AudioChannelLayoutTagExtensions
View
10 src/AudioUnit/AudioComponentDescription.cs
@@ -145,7 +145,13 @@ public enum AudioComponentManufacturerType : uint
{
Apple = 0x6170706c // little endian 0x6c707061 //'appl'
}
-
+
+ [Flags]
+ public enum AudioComponentFlag
+ {
+ Unsearchable = 1
+ }
+
// Why is this a class ??
[StructLayout(LayoutKind.Sequential)]
public class AudioComponentDescription
@@ -159,7 +165,7 @@ public class AudioComponentDescription
[MarshalAs(UnmanagedType.U4)]
public AudioComponentManufacturerType ComponentManufacturer;
- public int ComponentFlags;
+ public AudioComponentFlag ComponentFlags;
public int ComponentFlagsMask;
public AudioComponentDescription () {}
View
30 src/AudioUnit/ExtAudioFile.cs
@@ -100,6 +100,17 @@ public class ExtAudioFile : IDisposable
}
}
+ public AudioConverter AudioConverter {
+ get {
+ uint size = sizeof (uint);
+ IntPtr value;
+
+ if (ExtAudioFileGetProperty (_extAudioFile, PropertyIDType.AudioConverter, ref size, out value) != ExtAudioFileError.OK)
+ return null;
+
+ return new AudioConverter (value, false);
+ }
+ }
public long FileLengthFrames {
get {
@@ -292,6 +303,13 @@ public ExtAudioFileError Write (uint numberFrames, AudioBuffers audioBufferList)
return ExtAudioFileWrite (_extAudioFile, numberFrames, (IntPtr) audioBufferList);
}
+ public ExtAudioFileError SynchronizeAudioConverter ()
+ {
+ IntPtr value = IntPtr.Zero;
+ return ExtAudioFileSetProperty (_extAudioFile, PropertyIDType.ConverterConfig,
+ Marshal.SizeOf (value), value);
+ }
+
public void Dispose ()
{
Dispose (true);
@@ -370,12 +388,8 @@ protected virtual void Dispose (bool disposing)
[DllImport(MonoMac.Constants.AudioToolboxLibrary)]
static extern ExtAudioFileError ExtAudioFileGetProperty (IntPtr inExtAudioFile, PropertyIDType inPropertyID, ref uint ioPropertyDataSize, out uint outPropertyData);
- [DllImport(MonoMac.Constants.AudioToolboxLibrary, EntryPoint = "ExtAudioFileSetProperty")]
- static extern int ExtAudioFileSetProperty(
- IntPtr inExtAudioFile,
- PropertyIDType inPropertyID,
- uint ioPropertyDataSize,
- IntPtr outPropertyData);
+ [DllImport(MonoMac.Constants.AudioToolboxLibrary)]
+ static extern ExtAudioFileError ExtAudioFileSetProperty (IntPtr inExtAudioFile, PropertyIDType inPropertyID, int ioPropertyDataSize, IntPtr outPropertyData);
[DllImport(MonoMac.Constants.AudioToolboxLibrary, EntryPoint = "ExtAudioFileSetProperty")]
static extern int ExtAudioFileSetProperty(
@@ -393,14 +407,14 @@ enum PropertyIDType {
CodecManufacturer = 0x636d616e, // 'cman'
// read-only:
- //kExtAudioFileProperty_AudioConverter = 'acnv', // AudioConverterRef
+ AudioConverter = 0x61636e76, // 'acnv'
AudioFile = 0x6166696c, // 'afil'
FileMaxPacketSize = 0x666d7073, // 'fmps'
ClientMaxPacketSize = 0x636d7073, // 'cmps'
FileLengthFrames = 0x2366726d, // '#frm'
// writable:
- //kExtAudioFileProperty_ConverterConfig = 'accf', // CFPropertyListRef
+ ConverterConfig = 0x61636366, // 'accf'
//kExtAudioFileProperty_IOBufferSizeBytes = 'iobs', // UInt32
//kExtAudioFileProperty_IOBuffer = 'iobf', // void *
//kExtAudioFileProperty_PacketTable = 'xpti' // AudioFilePacketTableInfo
View
1  src/AudioUnit/_AudioConverter.cs
@@ -32,6 +32,7 @@
namespace MonoMac.AudioUnitWrapper
{
+ [Obsolete ("Use AudioConverter")]
public class _AudioConverter : IDisposable
{
#region Variables
View
1  src/AudioUnit/_AudioConverterEventArgs.cs
@@ -31,6 +31,7 @@
namespace MonoMac.AudioUnitWrapper
{
+ [Obsolete ("Use AudioConverter")]
public class _AudioConverterEventArgs : EventArgs
{
#region Variables
View
4 src/Foundation/Enum.cs
@@ -605,4 +605,8 @@ public enum NSLigatureType {
None, Default, All
}
+ public enum NSDateComponentsWrappingBehavior {
+ None = 0,
+ WrapCalendarComponents = 1 << 0,
+ }
}
View
6 src/Foundation/NSInputStream.cs
@@ -33,12 +33,6 @@ public partial class NSInputStream : NSStream {
IntPtr callback;
CFStreamClientContext context;
- // calling 'init' would create an instance that crash,
- // this one maintains API compatibility (without the crash)
- public NSInputStream () : this (new NSData ())
- {
- }
-
public int Read (byte [] buffer, uint len) {
return objc_msgSend (Handle, Selector.GetHandle (selReadMaxLength), buffer, len);
}
View
309 src/Foundation/NSObject2.cs
@@ -1,4 +1,4 @@
-// Copyright 2011, 2012 Xamarin Inc
+// Copyright 2011 - 2013 Xamarin Inc
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -33,11 +33,61 @@
using MonoMac.CoreGraphics;
namespace MonoMac.Foundation {
+ public class NSObjectFlag {
+ public static readonly NSObjectFlag Empty;
+
+ NSObjectFlag () {}
+ }
public partial class NSObject {
const string selConformsToProtocol = "conformsToProtocol:";
const string selEncodeWithCoder = "encodeWithCoder:";
+ const string selAwakeFromNib = "awakeFromNib";
+ const string selRespondsToSelector = "respondsToSelector:";
+
+ IntPtr handle;
+ IntPtr super;
+ bool disposed;
+
+ protected bool IsDirectBinding;
+
+#if COREBUILD
+ static readonly IntPtr class_ptr = Class.GetHandle ("NSObject");
+ public virtual IntPtr ClassHandle { get { return class_ptr; } }
+#endif
+
+ [Export ("init")]
+ public NSObject () {
+ bool alloced = AllocIfNeeded ();
+ InitializeObject (alloced);
+ }
+
+ // This is just here as a constructor chain that can will
+ // only do Init at the most derived class.
+ public NSObject (NSObjectFlag x)
+ {
+ bool alloced = AllocIfNeeded ();
+ InitializeObject (alloced);
+ }
+
+ public NSObject (IntPtr handle) : this (handle, false) {
+ }
+
+ public NSObject (IntPtr handle, bool alloced) {
+ this.handle = handle;
+ InitializeObject (alloced);
+ }
+ ~NSObject () {
+ Dispose (false);
+ }
+
+ public void Dispose () {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+#if !COREBUILD
[Export ("encodeWithCoder:")]
public virtual void EncodeTo (NSCoder coder)
{
@@ -50,6 +100,7 @@ public virtual void EncodeTo (NSCoder coder)
Messaging.void_objc_msgSendSuper_intptr (this.SuperHandle, Selector.GetHandle (selEncodeWithCoder), coder.Handle);
}
}
+#endif
[Export ("conformsToProtocol:")]
[Preserve ()]
@@ -74,6 +125,171 @@ public virtual bool ConformsToProtocol (IntPtr protocol)
return false;
}
+ [Export ("respondsToSelector:")]
+ public virtual bool RespondsToSelector (Selector sel) {
+ if (IsDirectBinding) {
+ return Messaging.bool_objc_msgSend_intptr (this.Handle, Selector.GetHandle (selRespondsToSelector), sel.Handle);
+ } else {
+ return Messaging.bool_objc_msgSendSuper_intptr (this.SuperHandle, Selector.GetHandle (selRespondsToSelector), sel.Handle);
+ }
+ }
+
+ [Export ("doesNotRecognizeSelector:")]
+ public virtual void DoesNotRecognizeSelector (Selector sel) {
+ Messaging.void_objc_msgSendSuper_intptr (SuperHandle, Selector.DoesNotRecognizeSelector, sel.Handle);
+ }
+
+ internal void Release () {
+ Messaging.void_objc_msgSend (handle, Selector.Release);
+ }
+
+ internal void Retain () {
+ Messaging.void_objc_msgSend (handle, Selector.Retain);
+ }
+
+ public IntPtr SuperHandle {
+ get {
+ if (super == IntPtr.Zero) {
+ super = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (objc_super)));
+ unsafe {
+ objc_super *sup = (objc_super *) super;
+ sup->receiver = handle;
+ sup->super = ClassHandle;
+ }
+ }
+ return super;
+ }
+ }
+
+ public IntPtr Handle {
+ get { return handle; }
+ set {
+ if (handle == value)
+ return;
+
+ if (handle != IntPtr.Zero)
+ Runtime.UnregisterNSObject (handle);
+
+ handle = value;
+
+ if (handle != IntPtr.Zero)
+ Runtime.RegisterNSObject (this, handle);
+ }
+ }
+
+ private bool AllocIfNeeded () {
+ if (handle == IntPtr.Zero) {
+ handle = Messaging.intptr_objc_msgSend (Class.GetHandle (this.GetType ()), Selector.Alloc);
+ return true;
+ }
+ return false;
+ }
+
+ private IntPtr GetObjCIvar (string name) {
+ IntPtr native;
+
+ object_getInstanceVariable (handle, name, out native);
+
+ return native;
+ }
+
+ public NSObject GetNativeField (string name) {
+ IntPtr field = GetObjCIvar (name);
+
+ if (field == IntPtr.Zero)
+ return null;
+ return Runtime.GetNSObject (field);
+ }
+
+ private void SetObjCIvar (string name, IntPtr value) {
+ object_setInstanceVariable (handle, name, value);
+ }
+
+ public void SetNativeField (string name, NSObject value) {
+ if (value == null)
+ SetObjCIvar (name, IntPtr.Zero);
+ else
+ SetObjCIvar (name, value.Handle);
+ }
+
+ [DllImport ("/usr/lib/libobjc.dylib")]
+ extern static void object_getInstanceVariable (IntPtr obj, string name, out IntPtr val);
+
+ [DllImport ("/usr/lib/libobjc.dylib")]
+ extern static void object_setInstanceVariable (IntPtr obj, string name, IntPtr val);
+
+ struct objc_super {
+ public IntPtr receiver;
+ public IntPtr super;
+ }
+
+ [Export ("performSelector:withObject:afterDelay:")]
+ public virtual void PerformSelector (Selector sel, NSObject obj, double delay) {
+ if (sel == null)
+ throw new ArgumentNullException ("sel");
+ if (IsDirectBinding) {
+ Messaging.void_objc_msgSend_intptr_intptr_double (this.Handle, Selector.PerformSelectorWithObjectAfterDelay, sel.Handle, obj == null ? IntPtr.Zero : obj.Handle, delay);
+ } else {
+ Messaging.void_objc_msgSendSuper_intptr_intptr_double (this.SuperHandle, Selector.PerformSelectorWithObjectAfterDelay, sel.Handle, obj == null ? IntPtr.Zero : obj.Handle, delay);
+ }
+ }
+
+ [Export ("awakeFromNib")]
+ public virtual void AwakeFromNib ()
+ {
+ if (IsDirectBinding) {
+ Messaging.void_objc_msgSend (this.Handle, Selector.GetHandle (selAwakeFromNib));
+ } else {
+ Messaging.void_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle (selAwakeFromNib));
+ }
+ }
+
+ private void InvokeOnMainThread (Selector sel, NSObject obj, bool wait)
+ {
+ Messaging.void_objc_msgSend_intptr_intptr_bool (this.Handle, Selector.PerformSelectorOnMainThreadWithObjectWaitUntilDone, sel.Handle, obj == null ? IntPtr.Zero : obj.Handle, wait);
+ }
+
+ public void BeginInvokeOnMainThread (Selector sel, NSObject obj)
+ {
+ InvokeOnMainThread (sel, obj, false);
+ }
+
+ public void InvokeOnMainThread (Selector sel, NSObject obj)
+ {
+ InvokeOnMainThread (sel, obj, true);
+ }
+
+ public void BeginInvokeOnMainThread (NSAction action)
+ {
+ var d = new NSAsyncActionDispatcher (action);
+ Messaging.void_objc_msgSend_intptr_intptr_bool (d.Handle, Selector.PerformSelectorOnMainThreadWithObjectWaitUntilDone,
+ NSActionDispatcher.Selector.Handle, d.Handle, false);
+ }
+
+ public void InvokeOnMainThread (NSAction action)
+ {
+ using (var d = new NSActionDispatcher (action)) {
+ Messaging.void_objc_msgSend_intptr_intptr_bool (d.Handle, Selector.PerformSelectorOnMainThreadWithObjectWaitUntilDone,
+ NSActionDispatcher.Selector.Handle, d.Handle, true);
+ }
+ }
+
+#if !COREBUILD
+ internal static readonly IntPtr retainCount = Selector.GetHandle ("retainCount");
+
+ [Export ("retainCount")]
+ public virtual int RetainCount {
+ get {
+ if (IsDirectBinding) {
+ return Messaging.int_objc_msgSend (this.Handle, retainCount);
+ } else {
+ return Messaging.int_objc_msgSendSuper (this.SuperHandle, retainCount);
+ }
+ }
+ }
+#endif
+
+#if !COREBUILD
public static NSObject FromObject (object obj)
{
if (obj == null)
@@ -145,24 +361,93 @@ public void SetValueForKeyPath (IntPtr handle, NSString keyPath)
} else {
MonoMac.ObjCRuntime.Messaging.void_objc_msgSendSuper_IntPtr_IntPtr (this.SuperHandle, Selector.GetHandle (selSetValueForKeyPath_), handle, keyPath.Handle);
}
-
}
public override string ToString ()
{
return Description ?? base.ToString ();
}
+#endif
+
+ public virtual void Invoke (NSAction action, double delay)
+ {
+ var d = new NSAsyncActionDispatcher (action);
+ PerformSelector (NSActionDispatcher.Selector, d, delay);
+ }
- public virtual void Invoke (NSAction action, double delay)
- {
- var d = new NSAsyncActionDispatcher (action);
- PerformSelector (NSActionDispatcher.Selector, d, delay);
- }
+ public virtual void Invoke (NSAction action, TimeSpan delay)
+ {
+ var d = new NSAsyncActionDispatcher (action);
+ PerformSelector (NSActionDispatcher.Selector, d, delay.TotalSeconds);
+ }
+
+ internal void ClearHandle ()
+ {
+ handle = IntPtr.Zero;
+ }
+
+ protected virtual void Dispose (bool disposing) {
+ if (disposed)
+ return;
+ disposed = true;
+
+ if (handle != IntPtr.Zero) {
+ if (disposing) {
+ ReleaseManagedRef ();
+ } else {
+ NSObject_Disposer.Add (this);
+ }
+ }
+ if (super != IntPtr.Zero) {
+ Marshal.FreeHGlobal (super);
+ super = IntPtr.Zero;
+ }
+ }
- public virtual void Invoke (NSAction action, TimeSpan delay)
- {
- var d = new NSAsyncActionDispatcher (action);
- PerformSelector (NSActionDispatcher.Selector, d, delay.TotalSeconds);
- }
+ [Register ("__NSObject_Disposer")]
+ [Preserve (AllMembers=true)]
+ internal class NSObject_Disposer : NSObject {
+ static readonly List <NSObject> drainList1 = new List<NSObject> ();
+ static readonly List <NSObject> drainList2 = new List<NSObject> ();
+ static List <NSObject> handles = drainList1;
+ static readonly IntPtr selDrain = Selector.GetHandle ("drain:");
+
+ static readonly IntPtr class_ptr = Class.GetHandle ("__NSObject_Disposer");
+
+ static readonly object lock_obj = new object ();
+
+ private NSObject_Disposer ()
+ {
+ // Disable default ctor, there should be no instances of this class.
+ }
+
+ static internal void Add (NSObject handle) {
+ bool call_drain;
+ lock (lock_obj) {
+ handles.Add (handle);
+ call_drain = handles.Count == 1;
+ }
+ if (!call_drain)
+ return;
+ Messaging.void_objc_msgSend_intptr_intptr_bool (class_ptr, Selector.PerformSelectorOnMainThreadWithObjectWaitUntilDone, selDrain, IntPtr.Zero, false);
+ }
+
+ [Export ("drain:")]
+ static void Drain (NSObject ctx) {
+ List<NSObject> drainList;
+
+ lock (lock_obj) {
+ drainList = handles;
+ if (handles == drainList1)
+ handles = drainList2;
+ else
+ handles = drainList1;
+ }
+
+ foreach (NSObject x in drainList)
+ x.ReleaseManagedRef ();
+ drainList.Clear();
+ }
+ }
}
}
View
44 src/Foundation/NSSearchPath.cs
@@ -0,0 +1,44 @@
+//
+// NSSearchPath.cs
+//
+// Authors:
+// Marek Safar (marek.safar@gmail.com)
+//
+// Copyright 2013 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace MonoMac.Foundation
+{
+ public static class NSSearchPath
+ {
+ public static string[] GetDirectories (NSSearchPathDirectory directory, NSSearchPathDomain domainMask, bool expandTilde = true)
+ {
+ return NSArray.StringArrayFromHandle (NSSearchPathForDirectoriesInDomains (directory, domainMask, expandTilde));
+ }
+
+ [DllImport (Constants.FoundationLibrary)]
+ static extern IntPtr NSSearchPathForDirectoriesInDomains (NSSearchPathDirectory directory, NSSearchPathDomain domainMask, bool expandTilde);
+ }
+}
View
4 src/Security/Certificate.cs
@@ -227,13 +227,13 @@ public class SecKey : INativeObject, IDisposable {
internal IntPtr handle;
// invoked by marshallers
- internal SecKey (IntPtr handle)
+ public SecKey (IntPtr handle)
: this (handle, false)
{
}
[Preserve (Conditional = true)]
- internal SecKey (IntPtr handle, bool owns)
+ public SecKey (IntPtr handle, bool owns)
{
this.handle = handle;
if (!owns)
View
16 src/avfoundation.cs
@@ -376,6 +376,7 @@ interface AVAudioPlayerDelegate {
[Export ("audioPlayerDecodeErrorDidOccur:error:")]
void DecoderError (AVAudioPlayer player, NSError error);
+#if !MONOMAC
[Export ("audioPlayerBeginInterruption:")]
void BeginInterruption (AVAudioPlayer player);
@@ -383,7 +384,7 @@ interface AVAudioPlayerDelegate {
[Obsolete ("Deprecated in iOS 6.0")]
void EndInterruption (AVAudioPlayer player);
- // Obsolete in 6,0
+ // Deprecated in iOS 6.0 but we have same C# signature
[Since (4,0)]
[Export ("audioPlayerEndInterruption:withFlags:")]
void EndInterruption (AVAudioPlayer player, AVAudioSessionInterruptionFlags flags);
@@ -391,6 +392,7 @@ interface AVAudioPlayerDelegate {
//[Since (6,0)]
//[Export ("audioPlayerEndInterruption:withOptions:")]
//void EndInterruption (AVAudioPlayer player, AVAudioSessionInterruptionFlags flags);
+#endif
}
[BaseType (typeof (NSObject))]
@@ -476,7 +478,8 @@ interface AVAudioRecorderDelegate {
[Export ("audioRecorderEncodeErrorDidOccur:error:")]
void EncoderError (AVAudioRecorder recorder, NSError error);
-
+
+#if !MONOMAC
[Export ("audioRecorderBeginInterruption:")]
void BeginInterruption (AVAudioRecorder recorder);
@@ -484,7 +487,7 @@ interface AVAudioRecorderDelegate {
[Export ("audioRecorderEndInterruption:")]
void EndInterruption (AVAudioRecorder recorder);
- // Obsolete in 6,0
+ // Deprecated in iOS 6.0 but we have same C# signature
[Since (4,0)]
[Export ("audioRecorderEndInterruption:withFlags:")]
void EndInterruption (AVAudioRecorder recorder, AVAudioSessionInterruptionFlags flags);
@@ -492,6 +495,7 @@ interface AVAudioRecorderDelegate {
//[Since (6,0)]
//[Export ("audioRecorderEndInterruption:withOptions:")]
//void EndInterruption (AVAudioRecorder recorder, AVAudioSessionInterruptionFlags flags);
+#endif
}
#if !MONOMAC
@@ -960,10 +964,6 @@ interface AVAsset {
[Since (6,0)]
[Export ("chapterMetadataGroupsBestMatchingPreferredLanguages:")]
AVTimedMetadataGroup [] GetChapterMetadataGroupsBestMatchingPreferredLanguages (string [] languages);
-
- [Since (6,0)]
- [Export ("resourceLoader")]
- AVAssetResourceLoader ResourceLoader { get; }
#endif
}
@@ -1153,10 +1153,12 @@ interface AVAssetReaderVideoCompositionOutput {
AVVideoComposition VideoComposition { get; set; }
[Advice ("Use Create method")]
+ [Static]
[Export ("assetReaderVideoCompositionOutputWithVideoTracks:videoSettings:")]
AVAssetReaderVideoCompositionOutput WeakFromTracks (AVAssetTrack [] videoTracks, [NullAllowed] NSDictionary videoSettings);
[Wrap ("WeakFromTracks (videoTracks, settings == null ? null : settings.Dictionary)")]
+ [Static]
AVAssetReaderVideoCompositionOutput Create (AVAssetTrack [] videoTracks, [NullAllowed] CVPixelBufferAttributes settings);
[Export ("initWithVideoTracks:videoSettings:")]
View
1  src/error.cs
@@ -38,6 +38,7 @@
// BI1019 Invalid [NoDefaultValue] attribute on method `{0}.{1}'
// BI1020 Unsupported type {0} used on exported method {1}.{2}
// BI1021 Unsupported type for read/write Fields: {0}
+// BI1022 Model classes can not be categories
// BI11xx warnings
// BI1101 Trying to use a string as a [Target]
// BI1102 Using the deprecated EventArgs for a delegate signature in {0}.{1}, please use DelegateName instead
View
204 src/foundation.cs
@@ -87,7 +87,7 @@ public interface NSArray {
[Since (3,2)]
[BaseType (typeof (NSObject))]
- public interface NSAttributedString {
+ public partial interface NSAttributedString {
[Export ("string")]
string Value { get; }
@@ -346,10 +346,18 @@ public interface NSCalendar {
//- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;
//- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;
//- (BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate **)datep interval:(NSTimeInterval *)tip forDate:(NSDate *)date AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
- //- (NSDate *)dateFromComponents:(NSDateComponents *)comps;
- //- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)date;
- //- (NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts;
- //- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts;
+
+ [Export ("components:fromDate:")]
+ NSDateComponents Components (NSCalendarUnit unitFlags, NSDate fromDate);
+
+ [Export ("components:fromDate:toDate:options:")]
+ NSDateComponents Components (NSCalendarUnit unitFlags, NSDate fromDate, NSDate toDate, NSDateComponentsWrappingBehavior opts);
+
+ [Export ("dateByAddingComponents:toDate:options:")]
+ NSDate DateByAddingComponents (NSDateComponents comps, NSDate date, NSDateComponentsWrappingBehavior opts);
+
+ [Export ("dateFromComponents:")]
+ NSDate DateFromComponents (NSDateComponents comps);
[Field ("NSGregorianCalendar"), Internal]
NSString NSGregorianCalendar { get; }
@@ -852,7 +860,173 @@ public interface NSDateFormatter {
[Export ("gregorianStartDate")]
NSDate GregorianStartDate { get; set; }
}
+
+ public delegate void NSFileHandleUpdateHandler (NSFileHandle handle);
+
+ public interface NSFileHandleReadEventArgs {
+ [Export ("NSFileHandleNotificationDataItem")]
+ NSData AvailableData { get; }
+
+ [Export ("NSFileHandleError", ArgumentSemantic.Assign)]
+ int UnixErrorCode { get; }
+ }
+
+ public interface NSFileHandleConnectionAcceptedEventArgs {
+ [Export ("NSFileHandleNotificationFileHandleItem")]
+ NSFileHandle NearSocketConnection { get; }
+
+ [Export ("NSFileHandleError", ArgumentSemantic.Assign)]
+ int UnixErrorCode { get; }
+ }
+ [BaseType (typeof (NSObject))]
+ [DisableDefaultCtor] // return invalid handle
+ public interface NSFileHandle
+ {
+ [Export ("availableData")]
+ NSData AvailableData ();
+
+ [Export ("readDataToEndOfFile")]
+ NSData ReadDataToEndOfFile ();
+
+ [Export ("readDataOfLength:")]
+ NSData ReadDataOfLength (uint length);
+
+ [Export ("writeData:")]
+ void WriteData (NSData data);
+
+ [Export ("offsetInFile")]
+ ulong OffsetInFile ();
+
+ [Export ("seekToEndOfFile")]
+ ulong SeekToEndOfFile ();
+
+ [Export ("seekToFileOffset:")]
+ void SeekToFileOffset (ulong offset);
+
+ [Export ("truncateFileAtOffset:")]
+ void TruncateFileAtOffset (ulong offset);
+
+ [Export ("synchronizeFile")]
+ void SynchronizeFile ();
+
+ [Export ("closeFile")]
+ void CloseFile ();
+
+ [Static]
+ [Export ("fileHandleWithStandardInput")]
+ NSFileHandle FromStandardInput ();
+
+ [Static]
+ [Export ("fileHandleWithStandardOutput")]
+ NSFileHandle FromStandardOutput ();
+
+ [Static]
+ [Export ("fileHandleWithStandardError")]
+ NSFileHandle FromStandardError ();
+
+ [Static]
+ [Export ("fileHandleWithNullDevice")]
+ NSFileHandle FromNullDevice ();
+
+ [Static]
+ [Export ("fileHandleForReadingAtPath:")]
+ NSFileHandle OpenRead (string path);
+
+ [Static]
+ [Export ("fileHandleForWritingAtPath:")]
+ NSFileHandle OpenWrite (string path);
+
+ [Static]
+ [Export ("fileHandleForUpdatingAtPath:")]
+ NSFileHandle OpenUpdate (string path);
+
+ [Static]
+ [Export ("fileHandleForReadingFromURL:error:")]
+ NSFileHandle OpenReadUrl (NSUrl url, out NSError error);
+
+ [Static]
+ [Export ("fileHandleForWritingToURL:error:")]
+ NSFileHandle OpenWriteUrl (NSUrl url, out NSError error);
+
+ [Static]
+ [Export ("fileHandleForUpdatingURL:error:")]
+ NSFileHandle OpenUpdateUrl (NSUrl url, out NSError error);
+
+ [Export ("readInBackgroundAndNotifyForModes:")]
+ void ReadInBackground (NSString [] notifyRunLoopModes);
+
+ [Export ("readInBackgroundAndNotify")]
+ void ReadInBackground ();
+
+ [Export ("readToEndOfFileInBackgroundAndNotifyForModes:")]
+ void ReadToEndOfFileInBackground (NSString [] notifyRunLoopModes);
+
+ [Export ("readToEndOfFileInBackgroundAndNotify")]
+ void ReadToEndOfFileInBackground ();
+
+ [Export ("acceptConnectionInBackgroundAndNotifyForModes:")]
+ void AcceptConnectionInBackground (NSString [] notifyRunLoopModes);
+
+ [Export ("acceptConnectionInBackgroundAndNotify")]
+ void AcceptConnectionInBackground ();
+
+ [Export ("waitForDataInBackgroundAndNotifyForModes:")]
+ void WaitForDataInBackground (NSString [] notifyRunLoopModes);
+
+ [Export ("waitForDataInBackgroundAndNotify")]
+ void WaitForDataInBackground ();
+
+ [Export ("initWithFileDescriptor:closeOnDealloc:")]
+ IntPtr Constructor (int fd, bool closeOnDealloc);
+
+ [Export ("initWithFileDescriptor:")]
+ IntPtr Constructor (int fd);
+
+ [Export ("fileDescriptor")]
+ int FileDescriptor { get; }
+
+ [Export ("setReadabilityHandler:")]
+ void SetReadabilityHandler ([NullAllowed] NSFileHandleUpdateHandler readCallback);
+
+ [Export ("writeabilityHandler:")]
+ void SetWriteabilityHandle ([NullAllowed] NSFileHandleUpdateHandler writeCallback);
+
+ [Field ("NSFileHandleOperationException")]
+ NSString OperationException { get; }
+
+ [Field ("NSFileHandleReadCompletionNotification")]
+ [Notification (typeof (NSFileHandleReadEventArgs))]
+ NSString ReadCompletionNotification { get; }
+
+ [Field ("NSFileHandleReadToEndOfFileCompletionNotification")]
+ [Notification (typeof (NSFileHandleReadEventArgs))]
+ NSString ReadToEndOfFileCompletionNotification { get; }
+
+ [Field ("NSFileHandleConnectionAcceptedNotification")]
+ [Notification (typeof (NSFileHandleConnectionAcceptedEventArgs))]
+ NSString ConnectionAcceptedNotification { get; }
+
+
+ [Field ("NSFileHandleDataAvailableNotification")]
+ [Notification]
+ NSString DataAvailableNotification { get; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ public interface NSPipe {
+
+ [Export ("fileHandleForReading")]
+ NSFileHandle ReadHandle { get; }
+
+ [Export ("fileHandleForWriting")]
+ NSFileHandle WriteHandle { get; }
+
+ [Static]
+ [Export ("pipe")]
+ NSPipe Create ();
+ }
+
//@interface NSFormatter : NSObject <NSCopying, NSCoding>
[BaseType (typeof (NSObject))]
public interface NSFormatter {
@@ -3639,7 +3813,7 @@ public interface NSStringDrawingContext {
}
#endif
[BaseType (typeof (NSStream))]
- [DisableDefaultCtor] // crash when used
+ [DefaultCtorVisibility (Visibility.Protected)]
public interface NSInputStream {
[Export ("hasBytesAvailable")]
bool HasBytesAvailable ();
@@ -4195,7 +4369,7 @@ public partial interface NSBundle {
#else
// http://developer.apple.com/library/ios/#documentation/uikit/reference/NSBundle_UIKitAdditions/Introduction/Introduction.html
[Export ("loadNibNamed:owner:options:")]
- NSArray LoadNib (string nibName, NSObject owner, [NullAllowed] NSDictionary options);
+ NSArray LoadNib (string nibName, [NullAllowed] NSObject owner, [NullAllowed] NSDictionary options);
#endif
[Export ("bundleURL")]
[Since (4,0)]
@@ -4676,7 +4850,7 @@ public interface NSNotificationQueue {
[BaseType (typeof (NSObject))]
// init returns NIL
[DisableDefaultCtor]
- public interface NSValue {
+ public partial interface NSValue {
[Export ("getValue:")]
void StoreValueAtAddress (IntPtr value);
@@ -4745,18 +4919,6 @@ public interface NSValue {
[Export ("rangeValue")]
NSRange RangeValue { get; }
-
- [Static, Export ("valueWithSCNVector3:")]
- NSValue FromVector (MonoMac.OpenGL.Vector3 vector);
-
- [Static, Export ("valueWithSCNVector4:")]
- NSValue FromVector (MonoMac.OpenGL.Vector4 vector);
-
- [Export ("SCNVector3Value")]
- MonoMac.OpenGL.Vector3 Vector3Value { get; }
-
- [Export ("SCNVector4Value")]
- MonoMac.OpenGL.Vector4 Vector4Value { get; }
#else
[Static, Export ("valueWithCMTime:"), Since (4,0)]
NSValue FromCMTime (CMTime time);
@@ -6170,7 +6332,7 @@ interface NSUrlProtocol {
IntPtr Constructor (NSUrlRequest request, [NullAllowed] NSCachedUrlResponse cachedResponse, NSUrlProtocolClient client);
[Export ("client")]
- NSObject WeakClient { get; set; }
+ NSObject WeakClient { get; }
[Export ("request")]
NSUrlRequest Request { get; }
View
208 src/generator.cs
@@ -370,14 +370,35 @@ public sealed class ProtectedAttribute : Attribute {
// still instantiate object of this class internally from your
// extension file, but it just wont be accessible to users of your
// class.
-public class PrivateDefaultCtorAttribute : Attribute {
- public PrivateDefaultCtorAttribute () {}
+public class PrivateDefaultCtorAttribute : DefaultCtorVisibilityAttribute {
+ public PrivateDefaultCtorAttribute () : base (Visibility.Private) {}
+}
+
+public enum Visibility {
+ Public,
+ Protected,
+ Internal,
+ ProtectedInternal,
+ Private,
+ Disabled
+}
+
+// When this attribute is applied to the interface definition it will
+// flag the default ctor with the corresponding visibility (or disabled
+// altogether if Visibility.Disabled is used).
+public class DefaultCtorVisibilityAttribute : Attribute {
+ public DefaultCtorVisibilityAttribute (Visibility visibility)
+ {
+ this.Visibility = visibility;
+ }
+
+ public Visibility Visibility { get; set; }
}
// When this attribute is applied to the interface definition it will
// prevent the generator from producing the default constructor.
-public class DisableDefaultCtorAttribute : Attribute {
- public DisableDefaultCtorAttribute () {}
+public class DisableDefaultCtorAttribute : DefaultCtorVisibilityAttribute {
+ public DisableDefaultCtorAttribute () : base (Visibility.Disabled) {}
}
//
@@ -634,6 +655,24 @@ public class NotImplementedAttribute : Attribute {
}
//
+// Apply this attribute to a class to add methods that in Objective-c
+// are added as categories
+//
+// Use the BaseType attribute to reference which class this is extending
+//
+// Like this:
+// [Category]
+// [BaseType (typeof (UIView))]
+// interface UIViewExtensions {
+// [Export ("method_in_the_objective_c_category")]
+// void ThisWillBecome_a_c_sharp_extension_method_in_class_UIViewExtensions ();
+// }
+[AttributeUsage (AttributeTargets.Interface, AllowMultiple=false)]
+public class CategoryAttribute : Attribute {
+ public CategoryAttribute () {}
+}
+
+//
// Used to encapsulate flags about types in either the parameter or the return value
// For now, it only supports the [PlainString] attribute on strings.
//
@@ -740,10 +779,10 @@ public static GeneratedType Lookup (Type t)
public GeneratedType (Type t)
{
Type = t;
- foreach (var iface in Type.GetInterfaces ())
+ foreach (var iface in Type.GetInterfaces ()){
if (iface.Name == "UIAppearance")