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