Skip to content

General code design

theGreatWhiteShark edited this page Oct 22, 2021 · 1 revision

Here I want to give you an overview of the general design of the application. It can be considered a must-read regardless of which part of Hydrogen you are interested in.

Viewed on an abstract and slightly oversimplified level Hydrogen can be considered to consist of two independent parts: its core and its GUI (both written in C++ and the latter using Qt5). They are not just separated physically at the source code level but also in terms of their responsibilities.

Responsibilities of the core

  • Creates the audio by combining samples from the drumkit
  • Contains the audio engine and controls playback/transport
  • Talks to the sound card and operation system
  • Loading and saving of songs and preferences
  • Holding representations of patterns, drumkits, samples, songs etc.
  • Receives, processes, and sends messages like MIDI or OSC
  • Encapsulated in the H2Core namespace
  • Runs in real-time.

Responsibilities of the GUI

  • Displays the current state of the core, like transport position, selected song, and pattern
  • Used to alter the state of the core (e.g. by changing preferences, creating and modifying patterns, or adjusting volumes)
  • Conveniently bundles properties in views, like the mixer or the pattern and instrument editor
  • Updated 20 times per second and is not real-time save

Interaction between the core and GUI

The core of Hydrogen can be considered its heart, which is pulsating in real-time and takes care of all the heavy lifting. It exposes an API to the GUI using its various classes and has its state altered directly through it when e.g. the user is pressing the play button or adjusting the volume of an instrument.

But the core also needs to propagate information back to the GUI. This is done by pushing an H2Core::Event to the H2Core::EventQueue. Whenever the GUI is updated (20 times per second) it checks its EventListener whether there are unprocessed events it has to handle.

\section startup Startup

For those of you not familiar with Qt or C++ programming in general it might not be obvious at all how a complex application like Hydrogen is starting up when invoked via command line (at least for me it wasn't). Since this knowledge might be essential for the bug you tackle, I try to sketch the overall startup process in this section (in order).

  1. The entry point after invocation is the main function in src/gui/src/main.cpp.

  2. It parses the command line arguments and sets the log level.

  3. It reates an instance of the Logger, Preferences, Hydrogen singletons and a couple of others.

    The later will start the core of part of the application and trigger a number of routines before returning to the context of the main function again.

  4. It starts the NSM client using.

  5. Creates and loads the src/gui/src/MainForm, which itself will create the instance of the src/gui/src/HydrogenApp singleton and thus initiate the whole GUI.

  6. Loads a drumkit if specified using command line arguments.

  7. Now Hydrogen is fully initialized and the Qt object enters an infinite loop. It will response to user interaction and checks for events queued by the core 20 times per second.