1 /*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23 #include <hydrogen/IO/jack_audio_driver.h>
24 #if defined(H2CORE_HAVE_JACK) || _DOXYGEN_
25
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <cstdlib>
29 #include <cassert>
30 #include <hydrogen/hydrogen.h>
31 #include <hydrogen/audio_engine.h>
32 #include <hydrogen/basics/drumkit_component.h>
33 #include <hydrogen/basics/instrument.h>
34 #include <hydrogen/basics/instrument_component.h>
35 #include <hydrogen/basics/instrument_list.h>
36 #include <hydrogen/basics/playlist.h>
37 #include <hydrogen/basics/song.h>
38 #include <hydrogen/helpers/files.h>
39 #include <hydrogen/helpers/filesystem.h>
40 #include <hydrogen/Preferences.h>
41 #include <hydrogen/globals.h>
42 #include <hydrogen/event_queue.h>
43
44 #ifdef H2CORE_HAVE_LASH
45 #include <hydrogen/LashClient.h>
46 #endif
47
48 #ifdef H2CORE_HAVE_JACKSESSION
49 #include <jack/session.h>
50 #endif
51
52 namespace H2Core {
53
54 /**
55 * Sample rate of the JACK audio server.
56 *
57 * It is set by the callback function jackDriverSampleRate()
58 * registered in the JACK server and accessed via
59 * JackAudioDriver::getSampleRate(). Its initialization is handled by
60 * JackAudioDriver::init(), which sets it to the sample rate of the
61 * Hydrogen's external JACK client via _jack_get_sample_rate()_
62 * (jack/jack.h).
63 */
64 unsigned long jackServerSampleRate = 0;
65 /**
66 * Buffer size of the JACK audio server.
67 *
68 * It is set by the callback function jackDriverBufferSize()
69 * registered in the JACK server and accessed via
70 * JackAudioDriver::getBufferSize(). Its initialization is handled by
71 * JackAudioDriver::init(), which sets it to the buffer size of the
72 * Hydrogen's external JACK client via _jack_get_buffer_size()_
73 * (jack/jack.h).
74 */
75 jack_nframes_t jackServerBufferSize = 0;
76 /**
77 * Instance of the JackAudioDriver.
78 */
79 JackAudioDriver* pJackDriverInstance = nullptr;
80
81 /**
82 * Callback function for the JACK audio server to set the sample rate
83 * #H2Core::jackServerSampleRate and prints a message to
84 * the #__INFOLOG, which has to be included via a Logger instance in
85 * the provided @a param.
86 *
87 * It gets registered as a callback function of the JACK server in
88 * JackAudioDriver::init() using _jack_set_sample_rate_callback()_.
89 *
90 * \param nframes New sample rate. The object has to be of type
91 * _jack_nframes_t_, which is defined in the jack/types.h header.
92 * \param param Object containing a Logger member to display the
93 * change in the sample rate in its INFOLOG.
94 *
95 * @return 0 on success
96 */
jackDriverSampleRate(jack_nframes_t nframes,void * param)97 int jackDriverSampleRate( jack_nframes_t nframes, void* param ){
98 // Used for logging.
99 Object* __object = ( Object* )param;
100 QString msg = QString("Jack SampleRate changed: the sample rate is now %1/sec").arg( QString::number( (int) nframes ) );
101 // The __INFOLOG macro uses the Object *__object and not the
102 // Object instance as INFOLOG does. It will call
103 // __object->logger()->log( H2Core::Logger::Info, ..., msg )
104 // (see object.h).
105 __INFOLOG( msg );
106 jackServerSampleRate = nframes;
107 return 0;
108 }
109 /**
110 * Callback function for the JACK audio server to set the buffer size
111 * #H2Core::jackServerBufferSize.
112 *
113 * It gets registered as a callback function of the JACK server in
114 * JackAudioDriver::init() using _jack_set_buffer_size_callback()_.
115 *
116 * \param nframes New buffer size. The object has to be of type @a
117 * jack_nframes_t, which is defined in the jack/types.h header.
118 * \param arg Not used within the function but kept for compatibility
119 * reasons since the _JackBufferSizeCallback_ (jack/types.h) requires a
120 * second input argument @a arg of type _void_, which is a pointer
121 * supplied by the jack_set_buffer_size_callback() function.
122 *
123 * @return 0 on success
124 */
jackDriverBufferSize(jack_nframes_t nframes,void * arg)125 int jackDriverBufferSize( jack_nframes_t nframes, void* arg ){
126 // This function does _NOT_ have to be realtime safe.
127 jackServerBufferSize = nframes;
128 return 0;
129 }
130 /**
131 * Callback function for the JACK audio server to shutting down the
132 * JACK driver.
133 *
134 * The JackAudioDriver::m_pClient pointer stored in the current
135 * instance of the JACK audio driver #pJackDriverInstance is set to
136 * the nullptr and a Hydrogen::JACK_SERVER_SHUTDOWN error is raised
137 * using Hydrogen::raiseError().
138 *
139 * It gets registered as a callback function of the JACK server in
140 * JackAudioDriver::init() using _jack_on_shutdown()_.
141 *
142 * \param arg Not used within the function but kept for compatibility
143 * reasons since _jack_shutdown()_ (jack/jack.h) the argument @a arg
144 * of type void.
145 */
jackDriverShutdown(void * arg)146 void jackDriverShutdown( void* arg )
147 {
148 UNUSED( arg );
149
150 pJackDriverInstance->m_pClient = nullptr;
151 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_SERVER_SHUTDOWN );
152 }
153
154 /**
155 * Required in JackTimebaseCallback() to keep the sync between the
156 * timebase master and all other JACK clients.
157 *
158 * Whenever a relocation takes place in Hydrogen as timebase master,
159 * the speed of the timeline at the destination frame must not be sent
160 * in the timebase callback. Instead, Hydrogen must wait two full
161 * cycles of the audioEngine before broadcasting the new tempo
162 * again. This is because the Hydrogen (as timebase master) requires
163 * two full cycles to set the tempo itself and there is a rather
164 * intricate dependence on values calculate in various other
165 * functions.
166 *
167 * TODO: Kill this variable and make the relocation behavior way more
168 * straight forward.
169 */
170 int nWaits = 0;
171
172 const char* JackAudioDriver::__class_name = "JackAudioDriver";
173
JackAudioDriver(JackProcessCallback m_processCallback)174 JackAudioDriver::JackAudioDriver( JackProcessCallback m_processCallback )
175 : AudioOutput( __class_name )
176 {
177 INFOLOG( "INIT" );
178
179 auto pPreferences = Preferences::get_instance();
180
181 // __track_out_enabled is inherited from AudioOutput and
182 // instantiated with false. It will be used by the Sampler and
183 // Hydrogen itself to check whether JackAudioDriver does create
184 // per-track audio output ports.
185 __track_out_enabled = pPreferences->m_bJackTrackOuts;
186
187 pJackDriverInstance = this;
188 this->m_processCallback = m_processCallback;
189
190 m_frameOffset = 0;
191 m_nTrackPortCount = 0;
192 m_pClient = nullptr;
193 m_pOutputPort1 = nullptr;
194 m_pOutputPort2 = nullptr;
195 m_bConnectDefaults = pPreferences->m_bJackConnectDefaults;
196 m_nIsTimebaseMaster = -1;
197
198 // Destination ports the output of Hydrogen will be connected
199 // to.
200 m_sOutputPortName1 = pPreferences->m_sJackPortName1;
201 m_sOutputPortName2 = pPreferences->m_sJackPortName2;
202
203 memset( m_pTrackOutputPortsL, 0, sizeof(m_pTrackOutputPortsL) );
204 memset( m_pTrackOutputPortsR, 0, sizeof(m_pTrackOutputPortsR) );
205 }
206
~JackAudioDriver()207 JackAudioDriver::~JackAudioDriver()
208 {
209 INFOLOG( "DESTROY" );
210 disconnect();
211 }
212
connect()213 int JackAudioDriver::connect()
214 {
215 INFOLOG( "connect" );
216
217 // The `jack_activate' function is defined in the jack/jack.h
218 // header files and tells the JACK server that the program is
219 // ready to start processing audio. It returns 0 on success
220 // and a non-zero error code otherwise.
221 if ( jack_activate( m_pClient ) ) {
222 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_ACTIVATE_CLIENT );
223 return 1;
224 }
225
226 bool bConnectDefaults = m_bConnectDefaults;
227
228 memset( m_pTrackOutputPortsL, 0, sizeof(m_pTrackOutputPortsL) );
229 memset( m_pTrackOutputPortsR, 0, sizeof(m_pTrackOutputPortsR) );
230
231 #ifdef H2CORE_HAVE_LASH
232 if ( Preferences::get_instance()->useLash() ){
233 LashClient* lashClient = LashClient::get_instance();
234 if (lashClient && lashClient->isConnected()){
235 // INFOLOG( "[LASH] Sending JACK client name to LASH server" );
236 lashClient->sendJackClientName();
237
238 if (!lashClient->isNewProject()){
239 bConnectDefaults = false;
240 }
241 }
242 }
243 #endif
244
245 if ( bConnectDefaults ) {
246 // Connect the left and right default ports of Hydrogen.
247 //
248 // The `jack_connect' function is defined in the
249 // jack/jack.h file. It establishes a connection between
250 // two ports. When a connection exists, data written
251 // to the source port will be available to be read at
252 // the destination port. Returns 0 on success, exits
253 // if the connection is already made, and returns a
254 // non-zero error code otherwise.
255 // Syntax: jack_connect( jack_client_t jack_client,
256 // const char *source_port )
257 // const char *destination_port
258 // )
259 // The `jack_port_name' function is also defined in
260 // the jack/jack.h header returns the full name of a
261 // provided port of type jack_port_t.
262 if ( jack_connect( m_pClient, jack_port_name( m_pOutputPort1 ),
263 m_sOutputPortName1.toLocal8Bit() ) == 0 &&
264 jack_connect( m_pClient, jack_port_name( m_pOutputPort2 ),
265 m_sOutputPortName2.toLocal8Bit() ) == 0 ) {
266 return 0;
267 }
268
269 WARNINGLOG( "Could not connect to the saved output ports. Connect to the first pair of input ports instead." );
270 // The `jack_get_ports' is defined in the jack/jack.h
271 // header file and performs a lookup of ports of the
272 // JACK server based on their e.g. flags. It returns a
273 // NULL-terminated array of ports that match the
274 // specified arguments. The caller is responsible for
275 // calling jack_free() any non-NULL returned
276 // value.
277 const char ** portnames = jack_get_ports( m_pClient, nullptr, nullptr, JackPortIsInput );
278 if ( !portnames || !portnames[0] || !portnames[1] ) {
279 ERRORLOG( "Couldn't locate two Jack input ports" );
280 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_CONNECT_OUTPUT_PORT );
281 return 2;
282 }
283 if ( jack_connect( m_pClient, jack_port_name( m_pOutputPort1 ),
284 portnames[0] ) != 0 ||
285 jack_connect( m_pClient, jack_port_name( m_pOutputPort2 ),
286 portnames[1] ) != 0 ) {
287 ERRORLOG( "Couldn't connect to first pair of Jack input ports" );
288 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_CONNECT_OUTPUT_PORT );
289 return 2;
290 }
291 free( portnames );
292 }
293
294 return 0;
295 }
296
disconnect()297 void JackAudioDriver::disconnect()
298 {
299 INFOLOG( "disconnect" );
300
301 deactivate();
302
303 jack_client_t* pOldClient = m_pClient;
304
305 m_pClient = nullptr;
306
307 if ( pOldClient != nullptr ) {
308 INFOLOG( "calling jack_client_close" );
309 int nReturnCode = jack_client_close( pOldClient );
310 if ( nReturnCode != 0 ) {
311 ERRORLOG( "Error in jack_client_close" );
312 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_CLOSE_CLIENT );
313 }
314 }
315 m_pClient = nullptr;
316 }
317
deactivate()318 void JackAudioDriver::deactivate()
319 {
320 if ( m_pClient != nullptr ) {
321 INFOLOG( "calling jack_deactivate" );
322 int nReturnCode = jack_deactivate( m_pClient );
323 if ( nReturnCode != 0 ) {
324 ERRORLOG( "Error in jack_deactivate" );
325 }
326 }
327 memset( m_pTrackOutputPortsL, 0, sizeof(m_pTrackOutputPortsL) );
328 memset( m_pTrackOutputPortsR, 0, sizeof(m_pTrackOutputPortsR) );
329 }
330
getBufferSize()331 unsigned JackAudioDriver::getBufferSize()
332 {
333 return jackServerBufferSize;
334 }
335
getSampleRate()336 unsigned JackAudioDriver::getSampleRate()
337 {
338 return jackServerSampleRate;
339 }
340
calculateFrameOffset(long long oldFrame)341 void JackAudioDriver::calculateFrameOffset(long long oldFrame)
342 {
343 if ( Hydrogen::get_instance()->getState() == STATE_PLAYING ) {
344 m_frameOffset = m_JackTransportPos.frame - m_transport.m_nFrames;
345 } else {
346 m_frameOffset = oldFrame - m_transport.m_nFrames;
347 }
348 }
349
updateTransportInfo()350 void JackAudioDriver::updateTransportInfo()
351 {
352
353 if ( Preferences::get_instance()->m_bJackTransportMode !=
354 Preferences::USE_JACK_TRANSPORT ){
355 return;
356 }
357
358 // jack_transport_query() (jack/transport.h) queries the
359 // current transport state and position. If called from the
360 // process thread, the second argument, which is a pointer to
361 // a structure for returning current transport, corresponds to
362 // the first frame of the current cycle and the state returned
363 // is valid for the entire cycle. #m_JackTransportPos->valid
364 // will show which fields contain valid data. If
365 // #m_JackTransportPos is NULL, do not return position
366 // information.
367 m_JackTransportState = jack_transport_query( m_pClient, &m_JackTransportPos );
368
369 switch ( m_JackTransportState ) {
370 case JackTransportStopped: // Transport is halted
371 m_transport.m_status = TransportInfo::STOPPED;
372 return;
373
374 case JackTransportRolling: // Transport is playing
375 m_transport.m_status = TransportInfo::ROLLING;
376 break;
377
378 case JackTransportStarting:
379 // Waiting for sync ready. If there are slow-sync clients,
380 // this can take more than one cycle.
381 m_transport.m_status = TransportInfo::STOPPED;
382 break;
383
384 default:
385 ERRORLOG( "Unknown jack transport state" );
386 }
387
388 m_currentPos = m_JackTransportPos.frame;
389
390 // Update the status regrading JACK timebase master.
391 if ( m_JackTransportState != JackTransportStopped ) {
392 if ( m_nIsTimebaseMaster > 1 ) {
393 m_nIsTimebaseMaster--;
394 } else if ( m_nIsTimebaseMaster == 1 ) {
395 // JackTimebaseCallback not called anymore -> timebase client
396 m_nIsTimebaseMaster = 0;
397 }
398 }
399 if ( m_nIsTimebaseMaster == 0 &&
400 !(m_JackTransportPos.valid & JackPositionBBT) ) {
401 // No external timebase master anymore -> regular client
402 m_nIsTimebaseMaster = -1;
403 } else if ( m_nIsTimebaseMaster < 0 &&
404 (m_JackTransportPos.valid & JackPositionBBT) ) {
405 // External timebase master detected -> timebase client
406 m_nIsTimebaseMaster = 0;
407 }
408
409 Hydrogen* pHydrogen = Hydrogen::get_instance();
410
411 // The relocation could be either triggered by an user interaction
412 // (e.g. clicking the forward button or clicking somewhere on the
413 // timeline) or by a different JACK client.
414 if ( m_transport.m_nFrames + m_frameOffset != m_JackTransportPos.frame ) {
415
416 m_transport.m_nFrames = m_JackTransportPos.frame;
417
418
419 // Reset playback to the beginning of the pattern if Hydrogen
420 // is in pattern mode.
421 pHydrogen->resetPatternStartTick();
422
423 // There maybe was an offset introduced when passing a tempo
424 // marker.
425 m_frameOffset = 0;
426 }
427
428 if ( m_nIsTimebaseMaster == 0 ){
429 // There is a JACK timebase master and it's not us. If it
430 // provides a tempo that differs from the local one, we will
431 // use the former instead.
432 float fBPM = ( float )m_JackTransportPos.beats_per_minute;
433
434 if ( m_transport.m_fBPM != fBPM ) {
435 setBpm( fBPM );
436 pHydrogen->getSong()->__bpm = fBPM;
437 pHydrogen->setNewBpmJTM( fBPM );
438 }
439 } else {
440 // Checks for local changes in speed (introduced by the user
441 // using BPM markers on the timeline) and update tempo
442 // accordingly.
443 pHydrogen->setTimelineBpm();
444 }
445 }
446
getOut_L()447 float* JackAudioDriver::getOut_L()
448 {
449 /**
450 * This returns a pointer to the memory area associated with
451 * the specified port. For an output port, it will be a memory
452 * area that can be written to; for an input port, it will be
453 * an area containing the data from the port's connection(s),
454 * or zero-filled. if there are multiple inbound connections,
455 * the data will be mixed appropriately.
456 */
457 jack_default_audio_sample_t *out = ( jack_default_audio_sample_t * ) jack_port_get_buffer ( m_pOutputPort1, jackServerBufferSize );
458 return out;
459 }
460
getOut_R()461 float* JackAudioDriver::getOut_R()
462 {
463 jack_default_audio_sample_t *out = ( jack_default_audio_sample_t * ) jack_port_get_buffer ( m_pOutputPort2, jackServerBufferSize );
464 return out;
465 }
466
getTrackOut_L(unsigned nTrack)467 float* JackAudioDriver::getTrackOut_L( unsigned nTrack )
468 {
469 if ( nTrack > (unsigned)m_nTrackPortCount ) {
470 return nullptr;
471 }
472
473 jack_port_t* pPort = m_pTrackOutputPortsL[nTrack];
474 jack_default_audio_sample_t* out = nullptr;
475 if( pPort ) {
476 out = (jack_default_audio_sample_t*) jack_port_get_buffer( pPort, jackServerBufferSize);
477 }
478 return out;
479 }
480
getTrackOut_R(unsigned nTrack)481 float* JackAudioDriver::getTrackOut_R( unsigned nTrack )
482 {
483 if( nTrack > (unsigned)m_nTrackPortCount ) {
484 return nullptr;
485 }
486
487 jack_port_t* pPort = m_pTrackOutputPortsR[nTrack];
488 jack_default_audio_sample_t* out = nullptr;
489 if( pPort ) {
490 out = (jack_default_audio_sample_t*) jack_port_get_buffer( pPort, jackServerBufferSize);
491 }
492 return out;
493 }
494
getTrackOut_L(Instrument * instr,InstrumentComponent * pCompo)495 float* JackAudioDriver::getTrackOut_L( Instrument* instr, InstrumentComponent* pCompo)
496 {
497 return getTrackOut_L(m_trackMap[instr->get_id()][pCompo->get_drumkit_componentID()]);
498 }
499
getTrackOut_R(Instrument * instr,InstrumentComponent * pCompo)500 float* JackAudioDriver::getTrackOut_R( Instrument* instr, InstrumentComponent* pCompo)
501 {
502 return getTrackOut_R(m_trackMap[instr->get_id()][pCompo->get_drumkit_componentID()]);
503 }
504
505
506 #define CLIENT_FAILURE(msg) { \
507 ERRORLOG("Could not connect to JACK server (" msg ")"); \
508 if ( m_pClient != nullptr ) { \
509 ERRORLOG("...but JACK returned a non-null pointer?"); \
510 m_pClient = nullptr; \
511 } \
512 if (nTries) ERRORLOG("...trying again."); \
513 }
514
515
516 #define CLIENT_SUCCESS(msg) { \
517 assert(m_pClient); \
518 INFOLOG(msg); \
519 nTries = 0; \
520 }
521
init(unsigned bufferSize)522 int JackAudioDriver::init( unsigned bufferSize )
523 {
524 auto pPreferences = Preferences::get_instance();
525
526 QString sClientName = "Hydrogen";
527
528 #ifdef H2CORE_HAVE_OSC
529 QString sNsmClientId = pPreferences->getNsmClientId();
530
531 if( !sNsmClientId.isEmpty() ){
532 sClientName = sNsmClientId;
533 }
534 #endif
535
536 // The address of the status object will be used by JACK to
537 // return information from the open operation.
538 jack_status_t status;
539 // Sometimes jackd doesn't stop and start fast enough.
540 int nTries = 2;
541 while ( nTries > 0 ) {
542 --nTries;
543
544 // Open an external client session with the JACK
545 // server. The `jack_client_open' function is defined
546 // in the jack/jack.h header. With it, clients may
547 // choose which of several servers to connect, and
548 // control whether and how to start the server
549 // automatically, if it was not already running. Its
550 // first argument _client_name_ of is at most
551 // jack_client_name_size() characters. The name scope
552 // is local to each server. Unless forbidden by the
553 // JackUseExactName option, the server will modify
554 // this name to create a unique variant, if
555 // needed. The second argument _options_ is formed by
556 // OR-ing together JackOptions bits. Only the
557 // JackOpenOptions bits are allowed. _status_ (if
558 // non-NULL) is an address for JACK to return
559 // information from the open operation. This status
560 // word is formed by OR-ing together the relevant
561 // JackStatus bits. Depending on the _status_, an
562 // optional argument _server_name_ selects from among
563 // several possible concurrent server
564 // instances. Server names are unique to each user. It
565 // returns an opaque client handle if successful. If
566 // this is NULL, the open operation failed, *status
567 // includes JackFailure and the caller is not a JACK
568 // client.
569 #ifdef H2CORE_HAVE_JACKSESSION
570 if ( pPreferences->getJackSessionUUID().isEmpty() ){
571 m_pClient = jack_client_open( sClientName.toLocal8Bit(),
572 JackNullOption,
573 &status);
574 } else {
575 // Unique name of the JACK server used within
576 // the JACK session.
577 const QByteArray uuid = pPreferences->getJackSessionUUID().toLocal8Bit();
578 // Using the JackSessionID option and the
579 // supplied SessionID Token the sessionmanager
580 // is able to identify the client again.
581 m_pClient = jack_client_open( sClientName.toLocal8Bit(),
582 JackSessionID,
583 &status,
584 uuid.constData());
585 }
586 #else
587 m_pClient = jack_client_open( sClientName.toLocal8Bit(),
588 JackNullOption,
589 &status);
590 #endif
591 // Check what did happen during the opening of the
592 // client. CLIENT_SUCCESS sets the nTries variable
593 // to 0 while CLIENT_FAILURE resets m_pClient to the
594 // nullptr.
595 switch(status) {
596 case JackFailure:
597 CLIENT_FAILURE("unknown error");
598 break;
599 case JackInvalidOption:
600 CLIENT_FAILURE("invalid option");
601 break;
602 case JackNameNotUnique:
603 if ( m_pClient != nullptr ) {
604 sClientName = jack_get_client_name(m_pClient);
605 CLIENT_SUCCESS(QString("Jack assigned the client name '%1'").arg(sClientName));
606 } else {
607 CLIENT_FAILURE("name not unique");
608 }
609 break;
610 case JackServerStarted:
611 CLIENT_SUCCESS("JACK Server started for Hydrogen.");
612 break;
613 case JackServerFailed:
614 CLIENT_FAILURE("unable to connect");
615 break;
616 case JackServerError:
617 CLIENT_FAILURE("communication error");
618 break;
619 case JackNoSuchClient:
620 CLIENT_FAILURE("unknown client type");
621 break;
622 case JackLoadFailure:
623 CLIENT_FAILURE("can't load internal client");
624 break;
625 case JackInitFailure:
626 CLIENT_FAILURE("can't initialize client");
627 break;
628 case JackShmFailure:
629 CLIENT_FAILURE("unable to access shared memory");
630 break;
631 case JackVersionError:
632 CLIENT_FAILURE("client/server protocol version mismatch");
633 break;
634 default:
635 if (status) {
636 ERRORLOG("Unknown status with JACK server.");
637 if ( m_pClient != nullptr ) {
638 CLIENT_SUCCESS("Client pointer is *not* null..."
639 " assuming we're OK");
640 }
641 } else {
642 CLIENT_SUCCESS("Connected to JACK server");
643 }
644 }
645 }
646
647 if ( m_pClient == nullptr ) {
648 return -1;
649 }
650
651 jackServerSampleRate = jack_get_sample_rate( m_pClient );
652 jackServerBufferSize = jack_get_buffer_size( m_pClient );
653
654 pPreferences->m_nSampleRate = jackServerSampleRate;
655 pPreferences->m_nBufferSize = jackServerBufferSize;
656
657 /* tell the JACK server to call `process()' whenever
658 there is work to be done.
659 */
660 jack_set_process_callback( m_pClient, this->m_processCallback, nullptr );
661
662 /* tell the JACK server to call `srate()' whenever
663 the sample rate of the system changes.
664 */
665 jack_set_sample_rate_callback( m_pClient, jackDriverSampleRate, this );
666
667 /* tell JACK server to update us if the buffer size
668 (frames per process cycle) changes.
669 */
670 jack_set_buffer_size_callback( m_pClient, jackDriverBufferSize, nullptr );
671
672 /* tell the JACK server to call `jack_shutdown()' if
673 it ever shuts down, either entirely, or if it
674 just decides to stop calling us.
675 */
676 jack_on_shutdown( m_pClient, jackDriverShutdown, nullptr );
677
678 // Create two new ports for Hydrogen's client. These are
679 // objects used for moving data of any type in or out of the
680 // client. Ports may be connected in various ways. The
681 // function `jack_port_register' (jack/jack.h) is called like
682 // jack_port_register( jack_client_t *client,
683 // const char *port_name,
684 // const char *port_type,
685 // unsigned long flags,
686 // unsigned long buffer_size)
687 //
688 // All ports have a type, which may be any non-NULL and non-zero
689 // length string, passed as an argument. Some port types are built
690 // into the JACK API, currently only JACK_DEFAULT_AUDIO_TYPE.
691 // It returns a _jack_port_t_ pointer on success, otherwise NULL.
692 m_pOutputPort1 = jack_port_register( m_pClient, "out_L", JACK_DEFAULT_AUDIO_TYPE,
693 JackPortIsOutput, 0 );
694 m_pOutputPort2 = jack_port_register( m_pClient, "out_R", JACK_DEFAULT_AUDIO_TYPE,
695 JackPortIsOutput, 0 );
696
697 Hydrogen* pHydrogen = Hydrogen::get_instance();
698 if ( ( m_pOutputPort1 == nullptr ) || ( m_pOutputPort2 == nullptr ) ) {
699 pHydrogen->raiseError( Hydrogen::JACK_ERROR_IN_PORT_REGISTER );
700 return 4;
701 }
702
703 #ifdef H2CORE_HAVE_LASH
704 if ( pPreferences->useLash() ){
705 LashClient* lashClient = LashClient::get_instance();
706 if ( lashClient->isConnected() ) {
707 lashClient->setJackClientName(sClientName.toLocal8Bit().constData());
708 }
709 }
710 #endif
711
712 #ifdef H2CORE_HAVE_JACKSESSION
713 jack_set_session_callback(m_pClient, jack_session_callback, (void*)this);
714 #endif
715
716 if ( pPreferences->m_bJackTransportMode == Preferences::USE_JACK_TRANSPORT &&
717 pPreferences->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER ){
718 initTimebaseMaster();
719 }
720
721 return 0;
722 }
723
makeTrackOutputs(Song * pSong)724 void JackAudioDriver::makeTrackOutputs( Song* pSong )
725 {
726 if( Preferences::get_instance()->m_bJackTrackOuts == false ) {
727 return;
728 }
729
730 InstrumentList* pInstrumentList = pSong->get_instrument_list();
731 Instrument* pInstrument;
732 int nInstruments = ( int ) pInstrumentList->size();
733
734 WARNINGLOG( QString( "Creating / renaming %1 ports" ).arg( nInstruments ) );
735
736 int nTrackCount = 0;
737
738 for( int i = 0 ; i < MAX_INSTRUMENTS ; i++ ){
739 for ( int j = 0 ; j < MAX_COMPONENTS ; j++ ){
740 m_trackMap[i][j] = 0;
741 }
742 }
743 // Creates a new output track or reassigns an existing one for
744 // each component of each instrument and stores the result in
745 // the `m_trackMap'.
746 InstrumentComponent* pInstrumentComponent;
747 for ( int n = 0; n <= nInstruments - 1; n++ ) {
748 pInstrument = pInstrumentList->get( n );
749 for ( auto it = pInstrument->get_components()->begin();
750 it != pInstrument->get_components()->end(); ++it) {
751
752 pInstrumentComponent = *it;
753 setTrackOutput( nTrackCount, pInstrument, pInstrumentComponent, pSong);
754 m_trackMap[pInstrument->get_id()][pInstrumentComponent->get_drumkit_componentID()] =
755 nTrackCount;
756 nTrackCount++;
757 }
758 }
759 // clean up unused ports
760 jack_port_t *pPortL, *pPortR;
761 for ( int n = nTrackCount; n < m_nTrackPortCount; n++ ) {
762 pPortL = m_pTrackOutputPortsL[n];
763 pPortR = m_pTrackOutputPortsR[n];
764 m_pTrackOutputPortsL[n] = nullptr;
765 jack_port_unregister( m_pClient, pPortL );
766 m_pTrackOutputPortsR[n] = nullptr;
767 jack_port_unregister( m_pClient, pPortR );
768 }
769
770 m_nTrackPortCount = nTrackCount;
771 }
772
setTrackOutput(int n,Instrument * pInstrument,InstrumentComponent * pInstrumentComponent,Song * pSong)773 void JackAudioDriver::setTrackOutput( int n, Instrument* pInstrument, InstrumentComponent *pInstrumentComponent, Song* pSong )
774 {
775 QString sComponentName;
776
777 // The function considers `m_nTrackPortCount' as the number of
778 // ports already present. If it's smaller than `n', new ports
779 // have to be created.
780 if ( m_nTrackPortCount <= n ) {
781 for ( int m = m_nTrackPortCount; m <= n; m++ ) {
782 sComponentName = QString( "Track_%1_" ).arg( m + 1 );
783 m_pTrackOutputPortsL[m] =
784 jack_port_register( m_pClient, ( sComponentName + "L" ).toLocal8Bit(),
785 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
786
787 m_pTrackOutputPortsR[m] =
788 jack_port_register( m_pClient, ( sComponentName + "R" ).toLocal8Bit(),
789 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
790
791 if ( ! m_pTrackOutputPortsR[m] || ! m_pTrackOutputPortsL[m] ) {
792 Hydrogen::get_instance()->raiseError( Hydrogen::JACK_ERROR_IN_PORT_REGISTER );
793 }
794 }
795 m_nTrackPortCount = n + 1;
796 }
797
798 // Now that we're sure there is an n'th port, rename it.
799 DrumkitComponent* pDrumkitComponent = pSong->get_component( pInstrumentComponent->get_drumkit_componentID() );
800 sComponentName = QString( "Track_%1_%2_%3_" ).arg( n + 1 )
801 .arg( pInstrument->get_name() ).arg( pDrumkitComponent->get_name() );
802
803 #ifdef HAVE_JACK_PORT_RENAME
804 // This differs from jack_port_set_name() by triggering
805 // PortRename notifications to clients that have registered a
806 // port rename handler.
807 jack_port_rename( m_pClient, m_pTrackOutputPortsL[n], ( sComponentName + "L" ).toLocal8Bit() );
808 jack_port_rename( m_pClient, m_pTrackOutputPortsR[n], ( sComponentName + "R" ).toLocal8Bit() );
809 #else
810 jack_port_set_name( m_pTrackOutputPortsL[n], ( sComponentName + "L" ).toLocal8Bit() );
811 jack_port_set_name( m_pTrackOutputPortsR[n], ( sComponentName + "R" ).toLocal8Bit() );
812 #endif
813 }
814
play()815 void JackAudioDriver::play()
816 {
817 Preferences* pPreferences = Preferences::get_instance();
818 if ( pPreferences->m_bJackTransportMode == Preferences::USE_JACK_TRANSPORT ) {
819 if ( m_pClient != nullptr ) {
820 INFOLOG( "jack_transport_start()" );
821 jack_transport_start( m_pClient );
822 }
823 } else {
824 m_transport.m_status = TransportInfo::ROLLING;
825 }
826 }
827
stop()828 void JackAudioDriver::stop()
829 {
830 Preferences* pPreferences = Preferences::get_instance();
831 if ( pPreferences->m_bJackTransportMode == Preferences::USE_JACK_TRANSPORT ) {
832 if ( m_pClient != nullptr ) {
833 INFOLOG( "jack_transport_stop()" );
834 jack_transport_stop( m_pClient );
835 }
836 } else {
837 m_transport.m_status = TransportInfo::STOPPED;
838 }
839 }
840
locate(unsigned long frame)841 void JackAudioDriver::locate( unsigned long frame )
842 {
843 if ( ( Preferences::get_instance() )->m_bJackTransportMode ==
844 Preferences::USE_JACK_TRANSPORT ) {
845 if ( m_pClient != nullptr ) {
846 // jack_transport_locate() (jack/transport.h )
847 // re-positions the transport to a new frame number. May
848 // be called at any time by any client.
849 jack_transport_locate( m_pClient, frame );
850 }
851 } else {
852 m_transport.m_nFrames = (long long)frame;
853 }
854 }
855
setBpm(float fBPM)856 void JackAudioDriver::setBpm( float fBPM )
857 {
858 if ( fBPM >= 1 ) {
859 m_transport.m_fBPM = fBPM;
860 }
861 }
862
863 #ifdef H2CORE_HAVE_JACKSESSION
jack_session_callback(jack_session_event_t * event,void * arg)864 void JackAudioDriver::jack_session_callback(jack_session_event_t *event, void *arg)
865 {
866 JackAudioDriver* pDriver = static_cast<JackAudioDriver*>(arg);
867 if ( pDriver != nullptr ) {
868 pDriver->jack_session_callback_impl( event );
869 }
870 }
871
baseName(QString sPath)872 static QString baseName( QString sPath ) {
873 return QFileInfo( sPath ).fileName();
874 }
875
jack_session_callback_impl(jack_session_event_t * event)876 void JackAudioDriver::jack_session_callback_impl(jack_session_event_t* event)
877 {
878 enum session_events{
879 SAVE_SESSION,
880 SAVE_AND_QUIT,
881 SAVE_TEMPLATE
882 };
883
884 Hydrogen* pHydrogen = Hydrogen::get_instance();
885 Song* pSong = pHydrogen->getSong();
886 Preferences* pPreferences = Preferences::get_instance();
887 EventQueue* pEventQueue = EventQueue::get_instance();
888
889 jack_session_event_t* ev = (jack_session_event_t *) event;
890
891 QString sJackSessionDirectory = (QString) ev->session_dir;
892 QString sRetval = pPreferences->getJackSessionApplicationPath() +
893 " --jacksessionid " + ev->client_uuid;
894
895 /* Playlist mode */
896 Playlist* pPlaylist = Playlist::get_instance();
897 if ( pPlaylist->size() > 0 ) {
898
899 if ( pPlaylist->getFilename().isEmpty() ) {
900 pPlaylist->setFilename( Filesystem::untitled_playlist_file_name() );
901 }
902
903 QString sFileName = baseName( pPlaylist->getFilename() );
904 sFileName.replace( QString(" "), QString("_") );
905 sRetval += " -p \"${SESSION_DIR}" + sFileName + "\"";
906
907 /* Copy all songs to Session Directory and update playlist */
908 SongReader reader;
909 for ( uint i = 0; i < pPlaylist->size(); ++i ) {
910 QString sBaseName = baseName( pPlaylist->get( i )->filePath );
911 QString sNewName = sJackSessionDirectory + sBaseName;
912 QString sSongPath = reader.getPath( pPlaylist->get( i )->filePath );
913 if ( sSongPath != nullptr && QFile::copy( sSongPath, sNewName ) ) {
914 /* Keep only filename on list for relative read */
915 pPlaylist->get( i )->filePath = sBaseName;
916 } else {
917 /* Note - we leave old path in playlist */
918 ERRORLOG( "Can't copy " + pPlaylist->get( i )->filePath + " to " + sNewName );
919 ev->flags = JackSessionSaveError;
920 }
921 }
922
923 /* Save updated playlist */
924 bool bRelativePaths = Preferences::get_instance()->isPlaylistUsingRelativeFilenames();
925 if ( Files::savePlaylistPath( sJackSessionDirectory + sFileName,
926 pPlaylist, bRelativePaths ) == nullptr ) {
927 ev->flags = JackSessionSaveError;
928 }
929 /* Song Mode */
930 } else {
931 /* Valid Song is needed */
932 if ( pSong->get_filename().isEmpty() ) {
933 pSong->set_filename( Filesystem::untitled_song_file_name() );
934 }
935
936 QString sFileName = baseName( pSong->get_filename() );
937 sFileName.replace( QString(" "), QString("_") );
938 pSong->set_filename( sJackSessionDirectory + sFileName);
939
940 /* SongReader will look into SESSION DIR anyway */
941 sRetval += " -s \"" + sFileName + "\"";
942
943 switch (ev->type) {
944 case JackSessionSave:
945 pEventQueue->push_event(EVENT_JACK_SESSION, SAVE_SESSION);
946 break;
947 case JackSessionSaveAndQuit:
948 pEventQueue->push_event(EVENT_JACK_SESSION, SAVE_SESSION);
949 pEventQueue->push_event(EVENT_JACK_SESSION, SAVE_AND_QUIT);
950 break;
951 default:
952 ERRORLOG( "JackSession: Unknown event type" );
953 ev->flags = JackSessionSaveError;
954 }
955 }
956
957 ev->command_line = strdup( sRetval.toUtf8().constData() );
958 jack_session_reply( m_pClient, ev );
959 jack_session_event_free( ev );
960 }
961 #endif
962
initTimebaseMaster()963 void JackAudioDriver::initTimebaseMaster()
964 {
965 if ( m_pClient == nullptr ) {
966 return;
967 }
968
969 Preferences* pPreferences = Preferences::get_instance();
970 if ( pPreferences->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER) {
971 // Defined in jack/transport.h
972 // Register as timebase master for the JACK
973 // subsystem.
974 //
975 // The timebase master registers a callback that
976 // updates extended position information such as
977 // beats or timecode whenever necessary. Without
978 // this extended information, there is no need for
979 // this function.
980 //
981 // There is never more than one master at a time.
982 // When a new client takes over, the former @a
983 // timebase_callback is no longer called. Taking
984 // over the timebase may be done conditionally, so
985 // it fails if there was a master already.
986 //
987 // @param client the JACK client structure.
988 // @param conditional non-zero for a conditional
989 // request.
990 // @param timebase_callback is a realtime function
991 // that returns position information.
992 // @param arg an argument for the @a timebase_callback
993 // function.
994 // @return
995 // - 0 on success;
996 // - EBUSY if a conditional request fails because
997 // there was already a timebase master;
998 // - other non-zero error code.
999 int nReturnValue = jack_set_timebase_callback(m_pClient, 0,
1000 JackTimebaseCallback, this);
1001 if ( nReturnValue != 0 ){
1002 pPreferences->m_bJackMasterMode = Preferences::NO_JACK_TIME_MASTER;
1003 } else {
1004 m_nIsTimebaseMaster = 2;
1005 }
1006 } else {
1007 releaseTimebaseMaster();
1008 }
1009 }
1010
releaseTimebaseMaster()1011 void JackAudioDriver::releaseTimebaseMaster()
1012 {
1013 if ( m_pClient == nullptr ) {
1014 return;
1015 }
1016
1017 jack_release_timebase( m_pClient );
1018
1019 if ( m_JackTransportPos.valid & JackPositionBBT ) {
1020 m_nIsTimebaseMaster = 0;
1021 } else {
1022 m_nIsTimebaseMaster = -1;
1023 }
1024 }
1025
JackTimebaseCallback(jack_transport_state_t state,jack_nframes_t nFrames,jack_position_t * pJackPosition,int new_pos,void * arg)1026 void JackAudioDriver::JackTimebaseCallback(jack_transport_state_t state,
1027 jack_nframes_t nFrames,
1028 jack_position_t* pJackPosition,
1029 int new_pos,
1030 void *arg)
1031 {
1032 JackAudioDriver* pDriver = static_cast<JackAudioDriver*>(arg);
1033 if ( pDriver == nullptr ){
1034 return;
1035 }
1036
1037 Hydrogen* pHydrogen = Hydrogen::get_instance();
1038 Song* pSong = pHydrogen->getSong();
1039 if ( pSong == nullptr ) {
1040 return;
1041 }
1042
1043 // ---------------------------------------------------------------
1044 // What is the BBT information?
1045 //
1046 // There is no formal definition in the JACK API but the way it is
1047 // interpreted by Hydrogen is the following:
1048 //
1049 // bar: Number of patterns played since the beginning of the song.
1050 // beat: Number of quarters passed since the beginning of the the
1051 // pattern.
1052 // tick: Number of ticks passed since the last beat (with respect
1053 // to the current frame).
1054 //
1055 // A tick is an internal measure representing the smallest
1056 // resolution of the transport position in terms of the
1057 // patterns. It consist of m_transport.m_fTickSize frames, which
1058 // changes depending on the current tempo.
1059 // ---------------------------------------------------------------
1060
1061 // First tick covered during the next cycle.
1062 float fTickSize = pDriver->m_transport.m_fTickSize;
1063 unsigned long nextTick =
1064 floor(( pJackPosition->frame - pDriver->m_frameOffset ) /
1065 fTickSize );
1066
1067 int nNextPatternStartTick;
1068 int nNextPattern =
1069 pHydrogen->getPosForTick( nextTick, &nNextPatternStartTick );
1070
1071 // In order to determine the tempo, which will be set by Hydrogen
1072 // during the next transport cycle, we have to look at the last
1073 // tick handled in audioEngine_updateNoteQueue() (during this
1074 // cycle and after the updateTransportInfo() returns.
1075 unsigned long nextTickInternal =
1076 floor(( pJackPosition->frame - pDriver->m_frameOffset +
1077 pHydrogen->calculateLookahead( fTickSize ) ) /
1078 fTickSize) - 1;
1079 int nNextPatternStartTickInternal;
1080 int nNextPatternInternal =
1081 pHydrogen->getPosForTick( nextTickInternal, &nNextPatternStartTickInternal );
1082
1083 // Calculate the length of the next pattern in ticks == number
1084 // of ticks in the next bar.
1085 long ticksPerBar = pHydrogen->getPatternLength( nNextPattern );
1086 if ( ticksPerBar < 1 ) {
1087 return;
1088 }
1089
1090 pJackPosition->ticks_per_beat = (double)ticksPerBar / 4;
1091 pJackPosition->valid = JackPositionBBT;
1092 // Time signature "numerator"
1093 pJackPosition->beats_per_bar =
1094 ((float)ticksPerBar / (float)pSong->__resolution);
1095 // Time signature "denominator"
1096 pJackPosition->beat_type = 4.0;
1097
1098 if ( pDriver->m_transport.m_nFrames + pDriver->m_frameOffset != pJackPosition->frame ) {
1099 // In case of a relocation, wait two full cycles till the new
1100 // tempo will be broadcast.
1101 nWaits = 2;
1102 }
1103
1104 if ( nWaits == 0 ) {
1105 // Average tempo in BPM for the block corresponding to
1106 // pJackPosition. In Hydrogen is guaranteed to be constant within
1107 // a block.
1108 pJackPosition->beats_per_minute =
1109 (double)pHydrogen->getTimelineBpm( nNextPatternInternal );
1110 } else {
1111 pJackPosition->beats_per_minute = (double)pDriver->m_transport.m_fBPM;
1112 }
1113
1114 nWaits = max( int(0), nWaits - 1);
1115
1116 if ( pDriver->m_transport.m_nFrames < 1 ) {
1117 pJackPosition->bar = 0;
1118 pJackPosition->beat = 1;
1119 pJackPosition->tick = 0;
1120 pJackPosition->bar_start_tick = 0;
1121 } else {
1122 // +1 since the counting bars starts at 1.
1123 pJackPosition->bar = nNextPattern + 1;
1124
1125 /* how many ticks elapsed from last bar ( where bar == pattern ) */
1126 int32_t nTicksFromBar = ( nextTick % (int32_t) ticksPerBar );
1127
1128 // Number of ticks that have elapsed between frame 0 and the
1129 // first beat of the next measure.
1130 pJackPosition->bar_start_tick = nextTick - nTicksFromBar;
1131
1132 pJackPosition->beat = nTicksFromBar / pJackPosition->ticks_per_beat;
1133 // +1 since the counting beats starts at 1.
1134 pJackPosition->beat++;
1135
1136 // Counting ticks starts at 0.
1137 pJackPosition->tick = nTicksFromBar % (int32_t) pJackPosition->ticks_per_beat;
1138
1139 }
1140
1141 // Tell Hydrogen it is still timebase master.
1142 pDriver->m_nIsTimebaseMaster = 2;
1143 }
1144
1145 }
1146
1147 #endif // H2CORE_HAVE_JACK
1148