static IntPtr InitializeMagicCookie(NativeAudioFile audioFile, NativeAudioConverter converter)
        {
            Contract.Requires(audioFile != null);
            Contract.Requires(converter != null);

            uint dataSize;
            uint isWritable;

            AudioFileStatus getStatus = audioFile.GetPropertyInfo(AudioFilePropertyId.MagicCookieData, out dataSize,
                                                                  out isWritable);

            if (getStatus != AudioFileStatus.Ok)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                    Resources.LosslessSampleDecoderGetCookieInfoError, getStatus));
            }

            if (dataSize == 0)
            {
                return(IntPtr.Zero);
            }

            IntPtr cookie = audioFile.GetProperty(AudioFilePropertyId.MagicCookieData, dataSize);

            AudioConverterStatus setStatus = converter.SetProperty(AudioConverterPropertyId.DecompressionMagicCookie,
                                                                   dataSize, cookie);

            if (setStatus != AudioConverterStatus.Ok)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                    Resources.LosslessSampleDecoderSetCookieError, setStatus));
            }

            return(cookie);
        }
示例#2
0
        internal NativeAudioFile(AudioFileType fileType, Stream stream)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead);
            Contract.Requires(stream.CanSeek);
            Contract.Ensures(_stream != null);
            Contract.Ensures(_stream == stream);
            Contract.Ensures(Handle != null);
            Contract.Ensures(!Handle.IsClosed);
            Contract.Ensures(_readCallback != null);
            Contract.Ensures(_getSizeCallback != null);

            _readCallback    = ReadCallback;
            _getSizeCallback = GetSizeCallback;

            _stream = stream;

            NativeAudioFileHandle outHandle;

            AudioFileStatus status = SafeNativeMethods.AudioFileOpenWithCallbacks(IntPtr.Zero, _readCallback, null,
                                                                                  _getSizeCallback, null, fileType, out outHandle);

            if (status != AudioFileStatus.Ok)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                    Resources.NativeAudioFileInitializationError, status));
            }

            Handle = outHandle;
        }
        AudioConverterStatus InputCallback(IntPtr handle, ref uint numberPackets, ref AudioBufferList data, IntPtr packetDescriptions, IntPtr userData)
        {
            Contract.Requires(data.Buffers.Length > 0);

            if (_buffer == null)
            {
                _buffer       = new byte[numberPackets * _audioFile.GetProperty <uint>(AudioFilePropertyId.PacketSizeUpperBound)];
                _bufferHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
            }

            if (_descriptionsHandle.IsAllocated)
            {
                _descriptionsHandle.Free();
            }

            uint            numBytes;
            var             inputDescriptions = new AudioStreamPacketDescription[numberPackets];
            AudioFileStatus status            = _audioFile.ReadPackets(out numBytes, inputDescriptions, _packetIndex,
                                                                       ref numberPackets, _bufferHandle.AddrOfPinnedObject());

            if (status != AudioFileStatus.Ok)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.NativeAudioConverterReadError,
                                                    status));
            }

            _packetIndex += numberPackets;

            data.Buffers[0].DataByteSize = numBytes;
            data.Buffers[0].Data         = _bufferHandle.AddrOfPinnedObject();

            // If this conversion requires packet descriptions, provide them:
            if (packetDescriptions != IntPtr.Zero)
            {
                _descriptionsHandle = GCHandle.Alloc(inputDescriptions, GCHandleType.Pinned);
                Marshal.WriteIntPtr(packetDescriptions, _descriptionsHandle.AddrOfPinnedObject());
            }

            return(AudioConverterStatus.Ok);
        }