|
hydrogen 1.1.1
|
JACK (Jack Audio Connection Kit) server driver. More...
#include <JackAudioDriver.h>
Public Types | |
| enum class | Timebase { Master = 1 , Slave = 0 , None = -1 } |
| Whether Hydrogen or another program is Jack timebase master. More... | |
Public Member Functions | |
| JackAudioDriver (JackProcessCallback m_processCallback) | |
| Constructor of the JACK server driver. More... | |
| ~JackAudioDriver () | |
| Destructor of the JACK server driver. More... | |
| int | connect () |
| Connects to output ports via the JACK server. More... | |
| void | disconnect () |
| Disconnects the JACK client of the Hydrogen from the JACK server. More... | |
| void | deactivate () |
| Deactivates the JACK client of Hydrogen and disconnects all ports belonging to it. More... | |
| unsigned | getBufferSize () |
| unsigned | getSampleRate () |
| void | clearPerTrackAudioBuffers (uint32_t nFrames) |
| Resets the buffers contained in m_pTrackOutputPortsL and m_pTrackOutputPortsR. More... | |
| void | makeTrackOutputs (Song *pSong) |
| Creates per component output ports for each instrument. More... | |
| void | setConnectDefaults (bool flag) |
| bool | getConnectDefaults () |
| float * | getOut_L () |
| Get content in the left stereo output port. More... | |
| float * | getOut_R () |
| Get content in the right stereo output port. More... | |
| float * | getTrackOut_L (unsigned nTrack) |
| Get content of left output port of a specific track. More... | |
| float * | getTrackOut_R (unsigned nTrack) |
| Get content of right output port of a specific track. More... | |
| float * | getTrackOut_L (Instrument *instr, InstrumentComponent *pCompo) |
| Convenience function looking up the track number of a component of an instrument using in m_trackMap using their IDs Instrument::__id and InstrumentComponent::__related_drumkit_componentID. More... | |
| float * | getTrackOut_R (Instrument *instr, InstrumentComponent *pCompo) |
| Convenience function looking up the track number of a component of an instrument using in m_trackMap using their IDs Instrument::__id and InstrumentComponent::__related_drumkit_componentID. More... | |
| int | init (unsigned bufferSize) |
| Initializes the JACK audio driver. More... | |
| virtual void | play () |
| Starts the JACK transport. More... | |
| virtual void | stop () |
| Stops the JACK transport. More... | |
| virtual void | locate (unsigned long nFrame) |
| Re-positions the transport position to nFrame. More... | |
| virtual void | updateTransportInfo () |
| virtual void | setBpm (float fBPM) |
| Set the tempo stored TransportInfo::m_fBPM of the local instance of the TransportInfo AudioOutput::m_transport. More... | |
| void | calculateFrameOffset (long long oldFrame) |
| Calculates the difference between the true transport position and the internal one. More... | |
| void | initTimebaseMaster () |
| Registers Hydrogen as JACK timebase master. More... | |
| void | releaseTimebaseMaster () |
| Calls jack_release_timebase() (jack/transport.h) to release Hydrogen from the JACK timebase master responsibilities. More... | |
| Timebase | getTimebaseState () const |
Public Member Functions inherited from AudioOutput | |
| AudioOutput (const char *class_name) | |
| virtual | ~AudioOutput () |
| virtual int | init (unsigned nBufferSize)=0 |
| virtual int | connect ()=0 |
| virtual void | disconnect ()=0 |
| virtual unsigned | getBufferSize ()=0 |
| virtual unsigned | getSampleRate ()=0 |
| virtual int | getLatency () |
| Approximate audio latency (in frames) A reasonable approximation is the buffer time on most audio systems. More... | |
| virtual float * | getOut_L ()=0 |
| virtual float * | getOut_R ()=0 |
| virtual void | updateTransportInfo ()=0 |
| virtual void | play ()=0 |
| virtual void | stop ()=0 |
| virtual void | locate (unsigned long nFrame)=0 |
| virtual void | setBpm (float fBPM)=0 |
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 int | jackDriverSampleRate (jack_nframes_t nframes, void *param) |
| Callback function for the JACK audio server to set the sample rate jackServerSampleRate and prints a message to the __INFOLOG, which has to be included via a Logger instance in the provided param. More... | |
| static int | jackDriverBufferSize (jack_nframes_t nframes, void *arg) |
| Callback function for the JACK audio server to set the buffer size jackServerBufferSize. More... | |
Static Public Member Functions inherited from AudioOutput | |
| static QStringList | getDevices () |
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 Logger * | logger () |
| return the logger instance More... | |
Data Fields | |
| jack_client_t * | m_pClient |
| Object holding the external client session with the JACK server. More... | |
| int | m_currentPos |
| Stores the latest transport position (for both rolling and stopped transport). More... | |
Data Fields inherited from AudioOutput | |
| TransportInfo | m_transport |
| Local instance of the TransportInfo. More... | |
Static Public Attributes | |
| static unsigned long | jackServerSampleRate = 0 |
| Sample rate of the JACK audio server. More... | |
| static jack_nframes_t | jackServerBufferSize = 0 |
| Buffer size of the JACK audio server. More... | |
| static JackAudioDriver * | pJackDriverInstance = nullptr |
| Instance of the JackAudioDriver. More... | |
| static int | nWaits = 0 |
| Required in JackTimebaseCallback() to keep the sync between the timebase master and all other JACK clients. More... | |
Static Public Attributes inherited from Object | |
| static QString | sPrintIndention = " " |
| String used to format the debugging string output of some core classes. More... | |
Protected Member Functions | |
| void | jack_session_callback_impl (jack_session_event_t *event) |
Static Protected Member Functions | |
| static void | JackTimebaseCallback (jack_transport_state_t state, jack_nframes_t nFrames, jack_position_t *pJackPosition, int new_pos, void *arg) |
| Callback function registered to the JACK server in initTimebaseMaster() if Hydrogen is set as JACK timebase master. More... | |
| static void | jackDriverShutdown (void *arg) |
| Callback function for the JACK audio server to shutting down the JACK driver. More... | |
| static void | jack_session_callback (jack_session_event_t *event, void *arg) |
| Function to call by the JACK server when a session event is to be delivered. More... | |
| static void | printJackTransportPos (const jack_position_t *pPos) |
Private Member Functions | |
| void | printState () const |
| Show debugging information. More... | |
| bool | compareAdjacentBBT () const |
| Compares the BBT information stored in m_JackTransportPos and m_previousJackTransportPos with respect to the tempo and the transport position in bars, beats, and ticks. More... | |
| void | relocateUsingBBT () |
| Uses the bar-beat-tick information to relocate the transport position. More... | |
| void | setTrackOutput (int n, Instrument *instr, InstrumentComponent *pCompo, Song *pSong) |
| Renames the n 'th port of JACK client and creates it if it's not already present. More... | |
Private Attributes | |
| long long | m_frameOffset |
| Constant offset between the internal transport position in TransportInfo::m_nFrames and the external one. More... | |
| JackProcessCallback | m_processCallback |
| Function the JACK server will call whenever there is work to do. More... | |
| jack_port_t * | m_pOutputPort1 |
| Left source port for which a connection to m_sOutputPortName1 will be established in connect() via the JACK server. More... | |
| jack_port_t * | m_pOutputPort2 |
| Right source port for which a connection to m_sOutputPortName2 will be established in connect() via the JACK server. More... | |
| QString | m_sOutputPortName1 |
| Destination of the left source port m_pOutputPort1, for which a connection will be established in connect(). More... | |
| QString | m_sOutputPortName2 |
| Destination of the right source port m_pOutputPort2, for which a connection will be established in connect(). More... | |
| int | m_trackMap [MAX_INSTRUMENTS][MAX_COMPONENTS] |
| Matrix containing the track number of each component of of all instruments. More... | |
| int | m_nTrackPortCount |
| Total number of output ports currently in use. More... | |
| jack_port_t * | m_pTrackOutputPortsL [MAX_INSTRUMENTS] |
| Vector of all left audio output ports currently used by the local JACK client. More... | |
| jack_port_t * | m_pTrackOutputPortsR [MAX_INSTRUMENTS] |
| Vector of all right audio output ports currently used by the local JACK client. More... | |
| jack_transport_state_t | m_JackTransportState |
| Current transport state returned by jack_transport_query() (jack/transport.h). More... | |
| jack_position_t | m_JackTransportPos |
| Current transport position obtained using jack_transport_query() (jack/transport.h). More... | |
| jack_position_t | m_previousJackTransportPos |
| Used for detecting changes in the BBT transport information with external timebase master application, which do not propagate these changes on time. More... | |
| bool | m_bConnectDefaults |
| Specifies whether the default left and right (master) audio JACK ports will be automatically connected to the system's sink when registering the JACK client in connect(). More... | |
| int | m_nTimebaseTracking |
| Whether Hydrogen or another program is Jack timebase master. More... | |
| Timebase | m_timebaseState |
| More user-friendly version of m_nTimebaseTracking. More... | |
Additional Inherited Members | |
Static Protected Attributes inherited from Object | |
| static Logger * | __logger = nullptr |
| logger instance pointer More... | |
JACK (Jack Audio Connection Kit) server driver.
Transport Control:
Each JACK client can start and stop the transport or relocate the current transport position. The request will take place in cycles. During the first the status of the transport changes to JackTransportStarting to inform all clients a change is about to happen. During the second the status is again JackTransportRolling and the transport position is updated according to the request. The current timebase master (see below), if present, needs another cycle to update the additional transport information.
Such a relocation request is also triggered when clicking on the timeline or the player control buttons of Hydrogen. Internally, audioEngine_stop() is called during the cycle in which the JACK transport status is JackTransportStarting and started again by audioEngine_start() when in JackTransportRolling in the next cycle. Note that if there are slow synchronizing client in JACK's connection graph, it can take multiple cycles until the JACK transport is rolling again.
Also note that Hydrogen overwrites its local TransportInfo stored in AudioOutput::m_transport only with the transport position of the JACK server if a relocation did happened or another timebase master did change the speed. During normal transport the current position TransportInfo::m_nFrames will be always the same as the one of JACK during a cycle and incremented by the buffer size in audioEngine_process() at the very end of the cycle. The same happens for the transport information of the JACK server but in parallel.
Timebase Master:
The timebase master is responsible to update additional information in the transport information of the JACK server apart from the transport position in frames (see TransportInfo::m_nFrames if you aren't familiar with frames), like the current beat, bar, tick, tick size, speed etc. Every client can be registered as timebase master by supplying a callback (for Hydrogen this would be JackTimebaseCallback()) but there can be at most one timebase master at a time. Having none at all is perfectly fine too. Apart from this additional responsibility, the registered client has no other rights compared to others.
After the status of the JACK transport has changed from JackTransportStarting to JackTransportRolling, the timebase master needs an additional cycle to update its information.
Having an external timebase master present will change the general behavior of Hydrogen. All local tempo settings on the Timeline will be disregarded and the tempo broadcasted by the JACK server will be used instead.
This object will only be accessible if H2CORE_HAVE_JACK was defined during the configuration and the user enables the support of the JACK server.
|
strong |
Whether Hydrogen or another program is Jack timebase master.
| Enumerator | |
|---|---|
| Master | Hydrogen itself is timebase master. |
| Slave | An external program is timebase master and Hydrogen will disregard all tempo marker on the Timeline and, instead, only use the BPM provided by JACK. |
| None | Only normal clients registered. |
| JackAudioDriver | ( | JackProcessCallback | m_processCallback | ) |
Constructor of the JACK server driver.
| m_processCallback | Prototype for the client supplied function that is called by the engine anytime there is work to be done. It gets two input arguments nframes of type jack_nframes_t, which specifies the number of frames to process, and a void pointer called arg, which points to a client supplied structure. Two preconditions do act on the nframes argument: nframes == getBufferSize() and nframes == pow(2,x) It returns zero on success and non-zero on error. |
| ~JackAudioDriver | ( | ) |
Destructor of the JACK server driver.
Calling disconnect().
| void calculateFrameOffset | ( | long long | oldFrame | ) |
Calculates the difference between the true transport position and the internal one.
The internal transport position used in most parts of Hydrogen is given in ticks. But since the size of a tick is tempo-dependent, passing a tempo marker in the Timeline will cause the corresponding internal transport position in frames to diverge from the external one by a constant offset. This function will calculate and store it in m_frameOffset.
| oldFrame | Provides the previous transport position in frames prior to the change in tick size. This is required if transport is not rolling during the relocation into a region of different speed since there is no up-to-date JACK query providing these information. |
| void clearPerTrackAudioBuffers | ( | uint32_t | nFrames | ) |
Resets the buffers contained in m_pTrackOutputPortsL and m_pTrackOutputPortsR.
| nFrames | Size of the buffers used in the audio process callback function. |
|
private |
Compares the BBT information stored in m_JackTransportPos and m_previousJackTransportPos with respect to the tempo and the transport position in bars, beats, and ticks.
|
virtual |
Connects to output ports via the JACK server.
Starts by telling the JACK server that Hydrogen is ready to process audio using the jack_activate function (from the jack/jack.h header) and overwriting the memory allocated by m_pTrackOutputPortsL and m_pTrackOutputPortsR with zeros. If the m_bConnectDefaults variable is true or LashClient is used and Hydrogen is not within a new Lash project, the function attempts to connect the m_pOutputPort1 port with m_sOutputPortName1 and the m_pOutputPort2 port with m_sOutputPortName2. To establish the connection, jack_connect() (jack/jack.h) will be used. In case this was not successful, the function will look up all ports containing the JackPortIsInput (jack/types.h) flag using jack_get_ports() (jack/jack.h) and attempts to connect to the first two it found.
Implements AudioOutput.
| void deactivate | ( | ) |
Deactivates the JACK client of Hydrogen and disconnects all ports belonging to it.
It calls the jack_deactivate() (jack/jack.h) function on the current client m_pClient and overwrites the memory allocated by m_pTrackOutputPortsL and m_pTrackOutputPortsR with zeros.
|
virtual |
Disconnects the JACK client of the Hydrogen from the JACK server.
Firstly, it calls deactivate(). Then, it closes the connection between the JACK server and the local client using jack_client_close (jack/jack.h), and sets the m_pClient pointer to nullptr.
Implements AudioOutput.
|
virtual |
Implements AudioOutput.
|
inline |
|
virtual |
Get content in the left stereo output port.
It calls jack_port_get_buffer() (jack/jack.h) with both the port name m_pOutputPort1 and buffer size jackServerBufferSize.
Implements AudioOutput.
|
virtual |
Get content in the right stereo output port.
It calls jack_port_get_buffer() (jack/jack.h) with both the port name m_pOutputPort2 and buffer size jackServerBufferSize.
Implements AudioOutput.
|
virtual |
Implements AudioOutput.
| JackAudioDriver::Timebase getTimebaseState | ( | ) | const |
| float * getTrackOut_L | ( | Instrument * | instr, |
| InstrumentComponent * | pCompo | ||
| ) |
Convenience function looking up the track number of a component of an instrument using in m_trackMap using their IDs Instrument::__id and InstrumentComponent::__related_drumkit_componentID.
Using the track number it then calls getTrackOut_L( unsigned ) and returns its result.
| instr | Pointer to an Instrument |
| pCompo | Pointer to one of the instrument's components. |
| float * getTrackOut_L | ( | unsigned | nTrack | ) |
Get content of left output port of a specific track.
It calls jack_port_get_buffer() (jack/jack.h) with the port in the nTrack element of m_pTrackOutputPortsL and buffer size jackServerBufferSize.
| nTrack | Track number. Must not be bigger than m_nTrackPortCount. |
| float * getTrackOut_R | ( | Instrument * | instr, |
| InstrumentComponent * | pCompo | ||
| ) |
Convenience function looking up the track number of a component of an instrument using in m_trackMap using their IDs Instrument::__id and InstrumentComponent::__related_drumkit_componentID.
Using the track number it then calls getTrackOut_R( unsigned ) and returns its result.
| instr | Pointer to an Instrument |
| pCompo | Pointer to one of the instrument's components. |
| float * getTrackOut_R | ( | unsigned | nTrack | ) |
Get content of right output port of a specific track.
It calls jack_port_get_buffer() (jack/jack.h) with the port in the nTrack element of m_pTrackOutputPortsR and buffer size jackServerBufferSize.
| nTrack | Track number. Must not be bigger than m_nTrackPortCount. |
|
virtual |
Initializes the JACK audio driver.
Firstly, it determines the destination ports m_sOutputPortName1 and m_sOutputPortName2 the output ports of Hydrogen will be connected to in connect() from Preferences::m_sJackPortName1 and Preferences::m_sJackPortName2. The name of the JACK client is either set to "Hydrogen" or, if H2CORE_HAVE_OSC was defined during compilation and OSC support is enabled, to Preferences::m_sNsmClientId via Preferences::getNsmClientId().
Next, the function attempts to open an external client session with the JACK server using jack_client_open() (jack/jack.h) and saves it to the pointer m_pClient. In case this didn't work properly, it will start two more attempts. Sometime JACK doesn't stop and start fast enough. If the compiler flag H2CORE_HAVE_JACKSESSION was set and the user enabled the usage of JACK session, the client will be opened using the corresponding option and the sessionID Token Preferences::jackSessionUUID, obtained via Preferences::getJackSessionUUID(), will be provided so the sessionmanager can identify the client again.
If the client was opened properly, the function will get its sample rate using jack_get_sample_rate() and buffer size using jack_get_buffer_size() (both jack/jack.h) and stores them in jackServerSampleRate, Preferences::m_nSampleRate, jackServerBufferSize, and Preferences::m_nBufferSize. In addition, it also registers JackAudioDriver::m_processCallback, jackDriverSampleRate, jackDriverBufferSize, and jackDriverShutdown using jack_set_process_callback(), jack_set_sample_rate_callback(), jack_set_buffer_size_callback(), and jack_on_shutdown() (all in jack/jack.h).
Next, two output ports called "out_L" and "out_R" are registered for the client m_pClient using jack_port_register().
If everything worked properly, LASH is used (Preferences::useLash()) by the user, and the LashClient is LashClient::isConnected() the name of the client will be stored in LashClient::jackClientName using LashClient::setJackClientName. If JACK session was enabled, the jack_session_callback() will be registered using jack_set_session_callback() (jack/session.h).
Finally, the function will check whether Hydrogen should be the JACK timebase master or not via Preferences::m_bJackMasterMode and calls initTimebaseMaster() if its indeed the case.
| bufferSize | Unused and only present to assure compatibility with the JACK API. |
Implements AudioOutput.
| void initTimebaseMaster | ( | ) |
Registers Hydrogen as JACK timebase master.
If for some reason registering Hydrogen as timebase master does not work, the function sets Preferences::m_bJackMasterMode to Preferences::NO_JACK_TIME_MASTER.
If the function is called with Preferences::m_bJackMasterMode set to Preferences::NO_JACK_TIME_MASTER, releaseTimebaseMaster() will be called instead.
|
staticprotected |
Function to call by the JACK server when a session event is to be delivered.
It is registered to the JACK client in init() using jack_set_session_callback() (jack/session.h) if H2CORE_HAVE_JACKSESSION was defined during compilation.
Internally it hands the event to jack_session_callback_impl().
| event | Jack session event (see jack/session.h) |
| arg | Pointer to an instance of the JackAudioDriver. |
|
protected |
|
static |
Callback function for the JACK audio server to set the buffer size jackServerBufferSize.
It gets registered as a callback function of the JACK server in JackAudioDriver::init() using jack_set_buffer_size_callback().
| nframes | New buffer size. The object has to be of type jack_nframes_t, which is defined in the jack/types.h header. |
| arg | Not used within the function but kept for compatibility reasons since the JackBufferSizeCallback (jack/types.h) requires a second input argument arg of type void, which is a pointer supplied by the jack_set_buffer_size_callback() function. |
|
static |
Callback function for the JACK audio server to set the sample rate jackServerSampleRate and prints a message to the __INFOLOG, which has to be included via a Logger instance in the provided param.
It gets registered as a callback function of the JACK server in JackAudioDriver::init() using jack_set_sample_rate_callback().
| nframes | New sample rate. The object has to be of type jack_nframes_t, which is defined in the jack/types.h header. |
| param | Object containing a Logger member to display the change in the sample rate in its INFOLOG. |
|
staticprotected |
Callback function for the JACK audio server to shutting down the JACK driver.
The JackAudioDriver::m_pClient pointer stored in the current instance of the JACK audio driver pJackDriverInstance is set to the nullptr and a Hydrogen::JACK_SERVER_SHUTDOWN error is raised using Hydrogen::raiseError().
It gets registered as a callback function of the JACK server in JackAudioDriver::init() using jack_on_shutdown().
| arg | Not used within the function but kept for compatibility reasons since jack_shutdown() (jack/jack.h) the argument arg of type void. |
|
staticprotected |
Callback function registered to the JACK server in initTimebaseMaster() if Hydrogen is set as JACK timebase master.
It will update the current position not just in frames till the beginning of the song, but also in terms of beat, bar, and tick values.
The function it will be called after the audioEngine_process() function and only if the m_JackTransportState is JackTransportRolling.
| state | Current transport state. Not used within the function but to ensure compatibility. |
| nFrames | Buffer size. Not used within the function but to ensure compatibility. |
| pJackPosition | Current transport position. |
| new_pos | Updated transport position in frames. Not used within the function but to ensure compatibility. |
| arg | Pointer to a JackAudioDriver instance. |
|
virtual |
Re-positions the transport position to nFrame.
If the Preferences::USE_JACK_TRANSPORT mode is chosen in Preferences::m_bJackTransportMode, the jack_transport_locate() (jack/transport.h) function will be used to request the new transport position. If not, nFrame will be assigned to TransportInfo::m_nFrames of the local instance of the TransportInfo AudioOutput::m_transport.
The new position takes effect in two process cycles during which JACK's state will be in JackTransportStarting and the transport won't be rolling.
| nFrame | Requested new transport position. |
Implements AudioOutput.
| void makeTrackOutputs | ( | Song * | pSong | ) |
Creates per component output ports for each instrument.
Firstly, it resets m_trackMap with zeros. Then, it loops through all the instruments and their components, creates a new output or resets an existing one for each of them using setTrackOutput(), and stores the corresponding track number in m_trackMap. Finally, all ports in m_pTrackOutputPortsL and m_pTrackOutputPortsR, which haven't been used in the previous step, are unregistered using jack_port_unregister() (jack/jack.h) and overwritten with 0. m_nTrackPortCount will be set to biggest track number encountered during the creation/reassignment step.
The function will only perform its tasks if the Preferences::m_bJackTrackOuts is set to true.
|
virtual |
Starts the JACK transport.
If the JACK transport was activated in the GUI by clicking either the "J.TRANS" or "J.MASTER" button, the jack_transport_start() (jack/transport.h) function will be called to start the JACK transport. Else, the internal TransportInfo::m_status will be set to TransportInfo::ROLLING instead.
Implements AudioOutput.
|
staticprotected |
|
private |
Show debugging information.
| void releaseTimebaseMaster | ( | ) |
Calls jack_release_timebase() (jack/transport.h) to release Hydrogen from the JACK timebase master responsibilities.
This causes the JackTimebaseCallback() callback function to not be called by the JACK server anymore.
|
private |
Uses the bar-beat-tick information to relocate the transport position.
This type of operation is triggered whenever the transport position gets relocated or the tempo is changed using Jack in the presence of an external timebase master. In addition, the function also updates the current tick size to prevent the audioEngine_checkBPMUpdate() function from doing so.
|
virtual |
Set the tempo stored TransportInfo::m_fBPM of the local instance of the TransportInfo AudioOutput::m_transport.
Only sets the tempo to fBPM if its value is at least
| fBPM | new tempo. |
Implements AudioOutput.
|
inline |
| flag | Sets m_bConnectDefaults |
|
private |
Renames the n 'th port of JACK client and creates it if it's not already present.
If the track number n is bigger than the number of ports currently in usage m_nTrackPortCount, n + 1 - m_nTrackPortCount new stereo ports will be created using jack_port_register() (jack/jack.h) and m_nTrackPortCount updated to n + 1.
Afterwards, the n 'th port is renamed to a concatenation of "Track_", DrumkitComponent::__name, "_", n + 1, "_", Instrument::__name, and "_L", or "_R" using either jack_port_rename() (if HAVE_JACK_PORT_RENAME is defined) or jack_port_set_name() (both jack/jack.h). The former renaming function triggers a PortRename notifications to clients that have registered a port rename handler.
| n | Track number for which a port should be renamed (and created). |
| instr | Pointer to the corresponding Instrument. |
| pCompo | Pointer to the corresponding InstrumentComponent. |
| pSong | Pointer to the corresponding Song. |
|
virtual |
Stops the JACK transport.
If the JACK transport was activated in the GUI by clicking either the "J.TRANS" or "J.MASTER" button, the jack_transport_stop() (jack/transport.h) function will be called to stop the JACK transport. Else, the internal TransportInfo::m_status will be set to TransportInfo::STOPPED instead.
Implements AudioOutput.
|
virtual |
Updating the local instance of the TransportInfo AudioOutput::m_transport. The function queries the transport position and additional information from the JACK server, writes them to #m_JackTransportPos and in #m_JackTransportState, and updates the information stored in AudioOutput::m_transport in case of a mismatch. If #m_JackTransportState is either _JackTransportStopped_ or
JackTransportStarting, transport will be (temporarily) stopped - TransportInfo::m_status will be set to TransportInfo::STOPPED. If it's JackTransportRolling, transport will be started - TransportInfo::m_status will be set to TransportInfo::ROLLING.
The function will check whether a relocation took place by the JACK server and whether the current tempo did change with respect to the last transport cycle and updates the transport information accordingly.
If Preferences::USE_JACK_TRANSPORT was not selected in Preferences::m_bJackTransportMode, the function will return without performing any action.
Implements AudioOutput.
|
static |
Buffer size of the JACK audio server.
It is set by the callback function jackDriverBufferSize() registered in the JACK server and accessed via JackAudioDriver::getBufferSize(). Its initialization is handled by JackAudioDriver::init(), which sets it to the buffer size of the Hydrogen's external JACK client via jack_get_buffer_size() (jack/jack.h).
|
static |
Sample rate of the JACK audio server.
It is set by the callback function jackDriverSampleRate() registered in the JACK server and accessed via JackAudioDriver::getSampleRate(). Its initialization is handled by JackAudioDriver::init(), which sets it to the sample rate of the Hydrogen's external JACK client via jack_get_sample_rate() (jack/jack.h).
|
private |
Specifies whether the default left and right (master) audio JACK ports will be automatically connected to the system's sink when registering the JACK client in connect().
After the JackAudioDriver has been created by createDriver(), the variable will be, again, set to Preferences::m_bJackConnectDefaults.
| int m_currentPos |
Stores the latest transport position (for both rolling and stopped transport).
In case the user is clicking on a different location SongEditorPositionRuler::mousePressEvent() will trigger both a relocation and a (possible) change in speed. The change in speed causes the audioEngine_checkBPMChange() function to update the ticksize in case playhead got moved into a region of different tempo and triggers the calculateFrameOffset() function. But the latter can only work properly if transport is rolling since it has to know the frame position prior to the change in tick size and there is no up-to-date JACK query providing this information.
|
private |
Constant offset between the internal transport position in TransportInfo::m_nFrames and the external one.
Imagine the following setting: During the playback you decide to change the speed of the song. This would cause a lot of position information within Hydrogen, which are given in ticks, to be off since the tick size depends on the speed and just got changed too. Instead, TransportInfo::m_nFrames will scaled to reflect the changes and everything will be still in place with the user to not note a single thing. Unfortunately, now the transport position in frames of the audio engine and of the JACK server are off by a constant offset. To nevertheless be able to identify relocation in updateTransportInfo(), this constant offset is stored in this variable and used in updateTransportInfo() to determine whether a relocation did happen.
Positive values correspond to a position ahead of the current transport information. The variable is initialized with 0 in JackAudioDriver() and updated in calculateFrameOffset().
|
private |
Current transport position obtained using jack_transport_query() (jack/transport.h).
It corresponds to the first frame of the current cycle. If it is NULL, jack_transport_query() won't return any position information.
The valid member of m_JackTransportPos will show which fields contain valid data. Thus, if it is set to JackPositionBBT, bar, beat, and tick information are provided by the current timebase master in addition to the transport information in frames. It is of class jack_position_bits_t (jack/types.h) and is an enumerator with five different options:
The frame member contains the current transport position.
It is set in updateTransportInfo(). Please see the documentation of JackTimebaseCallback() for more information about its different members.
|
private |
Current transport state returned by jack_transport_query() (jack/transport.h).
It is valid for the entire cycle and can have five different values:
The actual number of states depends on your JACK version. The listing above was done for version 1.9.12.
|
private |
Whether Hydrogen or another program is Jack timebase master.
While Hydrogen can unregister as timebase master on its own, it can not be observed directly whether another application has taken over as timebase master. When the JACK server is releasing Hydrogen in the later case, it won't advertise this fact but simply won't call the JackTimebaseCallback() anymore. But since this will be called in every cycle after updateTransportInfo(), we can use this variable to determine if Hydrogen is still timebase master.
As Hydrogen registered as timebase master using initTimebaseMaster() it will be initialized with 1, decremented in updateTransportInfo(), and reset to 1 in JackTimebaseCallback(). Whenever it is zero in updateTransportInfo(), m_nTimebaseTracking will be updated accordingly.
|
private |
Total number of output ports currently in use.
It gets updated by makeTrackOutputs().
| jack_client_t* m_pClient |
Object holding the external client session with the JACK server.
|
private |
Left source port for which a connection to m_sOutputPortName1 will be established in connect() via the JACK server.
|
private |
Right source port for which a connection to m_sOutputPortName2 will be established in connect() via the JACK server.
|
private |
Used for detecting changes in the BBT transport information with external timebase master application, which do not propagate these changes on time.
|
private |
Function the JACK server will call whenever there is work to do.
The audioEngine_process() function will be used and registered using jack_set_process_callback() (jack/jack.h) in init().
The code must be suitable for real-time execution. That means that it cannot call functions that might block for a long time. This includes malloc(), free(), printf(), pthread_mutex_lock(), sleep(), wait(), poll(), select(), pthread_join(), pthread_cond_wait(), etc, etc.
|
private |
Vector of all left audio output ports currently used by the local JACK client.
They will be initialized with all zeros in both JackAudioDriver(), deactivate(), and connect(). Individual components will be created, renamed, or reassigned in setTrackOutput(), deleted in makeTrackOutputs(), and accessed via getTrackOut_L(). It is set to a length of MAX_INSTRUMENTS.
|
private |
Vector of all right audio output ports currently used by the local JACK client.
They will be initialized with all zeros in both JackAudioDriver(), deactivate(), and connect(). Individual components will be created, renamed, or reassigned in setTrackOutput(), deleted in makeTrackOutputs(), and accessed via getTrackOut_R(). It is set to a length of MAX_INSTRUMENTS.
|
private |
Destination of the left source port m_pOutputPort1, for which a connection will be established in connect().
It is set to Preferences::m_sJackPortName1 during the call of init().
|
private |
Destination of the right source port m_pOutputPort2, for which a connection will be established in connect().
It is set to Preferences::m_sJackPortName2 during the call of init().
|
private |
More user-friendly version of m_nTimebaseTracking.
|
private |
Matrix containing the track number of each component of of all instruments.
Its rows represent the instruments and its columns their components. m_trackMap[2][1]=6 thus therefore mean the output of the second component of the third instrument is assigned the seventh output port. Since its total size is defined by MAX_INSTRUMENTS and MAX_COMPONENTS, most of its entries will be zero.
It gets updated by makeTrackOutputs().
|
static |
Required in JackTimebaseCallback() to keep the sync between the timebase master and all other JACK clients.
Whenever a relocation takes place in Hydrogen as timebase master, the speed of the timeline at the destination frame must not be sent in the timebase callback. Instead, Hydrogen must wait two full cycles of the audioEngine before broadcasting the new tempo again. This is because the Hydrogen (as timebase master) requires two full cycles to set the tempo itself and there is a rather intricate dependence on values calculate in various other functions.
|
static |
Instance of the JackAudioDriver.