private void OnAudioFilterRead(float[] samples, int channels) { buffer.Resize(sampleRate, channels); int samplesOffset = 0; while (buffer.Consume(samples, ref samplesOffset)) // consume 10 ms of data and send if 10 ms was availble (if not, finish filling the buffer on the next call) { var audioData = buffer.destination; var handle = GCHandle.Alloc(audioData, GCHandleType.Pinned); try { lock (this) { foreach (var sink in _sinks.Values) { sink.OnData( // OnData is an extension method in media_stream_interface.cs handle.AddrOfPinnedObject(), 16, sampleRate, channels, audioData.Length / channels); } } } finally { handle.Free(); } } for (int i = 0; i < samples.Length; i++) { samples[i] = 0f; } }