示例#1
0
        public AudioConverterError FillComplexBuffer(ref int outputDataPacketSize,
                                                     AudioBuffers outputData, AudioStreamPacketDescription[] packetDescription)
        {
            if (outputData == null)
            {
                throw new ArgumentNullException(nameof(outputData));
            }

            return(FillComplexBuffer(ref outputDataPacketSize, outputData, packetDescription, new Tuple <AudioConverter, AudioConverterComplexInputData> (this, null)));
        }
示例#2
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));
        }
示例#3
0
        public AudioConverterError ConvertComplexBuffer(int numberPCMFrames, AudioBuffers inputData, AudioBuffers outputData)
        {
            if (inputData is null)
            {
                ObjCRuntime.ThrowHelper.ThrowArgumentNullException(nameof(inputData));
            }
            if (outputData is null)
            {
                ObjCRuntime.ThrowHelper.ThrowArgumentNullException(nameof(outputData));
            }

            return(AudioConverterConvertComplexBuffer(Handle, numberPCMFrames, (IntPtr)inputData, (IntPtr)outputData));
        }
示例#4
0
        public AudioConverterError FillComplexBuffer(ref int outputDataPacketSize,
                                                     AudioBuffers outputData, AudioStreamPacketDescription[] packetDescription, AudioConverterComplexInputData newInputDataHandler)
        {
            if (outputData is null)
            {
                ObjCRuntime.ThrowHelper.ThrowArgumentNullException(nameof(outputData));
            }

            if (newInputDataHandler is null)
            {
                ObjCRuntime.ThrowHelper.ThrowArgumentNullException(nameof(newInputDataHandler));
            }

            return(FillComplexBuffer(ref outputDataPacketSize, outputData, packetDescription, new Tuple <AudioConverter, AudioConverterComplexInputData?> (this, newInputDataHandler)));
        }
示例#5
0
        AudioConverterError FillComplexBuffer(ref int outputDataPacketSize,
                                              AudioBuffers outputData, AudioStreamPacketDescription[] packetDescription, Tuple <AudioConverter, AudioConverterComplexInputData> instanceData)
        {
            var this_handle = GCHandle.Alloc(instanceData);

            try {
                var this_ptr = GCHandle.ToIntPtr(this_handle);

                if (packetDescription == null)
                {
                    return(AudioConverterFillComplexBuffer(handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr)outputData, IntPtr.Zero));
                }

                unsafe
                {
                    fixed(AudioStreamPacketDescription *pdesc = &packetDescription[0])
                    {
                        return(AudioConverterFillComplexBuffer(handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr)outputData, (IntPtr)pdesc));
                    }
                }
            } finally {
                this_handle.Free();
            }
        }
示例#6
0
        static AudioConverterError FillComplexBufferShared(IntPtr inAudioConverter, ref int ioNumberDataPackets, IntPtr ioData,
                                                           IntPtr outDataPacketDescription, IntPtr inUserData)
        {
            var handler      = GCHandle.FromIntPtr(inUserData);
            var instanceData = (Tuple <AudioConverter, AudioConverterComplexInputData>)handler.Target;
            var inst         = instanceData.Item1;
            var callback     = instanceData.Item2;

            // Invoke event handler with an argument
            // since callback is not provided, must come from the old FillComplexBuffer call
            if (callback == null && inst.InputData == null)
            {
                throw new ArgumentNullException("InputData");
            }
            // Check if subscribed to event and provided a callback, error out if true
            else if (callback != null && inst.InputData != null)
            {
                throw new InvalidOperationException("Please either only subscribe to InputData event or provide newInputDataHandler in FillComplexBuffer, using both is unsuported.");
            }

            using (var buffers = new AudioBuffers(ioData)) {
                //
                // Callback is supposed to fill outDataPacketDescription when outDataPacketDescription is not NULL
                // Using 0-size array as marker because the size of pre-allocated memory is not known
                //
                var data = outDataPacketDescription == IntPtr.Zero ? null : new AudioStreamPacketDescription [0];

                var res = inst.InputData != null?
                          inst.InputData(ref ioNumberDataPackets, buffers, ref data) :
                              callback(ref ioNumberDataPackets, buffers, ref data);

                if (outDataPacketDescription != IntPtr.Zero)
                {
                    if (ioNumberDataPackets > 0)
                    {
                        if (data == null || data.Length == 0)
                        {
                            throw new ArgumentException("ref argument outDataPacketDescription has to be set");
                        }

                        //
                        // Apple doc says the output buffer has to be pre-allocated using last argument to
                        // AudioConverterFillComplexBuffer but even if NULL is passed and convertor requires
                        // packet description outDataPacketDescription is not NULL and it such case we will
                        // write at some unknown pointer location, similar situation happens when initialization
                        // size does not match data size
                        //
                        int size = Marshal.SizeOf(data [0]);
                        // Clear our buffer if it's not big enough
                        if (inst.packetDescriptionSize < data.Length && inst.packetDescriptions != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(inst.packetDescriptions);
                            inst.packetDescriptions = IntPtr.Zero;
                        }
                        // Create a new buffer if we don't already have one
                        if (inst.packetDescriptions == IntPtr.Zero)
                        {
                            inst.packetDescriptionSize = data.Length;
                            inst.packetDescriptions    = Marshal.AllocHGlobal(data.Length * size);
                        }
                        unsafe
                        {
                            fixed(void *source = data)
                            {
                                Buffer.MemoryCopy(source, (void *)inst.packetDescriptions, inst.packetDescriptionSize * size, data.Length * size);
                            }
                        }
                        Marshal.WriteIntPtr(outDataPacketDescription, inst.packetDescriptions);
                    }
                    else
                    {
                        Marshal.WriteIntPtr(outDataPacketDescription, IntPtr.Zero);
                    }
                }

                return(res);
            }
        }