blob: d397458890a28c46fde22daf180682ede14652dd [file] [log] [blame] [view]
Phil Burke7143e02019-09-04 15:19:17 -07001# Notes on Implementation
2
3## Latency from Resampling
4
5There are two components of the latency. The resampler itself, and a buffer that
6is used to adapt the block sizes.
7
81) The resampler is an FIR running at the target sample rate. So its latency is the number of taps.
9From MultiChannelResampler.cpp, numTaps is
10
11 Fastest: 2
12 Low: 4
13 Medium: 8
14 High: 16
15 Best: 32
16
17For output, the device sampling rate is used, which is typically 48000.For input, the app sampling rate is used.
18
Phil Burk3be25532019-12-20 16:20:57 -0800192) There is a block size adapter that collects odd sized blocks into larger blocks of the correct size.
Phil Burke7143e02019-09-04 15:19:17 -070020
21The adapter contains one burst of frames, from getFramesPerBurst(). But if the app specifies a
22particular size using setFramesPerCallback() then that size will be used.
23Here is some pseudo-code to calculate the latency.
24
25 latencyMillis = 0
26 targetRate = isOutput ? deviceRate : applicationRate
27 // Add latency from FIR
28 latencyMillis += numTaps * 1000.0 / targetRate
29 // Add latency from block size adaptation
30 adapterSize = (callbackSize > 0) ? callbackSize : burstSize
31 if (isOutput && isCallbackUsed) latencyMillis += adapterSize * 1000.0 / deviceRate
32 else if (isInput && isCallbackUsed) latencyMillis += adapterSize * 1000.0 / applicationRate
33 else if (isInput && !isCallbackUsed) latencyMillis += adapterSize * 1000.0 / deviceRate