1 //=========================================================
2 // MusE
3 // Linux Music Editor
4 // $Id: jack.cpp,v 1.30.2.17 2009/12/20 05:00:35 terminator356 Exp $
5 // (C) Copyright 2002 Werner Schweer (ws@seh.de)
6 // (C) Copyright 2012-2015 Tim E. Real (terminator356 on sourceforge.net)
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License
10 // as published by the Free Software Foundation; version 2 of
11 // the License, or (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, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 //
22 //=========================================================
23
24 #include "config.h"
25 #include <list>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <unistd.h>
31 #include <jack/midiport.h>
32 #include <string.h>
33 #include <dlfcn.h>
34 #include <sys/time.h>
35
36 #include <QString>
37 #include <QStringList>
38
39 #include <jack/thread.h>
40
41 #include "strntcpy.h"
42 #include "audio.h"
43 #include "globals.h"
44 #include "song.h"
45 #include "jackaudio.h"
46 #include "track.h"
47 #include "pos.h"
48 #include "tempo.h"
49 #include "sync.h"
50 #include "utils.h"
51 #include "gconfig.h"
52 #include "route.h"
53
54 #include "midi_consts.h"
55 #include "mididev.h"
56 #include "mpevent.h"
57
58 #include "jackmidi.h"
59 #include "muse_atomic.h"
60
61 #include "al/al.h"
62
63 #define JACK_DEBUG 0
64
65 #define JACK_CALLBACK_FIFO_SIZE 512
66
67 // For debugging output: Uncomment the fprintf section.
68 #define DEBUG_JACK(dev, format, args...) // fprintf(dev, format, ##args);
69
70 // For debugging some of the 'persistent routes' code: Uncomment the fprintf section.
71 #define DEBUG_PRST_ROUTES(dev, format, args...) // fprintf(dev, format, ##args);
72
73 #ifdef VST_SUPPORT
74 #include <fst.h>
75 #endif
76
77 namespace MusEGlobal {
78
79 #ifndef RTCAP
80 extern void doSetuid();
81 extern void undoSetuid();
82 #endif
83
84 //---------------------------------------------------------
85 // checkAudioDevice - make sure audioDevice exists
86 //---------------------------------------------------------
87
checkAudioDevice()88 bool checkAudioDevice()
89 {
90 if (audioDevice == NULL) {
91 if(debugMsg)
92 fprintf(stderr, "Muse:checkAudioDevice: no audioDevice\n");
93 return false;
94 }
95 return true;
96 }
97
98 } // namespace MusEGlobal
99
100
101 namespace MusECore {
102
103 JackAudioDevice* jackAudio;
104
105 int jack_ver_maj = 0, jack_ver_min = 0, jack_ver_micro = 0, jack_ver_proto = 0;
106 muse_atomic_t atomicGraphChangedPending;
107 bool jack1_port_by_name_workaround = false;
108
109 // Function pointers obtained with dlsym:
110 jack_get_version_type jack_get_version_fp = NULL;
111 jack_port_set_name_type jack_port_set_name_fp = NULL;
112 jack_port_rename_type jack_port_rename_fp = NULL;
113
114 // REMOVE Tim. latency. Added. TESTING.
115 // Jack BUG ? :
116 // Before latency compensation was added, we would deactivate and reactivate the Jack server
117 // when loading a song. But tests revealed Jack does not like that, and ALL reported
118 // port latencies are ZERO after reactivation. So we have no choice but to leave the
119 // Jack server running all the time until program close.
120 bool jackStarted = false;
121
122 // Flag for detecting if sync callback is being called.
123 bool jack_sync_detect_flag = false;
124 JackAudioDevice::JackSyncPhases jackSyncPhase = JackAudioDevice::SyncCheck;
125 // If we are the timebase master.
126 bool jack_timebase_cur_master_state = false;
127 JackAudioDevice::JackTimebaseMasterPhases jackTimebaseMasterPhase = JackAudioDevice::MasterCheck;
128
129 //---------------------------------------------------------
130 // JackCallbackFifo
131 //---------------------------------------------------------
132
133 class JackCallbackFifo
134 {
135 JackCallbackEvent fifo[JACK_CALLBACK_FIFO_SIZE];
136 volatile int size;
137 int wIndex;
138 int rIndex;
139
140 public:
JackCallbackFifo()141 JackCallbackFifo() { clear(); }
142 bool put(const JackCallbackEvent& event); // returns true on fifo overflow
143 const JackCallbackEvent& get();
144 const JackCallbackEvent& peek(int n = 0);
145 void remove();
isEmpty() const146 bool isEmpty() const { return size == 0; }
clear()147 void clear() { size = 0, wIndex = 0, rIndex = 0; }
getSize() const148 int getSize() const { return size; }
149 };
150
151 //---------------------------------------------------------
152 // JackCallbackFifo
153 // put
154 // return true on fifo overflow
155 //---------------------------------------------------------
156
put(const JackCallbackEvent & event)157 bool JackCallbackFifo::put(const JackCallbackEvent& event)
158 {
159 if (size < JACK_CALLBACK_FIFO_SIZE) {
160 fifo[wIndex] = event;
161 wIndex = (wIndex + 1) % JACK_CALLBACK_FIFO_SIZE;
162 ++size;
163 return false;
164 }
165 return true;
166 }
167
168 //---------------------------------------------------------
169 // get
170 //---------------------------------------------------------
171
get()172 const JackCallbackEvent& JackCallbackFifo::get()
173 {
174 const JackCallbackEvent& event = fifo[rIndex];
175 rIndex = (rIndex + 1) % JACK_CALLBACK_FIFO_SIZE;
176 --size;
177 return event;
178 }
179
180 //---------------------------------------------------------
181 // peek
182 //---------------------------------------------------------
183
peek(int n)184 const JackCallbackEvent& JackCallbackFifo::peek(int n)
185 {
186 int idx = (rIndex + n) % JACK_CALLBACK_FIFO_SIZE;
187 return fifo[idx];
188 }
189
190 //---------------------------------------------------------
191 // remove
192 //---------------------------------------------------------
193
remove()194 void JackCallbackFifo::remove()
195 {
196 rIndex = (rIndex + 1) % JACK_CALLBACK_FIFO_SIZE;
197 --size;
198 }
199
200 JackCallbackFifo jackCallbackFifo;
201
202 //---------------------------------------------------------
203 // checkJackClient - make sure client is valid
204 //---------------------------------------------------------
checkJackClient(jack_client_t * _client)205 inline bool checkJackClient(jack_client_t* _client)
206 {
207 if (_client == NULL) {
208 fprintf(stderr, "Panic! no _client!\n");
209 return false;
210 }
211 return true;
212 }
213
214 //---------------------------------------------------------
215 // jack_thread_init
216 //---------------------------------------------------------
217
jack_thread_init(void *)218 static void jack_thread_init (void* )
219 {
220 DEBUG_JACK(stderr, "jack_thread_init()\n");
221 MusEGlobal::doSetuid();
222 #ifdef VST_SUPPORT
223 if (loadVST)
224 fst_adopt_thread();
225 #endif
226 MusEGlobal::undoSetuid();
227 }
228
processAudio(jack_nframes_t frames,void * arg)229 int JackAudioDevice::processAudio(jack_nframes_t frames, void* arg)
230 {
231 jackAudio->_frameCounter += frames;
232 MusEGlobal::segmentSize = frames;
233
234 if (MusEGlobal::audio->isRunning())
235 {
236 // Are we using Jack transport?
237 if(MusEGlobal::config.useJackTransport)
238 {
239
240 //--------------------------------------------------
241 // Jack timebase master acquire/loss detection
242 //--------------------------------------------------
243 if(arg)
244 {
245 JackAudioDevice* jad = (JackAudioDevice*)arg;
246 jack_client_t* client = jad->jackClient();
247 if(client)
248 {
249 jack_transport_state_t state = jack_transport_query(client, nullptr);
250 // The timebase callback is called after the process callback.
251 // Check if it got called, meaning we are timebase master.
252 if(state == JackTransportStopped || state == JackTransportRolling)
253 {
254 if(jackSyncPhase == SyncStarted)
255 {
256 // Reset and wait for the next cycle to see if we became master.
257 jackTimebaseMasterPhase = IsNotMaster;
258 }
259 else
260 if(jackTimebaseMasterPhase == IsNotMaster)
261 {
262 // The timebase callback was not called - phase was not set to IsMaster.
263 // Therefore we are not timebase master.
264 if(jack_timebase_cur_master_state)
265 {
266 jack_timebase_cur_master_state = false;
267 MusEGlobal::audio->sendMsgToGui('t');
268 }
269 }
270 else
271 // Bring in flag here in case sync timed out in stop mode.
272 // Jack may stop calling our sync, even though on the last sync
273 // we still requested more time by returning FALSE.
274 // There would be no other way to detect that condition.
275 if(jackSyncPhase == Synced || !jack_sync_detect_flag)
276 {
277 // Done with phase. Reset for future sync calls.
278 jackSyncPhase = SyncCheck;
279 }
280 }
281
282 if(state == JackTransportRolling)
283 {
284 // Reset and wait for the next cycle to see if we became master.
285 jackTimebaseMasterPhase = IsNotMaster;
286 }
287 }
288 }
289
290 // Just call the audio process normally. Jack transport will take care of itself.
291 // Don't process while we're syncing. ToDO: May need to deliver silence in process!
292 //if(jackAudio->getState() != Audio::START_PLAY)
293 MusEGlobal::audio->process((unsigned long)frames);
294 }
295 else
296 {
297 // Not using Jack transport. Use our built-in transport, which INCLUDES
298 // the necessary calls to Audio::sync() and ultimately Audio::process(),
299 // and increments the built-in play position.
300 jackAudio->processTransport((unsigned long)frames);
301 }
302 }
303 else {
304 if (MusEGlobal::debugMsg)
305 puts("jack calling when audio is disconnected!\n");
306 }
307
308 // Reset for next cycle.
309 jack_sync_detect_flag = false;
310
311 return 0;
312 }
313
314 //---------------------------------------------------------
315 // processSync
316 // return TRUE (non-zero) when ready to roll.
317 //---------------------------------------------------------
318
processSync(jack_transport_state_t state,jack_position_t * pos,void *)319 static int processSync(jack_transport_state_t state, jack_position_t* pos, void*)
320 {
321 #if JACK_DEBUG
322 fprintf(stderr, "processSync frame:%u state:%d\n", pos->frame, state);
323
324 if(pos->valid & JackPositionBBT)
325 {
326 fprintf(stderr, "processSync BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
327 pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
328 if(pos->valid & JackBBTFrameOffset)
329 fprintf(stderr, "processSync BBTFrameOffset: %u\n", pos->bbt_offset);
330 }
331 #endif
332
333 if(!MusEGlobal::config.useJackTransport)
334 return 1;
335
336 int audioState = Audio::STOP;
337 switch (int(state)) {
338 case JackTransportStopped:
339 audioState = Audio::STOP;
340 break;
341 case JackTransportLooping:
342 case JackTransportRolling:
343 audioState = Audio::PLAY;
344 break;
345 case JackTransportStarting:
346 //fprintf(stderr, "processSync JackTransportStarting\n");
347
348 audioState = Audio::START_PLAY;
349 break;
350 //case JackTransportNetStarting: -- only available in Jack-2!
351 // FIXME: Quick and dirty hack to support both Jack-1 and Jack-2
352 // Really need a config check of version...
353 case 4:
354 //fprintf(stderr, "processSync JackTransportNetStarting\n");
355
356 audioState = Audio::START_PLAY;
357 break;
358 }
359
360 unsigned frame = pos->frame;
361 //return MusEGlobal::audio->sync(audioState, frame);
362 int rv = MusEGlobal::audio->sync(audioState, frame);
363 //fprintf(stderr, "Jack processSync() after MusEGlobal::audio->sync frame:%d\n", frame);
364
365 jack_sync_detect_flag = true;
366 if(rv)
367 {
368 jackSyncPhase = JackAudioDevice::Synced;
369 }
370 else
371 {
372 if(jackSyncPhase == JackAudioDevice::SyncStarted)
373 jackSyncPhase = JackAudioDevice::Syncing;
374 else
375 jackSyncPhase = JackAudioDevice::SyncStarted;
376 }
377
378 return rv;
379 }
380
381 //---------------------------------------------------------
382 // timebase_callback
383 //---------------------------------------------------------
384
385 #if JACK_DEBUG
timebase_callback(jack_transport_state_t state,jack_nframes_t nframes,jack_position_t * pos,int new_pos,void *)386 static void timebase_callback(jack_transport_state_t state,
387 jack_nframes_t nframes,
388 jack_position_t* pos,
389 int new_pos,
390 void*)
391 #else
392 static void timebase_callback(jack_transport_state_t,
393 jack_nframes_t,
394 jack_position_t* pos,
395 int,
396 void*)
397 #endif
398 {
399 // I think, therefore I am... timebase master.
400 jackTimebaseMasterPhase = JackAudioDevice::IsMaster;
401 if(!jack_timebase_cur_master_state)
402 {
403 jack_timebase_cur_master_state = true;
404 MusEGlobal::audio->sendMsgToGui('T');
405 }
406
407 #if JACK_DEBUG
408 fprintf(stderr, "timebase_callback() state:%d\n", state);
409 if(pos->valid & JackPositionBBT)
410 fprintf(stderr, "timebase_callback BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
411 pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
412 if(pos->valid & JackBBTFrameOffset)
413 fprintf(stderr, "timebase_callback BBTFrameOffset: %u\n", pos->bbt_offset);
414 if(pos->valid & JackPositionTimecode)
415 fprintf(stderr, "timebase_callback JackPositionTimecode: frame_time:%f next_time:%f\n", pos->frame_time, pos->next_time);
416 if(pos->valid & JackAudioVideoRatio)
417 fprintf(stderr, "timebase_callback JackAudioVideoRatio: %f\n", pos->audio_frames_per_video_frame);
418 if(pos->valid & JackVideoFrameOffset)
419 fprintf(stderr, "timebase_callback JackVideoFrameOffset: %u\n", pos->video_offset);
420 #endif
421
422 //Pos p(pos->frame, false);
423 Pos p(MusEGlobal::extSyncFlag ? MusEGlobal::audio->tickPos() : pos->frame, MusEGlobal::extSyncFlag ? true : false);
424 // Can't use song pos - it is only updated every (slow) GUI heartbeat !
425 //Pos p(MusEGlobal::extSyncFlag ? MusEGlobal::song->cpos() : pos->frame, MusEGlobal::extSyncFlag ? true : false);
426
427 pos->valid = JackPositionBBT;
428 int bar, beat, tick;
429 p.mbt(&bar, &beat, &tick);
430 pos->bar = bar;
431 pos->beat = beat;
432 pos->tick = tick;
433
434 pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
435 pos->bar++;
436 pos->beat++;
437
438 int z, n;
439 MusEGlobal::sigmap.timesig(p.tick(), z, n);
440 pos->beats_per_bar = z;
441 pos->beat_type = n;
442 pos->ticks_per_beat = MusEGlobal::config.division;
443 //pos->ticks_per_beat = 24;
444
445 double tempo = MusEGlobal::tempomap.tempo(p.tick());
446 pos->beats_per_minute = ((double)MusEGlobal::tempomap.globalTempo() * 600000.0) / tempo;
447 #if JACK_DEBUG
448 fprintf(stderr, "timebase_callback is new_pos:%d nframes:%u frame:%u tickPos:%d cpos:%d\n", new_pos, nframes, pos->frame, MusEGlobal::audio->tickPos(), MusEGlobal::song->cpos());
449 fprintf(stderr, " new: bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
450 pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
451 #endif
452
453 }
454
455 //---------------------------------------------------------
456 // processShutdown
457 //---------------------------------------------------------
458
processShutdown(void *)459 static void processShutdown(void*)
460 {
461 DEBUG_JACK(stderr, "processShutdown()\n");
462 //fprintf(stderr, "processShutdown\n");
463 jackAudio->nullify_client();
464 MusEGlobal::audio->shutdown();
465
466 int c=0;
467 while(MusEGlobal::midiSeqRunning == true) {
468 if(c++ >10) {
469 fprintf(stderr, "sequencer still running, something is very wrong.\n");
470 break;
471 }
472 sleep(1);
473 }
474 delete jackAudio;
475 jackAudio=0;
476 MusEGlobal::audioDevice=0;
477 }
478
479 //---------------------------------------------------------
480 // jackError
481 //---------------------------------------------------------
482
jackError(const char * s)483 static void jackError(const char *s)
484 {
485 fprintf(stderr,"JACK ERROR: %s\n", s);
486 }
487
488 //---------------------------------------------------------
489 // noJackError
490 //---------------------------------------------------------
491
noJackError(const char *)492 static void noJackError(const char* /* s */)
493 {
494 //fprintf(stderr, "noJackError()\n");
495 }
496
497 //---------------------------------------------------------
498 // jackInfo
499 //---------------------------------------------------------
500
jackInfo(const char * s)501 static void jackInfo(const char* s)
502 {
503 fprintf(stderr, "JACK INFO: %s\n", s);
504 }
505
506 //---------------------------------------------------------
507 // noJackInfo
508 //---------------------------------------------------------
509
noJackInfo(const char *)510 static void noJackInfo(const char* /*s*/)
511 {
512 //fprintf(stderr, "noJackInfo()\n");
513 }
514
515 //---------------------------------------------------------
516 // JackAudioDevice
517 //---------------------------------------------------------
518
JackAudioDevice(jack_client_t * cl,char * name)519 JackAudioDevice::JackAudioDevice(jack_client_t* cl, char* name)
520 : AudioDevice()
521 {
522 _frameCounter = 0;
523 strcpy(jackRegisteredName, name);
524 _client = cl;
525 }
526
527 //---------------------------------------------------------
528 // ~JackAudioDevice
529 //---------------------------------------------------------
530
~JackAudioDevice()531 JackAudioDevice::~JackAudioDevice()
532 {
533 DEBUG_JACK(stderr, "~JackAudioDevice()\n");
534 if (_client) {
535
536 // REMOVE Tim. latency. Added. TESTING.
537 if (jack_deactivate(_client)) {
538 fprintf (stderr, "cannot deactivate client\n");
539 }
540
541 if (jack_client_close(_client)) {
542 fprintf(stderr,"jack_client_close() failed: %s\n", strerror(errno));
543 }
544 }
545
546 // REMOVE Tim. latency. Added. TESTING.
547 jackStarted = false;
548
549 DEBUG_JACK(stderr, "~JackAudioDevice() after jack_client_close()\n");
550 }
551
552 //---------------------------------------------------------
553 // realtimePriority
554 // return zero if not running realtime
555 // can only be called if JACK client thread is already
556 // running
557 //---------------------------------------------------------
558
realtimePriority() const559 int JackAudioDevice::realtimePriority() const
560 {
561 if(!_client)
562 return 0;
563
564 pthread_t t = (pthread_t) jack_client_thread_id(_client);
565 if(t == 0)
566 return jack_client_real_time_priority(_client);
567
568 int policy;
569 struct sched_param param;
570 memset(¶m, 0, sizeof(param));
571 int rv = pthread_getschedparam(t, &policy, ¶m);
572 if (rv) {
573 perror("MusE: JackAudioDevice::realtimePriority: Error: Get jack schedule parameter");
574 return 0;
575 }
576 if (policy != SCHED_FIFO) {
577 fprintf(stderr, "MusE: JackAudioDevice::realtimePriority: JACK is not running realtime\n");
578 return 0;
579 }
580 return param.sched_priority;
581 }
582
583 //---------------------------------------------------------
584 // initJackAudio
585 // return true if JACK not found
586 //---------------------------------------------------------
587
initJackAudio()588 bool initJackAudio()
589 {
590 DEBUG_JACK(stderr, "initJackAudio()\n");
591
592 muse_atomic_init(&atomicGraphChangedPending);
593 muse_atomic_set(&atomicGraphChangedPending, 0);
594
595 jack_get_version_fp = reinterpret_cast<jack_get_version_type>(dlsym(RTLD_DEFAULT, "jack_get_version"));
596 DEBUG_PRST_ROUTES(stderr, "initJackAudio jack_get_version() address:%p \n", jack_get_version_fp);
597 if(jack_get_version_fp) // ATM Only in Jack-2. Dlsym'd. Check for existence first.
598 {
599 jack_get_version_fp(&jack_ver_maj, &jack_ver_min, &jack_ver_micro, &jack_ver_proto);
600 DEBUG_PRST_ROUTES(stderr, "initJackAudio: jack_ver_maj:%d jack_ver_min:%d jack_ver_micro:%d jack_ver_proto:%d\n",
601 jack_ver_maj, jack_ver_min, jack_ver_micro, jack_ver_proto);
602 // FIXME: ATM Jack-2 jack_get_version() returns all zeros. When it is fixed, do something with the values.
603 if(jack_ver_maj == 0 && jack_ver_min == 0 && jack_ver_micro == 0 && jack_ver_proto == 0)
604 {
605 fprintf(stderr, "MusE:initJackAudio: jack_get_version() returned zeros. Setting version major to 1.\n");
606 jack_ver_maj = 1;
607 }
608 }
609
610 jack_port_set_name_fp = reinterpret_cast<jack_port_set_name_type>(dlsym(RTLD_DEFAULT, "jack_port_set_name"));
611 DEBUG_PRST_ROUTES(stderr, "initJackAudio jack_port_set_name() address:%p \n", jack_port_set_name_fp);
612 if(jack_port_set_name_fp)
613 {
614 }
615
616 jack_port_rename_fp = reinterpret_cast<jack_port_rename_type>(dlsym(RTLD_DEFAULT, "jack_port_rename"));
617 DEBUG_PRST_ROUTES(stderr, "initJackAudio jack_port_rename() address:%p \n", jack_port_rename_fp);
618 if(jack_port_rename_fp)
619 {
620 }
621
622 if (MusEGlobal::debugMsg) {
623 fprintf(stderr, "initJackAudio(): registering error and info callbacks...\n");
624 jack_set_error_function(jackError);
625 jack_set_info_function(jackInfo);
626 }
627 else {
628 jack_set_error_function(noJackError);
629 jack_set_info_function(noJackInfo);
630 }
631
632 MusEGlobal::doSetuid();
633
634 int opts = JackNullOption;
635 if(MusEGlobal::noAutoStartJack)
636 opts |= JackNoStartServer;
637 jack_status_t status;
638 jack_client_t* client = jack_client_open("MusE", (jack_options_t)opts, &status);
639 if (!client) {
640 if (status & JackServerStarted)
641 fprintf(stderr, "jack server started...\n");
642 if (status & JackServerFailed)
643 fprintf(stderr, "cannot connect to jack server\n");
644 if (status & JackServerError)
645 fprintf(stderr, "communication with jack server failed\n");
646 if (status & JackShmFailure)
647 fprintf(stderr, "jack cannot access shared memory\n");
648 if (status & JackVersionError)
649 fprintf(stderr, "jack server has wrong version\n");
650 fprintf(stderr, "cannot create jack client\n");
651 MusEGlobal::undoSetuid();
652 return true;
653 }
654
655 if (MusEGlobal::debugMsg)
656 fprintf(stderr, "initJackAudio(): client %s opened.\n", jack_get_client_name(client));
657
658 // Check if Jack-1 jack_port_by_name() workaround is required:
659 if(jack_ver_maj == 0)
660 {
661 sleep(1);
662 jack_port_t* p = jack_port_register(client, "jack1_test_port", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
663 if(p)
664 {
665 sleep(1);
666 int sz = jack_port_name_size();
667 char s[sz];
668 strcpy(s, jack_get_client_name(client));
669 strcat(s, ":jack1_test_port");
670 jack_port_t* sp = jack_port_by_name(client, s);
671 if(sp)
672 {
673 if(p != sp)
674 {
675 fprintf(stderr, "initJackAudio(): Enabling Jack-1 jack_port_by_name() workaround\n");
676 jack1_port_by_name_workaround = true;
677 }
678 }
679 else
680 fprintf(stderr, "initJackAudio(): Jack-1 jack_port_by_name() workaround: Error on jack_port_by_name(): port not found\n");
681
682 if(jack_port_unregister(client, p))
683 fprintf(stderr, "initJackAudio(): Jack-1 jack_port_by_name() workaround: Error on jack_port_unregister()\n");
684 else
685 sleep(1);
686 }
687 else
688 fprintf(stderr, "initJackAudio(): Jack-1 jack_port_by_name() workaround: Error on jack_port_register()\n");
689
690 }
691
692 jackAudio = new JackAudioDevice(client, jack_get_client_name(client));
693 if (MusEGlobal::debugMsg)
694 fprintf(stderr, "initJackAudio(): registering client...\n");
695
696 MusEGlobal::undoSetuid();
697
698 MusEGlobal::audioDevice = jackAudio;
699
700 // WARNING Don't do this here. Do it after any MusE ALSA client is registered, otherwise random crashes can occur.
701 //jackAudio->registerClient();
702
703 MusEGlobal::sampleRate = jack_get_sample_rate(client);
704
705 MusEGlobal::projectSampleRate = MusEGlobal::sampleRate;
706
707 // Make sure the AL namespace variables mirror our variables.
708 AL::sampleRate = MusEGlobal::sampleRate;
709 MusEGlobal::segmentSize = jack_get_buffer_size(client);
710
711 return false;
712 }
713
bufsize_callback(jack_nframes_t n,void *)714 static int bufsize_callback(jack_nframes_t n, void*)
715 {
716 fprintf(stderr, "JACK: buffersize changed %d\n", n);
717 return 0;
718 }
719
720 //---------------------------------------------------------
721 // freewheel_callback
722 //---------------------------------------------------------
723
freewheel_callback(int starting,void *)724 static void freewheel_callback(int starting, void*)
725 {
726 if (MusEGlobal::debugMsg || JACK_DEBUG)
727 fprintf(stderr, "JACK: freewheel_callback: starting%d\n", starting);
728 MusEGlobal::audio->setFreewheel(starting);
729 }
730
srate_callback(jack_nframes_t n,void *)731 static int srate_callback(jack_nframes_t n, void*)
732 {
733 if (MusEGlobal::debugMsg || JACK_DEBUG)
734 fprintf(stderr, "JACK: sample rate changed: %d\n", n);
735 return 0;
736 }
737
738 //---------------------------------------------------------
739 // registration_callback
740 //---------------------------------------------------------
741
registration_callback(jack_port_id_t port_id,int is_register,void *)742 static void registration_callback(jack_port_id_t port_id, int is_register, void*)
743 {
744 if(MusEGlobal::debugMsg || JACK_DEBUG)
745 fprintf(stderr, "JACK: registration_callback\n");
746
747 DEBUG_PRST_ROUTES(stderr, "JACK: registration_callback: port_id:%d is_register:%d\n", port_id, is_register);
748
749 // With Jack-1 do not use functions like jack_port_by_name and jack_port_by_id here.
750 // With registration the port has not been added yet, so they allocate a new
751 // 'external' port which is NOT the same as the port returned by jack_port_register !
752 // Thereafter each call to those functions returns THAT allocated port NOT the jack_port_register one.
753 // [ This was a bug in Jack1 due to a missing section. A fix by Tim was submitted late 2014 and was pending. ]
754 JackCallbackEvent ev;
755 ev.type = is_register ? PortRegister : PortUnregister;
756 ev.port_id_A = port_id;
757
758 jackCallbackFifo.put(ev);
759
760 // NOTE: Jack-1 does not issue a graph order callback after a registration call.
761 // Jack-1 callbacks: [ port connect -> graph order -> registration ] {...}
762 // Jack-2 callbacks: [ port connect {...} -> registration {...} -> graph order ] {...}
763 if(jack_ver_maj != 1)
764 {
765 // Add a GraphChanged event.
766 JackCallbackEvent ev;
767 ev.type = GraphChanged;
768 jackCallbackFifo.put(ev);
769 // we cannot call JackAudioDevice::graphChanged() from this
770 // context, so we send a message to the gui thread which in turn
771 // calls graphChanged()
772 if(muse_atomic_read(&atomicGraphChangedPending) == 0)
773 {
774 muse_atomic_set(&atomicGraphChangedPending, 1);
775 MusEGlobal::audio->sendMsgToGui('C');
776 }
777 }
778 }
779
780 //---------------------------------------------------------
781 // client_registration_callback
782 //---------------------------------------------------------
783
client_registration_callback(const char * name,int isRegister,void *)784 static void client_registration_callback(const char *name, int isRegister, void*)
785 {
786 if (MusEGlobal::debugMsg || JACK_DEBUG)
787 fprintf(stderr, "JACK: client registration changed:%s register:%d\n", name, isRegister);
788 DEBUG_PRST_ROUTES(stderr, "JACK: client registration changed:%s register:%d\n", name, isRegister);
789 }
790
791 //---------------------------------------------------------
792 // port_connect_callback
793 //---------------------------------------------------------
794
port_connect_callback(jack_port_id_t a,jack_port_id_t b,int isConnect,void * arg)795 static void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int isConnect, void* arg)
796 {
797 if (MusEGlobal::debugMsg || JACK_DEBUG)
798 fprintf(stderr, "JACK: port connections changed: A:%d B:%d isConnect:%d\n", a, b, isConnect);
799
800 DEBUG_PRST_ROUTES(stderr, "JACK: port_connect_callback id a:%d id b:%d isConnect:%d\n", a, b, isConnect);
801
802 JackCallbackEvent ev;
803 ev.type = isConnect ? PortConnect : PortDisconnect;
804 ev.port_id_A = a;
805 ev.port_id_B = b;
806 JackAudioDevice* jad = (JackAudioDevice*)arg;
807 jack_client_t* client = jad->jackClient();
808 if(client)
809 {
810 ev.port_A = jack_port_by_id(client, a);
811 ev.port_B = jack_port_by_id(client, b);
812 }
813 else
814 {
815 ev.port_A = NULL;
816 ev.port_B = NULL;
817 }
818
819 jackCallbackFifo.put(ev);
820 }
821
822 //---------------------------------------------------------
823 // graph_callback
824 // this is called from jack when the connections
825 // changed
826 //---------------------------------------------------------
827
graph_callback(void *)828 static int graph_callback(void*)
829 {
830 if (MusEGlobal::debugMsg || JACK_DEBUG)
831 fprintf(stderr, "graph_callback()\n");
832
833 DEBUG_PRST_ROUTES(stderr, "JACK: graph_callback\n");
834
835 // Add a GraphChanged event.
836 JackCallbackEvent ev;
837 ev.type = GraphChanged;
838 jackCallbackFifo.put(ev);
839
840 // we cannot call JackAudioDevice::graphChanged() from this
841 // context, so we send a message to the gui thread which in turn
842 // calls graphChanged()
843 if(muse_atomic_read(&atomicGraphChangedPending) == 0)
844 {
845 muse_atomic_set(&atomicGraphChangedPending, 1);
846 MusEGlobal::audio->sendMsgToGui('C');
847 }
848 return 0;
849 }
850
851 // static void latency_callback(jack_latency_callback_mode_t /*mode*/, void* /*arg*/)
852 // {
853 // //JackAudioDevice* jad = (JackAudioDevice*)arg;
854 //
855 // // TODO: Do all of our Input Track and Output Track ports.
856 //
857 // // jack_latency_range_t range;
858 // // if (mode == JackCaptureLatency) {
859 // // jack_port_get_latency_range (input_port, mode, &range);
860 // // range.min += latency;
861 // // range.max += latency;
862 // // jack_port_set_latency_range (output_port, mode, &range);
863 // // } else {
864 // // jack_port_get_latency_range (output_port, mode, &range);
865 // // range.min += latency;
866 // // range.max += latency;
867 // // jack_port_set_latency_range (input_port, mode, &range);
868 // // }
869 // }
870
871
processJackCallbackEvents(const Route & our_node,jack_port_t * our_port,RouteList * route_list,bool is_input)872 void JackAudioDevice::processJackCallbackEvents(const Route& our_node, jack_port_t* our_port,
873 RouteList* route_list, bool is_input)
874 {
875 jack_client_t* client = jackClient();
876 if(!client)
877 return;
878
879 jack_port_t* our_ext_port = our_port;
880 const char* our_port_name = our_port ? jack_port_name(our_port) : 0;
881
882 if(our_port && our_port_name && jack1_port_by_name_workaround)
883 {
884 jack_port_t* jp = jack_port_by_name(client, our_port_name);
885 if(jp && jp != our_port)
886 {
887 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::processJackCallbackEvents: changing audio input port!: channel:%d our_port:%p new port:%p\n",
888 our_node.channel, our_port, jp);
889 our_ext_port = jp;
890 }
891 }
892
893 for(iRoute ir = route_list->begin(); ir != route_list->end(); ++ir)
894 {
895 // Check correct route type, and channel if required.
896 if((ir->type != Route::JACK_ROUTE) || (our_node.channel != -1 && ir->channel != our_node.channel))
897 continue;
898 const char* route_jpname = ir->persistentJackPortName;
899 // FIXME: TODO: Maybe switch to get_ports
900 jack_port_t* jp = jack_port_by_name(client, route_jpname);
901 if(jp)
902 {
903 // TODO: For Jack-2 maybe alter this? Before calling jack_port_connected_to(), maybe first check if the IDs
904 // (hence jack ports) passed in the connect callback match here, to avoid calling jack_port_connected_to() ?
905 if(our_port && jack_port_connected_to(our_port, route_jpname))
906 {
907 // The ports are connected. Keep the route node but update its jack port pointer if necessary.
908 const char* s = NULL;
909 if(jp != ir->jackPort)
910 {
911 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports connected. Modifying route: our_port:%p old_route_jp:%p new_route_jp:%p route_persistent_name:%s\n",
912 our_port, ir->jackPort, jp, route_jpname);
913 s = route_jpname;
914 }
915 // Find a more appropriate name if necessary.
916 char fin_name[ROUTE_PERSISTENT_NAME_SIZE];
917 portName(jp, fin_name, ROUTE_PERSISTENT_NAME_SIZE);
918 if(strcmp(ir->persistentJackPortName, fin_name) != 0)
919 {
920 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports connected. Modifying route name: route_persistent_name:%s new name:%s\n", route_jpname, fin_name);
921 s = fin_name;
922 }
923
924 if(s)
925 operations.add(PendingOperationItem(Route(Route::JACK_ROUTE, 0, jp, ir->channel, 0, 0, s), &(*ir), PendingOperationItem::ModifyRouteNode));
926 }
927 else
928 {
929 if(ir->jackPort)
930 {
931 // Check whether the disconnect happened BEFORE this graphChanged() was called,
932 // or just now during it, or was followed by an unregister.
933 // Support our port == null (midi device not assigned to a midi port or I/O disabled etc.):
934 // If our port is null, treat this as an unregister...
935 const int ret = our_ext_port ? checkDisconnectCallback(our_ext_port, jp) : 1;
936 if(ret == 2)
937 {
938 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports not connected, ret=DeleteRouteNode. Deleting route: our_port:%p route_jp:%p found_jp:%p route_persistent_name:%s\n",
939 our_port, ir->jackPort, jp, route_jpname);
940 // The port exists but is not connected to our port. Remove the route node.
941 operations.add(PendingOperationItem(route_list, ir, PendingOperationItem::DeleteRouteNode));
942 }
943 else
944 if(ret == 1)
945 {
946 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports not connected, ret=ModifyRouteNode. Modifying route: our_port:%p route_jp:%p found_jp:%p route_persistent_name:%s\n",
947 our_port, ir->jackPort, jp, route_jpname);
948 operations.add(PendingOperationItem(Route(Route::JACK_ROUTE, 0, NULL, ir->channel, 0, 0, ir->persistentJackPortName), &(*ir), PendingOperationItem::ModifyRouteNode));
949 }
950 }
951 else
952 if(MusEGlobal::audio && MusEGlobal::audio->isRunning()) // Don't try to connect if not running.
953 {
954 // Check whether a port registration happened BEFORE this graphChanged() was called,
955 // or just now during it, or was followed by an unregister.
956 int ret = checkPortRegisterCallback(jp);
957 if(ret == 1)
958 {
959 // No failed attempts at connection to the Jack port now or in the previous call to graphChanged().
960 if(our_port)
961 {
962 // The port exists but is not connected to our port. Reconnect the route.
963 // NOTE: Jack2: graph changed callback will be called again regardless if jack_connect succeeds or fails...
964 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports not connected. Reconnecting route: our_port:%p route_jp:%p found_jp:%p our_port_name:%s route_persistent_name:%s\n",
965 our_port, ir->jackPort, jp, our_port_name, route_jpname);
966 if(our_port_name)
967 {
968 int err;
969 if(is_input)
970 err = jack_connect(client, route_jpname, our_port_name);
971 else
972 err = jack_connect(client, our_port_name, route_jpname);
973 if(err)
974 {
975 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports not connected. Reconnecting route: ERROR:%d our_port:%p route_jp:%p found_jp:%p our_port_name:%s route_persistent_name:%s\n",
976 err, our_port, ir->jackPort, jp, our_port_name, route_jpname);
977 }
978 else
979 {
980 // We have our jack port, on a supposedly active client. Update the route node's jack port pointer.
981 // Find a more appropriate name if necessary.
982 const char* s = ir->persistentJackPortName;
983 char fin_name[ROUTE_PERSISTENT_NAME_SIZE];
984 portName(jp, fin_name, ROUTE_PERSISTENT_NAME_SIZE);
985 if(strcmp(ir->persistentJackPortName, fin_name) != 0)
986 {
987 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Ports connected. Modifying route name: route_persistent_name:%s new name:%s\n", route_jpname, fin_name);
988 s = fin_name;
989 }
990 operations.add(PendingOperationItem(Route(Route::JACK_ROUTE, 0, jp, ir->channel, 0, 0, s), &(*ir), PendingOperationItem::ModifyRouteNode));
991 }
992 }
993 }
994 }
995 // State unchanged.
996 }
997 }
998 }
999 else
1000 {
1001 // Port does not exist. Keep the route node but clear its jack port pointer if necessary.
1002 if(ir->jackPort)
1003 {
1004 DEBUG_PRST_ROUTES(stderr, "processJackCallbackEvents: Port non-existent. Modifying route: our_port:%p route_jp:%p route_persistent_name:%s\n",
1005 our_port, ir->jackPort, route_jpname);
1006 operations.add(PendingOperationItem(Route(Route::JACK_ROUTE, 0, NULL, ir->channel, 0, 0, ir->persistentJackPortName), &(*ir), PendingOperationItem::ModifyRouteNode));
1007 }
1008 }
1009 }
1010
1011 if(our_port)
1012 checkNewRouteConnections(our_port, our_node.channel, route_list);
1013 }
1014
1015 //---------------------------------------------------------
1016 // JackAudioDevice::graphChanged
1017 // this is called from song in gui context triggered
1018 // by graph_callback()
1019 //---------------------------------------------------------
1020
graphChanged()1021 void JackAudioDevice::graphChanged()
1022 {
1023 DEBUG_JACK(stderr, "JackAudioDevice::graphChanged()\n");
1024
1025 if(!checkJackClient(_client))
1026 {
1027 jackCallbackFifo.clear(); // Want this?
1028 // Reset this now.
1029 muse_atomic_set(&atomicGraphChangedPending, 0);
1030 return;
1031 }
1032
1033 // For Jack-1 only: See if we need to wait, for example for a port unregister event.
1034 // Jack "2" does not require waiting, Jack "1" does, assume any other version requires the wait (no harm).
1035 if(MusEGlobal::audio && jack_ver_maj != 1)
1036 {
1037 // TODO: It may be desirable to always wait so that bunches of commands can be processed easier.
1038 //bool do_audio_wait = false;
1039 // This is safe because the writer only increases the size.
1040 int cb_fifo_sz = jackCallbackFifo.getSize();
1041 for(int i = 0; i < cb_fifo_sz; ++i)
1042 {
1043 const JackCallbackEvent& jcb = jackCallbackFifo.peek(i);
1044 if(jcb.type == PortDisconnect && (jack_port_is_mine(_client, jcb.port_A) || jack_port_is_mine(_client, jcb.port_B)))
1045 {
1046 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::graphChanged: *** calling msgAudioWait()\n");
1047 MusEGlobal::audio->msgAudioWait(); // Wait until upcoming process call has finished...
1048 break;
1049 }
1050 }
1051 }
1052
1053 // Reset this now.
1054 muse_atomic_set(&atomicGraphChangedPending, 0);
1055
1056 jackCallbackEvents.clear();
1057 // Find the last GraphChanged event, if any.
1058 // This is safe because the writer only increases the size.
1059 int cb_fifo_sz = jackCallbackFifo.getSize();
1060 if(cb_fifo_sz)
1061 {
1062 int last_gc_idx = cb_fifo_sz - 1;
1063 if(jack_ver_maj == 1)
1064 for(int i = 0; i < cb_fifo_sz; ++i)
1065 if(jackCallbackFifo.peek(i).type == GraphChanged)
1066 last_gc_idx = i;
1067 // Move the events into a list for processing, including the final GraphChanged event.
1068 // Leave any 'still in progress' ending events (without closing GraphChanged event) in the ring buffer.
1069 //jackCallbackEvents.clear();
1070 for(int i = 0; i <= last_gc_idx; ++i)
1071 jackCallbackEvents.push_back(jackCallbackFifo.get());
1072 }
1073 processGraphChanges();
1074
1075 if(!operations.empty())
1076 {
1077 MusEGlobal::audio->msgExecutePendingOperations(operations, true);
1078 operations.clear();
1079 }
1080 }
1081
processGraphChanges()1082 void JackAudioDevice::processGraphChanges()
1083 {
1084 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::processGraphChanges()\n");
1085 //---------------------------------------
1086 // Audio inputs:
1087 //---------------------------------------
1088
1089 InputList* il = MusEGlobal::song->inputs();
1090 for(iAudioInput ii = il->begin(); ii != il->end(); ++ii)
1091 {
1092 AudioInput* it = *ii;
1093 int channels = it->channels();
1094 for(int channel = 0; channel < channels; ++channel)
1095 {
1096 jack_port_t* port = (jack_port_t*)(it->jackPort(channel));
1097 // Support even if port == null.
1098 processJackCallbackEvents(Route(it, channel), port, it->inRoutes(), true);
1099 }
1100 }
1101
1102 //---------------------------------------
1103 // Audio outputs:
1104 //---------------------------------------
1105
1106 OutputList* ol = MusEGlobal::song->outputs();
1107 for(iAudioOutput ii = ol->begin(); ii != ol->end(); ++ii)
1108 {
1109 AudioOutput* it = *ii;
1110 int channels = it->channels();
1111 for(int channel = 0; channel < channels; ++channel)
1112 {
1113 jack_port_t* port = (jack_port_t*)(it->jackPort(channel));
1114 // Support even if port == null.
1115 processJackCallbackEvents(Route(it, channel), port, it->outRoutes(), false);
1116 }
1117 }
1118
1119 //---------------------------------------
1120 // Midi devices:
1121 //---------------------------------------
1122
1123 for(iMidiDevice ii = MusEGlobal::midiDevices.begin(); ii != MusEGlobal::midiDevices.end(); ++ii)
1124 {
1125 MidiDevice* md = *ii;
1126 if(md->deviceType() != MidiDevice::JACK_MIDI)
1127 continue;
1128
1129 //---------------------------------------
1130 // Midi outputs:
1131 //---------------------------------------
1132
1133 if(md->rwFlags() & 1) // Writable
1134 {
1135 jack_port_t* port = (jack_port_t*)md->outClientPort();
1136 // Support even if port == null.
1137 processJackCallbackEvents(Route(md, -1), port, md->outRoutes(), false);
1138 }
1139
1140 //------------------------
1141 // Midi inputs:
1142 //------------------------
1143
1144 if(md->rwFlags() & 2) // Readable
1145 {
1146 jack_port_t* port = (jack_port_t*)md->inClientPort();
1147 // Support even if port == null.
1148 processJackCallbackEvents(Route(md, -1), port, md->inRoutes(), true);
1149 }
1150 }
1151 }
1152
checkNewRouteConnections(jack_port_t * our_port,int channel,RouteList * route_list)1153 void JackAudioDevice::checkNewRouteConnections(jack_port_t* our_port, int channel, RouteList* route_list)
1154 {
1155 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::checkNewRouteConnections(): client:%p our_port:%p channel:%d route_list:%p\n",
1156 _client, our_port, channel, route_list);
1157 // Check for new connections...
1158 const char** ports = jack_port_get_all_connections(_client, our_port);
1159 if(ports)
1160 {
1161 const char** pn = ports;
1162 while(*pn)
1163 {
1164 // Should be safe and quick search here, we know that the port name is valid.
1165 jack_port_t* jp = jack_port_by_name(_client, *pn);
1166 if(jp)
1167 {
1168 bool found = false;
1169 for(ciRoute ir = route_list->begin(); ir != route_list->end(); ++ir)
1170 {
1171 if(ir->type != Route::JACK_ROUTE || (channel != -1 && ir->channel != channel))
1172 continue;
1173
1174 // See if any changes are pending for the route node and take them into account.
1175 jack_port_t* op_jp = (jack_port_t*)ir->jackPort;
1176 const char* op_ppname = ir->persistentJackPortName;
1177 iPendingOperation ipo = operations.end();
1178 while(ipo != operations.begin())
1179 {
1180 --ipo;
1181 switch(ipo->_type)
1182 {
1183 case PendingOperationItem::DeleteRouteNode:
1184 if(ipo->_route_list == route_list && &(*ipo->_iRoute) == &(*ir))
1185 {
1186 found = true;
1187 ipo = operations.begin(); // Breakout
1188 }
1189 break;
1190
1191 case PendingOperationItem::ModifyRouteNode:
1192 if(ipo->_dst_route_pointer == &(*ir))
1193 {
1194 op_jp = (jack_port_t*)ipo->_src_route.jackPort;
1195 op_ppname = ipo->_src_route.persistentJackPortName;
1196 ipo = operations.begin(); // Breakout
1197 }
1198 break;
1199
1200 default:
1201 break;
1202 }
1203 }
1204 if(found)
1205 {
1206 found = false;
1207 continue; // Ignore the route node - it has been scheduled for deletion.
1208 }
1209
1210 // TODO: Maybe switch to get_ports
1211 if(op_jp == jp || jack_port_by_name(_client, op_ppname) == jp)
1212 {
1213 found = true;
1214 break;
1215 }
1216 }
1217 if(!found)
1218 {
1219 Route r(Route::JACK_ROUTE, 0, jp, channel, 0, 0, NULL);
1220 // Find a better name.
1221 portName(jp, r.persistentJackPortName, ROUTE_PERSISTENT_NAME_SIZE);
1222 DEBUG_PRST_ROUTES(stderr, " adding route: route_jp:%p portname:%s route_persistent_name:%s\n",
1223 jp, *pn, r.persistentJackPortName);
1224 operations.add(PendingOperationItem(route_list, r, PendingOperationItem::AddRouteNode));
1225 }
1226 }
1227 ++pn;
1228 }
1229 jack_free(ports);
1230 }
1231 }
1232
checkDisconnectCallback(const jack_port_t * our_port,const jack_port_t * port)1233 int JackAudioDevice::checkDisconnectCallback(const jack_port_t* our_port, const jack_port_t* port)
1234 {
1235 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::checkDisconnectCallback(): our_port:%p port:%p\n", our_port, port);
1236
1237 iJackCallbackEvent ijce = jackCallbackEvents.end();
1238 while(ijce != jackCallbackEvents.begin())
1239 {
1240 --ijce;
1241 if(ijce->type == PortConnect && ((ijce->port_A == our_port && ijce->port_B == port) || (ijce->port_B == our_port && ijce->port_A == port)))
1242 return 0;
1243 if(ijce->type == PortDisconnect)
1244 {
1245 jack_port_id_t id;
1246 if(ijce->port_A == our_port && ijce->port_B == port)
1247 id = ijce->port_id_B;
1248 else if(ijce->port_B == our_port && ijce->port_A == port)
1249 id = ijce->port_id_A;
1250 else continue;
1251
1252 for( ++ijce ; ijce != jackCallbackEvents.end(); ++ijce)
1253 if(ijce->type == PortUnregister && ijce->port_id_A == id)
1254 return 1;
1255 return 2;
1256 }
1257 }
1258 return 0;
1259 }
1260
checkPortRegisterCallback(const jack_port_t * port)1261 int JackAudioDevice::checkPortRegisterCallback(const jack_port_t* port)
1262 {
1263 DEBUG_PRST_ROUTES(stderr, "JackAudioDevice::checkPortRegisterCallback(): port:%p\n", port);
1264
1265 iJackCallbackEvent ijce = jackCallbackEvents.end();
1266 while(ijce != jackCallbackEvents.begin())
1267 {
1268 --ijce;
1269 if(ijce->type == PortRegister)
1270 {
1271 jack_port_id_t id = ijce->port_id_A;
1272 if(jack_port_by_id(_client, id) == port)
1273 {
1274 for( ++ijce ; ijce != jackCallbackEvents.end(); ++ijce)
1275 if(ijce->type == PortUnregister && ijce->port_id_A == id)
1276 return 0;
1277 return 1;
1278 }
1279 }
1280 }
1281 return 0;
1282 }
1283
static_JackXRunCallback(void *)1284 int JackAudioDevice::static_JackXRunCallback(void *)
1285 {
1286 MusEGlobal::audio->incXruns();
1287 return 0;
1288 }
1289
1290 //static int xrun_callback(void*)
1291 // {
1292 // fprintf(stderr, "JACK: xrun\n");
1293 // return 0;
1294 // }
1295
1296 //---------------------------------------------------------
1297 // register
1298 //---------------------------------------------------------
1299
registerClient()1300 void JackAudioDevice::registerClient()
1301 {
1302 DEBUG_JACK(stderr, "registerClient()\n");
1303
1304 // if (MusEGlobal::debugMsg) {
1305 // fprintf(stderr, "JackAudioDevice::registerClient(): registering error and info callbacks...\n");
1306 // jack_set_error_function(jackError);
1307 // jack_set_info_function(jackInfo);
1308 // }
1309 // else {
1310 // fprintf(stderr, "JackAudioDevice::registerClient(): registering no error and no info callbacks...\n");
1311 // jack_set_error_function(noJackError);
1312 // jack_set_info_function(noJackInfo);
1313 // }
1314
1315 if(!checkJackClient(_client)) return;
1316
1317 jack_set_thread_init_callback(_client, (JackThreadInitCallback) jack_thread_init, 0);
1318 //jack_set_timebase_callback(client, 0, (JackTimebaseCallback) timebase_callback, 0);
1319 jack_set_process_callback(_client, processAudio, this);
1320
1321 // NOTE: We set the driver's sync timeout in the gui thread. See Song::seqSignal().
1322 jack_set_sync_callback(_client, processSync, 0);
1323
1324 jack_on_shutdown(_client, processShutdown, 0);
1325 jack_set_buffer_size_callback(_client, bufsize_callback, 0);
1326 jack_set_sample_rate_callback(_client, srate_callback, 0);
1327 jack_set_port_registration_callback(_client, registration_callback, this);
1328 jack_set_client_registration_callback(_client, client_registration_callback, 0);
1329 jack_set_port_connect_callback(_client, port_connect_callback, this);
1330 // Can't use this! Incompatible in jack 1/2 and unimplemented in jack1.
1331 //jack_set_port_rename_callback(_client, port_rename_callback, 0);
1332 jack_set_graph_order_callback(_client, graph_callback, this);
1333 // jack_set_xrun_callback(client, xrun_callback, 0);
1334 jack_set_freewheel_callback (_client, freewheel_callback, 0);
1335 // Tell the JACK server to call `latency()' whenever the latency needs to be recalculated.
1336 // if(jack_set_latency_callback)
1337 // jack_set_latency_callback(_client, latency_callback, this);
1338
1339
1340 jack_set_xrun_callback(_client, static_JackXRunCallback, this);
1341 }
1342
1343 //---------------------------------------------------------
1344 // registerInPort
1345 //---------------------------------------------------------
1346
registerInPort(const char * name,bool midi)1347 void* JackAudioDevice::registerInPort(const char* name, bool midi)
1348 {
1349 DEBUG_JACK(stderr, "registerInPort()\n");
1350 if(!checkJackClient(_client) || !name || name[0] == '\0')
1351 return NULL;
1352 const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
1353 void* p = jack_port_register(_client, name, type, JackPortIsInput, 0);
1354 DEBUG_PRST_ROUTES(stderr, "JACK: registerInPort: <%s> %p\n", name, p);
1355 return p;
1356 }
1357
1358 //---------------------------------------------------------
1359 // registerOutPort
1360 //---------------------------------------------------------
1361
registerOutPort(const char * name,bool midi)1362 void* JackAudioDevice::registerOutPort(const char* name, bool midi)
1363 {
1364 DEBUG_JACK(stderr, "registerOutPort()\n");
1365 if(!checkJackClient(_client) || !name || name[0] == '\0')
1366 return NULL;
1367 const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
1368 void* p = jack_port_register(_client, name, type, JackPortIsOutput, 0);
1369 DEBUG_PRST_ROUTES(stderr, "JACK: registerOutPort: <%s> %p\n", name, p);
1370 return p;
1371 }
1372
1373 //---------------------------------------------------------
1374 // connect
1375 //---------------------------------------------------------
1376
connect(void * src,void * dst)1377 bool JackAudioDevice::connect(void* src, void* dst)
1378 {
1379 DEBUG_JACK(stderr, "JackAudioDevice::connect()\n");
1380 if(!checkJackClient(_client)) return false;
1381 const char* sn = jack_port_name((jack_port_t*) src);
1382 const char* dn = jack_port_name((jack_port_t*) dst);
1383 if (sn == 0 || dn == 0) {
1384 fprintf(stderr, "JackAudio::connect: unknown jack ports\n");
1385 return false;
1386 }
1387 int err = jack_connect(_client, sn, dn);
1388 //if (jack_connect(_client, sn, dn)) {
1389 if (err) {
1390 fprintf(stderr, "jack connect <%s>%p - <%s>%p failed with err:%d\n",
1391 sn, src, dn, dst, err);
1392 return false;
1393 }
1394 else
1395 {
1396 DEBUG_JACK(stderr, "jack connect <%s>%p - <%s>%p succeeded\n",
1397 sn, src, dn, dst);
1398 }
1399 return true;
1400 }
1401
connect(const char * src,const char * dst)1402 bool JackAudioDevice::connect(const char* src, const char* dst)
1403 {
1404 DEBUG_JACK(stderr, "JackAudioDevice::connect()\n");
1405 if(!checkJackClient(_client) || !src || !dst || src[0] == '\0' || dst[0] == '\0')
1406 return false;
1407 int err = jack_connect(_client, src, dst);
1408 if(err)
1409 {
1410 fprintf(stderr, "jack connect <%s> - <%s> failed with err:%d\n", src, dst, err);
1411 return false;
1412 }
1413 return true;
1414 }
1415
1416 //---------------------------------------------------------
1417 // disconnect
1418 //---------------------------------------------------------
1419
disconnect(void * src,void * dst)1420 bool JackAudioDevice::disconnect(void* src, void* dst)
1421 {
1422 DEBUG_JACK(stderr, "JackAudioDevice::disconnect()\n");
1423 if(!checkJackClient(_client)) return false;
1424 if(!src || !dst)
1425 return false;
1426 const char* sn = jack_port_name((jack_port_t*) src);
1427 const char* dn = jack_port_name((jack_port_t*) dst);
1428 if (sn == nullptr || dn == nullptr) {
1429 fprintf(stderr, "JackAudio::disconnect: unknown jack ports\n");
1430 return false;
1431 }
1432 int err = jack_disconnect(_client, sn, dn);
1433 //if (jack_disconnect(_client, sn, dn)) {
1434 if (err) {
1435 fprintf(stderr, "jack disconnect <%s> - <%s> failed with err:%d\n",
1436 sn, dn, err);
1437 return false;
1438 }
1439 else
1440 {
1441 DEBUG_JACK(stderr, "jack disconnect <%s> - <%s> succeeded\n",
1442 sn, dn);
1443 }
1444 return true;
1445 }
1446
disconnect(const char * src,const char * dst)1447 bool JackAudioDevice::disconnect(const char* src, const char* dst)
1448 {
1449 DEBUG_JACK(stderr, "JackAudioDevice::disconnect()\n");
1450 if(!checkJackClient(_client) || !src || !dst || src[0] == '\0' || dst[0] == '\0')
1451 return false;
1452 int err = jack_disconnect(_client, src, dst);
1453 if(err)
1454 {
1455 fprintf(stderr, "jack disconnect <%s> - <%s> failed with err:%d\n", src, dst, err);
1456 return false;
1457 }
1458 return true;
1459 }
1460
1461 //---------------------------------------------------------
1462 // portsCanDisconnect
1463 //---------------------------------------------------------
1464
portsCanDisconnect(void * src,void * dst) const1465 bool JackAudioDevice::portsCanDisconnect(void* src, void* dst) const
1466 {
1467 if(!_client)
1468 return false;
1469 if(!src || !dst)
1470 return false;
1471
1472 const char** ports = jack_port_get_all_connections(_client, (jack_port_t*)src);
1473 if(!ports)
1474 return false;
1475
1476 bool rv = false;
1477 for(const char** p = ports; p && *p; ++p)
1478 {
1479 jack_port_t* jp = jack_port_by_name(_client, *p);
1480 if(jp == dst)
1481 {
1482 rv = true;
1483 break;
1484 }
1485 }
1486 jack_free(ports);
1487 return rv;
1488 }
1489
portsCanDisconnect(const char * src,const char * dst) const1490 bool JackAudioDevice::portsCanDisconnect(const char* src, const char* dst) const
1491 {
1492 if(!_client)
1493 return false;
1494 return portsCanDisconnect(jack_port_by_name(_client, src), jack_port_by_name(_client, dst));
1495 }
1496
1497 //---------------------------------------------------------
1498 // portsCanConnect
1499 //---------------------------------------------------------
1500
portsCanConnect(void * src,void * dst) const1501 bool JackAudioDevice::portsCanConnect(void* src, void* dst) const
1502 {
1503 if(!_client)
1504 return false;
1505 if(!src || !dst)
1506 return false;
1507 const char* src_type = jack_port_type((jack_port_t*)src);
1508 const char* dst_type = jack_port_type((jack_port_t*)dst);
1509 if(!src_type || !dst_type || (strcmp(src_type, dst_type) != 0))
1510 return false;
1511
1512 if(!(jack_port_flags((jack_port_t*)src) & JackPortIsOutput) || !(jack_port_flags((jack_port_t*)dst) & JackPortIsInput))
1513 return false;
1514
1515 const char** ports = jack_port_get_all_connections(_client, (jack_port_t*)src);
1516 if(!ports)
1517 return true;
1518
1519 bool rv = true;
1520 for(const char** p = ports; p && *p; ++p)
1521 {
1522 jack_port_t* jp = jack_port_by_name(_client, *p);
1523 if(jp == dst)
1524 {
1525 rv = false;
1526 break;
1527 }
1528 }
1529
1530 jack_free(ports);
1531 return rv;
1532 }
1533
portsCanConnect(const char * src,const char * dst) const1534 bool JackAudioDevice::portsCanConnect(const char* src, const char* dst) const
1535 {
1536 if(!_client)
1537 return false;
1538 return portsCanConnect(jack_port_by_name(_client, src), jack_port_by_name(_client, dst));
1539 }
1540
1541 //---------------------------------------------------------
1542 // portsCompatible
1543 //---------------------------------------------------------
1544
portsCompatible(void * src,void * dst) const1545 bool JackAudioDevice::portsCompatible(void* src, void* dst) const
1546 {
1547 if(!src || !dst)
1548 return false;
1549 const char* src_type = jack_port_type((jack_port_t*)src);
1550 const char* dst_type = jack_port_type((jack_port_t*)dst);
1551 if(!src_type || !dst_type || (strcmp(src_type, dst_type) != 0))
1552 return false;
1553
1554 if(!(jack_port_flags((jack_port_t*)src) & JackPortIsOutput) || !(jack_port_flags((jack_port_t*)dst) & JackPortIsInput))
1555 return false;
1556
1557 return true;
1558 }
1559
portsCompatible(const char * src,const char * dst) const1560 bool JackAudioDevice::portsCompatible(const char* src, const char* dst) const
1561 {
1562 if(!_client)
1563 return false;
1564 return portsCompatible(jack_port_by_name(_client, src), jack_port_by_name(_client, dst));
1565 }
1566
1567 //---------------------------------------------------------
1568 // start
1569 // Return true on success.
1570 //---------------------------------------------------------
1571
start(int)1572 bool JackAudioDevice::start(int /*priority*/)
1573 {
1574 DEBUG_JACK(stderr, "JackAudioDevice::start()\n");
1575 if(!checkJackClient(_client)) return false;
1576
1577 MusEGlobal::doSetuid();
1578
1579 DEBUG_PRST_ROUTES (stderr, "JackAudioDevice::start(): calling jack_activate()\n");
1580
1581 // REMOVE Tim. latency. Changed. TESTING.
1582 // if (jack_activate(_client)) {
1583 // MusEGlobal::undoSetuid();
1584 // fprintf (stderr, "JACK: cannot activate client\n");
1585 // exit(-1);
1586 // }
1587 if(!jackStarted)
1588 {
1589 if (jack_activate(_client)) {
1590 MusEGlobal::undoSetuid();
1591 fprintf (stderr, "JACK: cannot activate client\n");
1592 exit(-1);
1593 }
1594 }
1595 jackStarted = true;
1596
1597 MusEGlobal::undoSetuid();
1598
1599 /* connect the ports. Note: you can't do this before
1600 the client is activated, because we can't allow
1601 connections to be made to clients that aren't
1602 running.
1603 */
1604 MusEGlobal::song->connectAllPorts();
1605
1606 fflush(stdin);
1607
1608 return true;
1609 }
1610
1611 //---------------------------------------------------------
1612 // stop
1613 //---------------------------------------------------------
1614
stop()1615 void JackAudioDevice::stop()
1616 {
1617 DEBUG_JACK(stderr, "JackAudioDevice::stop()\n");
1618 if(!checkJackClient(_client)) return;
1619 DEBUG_PRST_ROUTES (stderr, "JackAudioDevice::stop(): calling jack_deactivate()\n");
1620
1621 // REMOVE Tim. latency. Changed. TESTING.
1622 // if (jack_deactivate(_client)) {
1623 // fprintf (stderr, "cannot deactivate client\n");
1624 // }
1625
1626 // //if(jackStarted)
1627 // {
1628 //
1629 // if (jack_deactivate(_client)) {
1630 // fprintf (stderr, "cannot deactivate client\n");
1631 // }
1632 //
1633 // }
1634 // jackStarted = false;
1635 }
1636
1637 //---------------------------------------------------------
1638 // transportQuery
1639 //---------------------------------------------------------
1640
transportQuery(jack_position_t * pos)1641 jack_transport_state_t JackAudioDevice::transportQuery(jack_position_t* pos)
1642 {
1643 DEBUG_JACK(stderr, "JackAudioDevice::transportQuery pos:%d\n", (unsigned int)pos->frame);
1644
1645 // TODO: Compose and return a state if MusE is disengaged from Jack transport.
1646
1647 return jack_transport_query(_client, pos);
1648 }
1649
1650 //---------------------------------------------------------
1651 // timebaseQuery
1652 // Given the number of frames in this period, get the bar, beat, tick,
1653 // and current absolute tick, and number of ticks in this period.
1654 // Return false if information could not be obtained.
1655 //---------------------------------------------------------
1656
timebaseQuery(unsigned frames,unsigned * bar,unsigned * beat,unsigned * tick,unsigned * curr_abs_tick,unsigned * next_ticks)1657 bool JackAudioDevice::timebaseQuery(unsigned frames, unsigned* bar, unsigned* beat, unsigned* tick, unsigned* curr_abs_tick, unsigned* next_ticks)
1658 {
1659 jack_position_t jp;
1660 jack_transport_query(_client, &jp);
1661
1662 DEBUG_JACK(stderr, "timebaseQuery frame:%u\n", jp.frame);
1663
1664 if(jp.valid & JackPositionBBT)
1665 {
1666 #if JACK_DEBUG
1667 fprintf(stderr, "timebaseQuery BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
1668 jp.bar, jp.beat, jp.tick, jp.bar_start_tick, jp.beats_per_bar, jp.beat_type, jp.ticks_per_beat, jp.beats_per_minute);
1669 if(jp.valid & JackBBTFrameOffset)
1670 fprintf(stderr, "timebaseQuery BBTFrameOffset: %u\n", jp.bbt_offset);
1671 #endif
1672
1673 if(jp.ticks_per_beat > 0.0)
1674 {
1675 unsigned muse_tick = unsigned((double(jp.tick) / jp.ticks_per_beat) * double(MusEGlobal::config.division));
1676 unsigned curr_tick = ((jp.bar - 1) * jp.beats_per_bar + (jp.beat - 1)) * double(MusEGlobal::config.division) + muse_tick;
1677 // Prefer the reported frame rate over the app's rate if possible.
1678 double f_rate = jp.frame_rate != 0 ? jp.frame_rate : MusEGlobal::sampleRate;
1679 // beats_per_minute is "supposed" to be quantized to period size - that is, computed
1680 // so that mid-period changes are averaged out to produce a single tempo which
1681 // produces the same tick in the end. If we can rely on that, we should be good accuracy.
1682 unsigned ticks = double(MusEGlobal::config.division) * (jp.beats_per_minute / 60.0) * double(frames) / f_rate;
1683
1684 DEBUG_JACK(stderr, "timebaseQuery curr_tick:%u f_rate:%f ticks:%u\n", curr_tick, f_rate, ticks);
1685
1686 if(bar) *bar = jp.bar;
1687 if(beat) *beat = jp.beat;
1688 if(tick) *tick = muse_tick;
1689
1690 if(curr_abs_tick) *curr_abs_tick = curr_tick;
1691 if(next_ticks) *next_ticks = ticks;
1692
1693 return true;
1694 }
1695 }
1696
1697 #if JACK_DEBUG
1698 if(jp.valid & JackPositionTimecode)
1699 fprintf(stderr, "timebaseQuery JackPositionTimecode: frame_time:%f next_time:%f\n", jp.frame_time, jp.next_time);
1700 if(jp.valid & JackAudioVideoRatio)
1701 fprintf(stderr, "timebaseQuery JackAudioVideoRatio: %f\n", jp.audio_frames_per_video_frame);
1702 if(jp.valid & JackVideoFrameOffset)
1703 fprintf(stderr, "timebaseQuery JackVideoFrameOffset: %u\n", jp.video_offset);
1704 #endif
1705
1706 return false;
1707 }
1708
1709 //---------------------------------------------------------
1710 // systemTimeUS
1711 // Return system time in microseconds as a 64-bit integer.
1712 // Depends on selected clock source.
1713 // With Jack, may be based upon wallclock time, the
1714 // processor cycle counter or the HPET clock etc.
1715 //---------------------------------------------------------
1716
systemTimeUS() const1717 uint64_t JackAudioDevice::systemTimeUS() const
1718 {
1719 // Client valid? According to sletz: For jack_get_time "There are some timing related
1720 // initialization that are done once when a first client is created."
1721 if(!checkJackClient(_client))
1722 return AudioDevice::systemTimeUS();
1723 return jack_get_time();
1724 }
1725
1726 //---------------------------------------------------------
1727 // getCurFrame
1728 //---------------------------------------------------------
1729
getCurFrame() const1730 unsigned int JackAudioDevice::getCurFrame() const
1731 {
1732 DEBUG_JACK(stderr, "JackAudioDevice::getCurFrame pos.frame:%d\n", pos.frame);
1733
1734 if(!MusEGlobal::config.useJackTransport)
1735 return AudioDevice::getCurFrame();
1736
1737 return pos.frame;
1738 }
1739
1740 //---------------------------------------------------------
1741 // framePos
1742 //---------------------------------------------------------
1743
framePos() const1744 unsigned JackAudioDevice::framePos() const
1745 {
1746 //if(!MusEGlobal::config.useJackTransport)
1747 //{
1748 // DEBUG_JACK(stderr, "JackAudioDevice::framePos dummyPos:%d\n", dummyPos);
1749 // return dummyPos;
1750 //}
1751
1752 if(!checkJackClient(_client)) return 0;
1753 jack_nframes_t n = jack_frame_time(_client);
1754
1755 //DEBUG_JACK(stderr, "JackAudioDevice::framePos jack frame:%d\n", (int)n);
1756
1757 return n;
1758 }
1759
1760 //---------------------------------------------------------
1761 // framesAtCycleStart
1762 // Frame count at the start of current cycle.
1763 // This is meant to be called from inside process thread only.
1764 //---------------------------------------------------------
1765
framesAtCycleStart() const1766 unsigned JackAudioDevice::framesAtCycleStart() const
1767 {
1768 if(!checkJackClient(_client)) return 0;
1769 jack_nframes_t n = jack_last_frame_time(_client);
1770 //DEBUG_JACK(stderr, "JackAudioDevice::framesAtCycleStart jack frame:%d\n", (unsigned)n);
1771 return (unsigned)n;
1772 }
1773
1774 //---------------------------------------------------------
1775 // framesSinceCycleStart
1776 // Estimated frames since the last process cycle began
1777 // This is meant to be called from inside process thread only.
1778 //---------------------------------------------------------
1779
framesSinceCycleStart() const1780 unsigned JackAudioDevice::framesSinceCycleStart() const
1781 {
1782 if(!checkJackClient(_client)) return 0;
1783 jack_nframes_t n = jack_frames_since_cycle_start(_client);
1784 //DEBUG_JACK(stderr, "JackAudioDevice::framesSinceCycleStart jack frame:%d\n", (unsigned)n);
1785
1786 // Safety due to inaccuracies. It cannot be after the segment, right?
1787 if(n >= MusEGlobal::segmentSize)
1788 n = MusEGlobal::segmentSize - 1;
1789
1790 return (unsigned)n;
1791 }
1792
1793 #if 0
1794 //---------------------------------------------------------
1795 // framesDelay
1796 // TODO
1797 //---------------------------------------------------------
1798
1799 int JackAudioDevice::frameDelay() const
1800 {
1801 jack_nframes_t n = (MusEGlobal::segmentSize * (segmentCount-1)) - jack_frames_since_cycle_start(client);
1802 return (int)n;
1803 }
1804 #endif
1805
curTransportFrame() const1806 unsigned JackAudioDevice::curTransportFrame() const
1807 {
1808 if(!checkJackClient(_client)) return 0;
1809 return jack_get_current_transport_frame(_client);
1810 }
1811
1812 //---------------------------------------------------------
1813 // getJackPorts
1814 //---------------------------------------------------------
1815
getJackPorts(const char ** ports,std::list<QString> & name_list,bool midi,bool physical,int aliases)1816 void JackAudioDevice::getJackPorts(const char** ports, std::list<QString>& name_list, bool midi, bool physical, int aliases)
1817 {
1818 DEBUG_JACK(stderr, "JackAudioDevice::getJackPorts()\n");
1819 QString qname;
1820 QString cname(jack_get_client_name(_client));
1821
1822 for (const char** p = ports; p && *p; ++p) {
1823 // Should be safe and quick search here, we know that the port name is valid.
1824 jack_port_t* port = jack_port_by_name(_client, *p);
1825 int port_flags = jack_port_flags(port);
1826
1827 // Ignore our own client ports.
1828 if(jack_port_is_mine(_client, port))
1829 {
1830 if(MusEGlobal::debugMsg)
1831 fprintf(stderr, "JackAudioDevice::getJackPorts ignoring own port: %s\n", *p);
1832 continue;
1833 }
1834
1835 int nsz = jack_port_name_size();
1836 char buffer[nsz];
1837
1838 bool mthrough = false;
1839
1840 if(midi)
1841 {
1842 strncpy(buffer, *p, nsz);
1843 char a2[nsz];
1844 char* al[2];
1845 al[0] = buffer;
1846 al[1] = a2;
1847 int na = jack_port_get_aliases(port, al);
1848 if(na >= 1)
1849 {
1850 qname = QString(al[0]);
1851 //fprintf(stderr, "Checking port name for: %s\n", (QString("alsa_pcm:") + cname + QString("/")).toLatin1().constData());
1852 // Ignore our own ALSA client!
1853 if(qname.startsWith(QString("alsa_pcm:") + cname + QString("/")))
1854 continue;
1855 // Put Midi Through after all others.
1856 mthrough = qname.startsWith(QString("alsa_pcm:Midi-Through/"));
1857 //if((physical && mthrough) || (!physical && !mthrough))
1858 //if(physical && mthrough)
1859 // continue;
1860 }
1861 }
1862 // Put physical/terminal ports before others.
1863 bool is_phys = (port_flags & (JackPortIsTerminal | JackPortIsPhysical)) && !mthrough;
1864 if((physical && !is_phys) || (!physical && is_phys))
1865 continue;
1866
1867
1868 strncpy(buffer, *p, nsz);
1869 if((aliases == 0) || (aliases == 1))
1870 {
1871 char a2[nsz];
1872 char* al[2];
1873 al[0] = buffer;
1874 al[1] = a2;
1875 int na = jack_port_get_aliases(port, al);
1876 int a = aliases;
1877 if(a >= na)
1878 {
1879 a = na;
1880 if(a > 0)
1881 a--;
1882 }
1883 qname = QString(al[a]);
1884 }
1885 else
1886 qname = QString(buffer);
1887
1888 name_list.push_back(qname);
1889 }
1890 }
1891
1892 //---------------------------------------------------------
1893 // outputPorts
1894 //---------------------------------------------------------
1895
outputPorts(bool midi,int aliases)1896 std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
1897 {
1898 DEBUG_JACK(stderr, "JackAudioDevice::outputPorts()\n");
1899 std::list<QString> clientList;
1900 if(!checkJackClient(_client)) return clientList;
1901 const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
1902 const char** ports = jack_get_ports(_client, 0, type, JackPortIsOutput);
1903
1904 if(ports)
1905 {
1906 getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first.
1907 getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last.
1908 jack_free(ports);
1909 }
1910
1911 return clientList;
1912 }
1913
1914 //---------------------------------------------------------
1915 // inputPorts
1916 //---------------------------------------------------------
1917
inputPorts(bool midi,int aliases)1918 std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
1919 {
1920 DEBUG_JACK(stderr, "JackAudioDevice::inputPorts()\n");
1921
1922 std::list<QString> clientList;
1923 if(!checkJackClient(_client)) return clientList;
1924 const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
1925 const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput);
1926
1927 if(ports)
1928 {
1929 getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first.
1930 getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last.
1931 jack_free(ports);
1932 }
1933
1934 return clientList;
1935 }
1936
1937 //---------------------------------------------------------
1938 // setPortName
1939 //---------------------------------------------------------
1940
setPortName(void * p,const char * n)1941 void JackAudioDevice::setPortName(void* p, const char* n)
1942 {
1943 // NOTE: jack_port_set_name() is deprecated as of Jack2 = 1.9.11, and Jack1 > 0.124.1
1944 if(jack_port_rename_fp)
1945 {
1946 if(!checkJackClient(_client))
1947 return;
1948 jack_port_rename_fp(_client, (jack_port_t*)p, n);
1949 }
1950 else if(jack_port_set_name_fp)
1951 jack_port_set_name_fp((jack_port_t*)p, n);
1952 }
1953
1954 //---------------------------------------------------------
1955 // portName
1956 // Returns name of port and sets success.
1957 // This method consults a blacklist of client names,
1958 // such as "system:", whether to pick the name or
1959 // one of the aliases, whichever does NOT contain
1960 // the blacklist names.
1961 // preferred_name_or_alias: -1: No preference 0: Prefer canonical name 1: Prefer 1st alias 2: Prefer 2nd alias.
1962 //---------------------------------------------------------
1963
portName(void * port,char * str,int str_size,int preferred_name_or_alias)1964 char* JackAudioDevice::portName(void* port, char* str, int str_size, int preferred_name_or_alias)
1965 {
1966 bool A = false, B = false, C = false;
1967 const char* p_name = jack_port_name((jack_port_t*)port);
1968 if(p_name && p_name[0] != '\0')
1969 {
1970 // TODO: Make this a user editable blacklist of client names!
1971 if((strncmp(p_name, "system:", 7) != 0 && preferred_name_or_alias == -1) || preferred_name_or_alias == 0)
1972 return MusELib::strntcpy(str, p_name, str_size);
1973 A = true;
1974 }
1975
1976 int nsz = jack_port_name_size();
1977 char a1[nsz];
1978 char a2[nsz];
1979 char* al[2];
1980 al[0] = &a1[0];
1981 al[1] = &a2[0];
1982
1983 int na = jack_port_get_aliases((jack_port_t*)port, al);
1984 if(na >= 1 && *al[0] != '\0')
1985 {
1986 if((strncmp(al[0], "system:", 7) != 0 && preferred_name_or_alias == -1) || preferred_name_or_alias == 1)
1987 return MusELib::strntcpy(str, al[0], str_size);
1988 B = true;
1989 }
1990
1991 if(na >= 2 && *al[1] != '\0')
1992 {
1993 if((strncmp(al[1], "system:", 7) != 0 && preferred_name_or_alias == -1) || preferred_name_or_alias == 2)
1994 return MusELib::strntcpy(str, al[1], str_size);
1995 C = true;
1996 }
1997
1998 if(A)
1999 return MusELib::strntcpy(str, p_name, str_size);
2000 if(B)
2001 return MusELib::strntcpy(str, al[0], str_size);
2002 if(C)
2003 return MusELib::strntcpy(str, al[1], str_size);
2004
2005 return MusELib::strntcpy(str, p_name, str_size); // strntcpy accepts NULL source
2006
2007 }
2008
2009 //---------------------------------------------------------
2010 // portLatency
2011 // If capture is true get the capture latency,
2012 // otherwise get the playback latency.
2013 //---------------------------------------------------------
2014
portLatency(void * port,bool capture) const2015 unsigned int JackAudioDevice::portLatency(void* port, bool capture) const
2016 {
2017 if(!checkJackClient(_client) || !port)
2018 return 0;
2019
2020 //QString s(jack_port_name((jack_port_t*)port));
2021 //fprintf(stderr, "Jack::portName %p %s\n", port, s.toLatin1().constData());
2022
2023
2024 // NOTICE: For at least the ALSA driver (tested), the input latency is
2025 // always 1 period while the output latency is always n periods
2026 // (or n-1 periods for Jack1 or Jack2 Sync mode).
2027 // (Also there is the user latency from command line or QJackCtl.)
2028 // In other words, the Jack command line -p (number of periods) ONLY applies to audio output ports.
2029
2030 jack_latency_range_t p_range;
2031 jack_port_get_latency_range((jack_port_t*)port, JackPlaybackLatency, &p_range);
2032
2033 jack_latency_range_t c_range;
2034 jack_port_get_latency_range((jack_port_t*)port, JackCaptureLatency, &c_range);
2035
2036 //if(MusEGlobal::audio->isPlaying())
2037 // fprintf(stderr, "JackAudioDevice::portLatency port:%p capture:%d c_range.min:%d c_range.max:%d p_range.min:%d p_range.max:%d\n",
2038 // port, capture, c_range.min, c_range.max, p_range.min, p_range.max);
2039
2040 if(capture)
2041 return c_range.max;
2042
2043 return p_range.max;
2044
2045 // Hm... for speed, maybe cache the values?
2046 }
2047
2048 //---------------------------------------------------------
2049 // unregisterPort
2050 //---------------------------------------------------------
2051
unregisterPort(void * p)2052 void JackAudioDevice::unregisterPort(void* p)
2053 {
2054 DEBUG_JACK(stderr, "JackAudioDevice::unregisterPort(%p)\n", p);
2055 if(!checkJackClient(_client) || !p)
2056 return;
2057 // fprintf(stderr, "JACK: unregister Port\n");
2058 jack_port_unregister(_client, (jack_port_t*)p);
2059 }
2060
getDSP_Load()2061 float JackAudioDevice::getDSP_Load()
2062 {
2063 return jack_cpu_load(_client);
2064 }
2065
portType(void * p) const2066 AudioDevice::PortType JackAudioDevice::portType(void* p) const
2067 {
2068 if(!p)
2069 return UnknownType;
2070 if(const char* type = jack_port_type((jack_port_t*)p))
2071 {
2072 if(strcmp(type, JACK_DEFAULT_AUDIO_TYPE) == 0)
2073 return AudioPort;
2074 if(strcmp(type, JACK_DEFAULT_MIDI_TYPE) == 0)
2075 return MidiPort;
2076 }
2077 return UnknownType;
2078 }
2079
portDirection(void * p) const2080 AudioDevice::PortDirection JackAudioDevice::portDirection(void* p) const
2081 {
2082 if(!p)
2083 return UnknownDirection;
2084 const int flags = jack_port_flags((jack_port_t*)p);
2085 if(flags & JackPortIsInput)
2086 return InputPort;
2087 if(flags & JackPortIsOutput)
2088 return OutputPort;
2089 return UnknownDirection;
2090 }
2091
2092 //---------------------------------------------------------
2093 // setSyncTimeout
2094 // Sets the amount of time to wait before sync times out, in microseconds.
2095 // Note that at least with the Jack driver, this function seems not realtime friendly.
2096 //---------------------------------------------------------
2097
setSyncTimeout(unsigned usec)2098 void JackAudioDevice::setSyncTimeout(unsigned usec)
2099 {
2100 // Make sure our built-in transport sync timeout is set as well.
2101 AudioDevice::setSyncTimeout(usec);
2102
2103 if(!checkJackClient(_client)) return;
2104 // Note that docs say default is 2 sec, but that's wrong,
2105 // Jack1 does set 2 sec, but Jack2 sets a default of 10 secs !
2106 jack_set_sync_timeout(_client, usec);
2107 }
2108
2109 //---------------------------------------------------------
2110 // transportSyncToPlayDelay
2111 // The number of frames which the driver waits to switch to PLAY
2112 // mode after the audio sync function says it is ready to roll.
2113 // For example Jack Transport waits one cycle while our own transport does not.
2114 //---------------------------------------------------------
2115
transportSyncToPlayDelay() const2116 unsigned JackAudioDevice::transportSyncToPlayDelay() const
2117 {
2118 // If Jack transport is being used, it delays by one cycle.
2119 if(MusEGlobal::config.useJackTransport)
2120 return MusEGlobal::segmentSize;
2121 // Otherwise return our internal transport's value.
2122 return AudioDevice::transportSyncToPlayDelay();
2123 }
2124
transportRelocateOrPlayDelay() const2125 unsigned JackAudioDevice::transportRelocateOrPlayDelay() const
2126 {
2127 // If Jack transport is being used, it delays by two cycles.
2128 if(MusEGlobal::config.useJackTransport)
2129 return 2 * MusEGlobal::segmentSize;
2130 // Otherwise return our internal transport's value.
2131 return AudioDevice::transportRelocateOrPlayDelay();
2132 }
2133
2134 //---------------------------------------------------------
2135 // getState
2136 //---------------------------------------------------------
2137
getState()2138 int JackAudioDevice::getState()
2139 {
2140 // If we're not using Jack's transport, just return current state.
2141 if(!MusEGlobal::config.useJackTransport)
2142 {
2143 //pos.valid = jack_position_bits_t(0);
2144 //pos.frame = MusEGlobal::audio->pos().frame();
2145 //return MusEGlobal::audio->getState();
2146 //DEBUG_JACK(stderr, "JackAudioDevice::getState dummyState:%d\n", dummyState);
2147 return AudioDevice::getState();
2148 }
2149
2150 //DEBUG_JACK(stderr, "JackAudioDevice::getState ()\n");
2151 if(!checkJackClient(_client)) return 0;
2152 transportState = jack_transport_query(_client, &pos);
2153 //DEBUG_JACK(stderr, "JackAudioDevice::getState transportState:%d\n", transportState);
2154
2155 switch (int(transportState)) {
2156 case JackTransportStopped:
2157 return Audio::STOP;
2158 case JackTransportLooping:
2159 case JackTransportRolling:
2160 return Audio::PLAY;
2161 case JackTransportStarting:
2162 //fprintf(stderr, "JackAudioDevice::getState JackTransportStarting\n");
2163
2164 return Audio::START_PLAY;
2165 //case JackTransportNetStarting: -- only available in Jack-2!
2166 // FIXME: Quick and dirty hack to support both Jack-1 and Jack-2
2167 // Really need a config check of version...
2168 case 4:
2169 //fprintf(stderr, "JackAudioDevice::getState JackTransportNetStarting\n");
2170
2171 return Audio::START_PLAY;
2172 break;
2173 default:
2174 return Audio::STOP;
2175 }
2176 }
2177
2178 //---------------------------------------------------------
2179 // setFreewheel
2180 //---------------------------------------------------------
2181
setFreewheel(bool f)2182 void JackAudioDevice::setFreewheel(bool f)
2183 {
2184 DEBUG_JACK(stderr, "JackAudioDevice::setFreewheel(\n");
2185 if(!checkJackClient(_client)) return;
2186 jack_set_freewheel(_client, f);
2187 }
2188
2189 //---------------------------------------------------------
2190 // startTransport
2191 //---------------------------------------------------------
2192
startTransport()2193 void JackAudioDevice::startTransport()
2194 {
2195 DEBUG_JACK(stderr, "JackAudioDevice::startTransport()\n");
2196
2197 // If we're not using Jack's transport, just pass PLAY and current frame along
2198 // as if processSync was called.
2199 if(!MusEGlobal::config.useJackTransport)
2200 {
2201 AudioDevice::startTransport();
2202 return;
2203 }
2204
2205 if(!checkJackClient(_client)) return;
2206 // fprintf(stderr, "JACK: startTransport\n");
2207 jack_transport_start(_client);
2208 }
2209
2210 //---------------------------------------------------------
2211 // stopTransport
2212 //---------------------------------------------------------
2213
stopTransport()2214 void JackAudioDevice::stopTransport()
2215 {
2216 DEBUG_JACK(stderr, "JackAudioDevice::stopTransport()\n");
2217
2218 if(!MusEGlobal::config.useJackTransport)
2219 {
2220 AudioDevice::stopTransport();
2221 return;
2222 }
2223
2224 if(!checkJackClient(_client)) return;
2225 if (transportState != JackTransportStopped) {
2226 // fprintf(stderr, "JACK: stopTransport\n");
2227 jack_transport_stop(_client);
2228 transportState=JackTransportStopped;
2229 }
2230 }
2231
2232 //---------------------------------------------------------
2233 // seekTransport
2234 //---------------------------------------------------------
2235
seekTransport(unsigned frame)2236 void JackAudioDevice::seekTransport(unsigned frame)
2237 {
2238 DEBUG_JACK(stderr, "JackAudioDevice::seekTransport() frame:%d\n", frame);
2239
2240 if(!MusEGlobal::config.useJackTransport)
2241 {
2242 // STOP -> STOP means seek in stop mode. PLAY -> START_PLAY means seek in play mode.
2243 AudioDevice::seekTransport(frame);
2244 return;
2245 }
2246
2247 if(!checkJackClient(_client)) return;
2248 // fprintf(stderr, "JACK: seekTransport %d\n", frame);
2249 jack_transport_locate(_client, frame);
2250 }
2251
2252 //---------------------------------------------------------
2253 // seekTransport
2254 //---------------------------------------------------------
2255
seekTransport(const Pos & p)2256 void JackAudioDevice::seekTransport(const Pos &p)
2257 {
2258 DEBUG_JACK(stderr, "JackAudioDevice::seekTransport(Pos) frame:%d\n", p.frame());
2259
2260 if(!MusEGlobal::config.useJackTransport)
2261 {
2262 // STOP -> STOP means seek in stop mode. PLAY -> START_PLAY means seek in play mode.
2263 AudioDevice::seekTransport(p);
2264 return;
2265 }
2266
2267 if(!checkJackClient(_client)) return;
2268
2269 // TODO: Be friendly to other apps... Sadly not many of us use jack_transport_reposition.
2270 // This is actually required IF we want the extra position info to show up
2271 // in the sync callback, otherwise we get just the frame only.
2272 // This information is shared on the server, it is directly passed around.
2273 // jack_transport_locate blanks the info from sync until the timebase callback reads
2274 // it again right after, from some timebase master. See process in audio.cpp
2275
2276 // jack_position_t jp;
2277 // jp.frame = p.frame();
2278 //
2279 // jp.valid = JackPositionBBT;
2280 // p.mbt(&jp.bar, &jp.beat, &jp.tick);
2281 // jp.bar_start_tick = Pos(jp.bar, 0, 0).tick();
2282 // jp.bar++;
2283 // jp.beat++;
2284 // jp.beats_per_bar = 5; // TODO Make this correct !
2285 // jp.beat_type = 8; //
2286 // jp.ticks_per_beat = MusEGlobal::config.division;
2287 // int tempo = MusEGlobal::tempomap.tempo(p.tick());
2288 // jp.beats_per_minute = (60000000.0 / tempo) * MusEGlobal::tempomap.globalTempo()/100.0;
2289 // jack_transport_reposition(_client, &jp);
2290
2291 jack_transport_locate(_client, p.frame());
2292 }
2293
2294 //---------------------------------------------------------
2295 // findPort
2296 //---------------------------------------------------------
2297
findPort(const char * name)2298 void* JackAudioDevice::findPort(const char* name)
2299 {
2300 DEBUG_JACK(stderr, "JackAudioDevice::findPort(%s)\n", name);
2301 if(!checkJackClient(_client) || !name || name[0] == '\0')
2302 return NULL;
2303 void* p = jack_port_by_name(_client, name);
2304 return p;
2305 }
2306
2307 //---------------------------------------------------------
2308 // setMaster
2309 //---------------------------------------------------------
2310
setMaster(bool f,bool unconditional)2311 int JackAudioDevice::setMaster(bool f, bool unconditional)
2312 {
2313 // Check this one-time hack flag so that it forces master.
2314 // MusEGlobal::audioDevice may be NULL, esp. at startup when loading a song file,
2315 // so this flag is necessary for the next valid call to setMaster.
2316 if(MusEGlobal::timebaseMasterForceFlag)
2317 {
2318 unconditional = true;
2319 MusEGlobal::timebaseMasterForceFlag = false;
2320 }
2321
2322 DEBUG_JACK(stderr, "JackAudioDevice::setMaster val:%d unconditional:%d\n", f, unconditional);
2323 if(!checkJackClient(_client))
2324 return 0;
2325
2326 int r = 0;
2327 if(f)
2328 {
2329 if(MusEGlobal::config.useJackTransport)
2330 {
2331 // Make Muse the Jack timebase master. Possibly do it unconditionally (second param = 0).
2332 // Note that if we are already the timebase master, this will succeed and it will still
2333 // call the timebase callback once afterwards.
2334 r = jack_set_timebase_callback(_client, !unconditional, (JackTimebaseCallback) timebase_callback, 0);
2335 if(MusEGlobal::debugMsg || JACK_DEBUG)
2336 {
2337 if(r && !MusEGlobal::timebaseMasterState && unconditional)
2338 fprintf(stderr, "JackAudioDevice::setMaster jack_set_timebase_callback failed: result:%d\n", r);
2339 }
2340 if(!(bool)r != MusEGlobal::timebaseMasterState)
2341 {
2342 MusEGlobal::timebaseMasterState = !(bool)r;
2343 MusEGlobal::song->update(SC_TIMEBASE_MASTER);
2344 }
2345 }
2346 else
2347 {
2348 r = 1;
2349 fprintf(stderr, "JackAudioDevice::setMaster cannot set master because useJackTransport is false\n");
2350 if(MusEGlobal::timebaseMasterState)
2351 {
2352 MusEGlobal::timebaseMasterState = false;
2353 MusEGlobal::song->update(SC_TIMEBASE_MASTER);
2354 }
2355 }
2356 }
2357 else
2358 {
2359 r = jack_release_timebase(_client);
2360 if(MusEGlobal::debugMsg || JACK_DEBUG)
2361 {
2362 if(r && MusEGlobal::timebaseMasterState)
2363 fprintf(stderr, "JackAudioDevice::setMaster jack_release_timebase failed: result:%d\n", r);
2364 }
2365 if(!r && MusEGlobal::timebaseMasterState)
2366 {
2367 MusEGlobal::timebaseMasterState = false;
2368 MusEGlobal::song->update(SC_TIMEBASE_MASTER);
2369 }
2370 }
2371 return r;
2372 }
2373
2374 //---------------------------------------------------------
2375 // exitJackAudio
2376 //---------------------------------------------------------
2377
exitJackAudio()2378 void exitJackAudio()
2379 {
2380 DEBUG_JACK(stderr, "exitJackAudio()\n");
2381 if (jackAudio)
2382 delete jackAudio;
2383
2384 DEBUG_JACK(stderr, "exitJackAudio() after delete jackAudio\n");
2385
2386 MusEGlobal::audioDevice = NULL;
2387 muse_atomic_destroy(&atomicGraphChangedPending);
2388 }
2389
2390 } // namespace MusECore
2391
2392
2393