lmms
lmms copied to clipboard
Engine decoupling proposal
I have a proposal for a large step to reduce the coupling between components managed by Engine
.
Certain components currently managed by Mixer
could be managed by Engine
directly: the audio and MIDI devices, MixerProfiler
, fifo
, and FifoWriter
. Engine
would also check for metronome samples and manage the song playing position (PlayPos
), as the metronome also needs it.
The core method for buffer rendering (Mixer::renderNextBuffer()
) would also be moved to Engine
, while the parts of the rendering process handled by Mixer
would be split into two methods (startNextBuffer()
and finishBuffer()
). Here is a pseudocode illustrating the new method:
void Engine::renderNextBuffer()
{
mixerProfiler.startPeriod();
mixer->startNextBuffer();
song->processNextBuffer(m_playPos[m_playMode]); //The argument is a reference
checkForMetronome(); //Decide if a metronome sample needs to be played
mixer->finishBuffer();
EnvelopeAndLfoParameters::instances()->trigger();
Controller::triggerFrameCounter();
AutomatableModel::incrementPeriodCounter();
BufferManager::refresh();
mixerProfiler.finishPeriod();
}
Similarly, Engine
would look like:
class Engine
{
public:
getNextBuffer(); //Decide between reading from the FIFO or calling renderNextBuffer(). Used by the audio device
/// [...]
private:
renderNextBuffer();
m_playPos;
m_playMode;
m_song;
m_bbTrackContainer;
m_dummyTrackContainer;
m_fxMixer;
m_mixer;
m_fifo;
m_fifoWriter;
m_ladspaManager;
m_audioDevice;
m_oldAudioDevice;
m_midiDevice;
m_instanceOfMe;
}
There are still other coupling problems, but these can be solved later. These include:
- The dependency of many objects on
Mixer
methods providing information, likeframesPerPeriod()
,baseSampleRate()
, andprocessingSampleRate()
, which are accessible globally. - Similarly, we have the methods
addPlayHandle()
andremovePlayHandle()
. A possibility is to create aPlayHandleManager
and freeMixer
from the task of managing play handles.
In case no one has objections, I can start writing the new code and create a pull request.
@sakertooth might wanna look at this.