/// <summary>
        /// Encodes a frame.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <returns></returns>
        public override byte[] Encode(AudioBuffer frame)
        {
            if (_Encoder == null)
            {
                _Encoder         = new CocoaOpusEncoder(ClockRate, Channels, PacketTime);
                _Encoder.Quality = 1.0;
                _Encoder.Bitrate = 125;
            }

            using (var pool = new NSAutoreleasePool())
            {
                GCHandle dataHandle = GCHandle.Alloc(frame.Data, GCHandleType.Pinned);
                try
                {
                    IntPtr dataPointer = dataHandle.AddrOfPinnedObject();

                    using (var buffer = new CocoaOpusBuffer {
                        Data = NSData.FromBytesNoCopy(dataPointer, (uint)frame.Data.Length, false),
                        Index = frame.Index,
                        Length = frame.Length
                    })
                    {
                        using (var encodedFrameData = _Encoder.EncodeBuffer(buffer))
                        {
                            return(encodedFrameData.ToArray());
                        }
                    }
                }
                finally
                {
                    dataHandle.Free();
                }
            }
        }
        /// <summary>
        /// Encodes a frame.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <returns></returns>
        public override byte[] Encode(AudioBuffer frame)
		{
			if (_Encoder == null)
			{
				_Encoder = new CocoaOpusEncoder(ClockRate, Channels, PacketTime);
                _Encoder.Quality = 1.0;
                _Encoder.Bitrate = 125;
			}

			using (var pool = new NSAutoreleasePool())
			{
				GCHandle dataHandle = GCHandle.Alloc(frame.Data, GCHandleType.Pinned);
				try
				{
					IntPtr dataPointer = dataHandle.AddrOfPinnedObject();

					using (var buffer = new CocoaOpusBuffer {
						Data = NSData.FromBytesNoCopy(dataPointer, (uint)frame.Data.Length, false),
						Index = frame.Index,
						Length = frame.Length
					})
					{
						using (var encodedFrameData = _Encoder.EncodeBuffer(buffer))
						{
							return encodedFrameData.ToArray();
						}
					}
				}
				finally
				{
					dataHandle.Free();
				}
			}
        }
        /// <summary>
        /// Destroys the codec.
        /// </summary>
        public override void Destroy()
        {
            if (_Encoder != null)
            {
                _Encoder.Destroy();
                _Encoder.Dispose();
                _Encoder = null;
            }

            if (_Decoder != null)
            {
                _Decoder.Destroy();
                _Decoder.Dispose();
                _Decoder = null;
            }
        }
        /// <summary>
        /// Destroys the codec.
        /// </summary>
        public override void Destroy()
        {
            if (_Encoder != null)
            {
                _Encoder.Destroy();
                _Encoder.Dispose();
                _Encoder = null;
            }

            if (_Decoder != null)
            {
                _Decoder.Destroy();
                _Decoder.Dispose();
                _Decoder = null;
            }
        }