Description
The upload() implementation of the various input plugins have subtly different and inconsistent characteristics that can cause synchronisation problems.
The current rendering logic (in LV::Bin) behaves best when:
- upload() returns a copy of the previous uploaded data if input cannot keep up with call frequency
- upload() drops samples that were not read in time
Please note that the above are not recommended as requirements. I discuss my reasons after the next section.
Below is an overview of how individual input plugins actually behave:
- input_pulseaudio violates (1) and (2), causing stuttering when call rate is too high, and lag when call rate is too low.
- input_debug violates (1) and (2) but has internal logic to slow the data generation down.
- input_mplayer observes (1) and (2), as it simply copies a fixed intermediary buffer written to by an external mplayer process during playback.
- input_wavein observes (1) and (2) by virtue of its threaded implementation and behaves like input_mplayer
- input_alsa observes the effects of (1) and (2) by draining all input data and passing it into LV::Audio
- input_jack observes (1) and (2) works in a similar way as input_wavein, but without explicit threading as JACK asynchronously calls the plugin-supplied handler to process new input data. It also uses a single buffer which may cause weird artifacts when it is both read and written at the same time,
The biggest challenge for the input system is to handle situations where the upload() call rate is either too low or too high. Both can happen due to the variability of frame rendering times that depend very much on specific actors and rendering dimensions.
(1) and (2) shouldn't be defined as requirements. The biggest reason is that duplicated or dropped samples can screw up beat detection and spectral analysis. It is best to keep the input as faithful as possible (up to a certain length of time to conserve memory).