5
5
// Miguel de Icaza (miguel@novell.com)
7
7
// Copyright 2009 Novell, Inc
8
// Copyright 2011, 2012 Xamarin Inc.
9
10
// Permission is hereby granted, free of charge, to any person obtaining
10
11
// a copy of this software and associated documentation files (the
31
32
using System.Collections.Generic;
32
33
using System.Runtime.InteropServices;
33
34
using MonoMac.CoreFoundation;
35
using MonoMac.Foundation;
35
37
using OSStatus = System.Int32;
36
38
using AudioFileStreamID = System.IntPtr;
164
166
AudioFileType fileTypeHint,
165
167
out IntPtr file_id);
167
static AudioFileStream_PacketsProc dInPackets;
168
static AudioFileStream_PropertyListenerProc dPropertyListener;
170
static AudioFileStream ()
172
dInPackets = InPackets;
173
dPropertyListener = PropertyListener;
169
static readonly AudioFileStream_PacketsProc dInPackets = InPackets;
170
static readonly AudioFileStream_PropertyListenerProc dPropertyListener = PropertyListener;
176
172
[MonoPInvokeCallback(typeof(AudioFileStream_PacketsProc))]
177
173
static void InPackets (IntPtr clientData, int numberBytes, int numberPackets, IntPtr inputData, IntPtr packetDescriptions)
233
229
public AudioFileStreamStatus ParseBytes (int size, IntPtr data, bool discontinuity)
235
return AudioFileStreamParseBytes (handle, size, data, discontinuity ? (uint) 1 : (uint) 0);
231
return LastError = AudioFileStreamParseBytes (handle, size, data, discontinuity ? (uint) 1 : (uint) 0);
238
234
public AudioFileStreamStatus ParseBytes (byte [] bytes, bool discontinuity)
241
237
throw new ArgumentNullException ("bytes");
243
239
fixed (byte *bp = &bytes[0]){
244
return AudioFileStreamParseBytes (handle, bytes.Length, (IntPtr) bp, discontinuity ? (uint) 1 : (uint) 0);
240
return LastError = AudioFileStreamParseBytes (handle, bytes.Length, (IntPtr) bp, discontinuity ? (uint) 1 : (uint) 0);
261
257
fixed (byte *bp = &bytes[0]){
262
return AudioFileStreamParseBytes (handle, count, (IntPtr) (bp + offset) , discontinuity ? (uint) 1 : (uint) 0);
258
return LastError = AudioFileStreamParseBytes (handle, count, (IntPtr) (bp + offset) , discontinuity ? (uint) 1 : (uint) 0);
273
269
public AudioFileStreamStatus Seek (long packetOffset, out long dataByteOffset, out bool isEstimate)
276
var code = AudioFileStreamSeek (handle, packetOffset, out dataByteOffset, ref v);
277
if (code != AudioFileStreamStatus.Ok){
272
LastError = AudioFileStreamSeek (handle, packetOffset, out dataByteOffset, ref v);
273
if (LastError != AudioFileStreamStatus.Ok){
278
274
isEstimate = false;
276
isEstimate = (v & 1) == 1;
281
isEstimate = (v & 1) == 1;
285
282
[DllImport (Constants.AudioToolboxLibrary)]
286
extern static OSStatus AudioFileStreamGetPropertyInfo(
283
extern static AudioFileStreamStatus AudioFileStreamGetPropertyInfo(
287
284
AudioFileStreamID inAudioFileStream,
288
285
AudioFileStreamProperty inPropertyID,
289
286
out int outPropertyDataSize,
290
287
out int isWritable);
292
289
[DllImport (Constants.AudioToolboxLibrary)]
293
extern static OSStatus AudioFileStreamGetProperty(
290
extern static AudioFileStreamStatus AudioFileStreamGetProperty(
294
291
AudioFileStreamID inAudioFileStream,
295
292
AudioFileStreamProperty inPropertyID,
296
293
ref int ioPropertyDataSize,
308
var r = AudioFileStreamGetPropertyInfo (handle, property, out size, out writable);
305
LastError = AudioFileStreamGetPropertyInfo (handle, property, out size, out writable);
310
307
return IntPtr.Zero;
312
309
var buffer = Marshal.AllocHGlobal (size);
313
310
if (buffer == IntPtr.Zero)
314
311
return IntPtr.Zero;
316
r = AudioFileStreamGetProperty (handle, property, ref size, buffer);
313
LastError = AudioFileStreamGetProperty (handle, property, ref size, buffer);
319
316
Marshal.FreeHGlobal (buffer);
320
317
return IntPtr.Zero;
328
if (AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val)) == 0)
325
LastError = AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val));
339
if (AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val)) == 0)
337
LastError = AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val));
350
if (AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val)) == 0)
349
LastError = AudioFileStreamGetProperty (handle, property, ref size, (IntPtr) (&val));
356
T GetProperty<T> (AudioFileStreamProperty property)
356
unsafe T? GetProperty<T> (AudioFileStreamProperty property) where T : struct
358
358
int size, writable;
360
if (AudioFileStreamGetPropertyInfo (handle, property, out size, out writable) != 0)
360
LastError = AudioFileStreamGetPropertyInfo (handle, property, out size, out writable);
362
363
var buffer = Marshal.AllocHGlobal (size);
363
364
if (buffer == IntPtr.Zero)
366
var r = AudioFileStreamGetProperty (handle, property, ref size, buffer);
368
return (T) Marshal.PtrToStructure (buffer, typeof (T));
367
LastError = AudioFileStreamGetProperty (handle, property, ref size, buffer);
369
T result = *(T*) buffer;
372
375
Marshal.FreeHGlobal (buffer);
376
379
[DllImport (Constants.AudioToolboxLibrary)]
377
extern static OSStatus AudioFileStreamSetProperty(
380
extern static AudioFileStreamStatus AudioFileStreamSetProperty(
378
381
AudioFileStreamID inAudioFileStream,
379
382
AudioFileStreamProperty inPropertyID,
380
383
int inPropertyDataSize,
383
386
public bool SetProperty (AudioFileStreamProperty property, int dataSize, IntPtr propertyData)
385
return AudioFileStreamSetProperty (handle, property, dataSize, propertyData) == 0;
388
LastError = AudioFileStreamSetProperty (handle, property, dataSize, propertyData);
389
return LastError == 0;
388
392
[DllImport (Constants.AudioToolboxLibrary)]
389
extern static OSStatus AudioFileStreamClose(AudioFileStreamID inAudioFileStream);
393
extern static AudioFileStreamStatus AudioFileStreamClose(AudioFileStreamID inAudioFileStream);
391
395
public bool ReadyToProducePackets {
407
[Advice ("Use DataFormat")]
403
408
public AudioStreamBasicDescription StreamBasicDescription {
405
return GetProperty<AudioStreamBasicDescription> (AudioFileStreamProperty.DataFormat);
410
// TODO: PacketTableInfo=0x706e666f,
414
public AudioStreamBasicDescription DataFormat {
416
return GetProperty<AudioStreamBasicDescription> (AudioFileStreamProperty.DataFormat) ?? default (AudioStreamBasicDescription);
420
public unsafe AudioFormat [] FormatList {
423
var r = GetProperty (AudioFileStreamProperty.FormatList, out size);
424
if (r == IntPtr.Zero)
427
var records = (AudioFormat *) r;
428
int itemSize = sizeof (AudioFormat);
429
int items = size/itemSize;
430
var ret = new AudioFormat [items];
432
for (int i = 0; i < items; i++)
433
ret [i] = records [i];
435
Marshal.FreeHGlobal (r);
440
public AudioFilePacketTableInfo? PacketTableInfo {
442
return GetProperty<AudioFilePacketTableInfo> (AudioFileStreamProperty.PacketTableInfo);
412
446
public byte [] MagicCookie {
472
506
AudioFramePacketTranslation *p = &buffer;
473
int size = Marshal.SizeOf (buffer);
474
if (AudioFileStreamGetProperty (handle, AudioFileStreamProperty.PacketToFrame, ref size, (IntPtr) p) == 0)
507
int size = sizeof (AudioFramePacketTranslation);
508
LastError = AudioFileStreamGetProperty (handle, AudioFileStreamProperty.PacketToFrame, ref size, (IntPtr) p);
475
510
return buffer.Frame;
486
521
AudioFramePacketTranslation *p = &buffer;
487
int size = Marshal.SizeOf (buffer);
488
if (AudioFileStreamGetProperty (handle, AudioFileStreamProperty.FrameToPacket, ref size, (IntPtr) p) == 0){
522
int size = sizeof (AudioFramePacketTranslation);
523
LastError = AudioFileStreamGetProperty (handle, AudioFileStreamProperty.FrameToPacket, ref size, (IntPtr) p);
489
525
frameOffsetInPacket = buffer.FrameOffsetInPacket;
490
526
return buffer.Packet;
503
539
AudioBytePacketTranslation *p = &buffer;
504
int size = Marshal.SizeOf (buffer);
505
if (AudioFileStreamGetProperty (handle, AudioFileStreamProperty.PacketToByte, ref size, (IntPtr) p) == 0){
506
isEstimate = (buffer.Flags & 1) == 1;
540
int size = sizeof (AudioBytePacketTranslation);
541
LastError = AudioFileStreamGetProperty (handle, AudioFileStreamProperty.PacketToByte, ref size, (IntPtr) p);
543
isEstimate = (buffer.Flags & BytePacketTranslationFlags.IsEstimate) != 0;
507
544
return buffer.Byte;
509
546
isEstimate = false;
520
557
AudioBytePacketTranslation *p = &buffer;
521
int size = Marshal.SizeOf (buffer);
522
if (AudioFileStreamGetProperty (handle, AudioFileStreamProperty.ByteToPacket, ref size, (IntPtr) p) == 0){
523
isEstimate = (buffer.Flags & 1) == 1;
558
int size = sizeof (AudioBytePacketTranslation);
559
LastError = AudioFileStreamGetProperty (handle, AudioFileStreamProperty.ByteToPacket, ref size, (IntPtr) p);
561
isEstimate = (buffer.Flags & BytePacketTranslationFlags.IsEstimate) != 0;
524
562
byteOffsetInPacket = buffer.ByteOffsetInPacket;
525
563
return buffer.Packet;