private unsafe void RenderAudioCallback(XtStream stream, object input, object output, int frames, double time, ulong position, bool timeValid, ulong error, object user) { var sampleCount = frames * 2; // 2 channels per frame, interleaved if (_scenes.Length == 0) { for (var i = 0; i < sampleCount; i++) { unsafe { ((float *)((IntPtr)output).ToPointer())[i] = 0; } } return; } var firstSceneFrames = _scenes[0].GetAudioData(frames); if (firstSceneFrames == null) { Array.Clear(_tmpAudioBuffer, 0, sampleCount); } else { Array.Copy(firstSceneFrames, _tmpAudioBuffer, sampleCount); } // for (var i = 1; i < _scenes.Length; i++) // { // var sceneFrames = _scenes[i].GetAudioData(frames); // // if (null == sceneFrames) continue; // // // Actual mixing. TODO: Optimize using SIMD intrinsics // for (var j = 0; j < sampleCount; j++) // { // var a = sceneFrames[j]; // var b = _tmpAudioBuffer[j]; // // _tmpAudioBuffer[j] = a + b - a * b; // } // } fixed(float *dataPtr = &_tmpAudioBuffer[0]) { SampleRate.src_float_to_short_array(dataPtr, (short *)((IntPtr)output).ToPointer(), sampleCount); } }