28#include <core/config.h>
61#define RIGHT_HERE __FILE__, __LINE__, __PRETTY_FUNCTION__
74 class TransportPosition;
201 void lock(
const char* file,
unsigned int line,
const char* function );
217 bool tryLock(
const char* file,
219 const char* function );
237 bool tryLockFor( std::chrono::microseconds duration,
240 const char* function );
253 void assertLocked(
const QString& sClass,
const char* sFunction,
254 const QString& sMsg );
273 static float computeTickSize(
const int nSampleRate,
const float fBpm,
const int nResolution);
454 QString
toQString(
const QString& sPrefix =
"",
bool bShort =
true )
const override;
492 void reset(
bool bWithJackBroadcast =
true );
520 long long computeTickInterval(
double* fTickStart,
double* fTickEnd,
unsigned nIntervalLengthInFrames );
527 void setSong( std::shared_ptr<Song>pNewSong );
537 void locate(
const double fTick,
bool bWithJackBroadcast =
true );
549 std::shared_ptr<TransportPosition> pPos );
551 std::shared_ptr<TransportPosition> pPos );
553 std::shared_ptr<TransportPosition> pPos );
608 #if defined(H2CORE_HAVE_LADSPA) || _DOXYGEN_
706#ifdef H2CORE_HAVE_DEBUG
707 #define ASSERT_AUDIO_ENGINE_LOCKED(x) assertAudioEngineLocked( _class_name(), __FUNCTION__, QString( "%1" ).arg( x ) );
709 #define ASSERT_AUDIO_ENGINE_LOCKED(x)
735 const char* sFunction,
736 const QString& sMsg )
const;
int(* audioProcessCallback)(uint32_t, void *)
void setNeedsLock(bool bNeedsLock)
The audio processing thread can modify some PatternLists.
void assertAudioEngineLocked(const QString &sClass, const char *sFunction, const QString &sMsg) const
Assert that the AudioEngine lock is held if needed.
int m_nLoopsDone
Indicates how many loops the transport already did when the user presses the Loop button again.
void makeTrackPorts(std::shared_ptr< Song > pSong)
void updateBpmAndTickSize(std::shared_ptr< TransportPosition > pTransportPosition)
float getMasterPeak_L() const
std::shared_ptr< Instrument > getMetronomeInstrument() const
void handleTimelineChange()
Updates the transport states and all notes in m_songNoteQueue and m_midiNoteQueue after adding or del...
QString getDriverNames() const
void flushAndAddNextPattern(int nPatternNumber)
Add pattern nPatternNumber to #m_pNextPatterns as well as the whole content of #m_pPlayingPatterns.
std::shared_ptr< TransportPosition > m_pTransportPosition
MidiOutput * m_pMidiDriverOut
friend void Hydrogen::removeSong()
Is allowed to call removeSong().
void setRealtimeFrame(long long nFrame)
bool tryLock(const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
friend void Hydrogen::setSong(std::shared_ptr< Song > pSong, bool bRelinking)
Is allowed to call setSong().
AudioOutput * m_pAudioDriver
void handleSelectedPattern()
Keeps the selected pattern in line with the one the transport position resides in while in Song::Mode...
const PatternList * getNextPatterns() const
std::deque< Note * > m_midiNoteQueue
Midi Note FIFO.
static float getBpmAtColumn(int nColumn)
void clearAudioBuffers(uint32_t nFrames)
Clear all audio buffers.
void setNextState(State state)
void renameJackPorts(std::shared_ptr< Song > pSong)
Hands the provided Song to JackAudioDriver::makeTrackOutputs() if pSong is not a null pointer and the...
static constexpr float fHumanizePitchSD
Maximum value the standard deviation of the Gaussian distribution the random pitch contribution will ...
audioProcessCallback m_AudioProcessCallback
double getSongSizeInTicks() const
int getEnqueuedNotesNumber() const
Returns the size of m_songNoteQueue.
void setMasterPeak_R(float value)
void handleLoopModeChanged()
In order to properly support H2Core::Song::LoopMode::Finishing - transport was already looped a coupl...
void toggleNextPattern(int nPatternNumber)
Add pattern nPatternNumber to #m_pNextPatterns or deletes it in case it is already present.
static QString StateToQString(const State &state)
void setState(State state)
std::timed_mutex m_EngineMutex
Mutex for synchronizing the access to the Song object and the AudioEngine.
void removePlayingPattern(Pattern *pPattern)
long long m_nRealtimeFrame
Variable keeping track of the transport position in realtime.
@ Prepared
Drivers are set up, but not ready to process audio.
@ Initialized
Not ready, but most pointers are now valid or NULL.
@ Playing
Transport is rolling.
@ Ready
Ready to process audio.
@ Uninitialized
Not even the constructors have been called.
@ Testing
State used during the unit tests of the AudioEngine.
float getElapsedTime() const
void setNextBpm(float fNextBpm)
Stores the new speed into a separate variable which will be adopted during the next processing cycle.
friend class AudioEngineTests
State m_nextState
State assigned during the next call to processTransport().
void locateToFrame(const long long nFrame)
Version of the locate() function intended to be directly used by frame-based audio drivers / servers.
void updatePlayingPatternsPos(std::shared_ptr< TransportPosition > pPos)
void updateTransportPosition(double fTick, long long nFrame, std::shared_ptr< TransportPosition > pPos)
long long getLeadLagInFrames(double fTick)
Calculates lead lag factor (in frames) relative to the transport position fTick.
void play()
Marks the audio engine to be started during the next call of the audioEngine_process() callback funct...
float getProcessTime() const
static constexpr float fHumanizeTimingSD
Maximum value the standard deviation of the Gaussian distribution the random pitch contribution will ...
void updatePlayingPatterns()
Update the list of currently played patterns associated with m_pTransportPosition and m_pQueuingPosit...
static constexpr int nMaxTimeHumanize
Maximum time (in frames) a note's position can be off due to the humanization (lead-lag).
std::priority_queue< Note *, std::deque< Note * >, compare_pNotes > m_songNoteQueue
void updateVirtualPatterns()
void handleTempoChange()
Updates all notes in m_songNoteQueue and m_midiNoteQueue to be still valid after a tempo change.
float m_fFXPeak_L[MAX_FX]
bool tryLockFor(std::chrono::microseconds duration, const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
State getNextState() const
AudioOutput * createAudioDriver(const Preferences::AudioDriver &driver)
Create an audio driver using audioEngine_process() as its argument based on the provided choice and c...
void handleSongModeChanged()
Called whenever Hydrogen switches from Song::Mode::Song into Song::Mode::Pattern or the other way aro...
EventQueue * m_pEventQueue
QMutex m_MutexOutputPointer
Mutex for locking the pointer to the audio output buffer, allowing multiple readers.
float getMasterPeak_R() const
double m_fSongSizeInTicks
Set to the total number of ticks in a Song.
friend class JackAudioDriver
bool isEndOfSongReached(std::shared_ptr< TransportPosition > pPos) const
void stop()
Marks the audio engine to be stopped during the next call of the audioEngine_process() callback funct...
void calculateTransportOffsetOnBpmChange(std::shared_ptr< TransportPosition > pTransportPosition)
void unlock()
Mutex unlocking of the AudioEngine.
float getMaxProcessTime() const
void lock(const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
const PatternList * getPlayingPatterns() const
State m_state
Current state of the H2Core::AudioEngine.
double coarseGrainTick(double fTick)
Ideally we just floor the provided tick.
static double getLeadLagInTicks()
Maximum lead lag factor in ticks.
std::shared_ptr< TransportPosition > m_pQueuingPosition
static constexpr float fHumanizeVelocitySD
Maximum value the standard deviation of the Gaussian distribution the random velocity contribution wi...
static float computeTickSize(const int nSampleRate, const float fBpm, const int nResolution)
Calculates the number of frames that make up a tick.
void updatePatternTransportPosition(double fTick, long long nFrame, std::shared_ptr< TransportPosition > pPos)
static int audioEngine_process(uint32_t nframes, void *arg)
Main audio processing function called by the audio drivers whenever there is work to do.
struct H2Core::AudioEngine::_locker_struct m_pLocker
void locate(const double fTick, bool bWithJackBroadcast=true)
AudioOutput * getAudioDriver() const
void processPlayNotes(unsigned long nframes)
void updateSongSize()
Function to be called every time the length of the current song does change, e.g.
Sampler * getSampler() const
void stopAudioDrivers()
Stops all audio and MIDI drivers.
void restartAudioDrivers()
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
const std::shared_ptr< TransportPosition > getTransportPosition() const
std::shared_ptr< Instrument > m_pMetronomeInstrument
Pointer to the metronome.
void handleSongSizeChange()
Updates all notes in m_songNoteQueue to be still valid after a change in song size.
void assertLocked(const QString &sClass, const char *sFunction, const QString &sMsg)
Assert that the calling thread is the current holder of the AudioEngine lock.
float m_fFXPeak_R[MAX_FX]
void handleDriverChange()
The audio driver was changed what possible changed the tick size - which depends on both the sample r...
void reset(bool bWithJackBroadcast=true)
MidiInput * m_pMidiDriver
void updateSongTransportPosition(double fTick, long long nFrame, std::shared_ptr< TransportPosition > pPos)
long long computeTickInterval(double *fTickStart, double *fTickEnd, unsigned nIntervalLengthInFrames)
void startAudioDrivers()
Creation and initialization of all audio and MIDI drivers called in Hydrogen::Hydrogen().
void processAudio(uint32_t nFrames)
MidiOutput * getMidiOutDriver() const
void incrementTransportPosition(uint32_t nFrames)
void updateNoteQueue(unsigned nIntervalLengthInFrames)
Takes all notes from the currently playing patterns, from the MIDI queue m_midiNoteQueue,...
static double computeDoubleTickSize(const int nSampleRate, const float fBpm, const int nResolution)
void raiseError(unsigned nErrorCode)
long long getRealtimeFrame() const
MidiInput * getMidiDriver() const
std::thread::id m_LockingThread
Thread ID of the current holder of the AudioEngine lock.
void setMasterPeak_L(float value)
Base abstract class for audio output classes.
bool locateToTick(long nTick, bool bWithJackBroadcast=true)
Relocates transport to a particular tick.
bool deleteTempoMarker(int nPosition)
Delete a tempo marker from the Timeline.
bool activateSongMode(bool bActivate)
Switches between Song and Pattern mode of playback.
bool activateLoopMode(bool bActivate)
Toggle loop mode of playback.
bool addTempoMarker(int nPosition, float fBpm)
Adds a tempo marker to the Timeline.
Object handling the communication between the core of Hydrogen and its GUI.
virtual int connect() override
void setIsTimelineActivated(bool bEnabled)
Wrapper around both Song::setIsTimelineActivated (recent) and Preferences::setUseTimelinebpm() (forme...
void setSong(std::shared_ptr< Song > newSong, bool bRelinking=true)
Sets the current song __song to newSong.
void updateSelectedPattern(bool bNeedsLock=true)
Updates the selected pattern to the one recorded note will be inserted to.
A note plays an associated instrument with a velocity left and right pan.
PatternList is a collection of patterns.
Pattern class is a Note container.
#define MAX_FX
Maximum number of effects.
int(* audioProcessCallback)(uint32_t, void *)
bool operator()(Note *pNote1, Note *pNote2)