Revert "When writing '.jackdrc' make sure we enclose any device names in
[ardour.git] / libs / backends / jack / jack_utils.cc
1 /*
2     Copyright (C) 2010 Paul Davis
3     Copyright (C) 2011 Tim Mayberry
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #ifdef HAVE_ALSA
22 #include <alsa/asoundlib.h>
23 #endif
24
25 #ifdef __APPLE__
26 #include <CoreAudio/CoreAudio.h>
27 #include <CoreFoundation/CFString.h>
28 #include <sys/param.h>
29 #include <mach-o/dyld.h>
30 #endif
31
32 #ifdef PLATFORM_WINDOWS
33 #include <shobjidl.h>  //  Needed for
34 #include <shlguid.h>   // 'IShellLink'
35 #endif
36
37 #ifdef HAVE_PORTAUDIO
38 #include <portaudio.h>
39 #endif
40
41 #include <jack/jack.h>
42
43 #include <fstream>
44
45 #include <boost/scoped_ptr.hpp>
46
47 #include <glibmm/miscutils.h>
48
49 #include "pbd/epa.h"
50 #include "pbd/error.h"
51 #include "pbd/convert.h"
52 #include "pbd/file_utils.h"
53 #include "pbd/search_path.h"
54
55 #include "jack_utils.h"
56
57 #ifdef __APPLE
58 #include <CFBundle.h>
59 #endif
60
61 #include "i18n.h"
62
63 using namespace std;
64 using namespace PBD;
65
66 namespace ARDOUR {
67         // The pretty driver names
68         const char * const portaudio_driver_name = X_("Portaudio");
69         const char * const coreaudio_driver_name = X_("CoreAudio");
70         const char * const alsa_driver_name = X_("ALSA");
71         const char * const oss_driver_name = X_("OSS");
72         const char * const freebob_driver_name = X_("FreeBoB");
73         const char * const ffado_driver_name = X_("FFADO");
74         const char * const netjack_driver_name = X_("NetJACK");
75         const char * const dummy_driver_name = X_("Dummy");
76 }
77
78 namespace {
79
80         // The real driver names
81         const char * const portaudio_driver_command_line_name = X_("portaudio");
82         const char * const coreaudio_driver_command_line_name = X_("coreaudio");
83         const char * const alsa_driver_command_line_name = X_("alsa");
84         const char * const oss_driver_command_line_name = X_("oss");
85         const char * const freebob_driver_command_line_name = X_("freebob");
86         const char * const ffado_driver_command_line_name = X_("firewire");
87         const char * const netjack_driver_command_line_name = X_("netjack");
88         const char * const dummy_driver_command_line_name = X_("dummy");
89
90         // should we provide more "pretty" names like above?
91         const char * const alsa_seq_midi_driver_name = X_("alsa");
92         const char * const alsa_raw_midi_driver_name = X_("alsarawmidi");
93         const char * const alsaseq_midi_driver_name = X_("seq");
94         const char * const alsaraw_midi_driver_name = X_("raw");
95         const char * const winmme_midi_driver_name = X_("winmme");
96         const char * const coremidi_midi_driver_name = X_("coremidi");
97
98         // this should probably be translated
99         const char * const default_device_name = X_("Default");
100 }
101
102 static ARDOUR::MidiOptions midi_options;
103
104 std::string
105 get_none_string ()
106 {
107         return _("None");
108 }
109
110 void
111 ARDOUR::get_jack_audio_driver_names (vector<string>& audio_driver_names)
112 {
113 #ifdef PLATFORM_WINDOWS
114         audio_driver_names.push_back (portaudio_driver_name);
115 #elif __APPLE__
116         audio_driver_names.push_back (coreaudio_driver_name);
117 #else
118 #ifdef HAVE_ALSA
119         audio_driver_names.push_back (alsa_driver_name);
120 #endif
121         audio_driver_names.push_back (oss_driver_name);
122         audio_driver_names.push_back (freebob_driver_name);
123         audio_driver_names.push_back (ffado_driver_name);
124 #endif
125         audio_driver_names.push_back (netjack_driver_name);
126         audio_driver_names.push_back (dummy_driver_name);
127 }
128
129 void
130 ARDOUR::get_jack_default_audio_driver_name (string& audio_driver_name)
131 {
132         vector<string> drivers;
133         get_jack_audio_driver_names (drivers);
134         audio_driver_name = drivers.front ();
135 }
136
137 void
138 ARDOUR::get_jack_sample_rate_strings (vector<string>& samplerates)
139 {
140         // do these really need to be translated?
141         samplerates.push_back (_("8000Hz"));
142         samplerates.push_back (_("22050Hz"));
143         samplerates.push_back (_("44100Hz"));
144         samplerates.push_back (_("48000Hz"));
145         samplerates.push_back (_("88200Hz"));
146         samplerates.push_back (_("96000Hz"));
147         samplerates.push_back (_("192000Hz"));
148 }
149
150 string
151 ARDOUR::get_jack_default_sample_rate ()
152 {
153         return _("48000Hz");
154 }
155
156 void
157 ARDOUR::get_jack_period_size_strings (std::vector<std::string>& period_sizes)
158 {
159         period_sizes.push_back ("32");
160         period_sizes.push_back ("64");
161         period_sizes.push_back ("128");
162         period_sizes.push_back ("256");
163         period_sizes.push_back ("512");
164         period_sizes.push_back ("1024");
165         period_sizes.push_back ("2048");
166         period_sizes.push_back ("4096");
167         period_sizes.push_back ("8192");
168 }
169
170 string
171 ARDOUR::get_jack_default_period_size ()
172 {
173         return "1024";
174 }
175
176 void
177 ARDOUR::get_jack_dither_mode_strings (const string& driver, vector<string>& dither_modes)
178 {
179         dither_modes.push_back (get_none_string ());
180
181         if (driver == alsa_driver_name ) {
182                 dither_modes.push_back (_("Triangular"));
183                 dither_modes.push_back (_("Rectangular"));
184                 dither_modes.push_back (_("Shaped"));
185         }
186 }
187
188 string
189 ARDOUR::get_jack_default_dither_mode (const string& /*driver*/)
190 {
191         return get_none_string ();
192 }
193
194 string
195 ARDOUR::get_jack_latency_string (string samplerate, float periods, string period_size)
196 {
197         uint32_t rate = atoi (samplerate);
198         float psize = atof (period_size);
199
200         char buf[32];
201         snprintf (buf, sizeof(buf), "%.1fmsec", (periods * psize) / (rate/1000.0));
202
203         return buf;
204 }
205
206 bool
207 get_jack_command_line_audio_driver_name (const string& driver_name, string& command_line_name)
208 {
209         using namespace ARDOUR;
210         if (driver_name == portaudio_driver_name) {
211                 command_line_name = portaudio_driver_command_line_name;
212                 return true;
213         } else if (driver_name == coreaudio_driver_name) {
214                 command_line_name = coreaudio_driver_command_line_name;
215                 return true;
216         } else if (driver_name == alsa_driver_name) {
217                 command_line_name = alsa_driver_command_line_name;
218                 return true;
219         } else if (driver_name == oss_driver_name) {
220                 command_line_name = oss_driver_command_line_name;
221                 return true;
222         } else if (driver_name == freebob_driver_name) {
223                 command_line_name = freebob_driver_command_line_name;
224                 return true;
225         } else if (driver_name == ffado_driver_name) {
226                 command_line_name = ffado_driver_command_line_name;
227                 return true;
228         } else if (driver_name == netjack_driver_name) {
229                 command_line_name = netjack_driver_command_line_name;
230                 return true;
231         } else if (driver_name == dummy_driver_name) {
232                 command_line_name = dummy_driver_command_line_name;
233                 return true;
234         }
235         return false;
236 }
237
238 bool
239 get_jack_command_line_audio_device_name (const string& driver_name,
240                 const string& device_name, string& command_line_device_name)
241 {
242         using namespace ARDOUR;
243         device_map_t devices;
244
245         get_jack_device_names_for_audio_driver (driver_name, devices);
246
247         for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) {
248                 if (i->first == device_name) {
249                         command_line_device_name = i->second;
250                         return true;
251                 }
252         }
253         return false;
254 }
255
256 bool
257 get_jack_command_line_dither_mode (const string& dither_mode, string& command_line_dither_mode)
258 {
259         using namespace ARDOUR;
260
261         if (dither_mode == _("Triangular")) {
262                 command_line_dither_mode = "triangular";
263                 return true;
264         } else if (dither_mode == _("Rectangular")) {
265                 command_line_dither_mode = "rectangular";
266                 return true;
267         } else if (dither_mode == _("Shaped")) {
268                 command_line_dither_mode = "shaped";
269                 return true;
270         }
271
272         return false;
273 }
274
275 void
276 ARDOUR::get_jack_alsa_device_names (device_map_t& devices)
277 {
278 #ifdef HAVE_ALSA
279         snd_ctl_t *handle;
280         snd_ctl_card_info_t *info;
281         snd_pcm_info_t *pcminfo;
282         snd_ctl_card_info_alloca(&info);
283         snd_pcm_info_alloca(&pcminfo);
284         string devname;
285         int cardnum = -1;
286         int device = -1;
287
288         while (snd_card_next (&cardnum) >= 0 && cardnum >= 0) {
289
290                 devname = "hw:";
291                 devname += PBD::to_string (cardnum, std::dec);
292
293                 if (snd_ctl_open (&handle, devname.c_str(), 0) >= 0 && snd_ctl_card_info (handle, info) >= 0) {
294
295                         if (snd_ctl_card_info (handle, info) < 0) {
296                                 continue;
297                         }
298                         
299                         string card_name = snd_ctl_card_info_get_name (info);
300
301                         /* change devname to use ID, not number */
302
303                         devname = "hw:";
304                         devname += snd_ctl_card_info_get_id (info);
305
306                         while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) {
307                                 
308                                 /* only detect duplex devices here. more
309                                  * complex arrangements are beyond our scope
310                                  */
311
312                                 snd_pcm_info_set_device (pcminfo, device);
313                                 snd_pcm_info_set_subdevice (pcminfo, 0);
314                                 snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_CAPTURE);
315                                 
316                                 if (snd_ctl_pcm_info (handle, pcminfo) >= 0) {
317
318                                         snd_pcm_info_set_device (pcminfo, device);
319                                         snd_pcm_info_set_subdevice (pcminfo, 0);
320                                         snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_PLAYBACK);
321
322                                         if (snd_ctl_pcm_info (handle, pcminfo) >= 0) {
323                                                 devname += ',';
324                                                 devname += PBD::to_string (device, std::dec);
325                                                 devices.insert (std::make_pair (card_name, devname));
326                                         }
327                                 }
328                         }
329
330                         snd_ctl_close(handle);
331                 }
332         }
333 #else
334         /* silence a compiler unused variable warning */
335         (void) devices;
336 #endif
337 }
338
339 #ifdef __APPLE__
340 static OSStatus
341 getDeviceUIDFromID( AudioDeviceID id, char *name, size_t nsize)
342 {
343         UInt32 size = sizeof(CFStringRef);
344         CFStringRef UI;
345         OSStatus res = AudioDeviceGetProperty(id, 0, false,
346                 kAudioDevicePropertyDeviceUID, &size, &UI);
347         if (res == noErr)
348                 CFStringGetCString(UI,name,nsize,CFStringGetSystemEncoding());
349         CFRelease(UI);
350         return res;
351 }
352 #endif
353
354 void
355 ARDOUR::get_jack_coreaudio_device_names (device_map_t& devices)
356 {
357 #ifdef __APPLE__
358         // Find out how many Core Audio devices are there, if any...
359         // (code snippet gently "borrowed" from St?hane Letz jackdmp;)
360         OSStatus err;
361         Boolean isWritable;
362         UInt32 outSize = sizeof(isWritable);
363
364         err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
365                                            &outSize, &isWritable);
366         if (err == noErr) {
367                 // Calculate the number of device available...
368                 int numCoreDevices = outSize / sizeof(AudioDeviceID);
369                 // Make space for the devices we are about to get...
370                 AudioDeviceID *coreDeviceIDs = new AudioDeviceID [numCoreDevices];
371                 err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
372                                                &outSize, (void *) coreDeviceIDs);
373                 if (err == noErr) {
374                         // Look for the CoreAudio device name...
375                         char coreDeviceName[256];
376                         UInt32 nameSize;
377
378                         for (int i = 0; i < numCoreDevices; i++) {
379
380                                 nameSize = sizeof (coreDeviceName);
381
382                                 /* enforce duplex devices only */
383
384                                 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
385                                                                  0, true, kAudioDevicePropertyStreams,
386                                                                  &outSize, &isWritable);
387
388                                 if (err != noErr || outSize == 0) {
389                                         continue;
390                                 }
391
392                                 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
393                                                                  0, false, kAudioDevicePropertyStreams,
394                                                                  &outSize, &isWritable);
395
396                                 if (err != noErr || outSize == 0) {
397                                         continue;
398                                 }
399
400                                 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
401                                                                  0, true, kAudioDevicePropertyDeviceName,
402                                                                  &outSize, &isWritable);
403                                 if (err == noErr) {
404                                         err = AudioDeviceGetProperty(coreDeviceIDs[i],
405                                                                      0, true, kAudioDevicePropertyDeviceName,
406                                                                      &nameSize, (void *) coreDeviceName);
407                                         if (err == noErr) {
408                                                 char drivername[128];
409
410                                                 // this returns the unique id for the device
411                                                 // that must be used on the commandline for jack
412
413                                                 if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) {
414                                                         devices.insert (make_pair (coreDeviceName, drivername));
415                                                 }
416                                         }
417                                 }
418                         }
419                 }
420                 delete [] coreDeviceIDs;
421         }
422 #else
423         /* silence a compiler unused variable warning */
424         (void) devices;
425 #endif
426 }
427
428 void
429 ARDOUR::get_jack_portaudio_device_names (device_map_t& devices)
430 {
431 #ifdef HAVE_PORTAUDIO
432         if (Pa_Initialize() != paNoError) {
433                 return;
434         }
435
436         for (PaDeviceIndex i = 0; i < Pa_GetDeviceCount (); ++i) {
437                 string api_name;
438                 string readable_name;
439                 string jack_device_name;
440                 const PaDeviceInfo* device_info = Pa_GetDeviceInfo(i);
441
442                 if (device_info != NULL) { // it should never be ?
443                         api_name = Pa_GetHostApiInfo (device_info->hostApi)->name;
444                         readable_name = api_name + " " + device_info->name;
445                         jack_device_name = api_name + "::" + device_info->name;
446                         devices.insert (make_pair (readable_name, jack_device_name));
447                 }
448         }
449         Pa_Terminate();
450 #else
451         /* silence a compiler unused variable warning */
452         (void) devices;
453 #endif
454 }
455
456 void
457 ARDOUR::get_jack_oss_device_names (device_map_t& devices)
458 {
459         devices.insert (make_pair (default_device_name, default_device_name));
460 }
461
462 void
463 ARDOUR::get_jack_freebob_device_names (device_map_t& devices)
464 {
465         devices.insert (make_pair (default_device_name, default_device_name));
466 }
467
468 void
469 ARDOUR::get_jack_ffado_device_names (device_map_t& devices)
470 {
471         devices.insert (make_pair (default_device_name, default_device_name));
472 }
473
474 void
475 ARDOUR::get_jack_netjack_device_names (device_map_t& devices)
476 {
477         devices.insert (make_pair (default_device_name, default_device_name));
478 }
479
480 void
481 ARDOUR::get_jack_dummy_device_names (device_map_t& devices)
482 {
483         devices.insert (make_pair (default_device_name, default_device_name));
484 }
485
486 bool
487 ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name, device_map_t& devices)
488 {
489         devices.clear();
490
491         if (driver_name == portaudio_driver_name) {
492                 get_jack_portaudio_device_names (devices);
493         } else if (driver_name == coreaudio_driver_name) {
494                 get_jack_coreaudio_device_names (devices);
495         } else if (driver_name == alsa_driver_name) {
496                 get_jack_alsa_device_names (devices);
497         } else if (driver_name == oss_driver_name) {
498                 get_jack_oss_device_names (devices);
499         } else if (driver_name == freebob_driver_name) {
500                 get_jack_freebob_device_names (devices);
501         } else if (driver_name == ffado_driver_name) {
502                 get_jack_ffado_device_names (devices);
503         } else if (driver_name == netjack_driver_name) {
504                 get_jack_netjack_device_names (devices);
505         } else if (driver_name == dummy_driver_name) {
506                 get_jack_dummy_device_names (devices);
507         }
508
509         return !devices.empty();
510 }
511
512
513 std::vector<std::string>
514 ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name)
515 {
516         std::vector<std::string> readable_names;
517         device_map_t devices;
518
519         get_jack_device_names_for_audio_driver (driver_name, devices);
520
521         for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) {
522                 readable_names.push_back (i->first);
523         }
524
525         return readable_names;
526 }
527
528 bool
529 ARDOUR::get_jack_audio_driver_supports_two_devices (const string& driver)
530 {
531         return (driver == alsa_driver_name || driver == oss_driver_name);
532 }
533
534 bool
535 ARDOUR::get_jack_audio_driver_supports_latency_adjustment (const string& driver)
536 {
537         return (driver == alsa_driver_name || driver == coreaudio_driver_name ||
538                         driver == ffado_driver_name || driver == portaudio_driver_name);
539 }
540
541 bool
542 ARDOUR::get_jack_audio_driver_supports_setting_period_count (const string& driver)
543 {
544         return !(driver == dummy_driver_name || driver == coreaudio_driver_name ||
545                         driver == portaudio_driver_name);
546 }
547
548 bool
549 ARDOUR::get_jack_server_application_names (std::vector<std::string>& server_names)
550 {
551 #ifdef PLATFORM_WINDOWS
552         server_names.push_back ("jackd.exe");
553 #else
554         server_names.push_back ("jackd");
555         server_names.push_back ("jackdmp");
556 #endif
557         return !server_names.empty();
558 }
559
560 void
561 ARDOUR::set_path_env_for_jack_autostart (const vector<std::string>& dirs)
562 {
563 #ifdef __APPLE__
564         // push it back into the environment so that auto-started JACK can find it.
565         // XXX why can't we just expect OS X users to have PATH set correctly? we can't ...
566         setenv ("PATH", Searchpath(dirs).to_string().c_str(), 1);
567 #else
568         /* silence a compiler unused variable warning */
569         (void) dirs;
570 #endif
571 }
572
573 bool
574 ARDOUR::get_jack_server_dir_paths (vector<std::string>& server_dir_paths)
575 {
576 #ifdef __APPLE__
577         /* this magic lets us finds the path to the OSX bundle, and then
578            we infer JACK's location from there
579         */
580
581         char execpath[MAXPATHLEN+1];
582         uint32_t pathsz = sizeof (execpath);
583
584         _NSGetExecutablePath (execpath, &pathsz);
585
586         server_dir_paths.push_back (Glib::path_get_dirname (execpath));
587 #endif
588
589         Searchpath sp(string(g_getenv("PATH")));
590
591 #ifdef PLATFORM_WINDOWS
592 // N.B. The #define (immediately below) can be safely removed once we know that this code builds okay with mingw
593 #ifdef COMPILER_MSVC
594         IShellLinkA  *pISL = NULL;    
595         IPersistFile *ppf  = NULL;
596
597         // Mixbus creates a Windows shortcut giving the location of its
598         // own (bundled) version of Jack. Let's see if that shortcut exists
599         if (SUCCEEDED (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL)))
600         {
601                 if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
602                 {
603                         char  target_path[MAX_PATH];
604                         char  shortcut_pathA[MAX_PATH];
605                         WCHAR shortcut_pathW[MAX_PATH];
606
607                         // Our Windows installer should have created a shortcut to the Jack
608                         // server so let's start by finding out what drive it got installed on
609                         if (char *env_path = getenv ("windir"))
610                         {
611                                 strcpy (shortcut_pathA, env_path);
612                                 shortcut_pathA[2] = '\0'; // Gives us just the drive letter and colon
613                         }
614                         else // Assume 'C:'
615                                 strcpy (shortcut_pathA, "C:");
616
617                         strcat (shortcut_pathA, "\\Program Files (x86)\\Jack\\Start Jack.lnk");
618
619                         MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut_pathA, -1, shortcut_pathW, MAX_PATH);
620
621                         // If it did, load the shortcut into our persistent file
622                         if (SUCCEEDED (ppf->Load(shortcut_pathW, 0)))
623                         {
624                                 // Read the target information from the shortcut object
625                                 if (S_OK == (pISL->GetPath (target_path, MAX_PATH, NULL, SLGP_UNCPRIORITY)))
626                                 {
627                                         char *p = strrchr (target_path, '\\');
628
629                                         if (p)
630                                         {
631                                                 *p = NULL;
632                                                 sp.push_back (target_path);
633                                         }
634                                 }
635                         }
636                 }
637         }
638
639         if (ppf)
640                 ppf->Release();
641
642         if (pISL)
643                 pISL->Release();
644 #endif
645
646         gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL);
647         if (install_dir) {
648                 sp.push_back (install_dir);
649                 g_free (install_dir);
650         }
651         // don't try and use a system wide JACK install yet.
652 #else
653         if (sp.empty()) {
654                 sp.push_back ("/usr/bin");
655                 sp.push_back ("/bin");
656                 sp.push_back ("/usr/local/bin");
657                 sp.push_back ("/opt/local/bin");
658         }
659 #endif
660
661         std::copy (sp.begin(), sp.end(), std::back_inserter(server_dir_paths));
662
663         return !server_dir_paths.empty();
664 }
665
666 bool
667 ARDOUR::get_jack_server_paths (const vector<std::string>& server_dir_paths,
668                 const vector<string>& server_names,
669                 vector<std::string>& server_paths)
670 {
671         for (vector<string>::const_iterator i = server_names.begin(); i != server_names.end(); ++i) {
672                 Glib::PatternSpec ps (*i);
673                 find_matching_files_in_directories (server_dir_paths, ps, server_paths);
674         }
675         return !server_paths.empty();
676 }
677
678 bool
679 ARDOUR::get_jack_server_paths (vector<std::string>& server_paths)
680 {
681         vector<std::string> server_dirs;
682
683         if (!get_jack_server_dir_paths (server_dirs)) {
684                 return false;
685         }
686
687         vector<string> server_names;
688
689         if (!get_jack_server_application_names (server_names)) {
690                 return false;
691         }
692
693         if (!get_jack_server_paths (server_dirs, server_names, server_paths)) {
694                 return false;
695         }
696
697         return !server_paths.empty();
698 }
699
700 bool
701 ARDOUR::get_jack_default_server_path (std::string& server_path)
702 {
703         vector<std::string> server_paths;
704
705         if (!get_jack_server_paths (server_paths)) {
706                 return false;
707         }
708
709         server_path = server_paths.front ();
710         return true;
711 }
712
713 string
714 quote_string (const string& str)
715 {
716         return "\"" + str + "\"";
717 }
718
719 ARDOUR::JackCommandLineOptions::JackCommandLineOptions ()
720         : server_path ()
721         , timeout(0)
722         , no_mlock(false)
723         , ports_max(128)
724         , realtime(true)
725         , priority(0)
726         , unlock_gui_libs(false)
727         , verbose(false)
728         , temporary(true)
729         , driver()
730         , input_device()
731         , output_device()
732         , num_periods(2)
733         , period_size(1024)
734         , samplerate(48000)
735         , input_latency(0)
736         , output_latency(0)
737         , hardware_metering(false)
738         , hardware_monitoring(false)
739         , dither_mode()
740         , force16_bit(false)
741         , soft_mode(false)
742         , midi_driver()
743 {
744
745 }
746
747 bool
748 ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line, bool for_latency_measurement)
749 {
750         vector<string> args;
751
752         args.push_back (options.server_path);
753
754 #ifdef PLATFORM_WINDOWS
755         // must use sync mode on windows
756         args.push_back ("-S");
757
758         // this needs to be added now on windows
759         if (!options.midi_driver.empty () && options.midi_driver != get_none_string ()) {
760                 args.push_back ("-X");
761                 args.push_back (options.midi_driver);
762         }
763 #endif
764
765         /* XXX hack to enforce qjackctl-like behaviour */
766         if (options.timeout == 0) {
767                 options.timeout = 200;
768         }
769
770         if (options.timeout) {
771                 args.push_back ("-t");
772                 args.push_back (to_string (options.timeout, std::dec));
773         }
774
775         if (options.no_mlock) {
776                 args.push_back ("-m");
777         }
778
779         args.push_back ("-p");
780         args.push_back (to_string(options.ports_max, std::dec));
781
782         if (options.realtime) {
783                 args.push_back ("-R");
784                 if (options.priority != 0) {
785                         args.push_back ("-P");
786                         args.push_back (to_string(options.priority, std::dec));
787                 }
788         } else {
789                 args.push_back ("-r");
790         }
791
792         if (options.unlock_gui_libs) {
793                 args.push_back ("-u");
794         }
795
796         if (options.verbose) {
797                 args.push_back ("-v");
798         }
799
800         if (options.temporary) {
801                 args.push_back ("-T");
802         }
803
804         if (options.driver == alsa_driver_name) {
805                 if (options.midi_driver == alsa_seq_midi_driver_name) {
806                         args.push_back ("-X");
807                         args.push_back ("alsa_midi");
808                 } else if (options.midi_driver == alsa_raw_midi_driver_name) {
809                         args.push_back ("-X");
810                         args.push_back ("alsarawmidi");
811                 }
812         }
813
814         string command_line_driver_name;
815
816         string command_line_input_device_name;
817         string command_line_output_device_name;
818
819         if (!get_jack_command_line_audio_driver_name (options.driver, command_line_driver_name)) {
820                 return false;
821         }
822
823         args.push_back ("-d");
824         args.push_back (command_line_driver_name);
825
826         if (options.driver != dummy_driver_name) {
827                 if (options.output_device.empty() && options.input_device.empty()) {
828                         return false;
829                 }
830
831
832                 if (!get_jack_command_line_audio_device_name (options.driver,
833                                         options.input_device, command_line_input_device_name)) {
834                         return false;
835                 }
836
837                 if (!get_jack_command_line_audio_device_name (options.driver,
838                                         options.output_device, command_line_output_device_name)) {
839                         return false;
840                 }
841
842                 if (options.input_device.empty()) {
843                         // playback only
844                         if (options.output_device.empty()) {
845                                 return false;
846                         }
847                         args.push_back ("-P");
848                 } else if (options.output_device.empty()) {
849                         // capture only
850                         if (options.input_device.empty()) {
851                                 return false;
852                         }
853                         args.push_back ("-C");
854                 } else if (options.input_device != options.output_device) {
855                         // capture and playback on two devices if supported
856                         if (get_jack_audio_driver_supports_two_devices (options.driver)) {
857                                 args.push_back ("-C");
858                                 args.push_back (command_line_input_device_name);
859                                 args.push_back ("-P");
860                                 args.push_back (command_line_output_device_name);
861                         } else {
862                                 return false;
863                         }
864                 }
865
866                 if (options.input_channels) {
867                         args.push_back ("-i");
868                         args.push_back (to_string (options.input_channels, std::dec));
869                 }
870
871                 if (options.output_channels) {
872                         args.push_back ("-o");
873                         args.push_back (to_string (options.output_channels, std::dec));
874                 }
875
876                 if (get_jack_audio_driver_supports_setting_period_count (options.driver)) {
877                         args.push_back ("-n");
878                         args.push_back (to_string (options.num_periods, std::dec));
879                 }
880         } else {
881                 // jackd dummy backend
882                 if (options.input_channels) {
883                         args.push_back ("-C");
884                         args.push_back (to_string (options.input_channels, std::dec));
885                 }
886
887                 if (options.output_channels) {
888                         args.push_back ("-P");
889                         args.push_back (to_string (options.output_channels, std::dec));
890                 }
891         }
892
893         args.push_back ("-r");
894         args.push_back (to_string (options.samplerate, std::dec));
895
896         args.push_back ("-p");
897         args.push_back (to_string (options.period_size, std::dec));
898
899         if (!for_latency_measurement && get_jack_audio_driver_supports_latency_adjustment (options.driver)) {
900                 if (options.input_latency) {
901                         args.push_back ("-I");
902                         args.push_back (to_string (options.input_latency, std::dec));
903                 }
904                 if (options.output_latency) {
905                         args.push_back ("-O");
906                         args.push_back (to_string (options.output_latency, std::dec));
907                 }
908         }
909
910         if (options.driver != dummy_driver_name) {
911                 if (options.input_device == options.output_device && options.input_device != default_device_name) {
912                         args.push_back ("-d");
913                         args.push_back (command_line_input_device_name);
914                 }
915         }
916
917         if (options.driver == alsa_driver_name) {
918                 if (options.hardware_metering) {
919                         args.push_back ("-M");
920                 }
921                 if (options.hardware_monitoring) {
922                         args.push_back ("-H");
923                 }
924
925                 string command_line_dither_mode;
926                 if (get_jack_command_line_dither_mode (options.dither_mode, command_line_dither_mode)) {
927                         args.push_back ("-z");
928                         args.push_back (command_line_dither_mode);
929                 }
930                 if (options.force16_bit) {
931                         args.push_back ("-S");
932                 }
933                 if (options.soft_mode) {
934                         args.push_back ("-s");
935                 }
936         }
937
938         if (options.driver == alsa_driver_name || options.driver == coreaudio_driver_name) {
939
940                 if (options.midi_driver != alsa_seq_midi_driver_name) {
941                         if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) {
942                                 args.push_back ("-X");
943                                 args.push_back (options.midi_driver);
944                         }
945                 }
946         }
947
948         ostringstream oss;
949
950         for (vector<string>::const_iterator i = args.begin(); i != args.end();) {
951                 oss << *i;
952                 if (++i != args.end()) oss << ' ';
953         }
954
955         command_line = oss.str();
956         return true;
957 }
958
959 string
960 ARDOUR::get_jack_server_config_file_name ()
961 {
962         return ".jackdrc";
963 }
964
965 std::string
966 ARDOUR::get_jack_server_user_config_dir_path ()
967 {
968         return Glib::get_home_dir ();
969 }
970
971 std::string
972 ARDOUR::get_jack_server_user_config_file_path ()
973 {
974         return Glib::build_filename (get_jack_server_user_config_dir_path (), get_jack_server_config_file_name ());
975 }
976
977 bool
978 ARDOUR::write_jack_config_file (const std::string& config_file_path, const string& command_line)
979 {
980         ofstream jackdrc (config_file_path.c_str());
981
982         if (!jackdrc) {
983                 error << string_compose (_("cannot open JACK rc file %1 to store parameters"), config_file_path) << endmsg;
984                 return false;
985         }
986
987         jackdrc << command_line << endl;
988         jackdrc.close ();
989         return true;
990 }
991
992 vector<string>
993 ARDOUR::enumerate_midi_options () 
994 {
995         if (midi_options.empty()) {
996 #ifdef HAVE_ALSA
997                 midi_options.push_back (make_pair (_("(legacy) ALSA raw devices"), alsaraw_midi_driver_name));
998                 midi_options.push_back (make_pair (_("(legacy) ALSA sequencer"), alsaseq_midi_driver_name));
999                 midi_options.push_back (make_pair (_("ALSA (JACK1, 0.124 and later)"), alsa_seq_midi_driver_name));
1000                 midi_options.push_back (make_pair (_("ALSA (JACK2, 1.9.8 and later)"), alsa_raw_midi_driver_name));
1001 #endif
1002 #ifdef HAVE_PORTAUDIO
1003                 /* Windows folks: what name makes sense here? Are there other
1004                    choices as well ?
1005                 */
1006                 midi_options.push_back (make_pair (_("Multimedia Extension"), winmme_midi_driver_name));
1007 #endif
1008 #ifdef __APPLE__
1009                 midi_options.push_back (make_pair (_("CoreMIDI"), coremidi_midi_driver_name));
1010 #endif
1011         }
1012
1013         vector<string> v;
1014
1015         v.push_back (get_none_string());
1016
1017         for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) {
1018                 v.push_back (i->first);
1019         }
1020
1021         return v;
1022 }
1023
1024 int
1025 ARDOUR::set_midi_option (ARDOUR::JackCommandLineOptions& options, const string& opt)
1026 {
1027         if (opt.empty() || opt == get_none_string()) {
1028                 options.midi_driver = "";
1029                 return 0;
1030         }
1031
1032         for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) {
1033                 if (i->first == opt) {
1034                         options.midi_driver = i->second;
1035                         return 0;
1036                 }
1037         }
1038
1039         return -1;
1040 }
1041