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