unsafe AudioUnitStatus AudioUnit_RenderCallback(AudioUnitRenderActionFlags actionFlags,
                                                        AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data)
        {
            _clock.Restart();
            AudioUnitStatus err = AudioUnitStatus.OK;

            if (_audioInputIsAvailable && _numInputChannels > 0)
            {
                err = _audioUnit.Render(ref actionFlags, timeStamp, 1, numberFrames, data);
            }

            var dataPtr = data[0].Data;

            if (_callback != null)
            {
                if (numberFrames > _sampleBuffer.NumSamples)
                {
                    PrepareFloatBuffers((int)numberFrames);
                }

                if (_audioInputIsAvailable && _numInputChannels > 0)
                {
                    var shortData = (short *)dataPtr.ToPointer();
                    if (_numInputChannels >= 2)
                    {
                        float *leftInput  = _inputChannels[0];
                        float *rightInput = _inputChannels[1];
                        for (var i = 0; i < numberFrames; ++i)
                        {
                            *leftInput++  = *shortData++ *ShortToFloat;
                            *rightInput++ = *shortData++ *ShortToFloat;
                        }
                    }
                    else
                    {
                        float *leftInput = _inputChannels[0];
                        for (var i = 0; i < numberFrames; ++i)
                        {
                            *leftInput++ = *shortData++ *ShortToFloat;
                            ++shortData;
                        }
                    }
                }
                else
                {
                    for (var i = _numInputChannels; --i >= 0;)
                    {
                        _sampleBuffer.ClearChannel(i);
                    }
                }

                _callback.AudioDeviceIOCallback(
                    _inputChannels, _numInputChannels,
                    _outputChannels, _numOutputChannels,
                    (int)numberFrames
                    );

                if (_out != null)
                {
                    byte *bytes = (byte *)_outputChannels[0];
                    for (var i = 0; i < numberFrames * sizeof(float); ++i)
                    {
                        _out.WriteByte(*bytes++);
                    }
                }

                {
                    var    shortData   = (short *)dataPtr.ToPointer();
                    float *leftOutput  = _outputChannels[0];
                    float *rightOutput = _outputChannels[1];
                    if (_numOutputChannels >= 2)
                    {
                        for (var i = 0; i < numberFrames; ++i)
                        {
                            *shortData++ = (short)(*leftOutput++ *FloatToShort);
                            *shortData++ = (short)(*rightOutput++ *FloatToShort);
                        }
                    }
                    else if (_numOutputChannels == 1)
                    {
                        float *output = _outputChannels[0];
                        for (var i = 0; i < numberFrames; ++i)
                        {
                            short sample      = (short)(*output++ *FloatToShort);
                            *     shortData++ = sample;
                            *     shortData++ = sample;
                        }
                    }
                    else
                    {
                        for (var i = 0; i < numberFrames; ++i)
                        {
                            *shortData++ = 0;
                            *shortData++ = 0;
                        }
                    }
                }
            }
            else
            {
                var shortData = (short *)dataPtr.ToPointer();
                for (var i = 0; i < numberFrames; ++i)
                {
                    *shortData++ = 0;
                    *shortData++ = 0;
                }
            }

            _clock.Stop();

            return(err);
        }