void OnAudioFilterRead(float[] samples, int channelCount)
        {
            lock (this)
            {
                int coeffCount = Ambisonic.GetCoeffCount(_order);
                if (_sink != null && coeffCount > 0)
                {
                    int samplesOffset = 0;
                    // While there are sample to process
                    while (samplesOffset < samples.Length)
                    {
                        // If the pending buffer is full, move it to the full ist
                        if (_activeSamples != null && _activeSamples.Length == _activeSampleIndex)
                        {
                            _fullBuffers.Enqueue(_activeSamples);
                            _activeSamples     = null;
                            _activeSampleIndex = 0;
                        }
                        // Assign a new pending queue
                        if (_activeSamples == null && _emptyBuffers.Count > 0)
                        {
                            _activeSamples = _emptyBuffers.Dequeue();
                        }
                        if (_activeSamples == null)
                        {
                            // Remaining samples are lost!
                            break;
                        }
                        int remainingFrameCount  = (samples.Length - samplesOffset) / channelCount;
                        int generatedSampleCount = remainingFrameCount * coeffCount;
                        int remainingSampleSpace = (_activeSamples.Length - _activeSampleIndex);

                        int samplesToProcess = Mathf.Min(remainingSampleSpace, generatedSampleCount);
                        // TODO: should we specify Floor/Ceil rounding behaviour?
                        int framesToProcess = samplesToProcess / coeffCount;
                        generatedSampleCount = framesToProcess * coeffCount;

                        if (framesToProcess > 0)
                        {
                            NativePlugin.EncodeMonoToAmbisonic(_sourceInstance, samples, samplesOffset, framesToProcess, channelCount, _activeSamples, _activeSampleIndex, _activeSamples.Length, _order);
                            _activeSampleIndex += generatedSampleCount;
                            samplesOffset      += framesToProcess * channelCount;
                        }
                        else
                        {
                            Debug.Log(coeffCount + " " + framesToProcess + "   " + remainingSampleSpace + " >>  " + samplesOffset + " /  " + samples.Length);
                            break;
                        }
                    }
                }
            }
        }