2 Copyright (C) 2010 Paul Davis
3 Copyright (C) 2011 Tim Mayberry
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.
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.
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.
22 #include "ardouralsautil/devicelist.h"
26 #include <CoreAudio/CoreAudio.h>
27 #include <CoreFoundation/CFString.h>
28 #include <sys/param.h>
29 #include <mach-o/dyld.h>
32 #ifdef PLATFORM_WINDOWS
33 #include <shobjidl.h> // Needed for
34 #include <shlguid.h> // 'IShellLink'
37 #if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO)
38 #include <portaudio.h>
41 #include <boost/scoped_ptr.hpp>
43 #include "pbd/gstdio_compat.h"
44 #include <glibmm/miscutils.h>
47 #include "pbd/error.h"
48 #include "pbd/convert.h"
49 #include "pbd/file_utils.h"
50 #include "pbd/search_path.h"
52 #include "jack_utils.h"
64 // The pretty driver names
65 const char * const portaudio_driver_name = X_("Portaudio");
66 const char * const coreaudio_driver_name = X_("CoreAudio");
67 const char * const alsa_driver_name = X_("ALSA");
68 const char * const oss_driver_name = X_("OSS");
69 const char * const freebob_driver_name = X_("FreeBoB");
70 const char * const ffado_driver_name = X_("FFADO");
71 const char * const netjack_driver_name = X_("NetJACK");
72 const char * const dummy_driver_name = X_("Dummy");
77 // The real driver names
78 const char * const portaudio_driver_command_line_name = X_("portaudio");
79 const char * const coreaudio_driver_command_line_name = X_("coreaudio");
80 const char * const alsa_driver_command_line_name = X_("alsa");
81 const char * const oss_driver_command_line_name = X_("oss");
82 const char * const freebob_driver_command_line_name = X_("freebob");
83 const char * const ffado_driver_command_line_name = X_("firewire");
84 const char * const netjack_driver_command_line_name = X_("netjack");
85 const char * const dummy_driver_command_line_name = X_("dummy");
87 // should we provide more "pretty" names like above?
88 const char * const alsa_seq_midi_driver_name = X_("alsa");
89 const char * const alsa_raw_midi_driver_name = X_("alsarawmidi");
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");
95 // this should probably be translated
96 const char * const default_device_name = X_("Default");
99 static ARDOUR::MidiOptions midi_options;
108 ARDOUR::get_jack_audio_driver_names (vector<string>& audio_driver_names)
110 #ifdef PLATFORM_WINDOWS
111 audio_driver_names.push_back (portaudio_driver_name);
113 audio_driver_names.push_back (coreaudio_driver_name);
116 audio_driver_names.push_back (alsa_driver_name);
118 audio_driver_names.push_back (oss_driver_name);
119 audio_driver_names.push_back (freebob_driver_name);
120 audio_driver_names.push_back (ffado_driver_name);
122 audio_driver_names.push_back (netjack_driver_name);
123 audio_driver_names.push_back (dummy_driver_name);
127 ARDOUR::get_jack_default_audio_driver_name (string& audio_driver_name)
129 vector<string> drivers;
130 get_jack_audio_driver_names (drivers);
131 audio_driver_name = drivers.front ();
135 ARDOUR::get_jack_sample_rate_strings (vector<string>& samplerates)
137 // do these really need to be translated?
138 samplerates.push_back (_("8000Hz"));
139 samplerates.push_back (_("22050Hz"));
140 samplerates.push_back (_("44100Hz"));
141 samplerates.push_back (_("48000Hz"));
142 samplerates.push_back (_("88200Hz"));
143 samplerates.push_back (_("96000Hz"));
144 samplerates.push_back (_("192000Hz"));
148 ARDOUR::get_jack_default_sample_rate ()
154 ARDOUR::get_jack_period_size_strings (std::vector<std::string>& period_sizes)
156 period_sizes.push_back ("32");
157 period_sizes.push_back ("64");
158 period_sizes.push_back ("128");
159 period_sizes.push_back ("256");
160 period_sizes.push_back ("512");
161 period_sizes.push_back ("1024");
162 period_sizes.push_back ("2048");
163 period_sizes.push_back ("4096");
164 period_sizes.push_back ("8192");
168 ARDOUR::get_jack_default_period_size ()
174 ARDOUR::get_jack_dither_mode_strings (const string& driver, vector<string>& dither_modes)
176 dither_modes.push_back (get_none_string ());
178 if (driver == alsa_driver_name ) {
179 dither_modes.push_back (_("Triangular"));
180 dither_modes.push_back (_("Rectangular"));
181 dither_modes.push_back (_("Shaped"));
186 ARDOUR::get_jack_default_dither_mode (const string& /*driver*/)
188 return get_none_string ();
192 ARDOUR::get_jack_latency_string (string samplerate, float periods, string period_size)
194 uint32_t rate = atoi (samplerate);
195 float psize = atof (period_size);
198 snprintf (buf, sizeof(buf), "%.1fmsec", (periods * psize) / (rate/1000.0));
204 get_jack_command_line_audio_driver_name (const string& driver_name, string& command_line_name)
206 using namespace ARDOUR;
207 if (driver_name == portaudio_driver_name) {
208 command_line_name = portaudio_driver_command_line_name;
210 } else if (driver_name == coreaudio_driver_name) {
211 command_line_name = coreaudio_driver_command_line_name;
213 } else if (driver_name == alsa_driver_name) {
214 command_line_name = alsa_driver_command_line_name;
216 } else if (driver_name == oss_driver_name) {
217 command_line_name = oss_driver_command_line_name;
219 } else if (driver_name == freebob_driver_name) {
220 command_line_name = freebob_driver_command_line_name;
222 } else if (driver_name == ffado_driver_name) {
223 command_line_name = ffado_driver_command_line_name;
225 } else if (driver_name == netjack_driver_name) {
226 command_line_name = netjack_driver_command_line_name;
228 } else if (driver_name == dummy_driver_name) {
229 command_line_name = dummy_driver_command_line_name;
236 get_jack_command_line_audio_device_name (const string& driver_name,
237 const string& device_name, string& command_line_device_name)
239 using namespace ARDOUR;
240 device_map_t devices;
242 get_jack_device_names_for_audio_driver (driver_name, devices);
244 for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) {
245 if (i->first == device_name) {
246 command_line_device_name = i->second;
254 get_jack_command_line_dither_mode (const string& dither_mode, string& command_line_dither_mode)
256 using namespace ARDOUR;
258 if (dither_mode == _("Triangular")) {
259 command_line_dither_mode = "triangular";
261 } else if (dither_mode == _("Rectangular")) {
262 command_line_dither_mode = "rectangular";
264 } else if (dither_mode == _("Shaped")) {
265 command_line_dither_mode = "shaped";
273 ARDOUR::get_jack_alsa_device_names (device_map_t& devices)
276 get_alsa_audio_device_names(devices);
278 /* silence a compiler unused variable warning */
285 getDeviceUIDFromID( AudioDeviceID id, char *name, size_t nsize)
287 UInt32 size = sizeof(CFStringRef);
289 OSStatus res = AudioDeviceGetProperty(id, 0, false,
290 kAudioDevicePropertyDeviceUID, &size, &UI);
292 CFStringGetCString(UI,name,nsize,CFStringGetSystemEncoding());
299 ARDOUR::get_jack_coreaudio_device_names (device_map_t& devices)
302 // Find out how many Core Audio devices are there, if any...
303 // (code snippet gently "borrowed" from St?hane Letz jackdmp;)
306 UInt32 outSize = sizeof(isWritable);
308 err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
309 &outSize, &isWritable);
311 // Calculate the number of device available...
312 int numCoreDevices = outSize / sizeof(AudioDeviceID);
313 // Make space for the devices we are about to get...
314 AudioDeviceID *coreDeviceIDs = new AudioDeviceID [numCoreDevices];
315 err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
316 &outSize, (void *) coreDeviceIDs);
318 // Look for the CoreAudio device name...
319 char coreDeviceName[256];
322 for (int i = 0; i < numCoreDevices; i++) {
324 nameSize = sizeof (coreDeviceName);
326 /* enforce duplex devices only */
328 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
329 0, true, kAudioDevicePropertyStreams,
330 &outSize, &isWritable);
332 if (err != noErr || outSize == 0) {
336 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
337 0, false, kAudioDevicePropertyStreams,
338 &outSize, &isWritable);
340 if (err != noErr || outSize == 0) {
344 err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
345 0, true, kAudioDevicePropertyDeviceName,
346 &outSize, &isWritable);
348 err = AudioDeviceGetProperty(coreDeviceIDs[i],
349 0, true, kAudioDevicePropertyDeviceName,
350 &nameSize, (void *) coreDeviceName);
352 char drivername[128];
354 // this returns the unique id for the device
355 // that must be used on the commandline for jack
357 if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) {
358 devices.insert (make_pair (coreDeviceName, drivername));
364 delete [] coreDeviceIDs;
367 /* silence a compiler unused variable warning */
373 ARDOUR::get_jack_portaudio_device_names (device_map_t& devices)
375 #if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO)
376 if (Pa_Initialize() != paNoError) {
380 for (PaDeviceIndex i = 0; i < Pa_GetDeviceCount (); ++i) {
382 string readable_name;
383 string jack_device_name;
384 const PaDeviceInfo* device_info = Pa_GetDeviceInfo(i);
386 if (device_info != NULL) { // it should never be ?
387 api_name = Pa_GetHostApiInfo (device_info->hostApi)->name;
388 readable_name = api_name + " " + device_info->name;
389 jack_device_name = api_name + "::" + device_info->name;
390 devices.insert (make_pair (readable_name, jack_device_name));
395 /* silence a compiler unused variable warning */
401 ARDOUR::get_jack_oss_device_names (device_map_t& devices)
403 devices.insert (make_pair (default_device_name, default_device_name));
407 ARDOUR::get_jack_freebob_device_names (device_map_t& devices)
409 devices.insert (make_pair (default_device_name, default_device_name));
413 ARDOUR::get_jack_ffado_device_names (device_map_t& devices)
415 devices.insert (make_pair (default_device_name, default_device_name));
419 ARDOUR::get_jack_netjack_device_names (device_map_t& devices)
421 devices.insert (make_pair (default_device_name, default_device_name));
425 ARDOUR::get_jack_dummy_device_names (device_map_t& devices)
427 devices.insert (make_pair (default_device_name, default_device_name));
431 ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name, device_map_t& devices)
435 if (driver_name == portaudio_driver_name) {
436 get_jack_portaudio_device_names (devices);
437 } else if (driver_name == coreaudio_driver_name) {
438 get_jack_coreaudio_device_names (devices);
439 } else if (driver_name == alsa_driver_name) {
440 get_jack_alsa_device_names (devices);
441 } else if (driver_name == oss_driver_name) {
442 get_jack_oss_device_names (devices);
443 } else if (driver_name == freebob_driver_name) {
444 get_jack_freebob_device_names (devices);
445 } else if (driver_name == ffado_driver_name) {
446 get_jack_ffado_device_names (devices);
447 } else if (driver_name == netjack_driver_name) {
448 get_jack_netjack_device_names (devices);
449 } else if (driver_name == dummy_driver_name) {
450 get_jack_dummy_device_names (devices);
453 return !devices.empty();
457 std::vector<std::string>
458 ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name)
460 std::vector<std::string> readable_names;
461 device_map_t devices;
463 get_jack_device_names_for_audio_driver (driver_name, devices);
465 for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) {
466 readable_names.push_back (i->first);
469 return readable_names;
473 ARDOUR::get_jack_audio_driver_supports_two_devices (const string& driver)
475 return (driver == alsa_driver_name || driver == oss_driver_name);
479 ARDOUR::get_jack_audio_driver_supports_latency_adjustment (const string& driver)
481 return (driver == alsa_driver_name || driver == coreaudio_driver_name ||
482 driver == ffado_driver_name || driver == portaudio_driver_name);
486 ARDOUR::get_jack_audio_driver_supports_setting_period_count (const string& driver)
488 return !(driver == dummy_driver_name || driver == coreaudio_driver_name ||
489 driver == portaudio_driver_name);
493 ARDOUR::get_jack_server_application_names (std::vector<std::string>& server_names)
495 #ifdef PLATFORM_WINDOWS
496 server_names.push_back ("jackd.exe");
498 server_names.push_back ("jackd");
499 server_names.push_back ("jackdmp");
501 return !server_names.empty();
505 ARDOUR::set_path_env_for_jack_autostart (const vector<std::string>& dirs)
508 // push it back into the environment so that auto-started JACK can find it.
509 // XXX why can't we just expect OS X users to have PATH set correctly? we can't ...
510 setenv ("PATH", Searchpath(dirs).to_string().c_str(), 1);
512 /* silence a compiler unused variable warning */
518 ARDOUR::get_jack_server_dir_paths (vector<std::string>& server_dir_paths)
521 /* this magic lets us finds the path to the OSX bundle, and then
522 we infer JACK's location from there
525 char execpath[MAXPATHLEN+1];
526 uint32_t pathsz = sizeof (execpath);
528 _NSGetExecutablePath (execpath, &pathsz);
530 server_dir_paths.push_back (Glib::path_get_dirname (execpath));
533 Searchpath sp(string(g_getenv("PATH")));
535 #ifdef PLATFORM_WINDOWS
536 // N.B. The #define (immediately below) can be safely removed once we know that this code builds okay with mingw
538 IShellLinkA *pISL = NULL;
539 IPersistFile *ppf = NULL;
541 // Mixbus creates a Windows shortcut giving the location of its
542 // own (bundled) version of Jack. Let's see if that shortcut exists
543 if (SUCCEEDED (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL)))
545 if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
547 char target_path[MAX_PATH];
548 char shortcut_pathA[MAX_PATH];
549 WCHAR shortcut_pathW[MAX_PATH];
551 // Our Windows installer should have created a shortcut to the Jack
552 // server so let's start by finding out what drive it got installed on
553 if (char *env_path = getenv ("windir"))
555 strcpy (shortcut_pathA, env_path);
556 shortcut_pathA[2] = '\0'; // Gives us just the drive letter and colon
559 strcpy (shortcut_pathA, "C:");
561 strcat (shortcut_pathA, "\\Program Files (x86)\\Jack\\Start Jack.lnk");
563 MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut_pathA, -1, shortcut_pathW, MAX_PATH);
565 // If it did, load the shortcut into our persistent file
566 if (SUCCEEDED (ppf->Load(shortcut_pathW, 0)))
568 // Read the target information from the shortcut object
569 if (S_OK == (pISL->GetPath (target_path, MAX_PATH, NULL, SLGP_UNCPRIORITY)))
571 char *p = strrchr (target_path, '\\');
576 sp.push_back (target_path);
590 gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL);
592 sp.push_back (install_dir);
593 g_free (install_dir);
595 // don't try and use a system wide JACK install yet.
598 sp.push_back ("/usr/bin");
599 sp.push_back ("/bin");
600 sp.push_back ("/usr/local/bin");
601 sp.push_back ("/opt/local/bin");
605 std::copy (sp.begin(), sp.end(), std::back_inserter(server_dir_paths));
607 return !server_dir_paths.empty();
611 ARDOUR::get_jack_server_paths (const vector<std::string>& server_dir_paths,
612 const vector<string>& server_names,
613 vector<std::string>& server_paths)
615 for (vector<string>::const_iterator i = server_names.begin(); i != server_names.end(); ++i) {
616 find_files_matching_pattern (server_paths, server_dir_paths, *i);
618 return !server_paths.empty();
622 ARDOUR::get_jack_server_paths (vector<std::string>& server_paths)
624 vector<std::string> server_dirs;
626 if (!get_jack_server_dir_paths (server_dirs)) {
630 vector<string> server_names;
632 if (!get_jack_server_application_names (server_names)) {
636 if (!get_jack_server_paths (server_dirs, server_names, server_paths)) {
640 return !server_paths.empty();
644 ARDOUR::get_jack_default_server_path (std::string& server_path)
646 vector<std::string> server_paths;
648 if (!get_jack_server_paths (server_paths)) {
652 server_path = server_paths.front ();
657 quote_string (const string& str)
659 return "\"" + str + "\"";
662 ARDOUR::JackCommandLineOptions::JackCommandLineOptions ()
669 , unlock_gui_libs(false)
680 , hardware_metering(false)
681 , hardware_monitoring(false)
691 ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line)
695 args.push_back (options.server_path);
697 #ifdef PLATFORM_WINDOWS
698 // must use sync mode on windows
699 args.push_back ("-S");
702 #if (defined PLATFORM_WINDOWS || defined __APPLE__)
703 // midi systems needs to be added before the audio driver for jack2
704 if (!options.midi_driver.empty () && options.midi_driver != get_none_string ()) {
705 args.push_back ("-X");
706 args.push_back (options.midi_driver);
710 /* XXX hack to enforce qjackctl-like behaviour */
711 if (options.timeout == 0) {
712 options.timeout = 200;
715 if (options.timeout) {
716 args.push_back ("-t");
717 args.push_back (to_string (options.timeout, std::dec));
720 if (options.no_mlock) {
721 args.push_back ("-m");
724 args.push_back ("-p");
725 args.push_back (to_string(options.ports_max, std::dec));
727 if (options.realtime) {
728 args.push_back ("-R");
729 if (options.priority != 0) {
730 args.push_back ("-P");
731 args.push_back (to_string(options.priority, std::dec));
734 args.push_back ("-r");
737 if (options.unlock_gui_libs) {
738 args.push_back ("-u");
741 if (options.verbose) {
742 args.push_back ("-v");
745 if (options.temporary) {
746 args.push_back ("-T");
749 if (options.driver == alsa_driver_name) {
750 if (options.midi_driver == alsa_seq_midi_driver_name) {
751 args.push_back ("-X");
752 args.push_back ("alsa_midi");
753 } else if (options.midi_driver == alsa_raw_midi_driver_name) {
754 args.push_back ("-X");
755 args.push_back ("alsarawmidi");
759 string command_line_driver_name;
761 string command_line_input_device_name;
762 string command_line_output_device_name;
764 if (!get_jack_command_line_audio_driver_name (options.driver, command_line_driver_name)) {
768 args.push_back ("-d");
769 args.push_back (command_line_driver_name);
771 if (options.driver != dummy_driver_name) {
772 if (options.output_device.empty() && options.input_device.empty()) {
777 if (!get_jack_command_line_audio_device_name (options.driver,
778 options.input_device, command_line_input_device_name)) {
782 if (!get_jack_command_line_audio_device_name (options.driver,
783 options.output_device, command_line_output_device_name)) {
787 if (options.input_device.empty()) {
789 if (options.output_device.empty()) {
792 args.push_back ("-P");
793 } else if (options.output_device.empty()) {
795 if (options.input_device.empty()) {
798 args.push_back ("-C");
799 } else if (options.input_device != options.output_device) {
800 // capture and playback on two devices if supported
801 if (get_jack_audio_driver_supports_two_devices (options.driver)) {
802 args.push_back ("-C");
803 args.push_back (command_line_input_device_name);
804 args.push_back ("-P");
805 args.push_back (command_line_output_device_name);
811 if (options.input_channels) {
812 args.push_back ("-i");
813 args.push_back (to_string (options.input_channels, std::dec));
816 if (options.output_channels) {
817 args.push_back ("-o");
818 args.push_back (to_string (options.output_channels, std::dec));
821 if (get_jack_audio_driver_supports_setting_period_count (options.driver)) {
822 args.push_back ("-n");
823 args.push_back (to_string (options.num_periods, std::dec));
826 // jackd dummy backend
827 if (options.input_channels) {
828 args.push_back ("-C");
829 args.push_back (to_string (options.input_channels, std::dec));
832 if (options.output_channels) {
833 args.push_back ("-P");
834 args.push_back (to_string (options.output_channels, std::dec));
838 args.push_back ("-r");
839 args.push_back (to_string (options.samplerate, std::dec));
841 args.push_back ("-p");
842 args.push_back (to_string (options.period_size, std::dec));
844 if (get_jack_audio_driver_supports_latency_adjustment (options.driver)) {
845 if (options.input_latency) {
846 args.push_back ("-I");
847 args.push_back (to_string (options.input_latency, std::dec));
849 if (options.output_latency) {
850 args.push_back ("-O");
851 args.push_back (to_string (options.output_latency, std::dec));
855 if (options.driver != dummy_driver_name) {
856 if (options.input_device == options.output_device && options.input_device != default_device_name) {
857 args.push_back ("-d");
858 args.push_back (command_line_input_device_name);
862 if (options.driver == alsa_driver_name) {
863 if (options.hardware_metering) {
864 args.push_back ("-M");
866 if (options.hardware_monitoring) {
867 args.push_back ("-H");
870 string command_line_dither_mode;
871 if (get_jack_command_line_dither_mode (options.dither_mode, command_line_dither_mode)) {
872 args.push_back ("-z");
873 args.push_back (command_line_dither_mode);
875 if (options.force16_bit) {
876 args.push_back ("-S");
878 if (options.soft_mode) {
879 args.push_back ("-s");
883 if (options.driver == alsa_driver_name) {
885 if (options.midi_driver != alsa_seq_midi_driver_name) {
886 if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) {
887 args.push_back ("-X");
888 args.push_back (options.midi_driver);
895 for (vector<string>::const_iterator i = args.begin(); i != args.end();) {
896 if (i->find_first_of(' ') != string::npos) {
897 oss << "\"" << *i << "\"";
901 if (++i != args.end()) oss << ' ';
904 command_line = oss.str();
909 ARDOUR::get_jack_server_config_file_name ()
915 ARDOUR::get_jack_server_user_config_dir_path ()
917 return Glib::get_home_dir ();
921 ARDOUR::get_jack_server_user_config_file_path ()
923 return Glib::build_filename (get_jack_server_user_config_dir_path (), get_jack_server_config_file_name ());
927 ARDOUR::write_jack_config_file (const std::string& config_file_path, const string& command_line)
929 if (!g_file_set_contents (config_file_path.c_str(), command_line.c_str(), -1, NULL)) {
930 error << string_compose (_("cannot open JACK rc file %1 to store parameters"), config_file_path) << endmsg;
937 ARDOUR::enumerate_midi_options ()
939 if (midi_options.empty()) {
941 midi_options.push_back (make_pair (_("(legacy) ALSA raw devices"), alsaraw_midi_driver_name));
942 midi_options.push_back (make_pair (_("(legacy) ALSA sequencer"), alsaseq_midi_driver_name));
943 midi_options.push_back (make_pair (_("ALSA (JACK1, 0.124 and later)"), alsa_seq_midi_driver_name));
944 midi_options.push_back (make_pair (_("ALSA (JACK2, 1.9.8 and later)"), alsa_raw_midi_driver_name));
946 #if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO)
947 /* Windows folks: what name makes sense here? Are there other
950 midi_options.push_back (make_pair (_("System MIDI (MME)"), winmme_midi_driver_name));
953 midi_options.push_back (make_pair (_("CoreMIDI"), coremidi_midi_driver_name));
959 for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) {
960 v.push_back (i->first);
963 v.push_back (get_none_string());
969 ARDOUR::set_midi_option (ARDOUR::JackCommandLineOptions& options, const string& opt)
971 if (opt.empty() || opt == get_none_string()) {
972 options.midi_driver = "";
976 for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) {
977 if (i->first == opt) {
978 options.midi_driver = i->second;