hydrogen 1.2.6
JackAudioDriver.h
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#ifndef H2_JACK_OUTPUT_H
24#define H2_JACK_OUTPUT_H
25
26#include <core/IO/AudioOutput.h>
27#include <core/IO/NullDriver.h>
28
29// check if jack support is disabled
30#if defined(H2CORE_HAVE_JACK) || _DOXYGEN_
31// JACK support is enabled.
32
33#include <map>
34#include <memory>
35#include <pthread.h>
36#include <jack/jack.h>
37#include <jack/transport.h>
38
39#include <core/Globals.h>
40
41
42
43namespace H2Core
44{
45
46class Song;
47class Instrument;
50
96class JackAudioDriver : public Object<JackAudioDriver>, public AudioOutput
97{
99public:
103 enum class Timebase {
115 None = -1
116 };
117 static QString TimebaseToQString( const Timebase& t );
118 static Timebase TimebaseFromInt( int nState );
119
124 jack_client_t* m_pClient;
131 JackAudioDriver( JackProcessCallback m_processCallback );
138
152 virtual int connect() override;
157 virtual void disconnect() override;
162 void deactivate();
164 virtual unsigned getBufferSize() override;
166 virtual unsigned getSampleRate() override;
167
168 virtual int getXRuns() const override;
169
176 void clearPerTrackAudioBuffers( uint32_t nFrames );
177
181 void makeTrackOutputs( std::shared_ptr<Song> pSong );
182
184 void setConnectDefaults( bool flag ) {
185 m_bConnectDefaults = flag;
186 }
187
189 return m_bConnectDefaults;
190 }
191
198 virtual float* getOut_L() override;
205 virtual float* getOut_R() override;
215 float* getTrackOut_L( unsigned nTrack );
225 float* getTrackOut_R( unsigned nTrack );
240 float* getTrackOut_L( std::shared_ptr<Instrument> instr, std::shared_ptr<InstrumentComponent> pCompo );
255 float* getTrackOut_R( std::shared_ptr<Instrument> instr, std::shared_ptr<InstrumentComponent> pCompo );
256
271 virtual int init( unsigned bufferSize ) override;
272
276 void startTransport();
280 void stopTransport();
290 void locateTransport( long long nFrame );
298
302 void initTimebaseControl();
310
315
319 static unsigned long jackServerSampleRate;
323 static jack_nframes_t jackServerBufferSize;
329 static int jackServerXRuns;
330
340 static int jackDriverSampleRate( jack_nframes_t nframes, void* param );
341
351 static int jackDriverBufferSize( jack_nframes_t nframes, void* arg );
353 static int jackXRunCallback( void* arg );
354
357 float getTimebaseControllerBpm() const;
358
366 void relocateUsingBBT();
369 bool checkBBTPos() const;
370
371 const jack_position_t& getJackPosition() const;
372
373 static bool isBBTValid( const jack_position_t& pos );
374 static double bbtToTick( const jack_position_t& pos );
375 static void transportToBBT( const TransportPosition& transportPos,
376 jack_position_t* pPos );
377 static QString JackTransportPosToQString( const jack_position_t& pPos );
378
379 friend class AudioEngineTests;
380private:
381
412 static QString TimebaseTrackingToQString( const TimebaseTracking& t );
413
445 static void JackTimebaseCallback( jack_transport_state_t state,
446 jack_nframes_t nFrames,
447 jack_position_t* pJackPosition,
448 int new_pos,
449 void* arg );
456 static void jackDriverShutdown( void* arg );
457
458 static QString JackTransportStateToQString( const jack_transport_state_t& pPos );
459
461 void printState() const;
462
488 void setTrackOutput( int n, std::shared_ptr<Instrument> instr, std::shared_ptr<InstrumentComponent> pCompo, std::shared_ptr<Song> pSong );
490 JackProcessCallback m_processCallback;
494 jack_port_t* m_pOutputPort1;
498 jack_port_t* m_pOutputPort2;
533
551 jack_transport_state_t m_JackTransportState;
574 jack_position_t m_JackTransportPos;
575
578 jack_position_t m_nextJackTransportPos;
579
586
593
596
609
619
635
636#ifdef HAVE_INTEGRATION_TESTS
639 static long m_nIntegrationLastRelocationFrame;
642 bool m_bIntegrationRelocationLoop;
643 bool m_bIntegrationCheckRelocationLoop;
644#endif
645};
646
647}; // H2Core namespace
648
649
650#else // H2CORE_HAVE_JACK
651// JACK is disabled
652
653namespace H2Core {
655class JackAudioDriver : public NullDriver {
657public:
658 enum class Timebase {
659 Controller = 1,
660 Listener = 0,
661 None = -1
662 };
663 static QString TimebaseToQString( const Timebase& t ) { return "Not supported"; };
664 static Timebase TimebaseFromInt( int nState ) { return Timebase::None; };
672
673 // Required since these functions are a friend of AudioEngine which
674 // need to be build even if no JACK support is desired.
676 void relocateUsingBBT() {}
677};
678
679}; // H2Core namespace
680
681
682#endif // H2CORE_HAVE_JACK
683
684#endif
685
#define H2_OBJECT(name)
Definition Object.h:227
Instrument class.
Definition Instrument.h:55
virtual void disconnect() override
Disconnects the JACK client of the Hydrogen from the JACK server.
int m_nTrackPortCount
Total number of output ports currently in use.
static QString JackTransportStateToQString(const jack_transport_state_t &pPos)
long long m_nTimebaseFrameOffset
Stores an intended deviation of our transport position from the one hold by the JACK server.
jack_port_t * m_pTrackOutputPortsL[MAX_INSTRUMENTS]
Vector of all left audio output ports currently used by the local JACK client.
jack_position_t m_nextJackTransportPos
Use for relocation if Hydrogen is Timebase controller (and needs to provide valid BBT information in ...
void initTimebaseControl()
Acquires control of JACK Timebase.
TimebaseTracking
Used internally to keep track of the current Timebase state.
@ Valid
Current timebase state is on par with JACK server.
@ OnHold
We are uncertain of the current timebase state and wait a processing cycle to determine what to do ne...
static void transportToBBT(const TransportPosition &transportPos, jack_position_t *pPos)
virtual float * getOut_L() override
Get content in the left stereo output port.
Timebase m_timebaseState
Whether Hydrogen is receiving relocation and tempo changes as part of BBT information,...
static QString JackTransportPosToQString(const jack_position_t &pPos)
virtual int init(unsigned bufferSize) override
Initializes the JACK audio driver.
JackAudioDriver(JackProcessCallback m_processCallback)
Constructor of the JACK server driver.
bool m_bConnectDefaults
Specifies whether the default left and right (master) audio JACK ports will be automatically connecte...
static unsigned long jackServerSampleRate
Sample rate of the JACK audio server.
static JackAudioDriver * pJackDriverInstance
Instance of the JackAudioDriver.
QString m_sOutputPortName2
Destination of the right source port m_pOutputPort2, for which a connection will be established in co...
QString m_sOutputPortName1
Destination of the left source port m_pOutputPort1, for which a connection will be established in con...
float * getTrackOut_R(unsigned nTrack)
Get content of right output port of a specific track.
float getTimebaseControllerBpm() const
static int jackDriverSampleRate(jack_nframes_t nframes, void *param)
Callback function for the JACK audio server to set the sample rate jackServerSampleRate.
void clearPerTrackAudioBuffers(uint32_t nFrames)
Resets the buffers contained in m_pTrackOutputPortsL and m_pTrackOutputPortsR.
const jack_position_t & getJackPosition() const
jack_port_t * m_pOutputPort2
Right source port.
int m_trackMap[MAX_INSTRUMENTS][MAX_COMPONENTS]
Matrix containing the track number of each component of all instruments.
void startTransport()
Tells the JACK server to start transport.
virtual float * getOut_R() override
Get content in the right stereo output port.
static int jackServerXRuns
Number of XRuns since the driver started.
bool checkBBTPos() const
Used within the unit tests and checks whether the last JACK transport position retrieved has valid BB...
virtual unsigned getBufferSize() override
static QString TimebaseTrackingToQString(const TimebaseTracking &t)
void releaseTimebaseControl()
Release Hydrogen from the JACK Timebase control.
void setTrackOutput(int n, std::shared_ptr< Instrument > instr, std::shared_ptr< InstrumentComponent > pCompo, std::shared_ptr< Song > pSong)
Renames the n 'th port of JACK client and creates it if it's not already present.
static double bbtToTick(const jack_position_t &pos)
Timebase
Whether Hydrogen or another program is in Timebase control.
@ Listener
An external program is Timebase controller and Hydrogen will disregard all tempo markers on the Timel...
@ None
Only normal clients registered.
@ Controller
Hydrogen itself is Timebase controller and provides its current tempo to other Timebase listeners.
jack_client_t * m_pClient
Object holding the external client session with the JACK server.
void deactivate()
Deactivates the JACK client of Hydrogen and disconnects all ports belonging to it.
void setConnectDefaults(bool flag)
static Timebase TimebaseFromInt(int nState)
float m_fLastTimebaseBpm
Stores the last tempo sent by an external Timebase controller.
int m_lastTransportBits
Remembers the BBT capability bit received in a JACK process cycle.
virtual int connect() override
Connects to output ports via the JACK server.
Timebase getTimebaseState() const
static QString TimebaseToQString(const Timebase &t)
jack_position_t m_JackTransportPos
Current transport position obtained using jack_transport_query() (jack/transport.h).
jack_port_t * m_pOutputPort1
Left source port.
static int jackDriverBufferSize(jack_nframes_t nframes, void *arg)
Callback function for the JACK audio server to set the buffer size jackServerBufferSize.
static jack_nframes_t jackServerBufferSize
Buffer size of the JACK audio server.
void stopTransport()
Tells the JACK server to stop transport.
void updateTransportPosition()
The function queries the transport position and additional information from the JACK server,...
static bool isBBTValid(const jack_position_t &pos)
static void jackDriverShutdown(void *arg)
Callback function for the JACK audio server to shutting down the JACK driver.
TimebaseTracking m_timebaseTracking
Whether the current timebase state is stable or about to change.
static int jackXRunCallback(void *arg)
Report an XRun event to the GUI.
void makeTrackOutputs(std::shared_ptr< Song > pSong)
Creates per component output ports for each instrument.
virtual unsigned getSampleRate() override
static void JackTimebaseCallback(jack_transport_state_t state, jack_nframes_t nFrames, jack_position_t *pJackPosition, int new_pos, void *arg)
Callback function for the JACK server to supply additional timebase information.
JackProcessCallback m_processCallback
Main process callback.
~JackAudioDriver()
Destructor of the JACK server driver.
void printState() const
Show debugging information.
float * getTrackOut_L(unsigned nTrack)
Get content of left output port of a specific track.
jack_transport_state_t m_JackTransportState
Current transport state returned by jack_transport_query() (jack/transport.h).
void relocateUsingBBT()
Uses the bar-beat-tick information to relocate the transport position.
jack_port_t * m_pTrackOutputPortsR[MAX_INSTRUMENTS]
Vector of all right audio output ports currently used by the local JACK client.
void locateTransport(long long nFrame)
Re-positions the transport position to nFrame.
virtual int getXRuns() const override
Get the number of XRuns that occurred since the audio driver has started.
Song class.
Definition Song.h:61
Object holding most of the information about the transport state of the AudioEngine.
#define MAX_INSTRUMENTS
Maximum number of instruments allowed in Hydrogen.
Definition config.dox:70
#define MAX_COMPONENTS
Maximum number of components each Instrument is allowed to have.
Definition config.dox:75
int(* audioProcessCallback)(uint32_t, void *)
Definition AudioOutput.h:32