hydrogen 1.2.3
TransportPosition Class Reference

Object holding most of the information about the transport state of the AudioEngine. More...

#include <TransportPosition.h>

Inheritance diagram for TransportPosition:
Object< TransportPosition > Base

Public Member Functions

 TransportPosition (const QString sLabel="")
 
 ~TransportPosition ()
 
int getBar () const
 
int getBeat () const
 
float getBpm () const
 
int getColumn () const
 
long long getFrame () const
 
long long getFrameOffsetTempo () const
 
const QString getLabel () const
 
long long getLastLeadLagFactor () const
 
const PatternListgetNextPatterns () const
 
int getPatternSize () const
 
long getPatternStartTick () const
 
long getPatternTickPosition () const
 
const PatternListgetPlayingPatterns () const
 
long getTick () const
 Retrieve a rounded version of m_fTick.
 
double getTickMismatch () const
 
double getTickOffsetQueuing () const
 
double getTickOffsetSongSize () const
 
float getTickSize () const
 
QString toQString (const QString &sPrefix="", bool bShort=true) const override
 Formatted string version for debugging purposes.
 
- Public Member Functions inherited from Object< TransportPosition >
 Object ()
 
 Object (const Object< TransportPosition > &other)
 
- Public Member Functions inherited from Base
 Base ()
 
 Base (const Base &other)
 
virtual const char * class_name () const
 
void Print (bool bShort=true) const
 Prints content of toQString() via DEBUGLOG.
 

Static Public Member Functions

static long long computeFrameFromTick (double fTick, double *fTickMismatch, int nSampleRate=0)
 Calculates frame equivalent of fTick.
 
static double computeTickFromFrame (long long nFrame, int nSampleRate=0)
 Calculates tick equivalent of nFrame.
 
- Static Public Member Functions inherited from Base
static const char * _class_name ()
 return the class name
 
static QString base_clock (const QString &sMsg)
 Measures the current time and stores it in __last_clock.
 
static QString base_clock_in (const QString &sMsg)
 
static int bootstrap (Logger *logger, bool count=false)
 must be called before any Object instantiation !
 
static bool count_active ()
 
static int getAliveObjectCount ()
 
static object_map_t getObjectMap ()
 
static Loggerlogger ()
 return the logger instance
 
static int objects_count ()
 
static void printObjectMapDiff (object_map_t map)
 Creates the difference between a snapshot of the object map and its current state and prints it to std::cout.
 
static void set_count (bool flag)
 enable/disable class instances counting
 
static void write_objects_map_to (std::ostream &out, object_map_t *map=nullptr)
 output the full objects map to a given ostream
 
static void write_objects_map_to_cerr ()
 output objects map to stderr
 

Private Member Functions

double getDoubleTick () const
 
PatternListgetNextPatterns ()
 
PatternListgetPlayingPatterns ()
 
void reset ()
 
void set (std::shared_ptr< TransportPosition > pOther)
 Copying the content of one position into the other is a lot cheaper than performing computations, like AudioEngine::updateTransportPosition(), twice.
 
void setBar (int nBar)
 
void setBeat (int nBeat)
 
void setBpm (float fNewBpm)
 
void setColumn (int nColumn)
 
void setFrame (long long nNewFrame)
 
void setFrameOffsetTempo (long long nFrameOffset)
 
void setLastLeadLagFactor (long long nValue)
 
void setNextPatterns (PatternList *pPatternList)
 
void setPatternSize (int nPatternSize)
 
void setPatternStartTick (long nPatternStartTick)
 
void setPatternTickPosition (long nPatternTickPosition)
 
void setPlayingPatterns (PatternList *pPatternList)
 
void setTick (double fNewTick)
 
void setTickOffsetQueuing (double nTickOffset)
 
void setTickOffsetSongSize (double fTickOffset)
 
void setTickSize (float fNewTickSize)
 

Static Private Member Functions

static long long computeFrame (double fTick, float fTickSize)
 Converts ticks into frames under the assumption of a constant fTickSize (sample rate, tempo, and resolution did not change).
 
static double computeTick (long long nFrame, float fTickSize)
 Converts frames into ticks under the assumption of a constant fTickSize (sample rate, tempo, and resolution did not change).
 

Private Attributes

float m_fBpm
 Current tempo in beats per minute.
 
double m_fTick
 Current transport position in number of ticks since the beginning of the song.
 
double m_fTickMismatch
 Number of ticks m_nFrame is ahead/behind of m_fTick.
 
double m_fTickOffsetQueuing
 Tick offset introduced when changing the tempo of the song.
 
double m_fTickOffsetSongSize
 Tick offset introduced when changing the size of the song.
 
float m_fTickSize
 Number of frames that make up one tick.
 
int m_nBar
 Last beat (column + 1) passed.
 
int m_nBeat
 Last bar passed since m_nBar.
 
int m_nColumn
 Specifies the column transport is located in and can be used as the index of the current PatternList/column in the Song::m_pPatternGroupSequence.
 
long long m_nFrame
 Current transport position in number of frames since the beginning of the song.
 
long long m_nFrameOffsetTempo
 Frame offset introduced when changing the tempo of the song.
 
long long m_nLastLeadLagFactor
 
int m_nPatternSize
 Maximum size of all patterns in m_pPlayingPatterns.
 
long m_nPatternStartTick
 Dicstance in ticks between the beginning of the song and the beginning of the current column (m_nColumn).
 
long m_nPatternTickPosition
 Ticks passed since m_nPatternStartTick.
 
PatternListm_pNextPatterns
 Patterns used to toggle the ones in m_pPlayingPatterns in Song::PatternMode::Stacked.
 
PatternListm_pPlayingPatterns
 Contains all Patterns currently played back.
 
const QString m_sLabel
 Identifier of the transport position.
 

Friends

class AudioEngine
 
class AudioEngineTests
 

Additional Inherited Members

- Static Public Attributes inherited from Base
static QString sPrintIndention = " "
 String used to format the debugging string output of some core classes.
 
- Protected Member Functions inherited from Object< TransportPosition >
 ~Object ()
 
- Protected Member Functions inherited from Base
 ~Base ()
 
- Static Protected Member Functions inherited from Base
static void registerClass (const char *name, const atomic_obj_cpt_t *counters)
 
- Static Protected Attributes inherited from Base
static bool __count = false
 should we count class instances
 
static timeval __last_clock = { 0, 0 }
 
static Logger__logger = nullptr
 

Detailed Description

Object holding most of the information about the transport state of the AudioEngine.

Due to the original design of Hydrogen the fundamental variable to determine the transport position is a tick. Whenever a tempo or song size change is encountered, the tick and frame information are shifted or rescaled. To nevertheless ensure consistency, the amount of compensation required to retrieve the original position is stored in a number of dedicated offset variables.

Definition at line 47 of file TransportPosition.h.

Constructor & Destructor Documentation

◆ TransportPosition()

TransportPosition ( const QString sLabel = "")

Definition at line 35 of file TransportPosition.cpp.

◆ ~TransportPosition()

Definition at line 46 of file TransportPosition.cpp.

Member Function Documentation

◆ computeFrame()

long long computeFrame ( double fTick,
float fTickSize )
staticprivate

Converts ticks into frames under the assumption of a constant fTickSize (sample rate, tempo, and resolution did not change).

As the assumption above does not hold once a tempo marker is introduced, computeFrameFromTick() should be used instead while this function is only meant for internal use.

Definition at line 646 of file TransportPosition.cpp.

◆ computeFrameFromTick()

long long computeFrameFromTick ( double fTick,
double * fTickMismatch,
int nSampleRate = 0 )
static

Calculates frame equivalent of fTick.

In case the #Timeline is activated, the function takes all passed tempo markers into account in order to determine the number of frames passed when letting the AudioEngine roll for fTick ticks.

It depends on the sample rate nSampleRate and assumes that it as well as the resolution to be constant over the whole song.

Parameters
fTickCurrent transport position in ticks.
fTickMismatchSince ticks are stored as doubles and there is some loss in precision, this variable is used report how much @fTick exceeds/is ahead of the resulting frame.
nSampleRateIf set to 0, the sample rate provided by the audio driver will be used.
Returns
frame

Definition at line 213 of file TransportPosition.cpp.

◆ computeTick()

double computeTick ( long long nFrame,
float fTickSize )
staticprivate

Converts frames into ticks under the assumption of a constant fTickSize (sample rate, tempo, and resolution did not change).

As the assumption above does not hold once a tempo marker is introduced, computeFrameFromTick() should be used instead while this function is only meant for internal use.

Definition at line 650 of file TransportPosition.cpp.

◆ computeTickFromFrame()

double computeTickFromFrame ( long long nFrame,
int nSampleRate = 0 )
static

Calculates tick equivalent of nFrame.

In case the #Timeline is activated, the function takes all passed tempo markers into account in order to determine the number of ticks passed when letting the AudioEngine roll for nFrame frames.

It depends on the sample rate nSampleRate and assumes that it as well as the resolution to be constant over the whole song.

Parameters
nFrameTransport position in frame which should be converted into ticks.
nSampleRateIf set to 0, the sample rate provided by the audio driver will be used.

Definition at line 466 of file TransportPosition.cpp.

◆ getBar()

int getBar ( ) const
inline

Definition at line 477 of file TransportPosition.h.

◆ getBeat()

int getBeat ( ) const
inline

Definition at line 480 of file TransportPosition.h.

◆ getBpm()

float getBpm ( ) const
inline

Definition at line 423 of file TransportPosition.h.

◆ getColumn()

int getColumn ( ) const
inline

Definition at line 432 of file TransportPosition.h.

◆ getDoubleTick()

double getDoubleTick ( ) const
inlineprivate

Definition at line 414 of file TransportPosition.h.

◆ getFrame()

long long getFrame ( ) const
inline

Definition at line 411 of file TransportPosition.h.

◆ getFrameOffsetTempo()

long long getFrameOffsetTempo ( ) const
inline

Definition at line 438 of file TransportPosition.h.

◆ getLabel()

const QString getLabel ( ) const
inline

Definition at line 408 of file TransportPosition.h.

◆ getLastLeadLagFactor()

long long getLastLeadLagFactor ( ) const
inline

Definition at line 471 of file TransportPosition.h.

◆ getNextPatterns() [1/2]

PatternList * getNextPatterns ( )
inlineprivate

Definition at line 465 of file TransportPosition.h.

◆ getNextPatterns() [2/2]

const PatternList * getNextPatterns ( ) const
inline

Definition at line 462 of file TransportPosition.h.

◆ getPatternSize()

int getPatternSize ( ) const
inline

Definition at line 468 of file TransportPosition.h.

◆ getPatternStartTick()

long getPatternStartTick ( ) const
inline

Definition at line 426 of file TransportPosition.h.

◆ getPatternTickPosition()

long getPatternTickPosition ( ) const
inline

Definition at line 429 of file TransportPosition.h.

◆ getPlayingPatterns() [1/2]

PatternList * getPlayingPatterns ( )
inlineprivate

Definition at line 459 of file TransportPosition.h.

◆ getPlayingPatterns() [2/2]

const PatternList * getPlayingPatterns ( ) const
inline

Definition at line 456 of file TransportPosition.h.

◆ getTick()

long getTick ( ) const
inline

Retrieve a rounded version of m_fTick.

Only within the AudioEngine ticks are handled as doubles. This is required to allow for a seamless transition between frames and ticks without any rounding error. All other parts use integer values (due to historical reasons).

Definition at line 417 of file TransportPosition.h.

◆ getTickMismatch()

double getTickMismatch ( ) const
inline

Definition at line 435 of file TransportPosition.h.

◆ getTickOffsetQueuing()

double getTickOffsetQueuing ( ) const
inline

Definition at line 444 of file TransportPosition.h.

◆ getTickOffsetSongSize()

double getTickOffsetSongSize ( ) const
inline

Definition at line 450 of file TransportPosition.h.

◆ getTickSize()

float getTickSize ( ) const
inline

Definition at line 420 of file TransportPosition.h.

◆ reset()

void reset ( )
private

Definition at line 84 of file TransportPosition.cpp.

◆ set()

void set ( std::shared_ptr< TransportPosition > pOther)
private

Copying the content of one position into the other is a lot cheaper than performing computations, like AudioEngine::updateTransportPosition(), twice.

Definition at line 51 of file TransportPosition.cpp.

◆ setBar()

void setBar ( int nBar)
private

Definition at line 193 of file TransportPosition.cpp.

◆ setBeat()

void setBeat ( int nBeat)
private

Definition at line 202 of file TransportPosition.cpp.

◆ setBpm()

void setBpm ( float fNewBpm)
private

Definition at line 105 of file TransportPosition.cpp.

◆ setColumn()

void setColumn ( int nColumn)
private

Definition at line 173 of file TransportPosition.cpp.

◆ setFrame()

void setFrame ( long long nNewFrame)
private

Definition at line 123 of file TransportPosition.cpp.

◆ setFrameOffsetTempo()

void setFrameOffsetTempo ( long long nFrameOffset)
inlineprivate

Definition at line 441 of file TransportPosition.h.

◆ setLastLeadLagFactor()

void setLastLeadLagFactor ( long long nValue)
inlineprivate

Definition at line 474 of file TransportPosition.h.

◆ setNextPatterns()

void setNextPatterns ( PatternList * pPatternList)
private

◆ setPatternSize()

void setPatternSize ( int nPatternSize)
private

Definition at line 184 of file TransportPosition.cpp.

◆ setPatternStartTick()

void setPatternStartTick ( long nPatternStartTick)
private

Definition at line 153 of file TransportPosition.cpp.

◆ setPatternTickPosition()

void setPatternTickPosition ( long nPatternTickPosition)
private

Definition at line 163 of file TransportPosition.cpp.

◆ setPlayingPatterns()

void setPlayingPatterns ( PatternList * pPatternList)
private

◆ setTick()

void setTick ( double fNewTick)
private

Definition at line 133 of file TransportPosition.cpp.

◆ setTickOffsetQueuing()

void setTickOffsetQueuing ( double nTickOffset)
inlineprivate

Definition at line 447 of file TransportPosition.h.

◆ setTickOffsetSongSize()

void setTickOffsetSongSize ( double fTickOffset)
inlineprivate

Definition at line 453 of file TransportPosition.h.

◆ setTickSize()

void setTickSize ( float fNewTickSize)
private

Definition at line 143 of file TransportPosition.cpp.

◆ toQString()

QString toQString ( const QString & sPrefix = "",
bool bShort = true ) const
overridevirtual

Formatted string version for debugging purposes.

Parameters
sPrefixString prefix which will be added in front of every new line
bShortInstead of the whole content of all classes stored as members just a single unique identifier will be displayed without line breaks.
Returns
String presentation of current object.

Reimplemented from Base.

Definition at line 654 of file TransportPosition.cpp.

Friends And Related Symbol Documentation

◆ AudioEngine

friend class AudioEngine
friend

Definition at line 134 of file TransportPosition.h.

◆ AudioEngineTests

friend class AudioEngineTests
friend

Definition at line 135 of file TransportPosition.h.

Field Documentation

◆ m_fBpm

float m_fBpm
private

Current tempo in beats per minute.

It can be set through three different mechanisms and the corresponding values are stored in different places.

  1. The most fundamental one is stored in Song::m_fBpm and can be set using the BPM widget in the PlayerControl or via MIDI and OSC commands. Writing the value to the current #Song is done by the latter commands and widget and not within the AudioEngine.
  2. It is superseded by the tempo markers as soon as the #Timeline is activated and at least one TempoMarker is set. The current speed during Timeline-based transport will not override Song::m_fBpm and is stored using the tempo markers in the .h2song file instead. (see #Timeline for details)
  3. Both #Song and #Timeline tempo are superseded by the BPM broadcasted by the JACK timebase master application once Hydrogen acts as timebase slave. The corresponding value depends entirely on the external application and will not be stored by Hydrogen.

Definition at line 255 of file TransportPosition.h.

◆ m_fTick

double m_fTick
private

Current transport position in number of ticks since the beginning of the song.

A tick is the smallest temporal unit used for transport, navigation, and audio rendering within Hydrogen. (Note that the smallest unit for positioning a #Note is a frame due to the humanization capabilities.)

Although the precision of this variable is double, only a version of it rounded to integer is used outside of the AudioEngine.

Float is, unfortunately, not enough. When the engine is running for a long time the high precision digits after decimal point required to keep frames and ticks in sync would be lost.

Definition at line 224 of file TransportPosition.h.

◆ m_fTickMismatch

double m_fTickMismatch
private

Number of ticks m_nFrame is ahead/behind of m_fTick.

This is due to the rounding error introduced when calculating the frame counterpart m_nFrame of m_fTick using computeFrameFromTick(). m_nFrame.

Definition at line 293 of file TransportPosition.h.

◆ m_fTickOffsetQueuing

double m_fTickOffsetQueuing
private

Tick offset introduced when changing the tempo of the song.

In case the #Timeline is deactivate each tempo change does alter m_fTickSize and results in the start of the new tick interval covered for note enqueuing in AudioEngine::updateNoteQueue() to not be consistent with the previous interval end anymore. Holes or overlaps could lead to note misses or double enqueuings. We will handle this by compensating the difference in ticks using m_fTickOffsetQueuing as an additive offset internally.

When locating transport or stopping playback both the tick interval and m_fTickOffsetQueuing get resetted.

Note this is not the tick equivalent of m_nFrameOffsetTempo.

Definition at line 329 of file TransportPosition.h.

◆ m_fTickOffsetSongSize

double m_fTickOffsetSongSize
private

Tick offset introduced when changing the size of the song.

When altering the size of the song, e.g. by enlarging a pattern prior to the one currently playing, both m_nFrame and m_fTick become invalid. We will handle this by compensating the difference between the old and new tick position using m_fTickOffsetSongSize as an additive offset internally. In addition, m_nFrameOffsetTempo and m_fTickOffsetQueuing will be used to compensate for the change in the current frame position and tick interval end.

When locating transport or stopping playback both m_nFrame and m_fTick become synced again and m_fTickOffsetSongSize gets resetted.

Definition at line 347 of file TransportPosition.h.

◆ m_fTickSize

float m_fTickSize
private

Number of frames that make up one tick.

Calculated using AudioEngine::computeTickSize().

Definition at line 231 of file TransportPosition.h.

◆ m_nBar

int m_nBar
private

Last beat (column + 1) passed.

Note that this variable starts at 1 not at 0.

Definition at line 399 of file TransportPosition.h.

◆ m_nBeat

int m_nBeat
private

Last bar passed since m_nBar.

A bar is composed of 48 ticks.

Note that this variable starts at 1 not at 0.

Definition at line 405 of file TransportPosition.h.

◆ m_nColumn

int m_nColumn
private

Specifies the column transport is located in and can be used as the index of the current PatternList/column in the Song::m_pPatternGroupSequence.

A value of -1 corresponds to "pattern list could not be found" and is used to indicate that transport reached the end of the song (with transport not looped).

Definition at line 283 of file TransportPosition.h.

◆ m_nFrame

long long m_nFrame
private

Current transport position in number of frames since the beginning of the song.

A frame is a single sample of an audio signal. Thus, with a sample rate of 48000Hz, 48000 frames will be recorded in one second and, with a buffer size = 1024, 1024 consecutive frames will be accumulated before they are handed over to the audio engine for processing. Internally, the transport is based on ticks. (m_nFrame / m_fTickSize)

Definition at line 205 of file TransportPosition.h.

◆ m_nFrameOffsetTempo

long long m_nFrameOffsetTempo
private

Frame offset introduced when changing the tempo of the song.

In case the #Timeline is deactivate each tempo change does alter m_fTickSize and results in m_nFrame and m_fTick to not be consistent anymore. We will handle this by compensating the difference in frames (m_fTick is kept constant during a tempo change while m_nFrame gets rescaled) using m_nFrameOffsetTempo as an additive offset internally.

When locating transport or stopping playback both m_nFrame and m_fTick become synced again and m_nFrameOffsetTempo gets resetted.

Note this is not the frame equivalent of m_fTickOffsetQueuing.

Definition at line 311 of file TransportPosition.h.

◆ m_nLastLeadLagFactor

long long m_nLastLeadLagFactor
private
#AudioEngine::getLeadLagInFrames() calculated for the previous

transport position.

It is required to ensure a smooth update of the queuing
position in AudioEngine::updateNoteQueue() without any holes or
overlaps in the covered ticks (while using the #Timeline in
#Song::Mode::Song).

Definition at line 392 of file TransportPosition.h.

◆ m_nPatternSize

int m_nPatternSize
private

Maximum size of all patterns in m_pPlayingPatterns.

If m_pPlayingPatterns is empty, #H2Core::MAX_NOTES will be used as fallback.

Definition at line 381 of file TransportPosition.h.

◆ m_nPatternStartTick

long m_nPatternStartTick
private

Dicstance in ticks between the beginning of the song and the beginning of the current column (m_nColumn).

The current transport position corresponds to m_fTick = (roughly) m_nPatternStartTick + m_nPatternTickPosition.

Definition at line 265 of file TransportPosition.h.

◆ m_nPatternTickPosition

long m_nPatternTickPosition
private

Ticks passed since m_nPatternStartTick.

The current transport position thus corresponds to m_fTick = (roughly) m_nPatternStartTick + m_nPatternTickPosition.

Definition at line 273 of file TransportPosition.h.

◆ m_pNextPatterns

PatternList* m_pNextPatterns
private

Patterns used to toggle the ones in m_pPlayingPatterns in Song::PatternMode::Stacked.

If a #Pattern is already playing and added to m_pNextPatterns, it will the removed from m_pPlayingPatterns next time transport is looped to the beginning and vice versa.

See AudioEngine::updatePlayingPatterns() for details.

Definition at line 359 of file TransportPosition.h.

◆ m_pPlayingPatterns

PatternList* m_pPlayingPatterns
private

Contains all Patterns currently played back.

If transport is in H2Core::Song::Mode::Song, it corresponds to the patterns present in column m_nColumn.

Due to performance reasons no virtual patterns will be checked and expanded in this list. Instead, all contained patterns have to be added explicitly.

See AudioEngine::updatePlayingPatterns() for details.

Definition at line 373 of file TransportPosition.h.

◆ m_sLabel

const QString m_sLabel
private

Identifier of the transport position.

Used to keep different instances apart.

Definition at line 192 of file TransportPosition.h.