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