hydrogen 1.1.1
AudioEngine Class Reference

Audio Engine main class (Singleton). More...

#include <AudioEngine.h>

Inheritance diagram for AudioEngine:
Object

Data Structures

struct  _locker_struct
 This struct is most probably intended to be used for logging the locking of the AudioEngine. More...
 

Public Member Functions

 ~AudioEngine ()
 Destructor of the AudioEngine. More...
 
void lock (const char *file, unsigned int line, const char *function)
 Mutex locking of the AudioEngine. More...
 
bool try_lock (const char *file, unsigned int line, const char *function)
 Mutex locking of the AudioEngine. More...
 
bool try_lock_for (std::chrono::microseconds duration, const char *file, unsigned int line, const char *function)
 Mutex locking of the AudioEngine. More...
 
void unlock ()
 Mutex unlocking of the AudioEngine. More...
 
void assertLocked ()
 Assert that the calling thread is the current holder of the AudioEngine lock. More...
 
Samplerget_sampler ()
 
Synthget_synth ()
 
float getElapsedTime () const
 
void calculateElapsedTime (unsigned sampleRate, unsigned long nFrame, int nResolution)
 Calculates the elapsed time for an arbitrary position. More...
 
void updateElapsedTime (unsigned bufferSize, unsigned sampleRate)
 Increments m_fElapsedTime at the end of a process cycle. More...
 
void locate (unsigned long nFrame)
 Relocate using the audio driver and update the m_fElapsedTime. More...
 
- Public Member Functions inherited from Object
 ~Object ()
 destructor More...
 
 Object (const Object &obj)
 copy constructor More...
 
 Object (const char *class_name)
 constructor More...
 
const char * class_name () const
 return the class name More...
 
virtual QString toQString (const QString &sPrefix, bool bShort=true) const
 Formatted string version for debugging purposes. More...
 
void Print (bool bShort=true) const
 Prints content of toQString() via DEBUGLOG. More...
 

Static Public Member Functions

static void create_instance ()
 If __instance equals 0, a new AudioEngine singleton will be created and stored in it. More...
 
static AudioEngineget_instance ()
 
static float compute_tick_size (const int nSampleRate, const float fBpm, const int nResolution)
 
- Static Public Member Functions inherited from Object
static void set_count (bool flag)
 enable/disable class instances counting More...
 
static bool count_active ()
 return true if class instances counting is enabled More...
 
static unsigned objects_count ()
 return the number of objects More...
 
static void write_objects_map_to (std::ostream &out)
 output the full objects map to a given ostream More...
 
static void write_objects_map_to_cerr ()
 output objects map to stderr More...
 
static int bootstrap (Logger *logger, bool count=false)
 must be called before any Object instantiation ! More...
 
static Loggerlogger ()
 return the logger instance More...
 

Private Member Functions

 AudioEngine ()
 Constructor of the AudioEngine. More...
 

Private Attributes

Sampler__sampler
 Local instance of the Sampler. More...
 
Synth__synth
 Local instance of the Synth. More...
 
std::timed_mutex __engine_mutex
 Mutex for synchronizing the access to the Song object and the AudioEngine. More...
 
std::thread::id m_lockingThread
 Thread ID of the current holder of the AudioEngine lock. More...
 
struct H2Core::AudioEngine::_locker_struct __locker
 This struct is most probably intended to be used for logging the locking of the AudioEngine. More...
 
float m_fElapsedTime
 Time in seconds since the beginning of the Song. More...
 

Static Private Attributes

static AudioEngine__instance = nullptr
 Object holding the current AudioEngine singleton. More...
 

Additional Inherited Members

- Static Public Attributes inherited from Object
static QString sPrintIndention = " "
 String used to format the debugging string output of some core classes. More...
 
- Static Protected Attributes inherited from Object
static Logger__logger = nullptr
 logger instance pointer More...
 

Detailed Description

Audio Engine main class (Singleton).

It serves as a container for the Sampler and Synth stored in the __sampler and __synth member objects and provides a mutex __engine_mutex enabling the user to synchronize the access of the Song object and the AudioEngine itself. lock() and try_lock() can be called by a thread to lock the engine and unlock() to make it accessible for other threads once again.

Constructor & Destructor Documentation

◆ ~AudioEngine()

Destructor of the AudioEngine.

Deletes the Effects singleton and the __sampler and __synth objects.

◆ AudioEngine()

AudioEngine ( )
private

Constructor of the AudioEngine.

  • Assigns __instance to itself.
  • Initializes the Mutex of the AudioEngine __engine_mutex by calling pthread_mutex_init() (pthread.h) on its address.
  • Assigns a new instance of the Sampler to __sampler and of the Synth to __synth.
  • Creates an instance of the Effects singleton. This call should not be necessary since this singleton was created right before creating the AudioEngine. But its costs are cheap, so I just keep it.

Member Function Documentation

◆ assertLocked()

void assertLocked ( )
inline

Assert that the calling thread is the current holder of the AudioEngine lock.

◆ calculateElapsedTime()

void calculateElapsedTime ( unsigned  sampleRate,
unsigned long  nFrame,
int  nResolution 
)

Calculates the elapsed time for an arbitrary position.

After locating the transport position to nFrame the function calculates the amount of time required to reach the position during playback. If the Timeline is activated, it will take all markers and the resulting tempo changes into account.

Right now the tempo in the region before the first marker is undefined. In order to make reproducible estimates of the elapsed time, this function assume it to have the same BPM as the first marker.

Parameters
sampleRateTemporal resolution used by the sound card in frames per second.
nFrameNext transport position in frames.
nResolutionResolution of the Song (number of ticks per quarter).

◆ compute_tick_size()

float compute_tick_size ( const int  nSampleRate,
const float  fBpm,
const int  nResolution 
)
static

◆ create_instance()

void create_instance ( )
static

If __instance equals 0, a new AudioEngine singleton will be created and stored in it.

It is called in Hydrogen::audioEngine_init().

◆ get_instance()

static AudioEngine * get_instance ( )
inlinestatic
Returns
a pointer to the current AudioEngine singleton stored in __instance.

◆ get_sampler()

Sampler * get_sampler ( )
Returns
__sampler

◆ get_synth()

Synth * get_synth ( )
Returns
__synth

◆ getElapsedTime()

float getElapsedTime ( ) const
inline

◆ locate()

void locate ( unsigned long  nFrame)

Relocate using the audio driver and update the m_fElapsedTime.

Parameters
nFrameNext transport position in frames.

◆ lock()

void lock ( const char *  file,
unsigned int  line,
const char *  function 
)

Mutex locking of the AudioEngine.

Lock the AudioEngine for exclusive access by this thread.

The documentation below may serve as a guide for future implementations. At the moment the logging of the locking is not supported yet and the arguments will be just stored in the __locker variable, which itself won't be ever used.

Easy usage: Use the RIGHT_HERE macro like this...

#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
Definition: AudioEngine.h:46
static AudioEngine * get_instance()
Definition: AudioEngine.h:77
void lock(const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
Definition: AudioEngine.cpp:98

More complex usage: The parameters file and function need to be pointers to null-terminated strings that are persistent for the entire session. This does not include the return value of std::string::c_str(), or QString::toLocal8Bit().data().

Tracing the locks: Enable the Logger::AELockTracing logging level. When you do, there will be a performance penalty because the strings will be converted to a QString. At the moment, you'll have to do that with your debugger.

Notes: The order of the parameters match GCC's implementation of the assert() macros.

Parameters
fileFile the locking occurs in.
lineLine of the file the locking occurs in.
functionFunction the locking occurs in.

◆ try_lock()

bool try_lock ( const char *  file,
unsigned int  line,
const char *  function 
)

Mutex locking of the AudioEngine.

This function is equivalent to lock() but returns false immediaely if the lock cannot be obtained immediately.

Parameters
fileFile the locking occurs in.
lineLine of the file the locking occurs in.
functionFunction the locking occurs in.
Returns
  • true : On success
  • false : Else

◆ try_lock_for()

bool try_lock_for ( std::chrono::microseconds  duration,
const char *  file,
unsigned int  line,
const char *  function 
)

Mutex locking of the AudioEngine.

This function is equivalent to lock() but will only wait for a given period of time. If the lock cannot be acquired in this time, it will return false.

Parameters
durationTime (in microseconds) to wait for the lock.
fileFile the locking occurs in.
lineLine of the file the locking occurs in.
functionFunction the locking occurs in.
Returns
  • true : On successful acquisition of the lock
  • false : On failure

◆ unlock()

void unlock ( )

Mutex unlocking of the AudioEngine.

Unlocks the AudioEngine to allow other threads acces, and leaves __locker untouched.

◆ updateElapsedTime()

void updateElapsedTime ( unsigned  bufferSize,
unsigned  sampleRate 
)

Increments m_fElapsedTime at the end of a process cycle.

At the end of H2Core::audioEngine_process() this function will be used to add the time passed during the last process cycle to m_fElapsedTime.

Parameters
bufferSizeNumber of frames process during a cycle of the audio engine.
sampleRateTemporal resolution used by the sound card in frames per second.

Field Documentation

◆ __engine_mutex

std::timed_mutex __engine_mutex
private

Mutex for synchronizing the access to the Song object and the AudioEngine.

It can be used lock the access using either lock() or try_lock() and to unlock it via unlock(). It is initialized in AudioEngine() and not explicitly exited.

◆ __instance

AudioEngine * __instance = nullptr
staticprivate

Object holding the current AudioEngine singleton.

It is initialized with NULL, set with create_instance(), and accessed with get_instance().

◆ __locker

struct H2Core::AudioEngine::_locker_struct __locker
private

This struct is most probably intended to be used for logging the locking of the AudioEngine.

But neither it nor the Logger::AELockTracing state is ever used.

◆ __sampler

Sampler* __sampler
private

Local instance of the Sampler.

◆ __synth

Synth* __synth
private

Local instance of the Synth.

◆ m_fElapsedTime

float m_fElapsedTime
private

Time in seconds since the beginning of the Song.

In Hydrogen the current transport position is not measured in time but in past ticks. Whenever transport is passing a BPM marker on the Timeline, the tick size and effectively also time will be rescaled. To nevertheless show the correct time elapsed since the beginning of the Song, this variable will be used.

At the end of each transport cycle updateElapsedTime() will be used to increment it (its smallest resolution is thus controlled by the buffer size). If, instead, a relocation was triggered by the user or an external transport control (e.g. JACK server), calculateElapsedTime() will be used to determine the time anew.

If loop transport is enabled #Song::__is_loop_enabled, the elapsed time will increase constantly. However, if relocation did happen, only the time relative to the beginning of the Song will be calculated irrespective of the number of loops played so far.

Retrieved using getElapsedTime().

◆ m_lockingThread

std::thread::id m_lockingThread
private

Thread ID of the current holder of the AudioEngine lock.