hydrogen 1.1.1
H2Core Namespace Reference

Namespaces

namespace  Interpolation
 

Data Structures

class  ADSR
 Attack Decay Sustain Release envelope. More...
 
class  AlsaAudioDriver
 
class  AlsaMidiDriver
 Alsa Midi Driver Based on Matthias Nagorni alsa sequencer example. More...
 
class  AudioEngine
 Audio Engine main class (Singleton). More...
 
class  AudioEngineLocking
 AudioEngineLocking. More...
 
class  AudioOutput
 Base abstract class for audio output classes. More...
 
class  AutomationPath
 
class  AutomationPathSerializer
 
struct  compare_pNotes
 
class  CoreActionController
 
class  CoreAudioDriver
 
class  CoreMidiDriver
 
class  DiskWriterDriver
 Driver for export audio to disk. More...
 
class  Drumkit
 Drumkit info. More...
 
class  DrumkitComponent
 
class  Effects
 
class  EnvelopePoint
 A container for a sample, being able to apply modifications on it. More...
 
class  Event
 Basic building block for the communication between the core of Hydrogen and its GUI. More...
 
class  EventQueue
 Object handling the communication between the core of Hydrogen and its GUI. More...
 
class  FakeDriver
 Fake audio driver. More...
 
class  Files
 Files is in charge of writing and reading Patterns, Drumkits, Songs to the filesystem. More...
 
class  Filesystem
 Filesystem is a thin layer over QDir, QFile and QFileInfo. More...
 
class  H2Exception
 
class  H2RGBColor
 
class  Hydrogen
 Hydrogen Audio Engine. More...
 
class  Instrument
 Instrument class. More...
 
class  InstrumentComponent
 
class  InstrumentLayer
 InstrumentLayer is part of an instrument
each layer has it's own :
gain which is the ration between the input sample and the output signal,
pitch which allows you to play the sample at a faster or lower frequency,
start velocity and end velocity which allows you to chose between a layer or another within an instrument by changing the velocity of the played note. More...
 
class  InstrumentList
 InstrumentList is a collection of instruments used within a song, a drumkit, ... More...
 
class  JackAudioDriver
 JACK (Jack Audio Connection Kit) server driver. More...
 
class  JackMidiDriver
 
class  LadspaControlPort
 
class  LadspaFX
 
class  LadspaFXGroup
 
class  LadspaFXInfo
 
class  Legacy
 Legacy is a container for legacy code which should be once removed. More...
 
class  LilyPond
 A class to convert a Hydrogen song to LilyPond format. More...
 
class  LocalFileMng
 
class  Logger
 Class for writing logs to the console. More...
 
class  MidiInput
 MIDI input base class. More...
 
class  MidiMessage
 
class  MidiOutput
 MIDI input base class. More...
 
class  MidiPortInfo
 
class  Note
 A note plays an associated instrument with a velocity left and right pan. More...
 
class  NullDriver
 
class  Object
 Base class. More...
 
class  OssDriver
 OSS Audio Driver. More...
 
class  Pattern
 Pattern class is a Note container. More...
 
class  PatternList
 PatternList is a collection of patterns. More...
 
class  Playlist
 Drumkit info. More...
 
class  PortAudioDriver
 
class  PortMidiDriver
 
class  Preferences
 Manager for User Preferences File (singleton) More...
 
class  PulseAudioDriver
 PulseAudio driver. More...
 
class  Sample
 
class  Sampler
 Waveform based sampler. More...
 
struct  SelectedLayerInfo
 
class  SilentMessageHandler
 
class  SMF
 
class  SMF0Writer
 
class  SMF1Writer
 
class  SMF1WriterMulti
 
class  SMF1WriterSingle
 
class  SMFBase
 
class  SMFBuffer
 
class  SMFCopyRightNoticeMetaEvent
 
class  SMFEvent
 
class  SMFHeader
 
class  SMFNoteOffEvent
 
class  SMFNoteOnEvent
 
class  SMFSetTempoMetaEvent
 
class  SMFTimeSignatureMetaEvent
 
class  SMFTrack
 
class  SMFTrackNameMetaEvent
 
class  SMFWriter
 
class  Song
 Song class. More...
 
class  SongEditorPanelBpmWidget
 
class  SongEditorPanelTagWidget
 
class  SongReader
 Read XML file of a song. More...
 
class  SongWriter
 Write XML file of a song. More...
 
class  SoundLibraryPropertiesDialog
 
class  Synth
 A simple synthetizer... More...
 
class  Timeline
 Timeline class storing and handling all TempoMarkers and Tags. More...
 
class  Translations
 Translations manager. More...
 
class  TransportInfo
 Object holding most of the information about the transport state of the AudioEngine, like if it is playing or stopped or its current transport position and speed. More...
 
class  UIStyle
 Colors for hydrogen. More...
 
class  WindowProperties
 
class  XMLDoc
 XMLDoc is a subclass of QDomDocument with read and write methods. More...
 
class  XMLNode
 XMLNode is a subclass of QDomNode with read and write values methods. More...
 

Typedefs

typedef int(* audioProcessCallback) (uint32_t, void *)
 
typedef std::vector< SMFEvent * > EventList
 

Enumerations

enum  EventType {
  EVENT_NONE , EVENT_STATE , EVENT_PATTERN_CHANGED , EVENT_PATTERN_MODIFIED ,
  EVENT_SELECTED_PATTERN_CHANGED , EVENT_SELECTED_INSTRUMENT_CHANGED , EVENT_PARAMETERS_INSTRUMENT_CHANGED , EVENT_MIDI_ACTIVITY ,
  EVENT_XRUN , EVENT_NOTEON , EVENT_ERROR , EVENT_METRONOME ,
  EVENT_RECALCULATERUBBERBAND , EVENT_PROGRESS , EVENT_JACK_SESSION , EVENT_PLAYLIST_LOADSONG ,
  EVENT_UNDO_REDO , EVENT_SONG_MODIFIED , EVENT_TEMPO_CHANGED , EVENT_UPDATE_PREFERENCES ,
  EVENT_UPDATE_SONG , EVENT_QUIT , EVENT_TIMELINE_ACTIVATION , EVENT_TIMELINE_UPDATE ,
  EVENT_JACK_TRANSPORT_ACTIVATION , EVENT_JACK_TIMEBASE_ACTIVATION , EVENT_SONG_MODE_ACTIVATION , EVENT_LOOP_MODE_ACTIVATION ,
  EVENT_ACTION_MODE_CHANGE
}
 Basic types of communication between the core part of Hydrogen and its GUI. More...
 
enum  SMFEventType { NOTE_OFF = 128 , NOTE_ON = 144 }
 
enum  SMFMetaEventType {
  SEQUENCE_NUMBER = 0 , TEXT_EVENT , COPYRIGHT_NOTICE , TRACK_NAME ,
  INSTRUMENT_NAME , LYRIC , MARKER , CUE_POINT ,
  END_OF_TRACK = 0x2f , SET_TEMPO = 0x51 , TIME_SIGNATURE = 0x58 , KEY_SIGNATURE
}
 

Functions

static float linear_interpolation (float fVal_A, float fVal_B, double fVal)
 
bool operator== (const AutomationPath &lhs, const AutomationPath &rhs)
 Compare two paths. More...
 
bool operator!= (const AutomationPath &lhs, const AutomationPath &rhs)
 
static float check_boundary (float v, float min, float max)
 
static double compute_pitch_scale (const Sample::Rubberband &r)
 
static RubberBand::RubberBandStretcher::Options compute_rubberband_options (const Sample::Rubberband &r)
 
void audioEngine_init ()
 Initialization of the H2Core::AudioEngine called in Hydrogen::Hydrogen(). More...
 
void audioEngine_destroy ()
 
int audioEngine_start (bool bLockEngine=false, unsigned nTotalFrames=0)
 If the audio engine is in state m_audioEngineState STATE_READY, this function will. More...
 
void audioEngine_stop (bool bLockEngine=false)
 If the audio engine is in state m_audioEngineState STATE_PLAYING, this function will. More...
 
void audioEngine_setSong (Song *pNewSong)
 Updates the global objects of the audioEngine according to new Song. More...
 
void audioEngine_removeSong ()
 Does the necessary cleanup of the global objects in the audioEngine. More...
 
static void audioEngine_noteOn (Note *note)
 
int audioEngine_process (uint32_t nframes, void *arg)
 Main audio processing function called by the audio drivers whenever there is work to do. More...
 
void audioEngine_clearNoteQueue ()
 
void audioEngine_process_checkBPMChanged (Song *pSong)
 Update the tick size based on the current tempo without affecting the current transport position. More...
 
void audioEngine_process_playNotes (unsigned long nframes)
 
void audioEngine_process_transport (unsigned nFrames)
 Updating the TransportInfo of the audio driver. More...
 
unsigned audioEngine_renderNote (Note *pNote, const unsigned &nBufferSize)
 
int audioEngine_updateNoteQueue (unsigned nFrames)
 Takes all notes from the current patterns, from the MIDI queue m_midiNoteQueue, and those triggered by the metronome and pushes them onto m_songNoteQueue for playback. More...
 
void audioEngine_prepNoteQueue ()
 
int findPatternInTick (int nTick, bool bLoopMode, int *pPatternStartTick)
 Find a PatternList corresponding to the supplied tick position nTick. More...
 
void audioEngine_seek (long long nFrames, bool bLoopMode=false)
 
void audioEngine_restartAudioDrivers ()
 Restart all audio and midi drivers by calling first audioEngine_stopAudioDrivers() and then audioEngine_startAudioDrivers(). More...
 
void audioEngine_startAudioDrivers ()
 Creation and initialization of all audio and MIDI drivers called in Hydrogen::Hydrogen(). More...
 
void audioEngine_stopAudioDrivers ()
 Stops all audio and MIDI drivers. More...
 
timeval currentTime2 ()
 Gets the current time. More...
 
int randomValue (int max)
 
float getGaussian (float z)
 
void audioEngine_raiseError (unsigned nErrorCode)
 
void audioEngine_process_clearAudioBuffers (uint32_t nFrames)
 Clear all audio buffers. More...
 
void audioEngine_setupLadspaFX ()
 
void audioEngine_renameJackPorts (Song *pSong)
 Hands the provided Song to JackAudioDriver::makeTrackOutputs() if pSong is not a null pointer and the audio driver m_pAudioDriver is an instance of the JackAudioDriver. More...
 
AudioOutputcreateDriver (const QString &sDriver)
 Create an audio driver using audioEngine_process() as its argument based on the provided choice and calling their init() function to trigger their initialization. More...
 
static int alsa_xrun_recovery (snd_pcm_t *handle, int err)
 
void * alsaAudioDriver_processCaller (void *param)
 
void * alsaMidiDriver_thread (void *param)
 
static void midiProc (const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)
 
void * diskWriterDriver_thread (void *param)
 
static int JackMidiProcessCallback (jack_nframes_t nframes, void *arg)
 
static void JackMidiShutdown (void *arg)
 
void * ossDriver_processCaller (void *param)
 
int portAudioCallback (const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
 
void * PortMidiDriver_thread (void *param)
 
void * loggerThread_func (void *param)
 
std::ostream & operator<< (std::ostream &os, const Object &object)
 
std::ostream & operator<< (std::ostream &os, const Object *object)
 
QDebug operator<< (QDebug d, Object *o)
 
QDebug operator<< (QDebug d, std::shared_ptr< Object > o)
 
static InstrumentcreateInstrument (int id, const QString &filepath, float volume)
 
std::string get_version ()
 Returns the current Hydrogen version string. More...
 
bool version_older_than (int major, int minor, int patch)
 return true of the current version is older than the given values More...
 

Variables

float m_fMasterPeak_L = 0.0f
 Master peak (left channel) More...
 
float m_fMasterPeak_R = 0.0f
 Master peak (right channel) More...
 
float m_fProcessTime = 0.0f
 time used in process function More...
 
float m_fMaxProcessTime = 0.0f
 max ms usable in process with no xrun More...
 
float m_fNewBpmJTM = 120
 Fallback speed in beats per minute. More...
 
AudioOutputm_pAudioDriver = nullptr
 Pointer to the current instance of the audio driver. More...
 
QMutex mutex_OutputPointer
 Mutex for locking the pointer to the audio output buffer, allowing multiple readers. More...
 
MidiInputm_pMidiDriver = nullptr
 MIDI input. More...
 
MidiOutputm_pMidiDriverOut = nullptr
 MIDI output. More...
 
std::priority_queue< Note *, std::deque< Note * >, compare_pNotesm_songNoteQueue
 Song Note FIFO. More...
 
std::deque< Note * > m_midiNoteQueue
 Midi Note FIFO. More...
 
PatternListm_pNextPatterns
 Patterns to be played next in Song::PATTERN_MODE. More...
 
bool m_bAppendNextPattern
 Add the next pattern to the list instead of replace. More...
 
bool m_bDeleteNextPattern
 Delete the next pattern from the list. More...
 
PatternListm_pPlayingPatterns
 PatternList containing all Patterns currently played back. More...
 
int m_nSongPos
 Index of the current PatternList in the Song::m_pPatternGroupSequence. More...
 
int m_nSelectedPatternNumber
 Index of the pattern selected in the GUI or by a MIDI event. More...
 
int m_nSelectedInstrumentNumber
 Instrument currently focused/selected in the GUI. More...
 
Instrumentm_pMetronomeInstrument = nullptr
 Pointer to the metronome. More...
 
int m_audioEngineState = STATE_UNINITIALIZED
 Current state of the H2Core::AudioEngine. More...
 
float m_fFXPeak_L [MAX_FX]
 
float m_fFXPeak_R [MAX_FX]
 
int m_nPatternStartTick = -1
 Beginning of the current pattern in ticks. More...
 
unsigned int m_nPatternTickPosition = 0
 Ticks passed since the beginning of the current pattern. More...
 
int m_nSongSizeInTicks = 0
 Set to the total number of ticks in a Song in findPatternInTick() if Song::SONG_MODE is chosen and playback is at least in the second loop. More...
 
struct timeval m_currentTickTime
 Updated in audioEngine_updateNoteQueue(). More...
 
unsigned long m_nRealtimeFrames = 0
 Variable keeping track of the transport position in realtime. More...
 
unsigned int m_naddrealtimenotetickposition = 0
 
pthread_t alsaAudioDriverThread
 
pthread_t midiDriverThread
 
bool isMidiDriverRunning = false
 
snd_seq_t * seq_handle = nullptr
 
int npfd
 
struct pollfd * pfd
 
int portId
 
int clientId
 
int outPortId
 
pthread_t diskWriterDriverThread
 
audioProcessCallback ossDriver_audioProcessCallback
 
bool ossDriver_running
 
pthread_t ossDriverThread
 
int oss_driver_bufferSize = -1
 
OssDriverm_pOssDriverInstance = NULL
 
unsigned nNextFrames = 0
 
pthread_t PortMidiDriverThread
 
pthread_t loggerThread
 
const float FALLOFF_SLOW = 1.08f
 
const float FALLOFF_NORMAL = 1.1f
 
const float FALLOFF_FAST = 1.5f
 
constexpr unsigned int TPQN = 192
 
constexpr unsigned int DRUM_CHANNEL = 9
 
constexpr unsigned int NOTE_LENGTH = 12
 
static const std::string version = H2CORE_VERSION
 

Typedef Documentation

◆ audioProcessCallback

typedef int(* audioProcessCallback)(uint32_t, void *)

◆ EventList

typedef std::vector<SMFEvent*> EventList

Enumeration Type Documentation

◆ EventType

enum EventType

Basic types of communication between the core part of Hydrogen and its GUI.

Enumerator
EVENT_NONE 

Fallback event.

EVENT_STATE 
EVENT_PATTERN_CHANGED 

The current pattern changed during the processing of the AudioEngine with respect to the previous process cycle.

It is handled by EventListener::patternChangedEvent().

EVENT_PATTERN_MODIFIED 
EVENT_SELECTED_PATTERN_CHANGED 

Another pattern was selected via MIDI or the GUI without affecting the audio transport (e.g in Song::PATTERN_MODE when Preferences::m_bPatternModePlaysSelected is set to true).

While the selection in the former case already happens in the GUI, this event will be used to tell it the selection was successful and had been done.

Handled by EventListener::selectedPatternChangedEvent().

EVENT_SELECTED_INSTRUMENT_CHANGED 
EVENT_PARAMETERS_INSTRUMENT_CHANGED 
EVENT_MIDI_ACTIVITY 
EVENT_XRUN 
EVENT_NOTEON 
EVENT_ERROR 
EVENT_METRONOME 

Event indicating the triggering of the m_pMetronomeInstrument.

In audioEngine_updateNoteQueue() the pushing of this Event is decoupled from the creation and queuing of the corresponding Note itself.

In Director it triggers a change in the displayed number, color, tag, and triggers Director::update(). In case the provided value is 3, instead of performing the changes above, the Director loads the metadata a the current Song.

The associated values do correspond to the following actions:

Handled by EventListener::metronomeEvent().

EVENT_RECALCULATERUBBERBAND 
EVENT_PROGRESS 
EVENT_JACK_SESSION 
EVENT_PLAYLIST_LOADSONG 
EVENT_UNDO_REDO 
EVENT_SONG_MODIFIED 
EVENT_TEMPO_CHANGED 
EVENT_UPDATE_PREFERENCES 

Event triggering the loading or saving of the H2Core::Preferences whenever they were changed outside of the GUI, e.g.

by session management or an OSC command.

If the value of the event is

  • 0 - tells the GUI to save the current geometry settings in the H2Core::Preferences file.
  • 1 - tells the GUI to load the Preferences file and to update a bunch of widgets, checkboxes etc. to reflect the changes in the configuration.
EVENT_UPDATE_SONG 

Event triggering HydrogenApp::updateSongEvent() whenever the Song was changed outside of the GUI, e.g.

by session management or and OSC command.

If the value of the event is

EVENT_QUIT 

Triggering HydrogenApp::quitEvent() and enables a shutdown of the entire application via the command line.

EVENT_TIMELINE_ACTIVATION 

Enables/disables the usage of the Timeline.

EVENT_TIMELINE_UPDATE 

Tells the GUI some parts of the Timeline - currently adding/deleting of tempo markers - were modified.

EVENT_JACK_TRANSPORT_ACTIVATION 

Toggles the button indicating the usage Jack transport.

EVENT_JACK_TIMEBASE_ACTIVATION 

Toggles the button indicating the usage Jack timebase master.

EVENT_SONG_MODE_ACTIVATION 

Activates either Pattern mode (0) or Song mode (else) of the playback.

EVENT_LOOP_MODE_ACTIVATION 

Toggles the button indicating the usage loop mode.

EVENT_ACTION_MODE_CHANGE 

Switches between select mode (0) and draw mode (1) in the *SongEditor.

◆ SMFEventType

Enumerator
NOTE_OFF 
NOTE_ON 

◆ SMFMetaEventType

Enumerator
SEQUENCE_NUMBER 
TEXT_EVENT 
COPYRIGHT_NOTICE 
TRACK_NAME 
INSTRUMENT_NAME 
LYRIC 
MARKER 
CUE_POINT 
END_OF_TRACK 
SET_TEMPO 
TIME_SIGNATURE 
KEY_SIGNATURE 

Function Documentation

◆ alsa_xrun_recovery()

static int H2Core::alsa_xrun_recovery ( snd_pcm_t *  handle,
int  err 
)
static

◆ alsaAudioDriver_processCaller()

void * H2Core::alsaAudioDriver_processCaller ( void *  param)

◆ alsaMidiDriver_thread()

void * H2Core::alsaMidiDriver_thread ( void *  param)

◆ audioEngine_clearNoteQueue()

void audioEngine_clearNoteQueue ( )
inline

◆ audioEngine_destroy()

void audioEngine_destroy ( )

◆ audioEngine_init()

void audioEngine_init ( )

Initialization of the H2Core::AudioEngine called in Hydrogen::Hydrogen().

  1. It creates two new instances of the H2Core::PatternList and stores them in m_pPlayingPatterns and m_pNextPatterns.
  2. It sets m_nSongPos = -1.
  3. It sets m_nSelectedPatternNumber, m_nSelectedInstrumentNumber, and m_nPatternTickPosition to 0.
  4. It sets m_pMetronomeInstrument, m_pAudioDriver to NULL.
  5. It uses the current time to a random seed via std::srand(). This way the states of the pseudo-random number generator are not cross-correlated between different runs of Hydrogen.
  6. It initializes the metronome with the sound stored in H2Core::Filesystem::click_file_path() by creating a new Instrument with METRONOME_INSTR_ID as first argument.
  7. It sets the H2Core::AudioEngine state m_audioEngineState to STATE_INITIALIZED.
  8. It calls H2Core::Effects::create_instance() (if the H2CORE_HAVE_LADSPA is set), H2Core::AudioEngine::create_instance(), and H2Core::Playlist::create_instance().
  9. Finally, it pushes the H2Core::EVENT_STATE, STATE_INITIALIZED on the H2Core::EventQueue using H2Core::EventQueue::push_event().

If the current state of the H2Core::AudioEngine m_audioEngineState is not STATE_UNINITIALIZED, it will thrown an error and H2Core::AudioEngine::unlock() it.

◆ audioEngine_noteOn()

void audioEngine_noteOn ( Note note)
static

◆ audioEngine_prepNoteQueue()

void H2Core::audioEngine_prepNoteQueue ( )
inline

◆ audioEngine_process()

int audioEngine_process ( uint32_t  nframes,
void *  arg 
)

Main audio processing function called by the audio drivers whenever there is work to do.

In short, it resets the audio buffers, checks the current transport position and configuration, updates the queue of notes, which are about to be played, plays those notes and writes their output to the audio buffers, and, finally, increment the transport position in order to move forward in time.

In detail the function

If the H2Core::m_audioEngineState is neither in STATE_READY nor STATE_PLAYING or the locking of the AudioEngine failed, the function will return 0 without performing any actions.

Parameters
nframesBuffersize.
argUnused.
Returns

◆ audioEngine_process_checkBPMChanged()

void audioEngine_process_checkBPMChanged ( Song pSong)
inline

Update the tick size based on the current tempo without affecting the current transport position.

To access a change in the tick size, the value stored in TransportInfo::m_fTickSize will be compared to the one calculated from the AudioOutput::getSampleRate(), Song::m_fBpm, and Song::m_resolution. Thus, if any of those quantities did change, the transport position will be recalculated.

The new transport position gets calculated by

virtual unsigned getSampleRate()=0
TransportInfo m_transport
Local instance of the TransportInfo.
Definition: AudioOutput.h:40
float m_fBpm
Current speed in beats per minutes.
Definition: Song.h:231
unsigned m_resolution
Definition: Song.h:222
long long m_nFrames
Current transport position in number of frames since the beginning of the song.
Definition: TransportInfo.h:69
float m_fTickSize
Number of frames that make up one tick.
Definition: TransportInfo.h:85
AudioOutput * m_pAudioDriver
Pointer to the current instance of the audio driver.
Definition: Hydrogen.cpp:124

If the JackAudioDriver is used and the audio engine is playing, a potential mismatch in the transport position is determined by JackAudioDriver::calculateFrameOffset() and covered by JackAudioDriver::updateTransportInfo() in the next cycle.

Finally, EventQueue::push_event() is called with EVENT_RECALCULATERUBBERBAND and -1 as arguments.

Called in audioEngine_process() and audioEngine_setSong(). The function will only perform actions if m_audioEngineState is in either STATE_READY or STATE_PLAYING.

◆ audioEngine_process_clearAudioBuffers()

void H2Core::audioEngine_process_clearAudioBuffers ( uint32_t  nFrames)
inline

Clear all audio buffers.

It locks the audio output buffer using mutex_OutputPointer, gets pointers to the output buffers using AudioOutput::getOut_L() and AudioOutput::getOut_R() of the current instance of the audio driver m_pAudioDriver, and overwrites their memory with

nFrames * sizeof( float )

zeros.

If the JACK driver is used and Preferences::m_bJackTrackOuts is set to true, the stereo buffers for all tracks of the components of each instrument will be reset as well. If LadspaFX are used, the output buffers of all effects LadspaFX::m_pBuffer_L and LadspaFX::m_pBuffer_L have to be reset as well.

If the audio driver m_pAudioDriver isn't set yet, it will just unlock and return.

◆ audioEngine_process_playNotes()

void audioEngine_process_playNotes ( unsigned long  nframes)
inline

◆ audioEngine_process_transport()

void audioEngine_process_transport ( unsigned  nFrames)
inline

Updating the TransportInfo of the audio driver.

Firstly, it calls AudioOutput::updateTransportInfo() and then updates the state of the audio engine m_audioEngineState depending on the status of the audio driver. E.g. if the JACK transport was started by another client, the audio engine has to be started as well. If TransportInfo::m_status is TransportInfo::ROLLING, audioEngine_start() is called with TransportInfo::m_nFrames as argument if the engine is in STATE_READY. If m_audioEngineState is then still not in STATE_PLAYING, the function will return. Otherwise, the current speed is getting updated by calling Hydrogen::setBPM using TransportInfo::m_fBPM and m_nRealtimeFrames is set to TransportInfo::m_nFrames.

If the status is TransportInfo::STOPPED but the engine is still running, audioEngine_stop() will be called. In any case, m_nRealtimeFrames will be incremented by #nFrames to support realtime keyboard and MIDI event timing.

If the H2Core::m_audioEngineState is neither in STATE_READY nor STATE_PLAYING the function will immediately return.

◆ audioEngine_raiseError()

void H2Core::audioEngine_raiseError ( unsigned  nErrorCode)

◆ audioEngine_removeSong()

void audioEngine_removeSong ( )

Does the necessary cleanup of the global objects in the audioEngine.

Class the clear() member of m_pPlayingPatterns and m_pNextPatterns as well as audioEngine_clearNoteQueue();

◆ audioEngine_renameJackPorts()

void H2Core::audioEngine_renameJackPorts ( Song pSong)

Hands the provided Song to JackAudioDriver::makeTrackOutputs() if pSong is not a null pointer and the audio driver m_pAudioDriver is an instance of the JackAudioDriver.

Parameters
pSongSong for which per-track output ports should be generated.

◆ audioEngine_renderNote()

unsigned H2Core::audioEngine_renderNote ( Note pNote,
const unsigned &  nBufferSize 
)
inline

◆ audioEngine_restartAudioDrivers()

void audioEngine_restartAudioDrivers ( )

Restart all audio and midi drivers by calling first audioEngine_stopAudioDrivers() and then audioEngine_startAudioDrivers().

If no audio driver is set yet, audioEngine_stopAudioDrivers() is omitted and the audio driver will be started right away.

◆ audioEngine_seek()

void audioEngine_seek ( long long  nFrames,
bool  bLoopMode = false 
)

◆ audioEngine_setSong()

void audioEngine_setSong ( Song pNewSong)

Updates the global objects of the audioEngine according to new Song.

It also updates all member variables of the audio driver specific to the particular song (BPM and tick size).

Parameters
pNewSongSong to load.

◆ audioEngine_setupLadspaFX()

void H2Core::audioEngine_setupLadspaFX ( )

◆ audioEngine_start()

int audioEngine_start ( bool  bLockEngine = false,
unsigned  nTotalFrames = 0 
)

If the audio engine is in state m_audioEngineState STATE_READY, this function will.

Parameters
bLockEngineWhether or not to lock the audio engine before performing any actions. The audio engine must be locked! This option should only be used, if the process calling this function did already locked it.
nTotalFramesNew value of the transport position.
Returns
0 regardless what happens inside the function.

◆ audioEngine_startAudioDrivers()

void audioEngine_startAudioDrivers ( )

Creation and initialization of all audio and MIDI drivers called in Hydrogen::Hydrogen().

Which audio driver to use is specified in Preferences::m_sAudioDriver. If "Auto" is selected, it will try to initialize drivers using createDriver() in the following order:

  • Windows: "PortAudio", "ALSA", "CoreAudio", "JACK", "OSS", and "PulseAudio"
  • all other systems: "JACK", "ALSA", "CoreAudio", "PortAudio", "OSS", and "PulseAudio". If all of them return NULL, m_pAudioDriver will be initialized with the NullDriver instead. If a specific choice is contained in Preferences::m_sAudioDriver and createDriver() returns NULL, the NullDriver will be initialized too.

It probes Preferences::m_sMidiDriver to create a midi driver using either AlsaMidiDriver::AlsaMidiDriver(), PortMidiDriver::PortMidiDriver(), CoreMidiDriver::CoreMidiDriver(), or JackMidiDriver::JackMidiDriver(). Afterwards, it sets m_pMidiDriverOut and m_pMidiDriver to the freshly created midi driver and calls their open() and setActive( true ) functions.

If a Song is already present, the state of the AudioEngine m_audioEngineState will be set to STATE_READY, the bpm of the m_pAudioDriver will be set to the tempo of the Song Song::m_fBpm using AudioOutput::setBpm(), and STATE_READY is pushed on the EventQueue. If no Song is present, the state will be STATE_PREPARED and no bpm will be set.

All the actions mentioned so far will be performed after locking both the AudioEngine using AudioEngine::lock() and the mutex of the audio output buffer mutex_OutputPointer. When they are completed both mutex are unlocked and the audio driver is connected via AudioOutput::connect(). If this is not successful, the audio driver will be overwritten with the NullDriver and this one is connected instead.

Finally, audioEngine_renameJackPorts() (if H2CORE_HAVE_JACK is set) and audioEngine_setupLadspaFX() are called.

The state of the AudioEngine m_audioEngineState must not be in STATE_INITIALIZED or the function will just unlock both mutex and returns.

◆ audioEngine_stop()

void audioEngine_stop ( bool  bLockEngine = false)

If the audio engine is in state m_audioEngineState STATE_PLAYING, this function will.

Parameters
bLockEngineWhether or not to lock the audio engine before performing any actions. The audio engine must be locked! This option should only be used, if the process calling this function did already locked it.

◆ audioEngine_stopAudioDrivers()

void audioEngine_stopAudioDrivers ( )

Stops all audio and MIDI drivers.

Uses audioEngine_stop() if the AudioEngine is still in state m_audioEngineState STATE_PLAYING, sets its state to STATE_INITIALIZED, locks the AudioEngine using AudioEngine::lock(), deletes m_pMidiDriver and m_pAudioDriver and reinitializes them to NULL.

If m_audioEngineState is neither in STATE_PREPARED or STATE_READY, the function returns before deleting anything.

◆ audioEngine_updateNoteQueue()

int audioEngine_updateNoteQueue ( unsigned  nFrames)
inline

Takes all notes from the current patterns, from the MIDI queue m_midiNoteQueue, and those triggered by the metronome and pushes them onto m_songNoteQueue for playback.

Apart from the MIDI queue, the extraction of all notes will be based on their position measured in ticks. Since Hydrogen does support humanization, which also involves triggering a Note earlier or later than its actual position, the loop over all ticks won't be done starting from the current position but at some position in the future. This value, also called lookahead, is set to the sum of the maximum offsets introduced by both the random humanization (2000 frames) and the deterministic lead-lag offset (5 times TransportInfo::m_nFrames) plus 1 (note that it's not given in ticks but in frames!). Hydrogen thus loops over nFrames frames starting at the current position + the lookahead (or at 0 when at the beginning of the Song).

Within this loop all MIDI notes in m_midiNoteQueue with a Note::__position smaller or equal the current tick will be popped and added to m_songNoteQueue and the EVENT_METRONOME Event is pushed to the EventQueue at a periodic rate. If in addition Preferences::m_bUseMetronome is set to true, m_pMetronomeInstrument will be used to push a 'click' to the m_songNoteQueue too. All patterns enclosing the current tick will be added to m_pPlayingPatterns and all their containing notes, which position enclose the current tick too, will be added to the m_songNoteQueue. If the Song is in Song::PATTERN_MODE, the patterns used are not chosen by the actual position but by m_nSelectedPatternNumber and m_pNextPatterns.

All notes obtained by the current patterns (and only those) are also subject to humanization in the onset position of the created Note. For now Hydrogen does support three options of altering these:

  • Swing - A deterministic offset determined by Song::m_fSwingFactor will be added for some notes in a periodic way.
  • Humanize - A random offset drawn from Gaussian white noise with a variance proportional to Song::m_fHumanizeTimeValue will be added to every Note.
  • Lead/Lag - A deterministic offset determined by Note::__lead_lag will be added for every note.

If the AudioEngine it not in STATE_PLAYING, the loop jumps right to the next tick.

Returns
  • -1 if in Song::SONG_MODE and no patterns left.
  • 2 if the current pattern changed with respect to the last cycle.

◆ check_boundary()

static float H2Core::check_boundary ( float  v,
float  min,
float  max 
)
inlinestatic

◆ compute_pitch_scale()

static double H2Core::compute_pitch_scale ( const Sample::Rubberband r)
static

◆ compute_rubberband_options()

static RubberBand::RubberBandStretcher::Options H2Core::compute_rubberband_options ( const Sample::Rubberband r)
static

◆ createDriver()

AudioOutput * H2Core::createDriver ( const QString &  sDriver)

Create an audio driver using audioEngine_process() as its argument based on the provided choice and calling their init() function to trigger their initialization.

For a listing of all possible choices, please see Preferences::m_sAudioDriver.

Parameters
sDriverString specifying which audio driver should be created.
Returns
Pointer to the freshly created audio driver. If the creation resulted in a NullDriver, the corresponding object will be deleted and a null pointer returned instead.

◆ createInstrument()

static Instrument * H2Core::createInstrument ( int  id,
const QString &  filepath,
float  volume 
)
static

◆ currentTime2()

timeval H2Core::currentTime2 ( )
inline

Gets the current time.

Returns
Current time obtained by gettimeofday()

◆ diskWriterDriver_thread()

void * H2Core::diskWriterDriver_thread ( void *  param)

◆ findPatternInTick()

int findPatternInTick ( int  nTick,
bool  bLoopMode,
int *  pPatternStartTick 
)
inline

Find a PatternList corresponding to the supplied tick position nTick.

Adds up the lengths of all pattern columns until nTick lies in between the bounds of a Pattern.

Parameters
nTickPosition in ticks.
bLoopModeWhether looping is enabled in the Song, see Song::getIsLoopEnabled(). If true, nTick is allowed to be larger than the total length of the Song.
pPatternStartTickPointer to an integer the beginning of the found pattern list will be stored in (in ticks).
Returns

◆ get_version()

std::string get_version ( )

Returns the current Hydrogen version string.

◆ getGaussian()

float H2Core::getGaussian ( float  z)
inline

◆ JackMidiProcessCallback()

static int H2Core::JackMidiProcessCallback ( jack_nframes_t  nframes,
void *  arg 
)
static

◆ JackMidiShutdown()

static void H2Core::JackMidiShutdown ( void *  arg)
static

◆ linear_interpolation()

static float H2Core::linear_interpolation ( float  fVal_A,
float  fVal_B,
double  fVal 
)
inlinestatic

◆ loggerThread_func()

void * H2Core::loggerThread_func ( void *  param)
Parameters
paramis a pointer to the logger instance

◆ midiProc()

static void H2Core::midiProc ( const MIDIPacketList *  pktlist,
void *  readProcRefCon,
void *  srcConnRefCon 
)
static

◆ operator!=()

bool H2Core::operator!= ( const AutomationPath lhs,
const AutomationPath rhs 
)

◆ operator<<() [1/4]

QDebug H2Core::operator<< ( QDebug  d,
Object o 
)
inline

◆ operator<<() [2/4]

QDebug H2Core::operator<< ( QDebug  d,
std::shared_ptr< Object o 
)
inline

◆ operator<<() [3/4]

std::ostream & operator<< ( std::ostream &  os,
const Object object 
)

◆ operator<<() [4/4]

std::ostream & operator<< ( std::ostream &  os,
const Object object 
)

◆ operator==()

bool H2Core::operator== ( const AutomationPath lhs,
const AutomationPath rhs 
)

Compare two paths.

Two paths are considered equal, if they have the same settings (min, max, default) and points in the same places.

◆ ossDriver_processCaller()

void * H2Core::ossDriver_processCaller ( void *  param)

◆ portAudioCallback()

int H2Core::portAudioCallback ( const void *  inputBuffer,
void *  outputBuffer,
unsigned long  framesPerBuffer,
const PaStreamCallbackTimeInfo *  timeInfo,
PaStreamCallbackFlags  statusFlags,
void *  userData 
)

◆ PortMidiDriver_thread()

void * H2Core::PortMidiDriver_thread ( void *  param)

◆ randomValue()

int H2Core::randomValue ( int  max)
inline

◆ version_older_than()

bool version_older_than ( int  major,
int  minor,
int  patch 
)

return true of the current version is older than the given values

Variable Documentation

◆ alsaAudioDriverThread

pthread_t alsaAudioDriverThread

◆ clientId

int clientId

◆ diskWriterDriverThread

pthread_t diskWriterDriverThread

◆ DRUM_CHANNEL

constexpr unsigned int DRUM_CHANNEL = 9
constexpr

◆ FALLOFF_FAST

const float FALLOFF_FAST = 1.5f

◆ FALLOFF_NORMAL

const float FALLOFF_NORMAL = 1.1f

◆ FALLOFF_SLOW

const float FALLOFF_SLOW = 1.08f

◆ isMidiDriverRunning

bool isMidiDriverRunning = false

◆ loggerThread

pthread_t loggerThread

◆ m_audioEngineState

int m_audioEngineState = STATE_UNINITIALIZED

Current state of the H2Core::AudioEngine.

It is supposed to take five different states:

It gets initialized with STATE_UNINITIALIZED.

◆ m_bAppendNextPattern

bool m_bAppendNextPattern

Add the next pattern to the list instead of replace.

◆ m_bDeleteNextPattern

bool m_bDeleteNextPattern

Delete the next pattern from the list.

◆ m_currentTickTime

struct timeval m_currentTickTime

◆ m_fFXPeak_L

float m_fFXPeak_L[MAX_FX]

◆ m_fFXPeak_R

float m_fFXPeak_R[MAX_FX]

◆ m_fMasterPeak_L

float m_fMasterPeak_L = 0.0f

Master peak (left channel)

◆ m_fMasterPeak_R

float m_fMasterPeak_R = 0.0f

Master peak (right channel)

◆ m_fMaxProcessTime

float m_fMaxProcessTime = 0.0f

max ms usable in process with no xrun

◆ m_fNewBpmJTM

float m_fNewBpmJTM = 120

Fallback speed in beats per minute.

It is set by Hydrogen::setNewBpmJTM() and accessed via Hydrogen::getNewBpmJTM().

◆ m_fProcessTime

float m_fProcessTime = 0.0f

time used in process function

◆ m_midiNoteQueue

std::deque<Note*> m_midiNoteQueue

Midi Note FIFO.

◆ m_naddrealtimenotetickposition

unsigned int m_naddrealtimenotetickposition = 0

◆ m_nPatternStartTick

int m_nPatternStartTick = -1

Beginning of the current pattern in ticks.

It is set using finPatternInTick() and reset to -1 in audioEngine_start(), audioEngine_stop(), Hydrogen::startExportSong(), and Hydrogen::triggerRelocateDuringPlay() (if the playback it in Song::PATTERN_MODE).

◆ m_nPatternTickPosition

unsigned int m_nPatternTickPosition = 0

Ticks passed since the beginning of the current pattern.

Queried using Hydrogen::getTickPosition().

Initialized to 0 in audioEngine_init() and reset to 0 in Hydrogen::setPatternPos(), if the AudioEngine is not playing, in audioEngine_start(), Hydrogen::startExportSong() and Hydrogen::stopExportSong(), which marks the beginning of a Song.

◆ m_nRealtimeFrames

unsigned long m_nRealtimeFrames = 0

Variable keeping track of the transport position in realtime.

Even if the audio engine is stopped, the variable will be incremented (as audioEngine_process() would do at the beginning of each cycle) to support realtime keyboard and MIDI event timing. It is set using Hydrogen::setRealtimeFrames(), accessed via Hydrogen::getRealtimeFrames(), and updated in audioEngine_process_transport() using the current transport position TransportInfo::m_nFrames.

◆ m_nSelectedInstrumentNumber

int m_nSelectedInstrumentNumber

Instrument currently focused/selected in the GUI.

Within the core it is relevant for the MIDI input. Using Preferences::__playselectedinstrument incoming MIDI signals can be used to play back only the selected instrument or the whole drumkit.

Queried using Hydrogen::getSelectedInstrumentNumber() and set by Hydrogen::setSelectedInstrumentNumber().

◆ m_nSelectedPatternNumber

int m_nSelectedPatternNumber

Index of the pattern selected in the GUI or by a MIDI event.

If Preferences::m_bPatternModePlaysSelected is set to true and the playback is in Song::PATTERN_MODE, the corresponding pattern will be assigned to m_pPlayingPatterns in audioEngine_updateNoteQueue(). This way the user can specify to play back the pattern she is currently viewing/editing.

Queried using Hydrogen::getSelectedPatternNumber() and set by Hydrogen::setSelectedPatternNumber().

Initialized to 0 in audioEngine_init().

◆ m_nSongPos

int m_nSongPos

Index of the current PatternList in the Song::m_pPatternGroupSequence.

A value of -1 corresponds to "pattern list could not be found".

Assigned using findPatternInTick() in audioEngine_updateNoteQueue(), queried using Hydrogen::getPatternPos() and set using Hydrogen::setPatternPos() if it AudioEngine is playing.

It is initialized with -1 value in audioEngine_init(), and reset to the same value in audioEngine_start(), and Hydrogen::stopExportSong(). In Hydrogen::startExportSong() it will be set to 0. Please note that ALL of these functions do access the variable directly!

◆ m_nSongSizeInTicks

int m_nSongSizeInTicks = 0

Set to the total number of ticks in a Song in findPatternInTick() if Song::SONG_MODE is chosen and playback is at least in the second loop.

◆ m_pAudioDriver

AudioOutput* m_pAudioDriver = nullptr

Pointer to the current instance of the audio driver.

Initialized with NULL inside audioEngine_init(). Inside audioEngine_startAudioDrivers() either the audio driver specified in Preferences::m_sAudioDriver and created via createDriver() or the NullDriver, in case the former failed, will be assigned.

◆ m_pMetronomeInstrument

Instrument* m_pMetronomeInstrument = nullptr

Pointer to the metronome.

Initialized in audioEngine_init().

◆ m_pMidiDriver

MidiInput* m_pMidiDriver = nullptr

MIDI input.

In audioEngine_startAudioDrivers() it is assigned the midi driver specified in Preferences::m_sMidiDriver.

◆ m_pMidiDriverOut

MidiOutput* m_pMidiDriverOut = nullptr

MIDI output.

In audioEngine_startAudioDrivers() it is assigned the midi driver specified in Preferences::m_sMidiDriver.

◆ m_pNextPatterns

PatternList* m_pNextPatterns

Patterns to be played next in Song::PATTERN_MODE.

In audioEngine_updateNoteQueue() whenever the end of the current pattern is reached the content of m_pNextPatterns will be added to m_pPlayingPatterns.

Queried with Hydrogen::getNextPatterns(), set by Hydrogen::sequencer_setNextPattern() and Hydrogen::sequencer_setOnlyNextPattern(), initialized with an empty PatternList in audioEngine_init(), destroyed and set to NULL in audioEngine_destroy(), cleared in audioEngine_remove_Song(), and updated in audioEngine_updateNoteQueue(). Please note that ALL of these functions do access the variable directly!

◆ m_pOssDriverInstance

OssDriver* m_pOssDriverInstance = NULL

◆ m_pPlayingPatterns

PatternList* m_pPlayingPatterns

PatternList containing all Patterns currently played back.

Queried using Hydrogen::getCurrentPatternList(), set using Hydrogen::setCurrentPatternList(), initialized with an empty PatternList in audioEngine_init(), destroyed and set to NULL in audioEngine_destroy(), set to the first pattern list of the new song in audioEngine_setSong(), cleared in audioEngine_removeSong(), reset in Hydrogen::togglePlaysSelected() and processed in audioEngine_updateNoteQueue(). Please note that ALL of these functions do access the variable directly!

◆ m_songNoteQueue

std::priority_queue<Note*, std::deque<Note*>, compare_pNotes > m_songNoteQueue

Song Note FIFO.

◆ midiDriverThread

pthread_t midiDriverThread

◆ mutex_OutputPointer

QMutex mutex_OutputPointer

Mutex for locking the pointer to the audio output buffer, allowing multiple readers.

When locking this and the AudioEngine, always lock the AudioEngine first using AudioEngine::lock() or AudioEngine::try_lock(). Always use a QMutexLocker to lock this mutex.

◆ nNextFrames

unsigned nNextFrames = 0

◆ NOTE_LENGTH

constexpr unsigned int NOTE_LENGTH = 12
constexpr

◆ npfd

int npfd

◆ oss_driver_bufferSize

int oss_driver_bufferSize = -1

◆ ossDriver_audioProcessCallback

audioProcessCallback ossDriver_audioProcessCallback

◆ ossDriver_running

bool ossDriver_running

◆ ossDriverThread

pthread_t ossDriverThread

◆ outPortId

int outPortId

◆ pfd

struct pollfd* pfd

◆ portId

int portId

◆ PortMidiDriverThread

pthread_t PortMidiDriverThread

◆ seq_handle

snd_seq_t* seq_handle = nullptr

◆ TPQN

constexpr unsigned int TPQN = 192
constexpr

◆ version

const std::string version = H2CORE_VERSION
static