X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fbackends%2Fjack%2Fjack_utils.cc;h=b26cb4036797194112457aba6ea1c4a53396773a;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=331c164353604000fa672c4776c50209e03d7522;hpb=848e75aaeaa04a81883ed30bcd04abd862f9d1fd;p=ardour.git diff --git a/libs/backends/jack/jack_utils.cc b/libs/backends/jack/jack_utils.cc index 331c164353..b26cb40367 100644 --- a/libs/backends/jack/jack_utils.cc +++ b/libs/backends/jack/jack_utils.cc @@ -19,7 +19,7 @@ */ #ifdef HAVE_ALSA -#include +#include "ardouralsautil/devicelist.h" #endif #ifdef __APPLE__ @@ -29,16 +29,18 @@ #include #endif -#ifdef HAVE_PORTAUDIO -#include +#ifdef PLATFORM_WINDOWS +#include // Needed for +#include // 'IShellLink' #endif -#include - -#include +#if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO) +#include +#endif #include +#include "pbd/gstdio_compat.h" #include #include "pbd/epa.h" @@ -53,7 +55,7 @@ #include #endif -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace PBD; @@ -105,7 +107,7 @@ get_none_string () void ARDOUR::get_jack_audio_driver_names (vector& audio_driver_names) { -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS audio_driver_names.push_back (portaudio_driver_name); #elif __APPLE__ audio_driver_names.push_back (coreaudio_driver_name); @@ -271,60 +273,7 @@ void ARDOUR::get_jack_alsa_device_names (device_map_t& devices) { #ifdef HAVE_ALSA - snd_ctl_t *handle; - snd_ctl_card_info_t *info; - snd_pcm_info_t *pcminfo; - snd_ctl_card_info_alloca(&info); - snd_pcm_info_alloca(&pcminfo); - string devname; - int cardnum = -1; - int device = -1; - - while (snd_card_next (&cardnum) >= 0 && cardnum >= 0) { - - devname = "hw:"; - devname += PBD::to_string (cardnum, std::dec); - - if (snd_ctl_open (&handle, devname.c_str(), 0) >= 0 && snd_ctl_card_info (handle, info) >= 0) { - - if (snd_ctl_card_info (handle, info) < 0) { - continue; - } - - string card_name = snd_ctl_card_info_get_name (info); - - /* change devname to use ID, not number */ - - devname = "hw:"; - devname += snd_ctl_card_info_get_id (info); - - while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) { - - /* only detect duplex devices here. more - * complex arrangements are beyond our scope - */ - - snd_pcm_info_set_device (pcminfo, device); - snd_pcm_info_set_subdevice (pcminfo, 0); - snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_CAPTURE); - - if (snd_ctl_pcm_info (handle, pcminfo) >= 0) { - - snd_pcm_info_set_device (pcminfo, device); - snd_pcm_info_set_subdevice (pcminfo, 0); - snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_PLAYBACK); - - if (snd_ctl_pcm_info (handle, pcminfo) >= 0) { - devname += ','; - devname += PBD::to_string (device, std::dec); - devices.insert (std::make_pair (card_name, devname)); - } - } - } - - snd_ctl_close(handle); - } - } + get_alsa_audio_device_names(devices); #else /* silence a compiler unused variable warning */ (void) devices; @@ -423,7 +372,7 @@ ARDOUR::get_jack_coreaudio_device_names (device_map_t& devices) void ARDOUR::get_jack_portaudio_device_names (device_map_t& devices) { -#ifdef HAVE_PORTAUDIO +#if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO) if (Pa_Initialize() != paNoError) { return; } @@ -543,7 +492,7 @@ ARDOUR::get_jack_audio_driver_supports_setting_period_count (const string& drive bool ARDOUR::get_jack_server_application_names (std::vector& server_names) { -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS server_names.push_back ("jackd.exe"); #else server_names.push_back ("jackd"); @@ -583,7 +532,61 @@ ARDOUR::get_jack_server_dir_paths (vector& server_dir_paths) Searchpath sp(string(g_getenv("PATH"))); -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS +// N.B. The #define (immediately below) can be safely removed once we know that this code builds okay with mingw +#ifdef COMPILER_MSVC + IShellLinkA *pISL = NULL; + IPersistFile *ppf = NULL; + + // Mixbus creates a Windows shortcut giving the location of its + // own (bundled) version of Jack. Let's see if that shortcut exists + if (SUCCEEDED (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL))) + { + if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + char target_path[MAX_PATH]; + char shortcut_pathA[MAX_PATH]; + WCHAR shortcut_pathW[MAX_PATH]; + + // Our Windows installer should have created a shortcut to the Jack + // server so let's start by finding out what drive it got installed on + if (char *env_path = getenv ("windir")) + { + strcpy (shortcut_pathA, env_path); + shortcut_pathA[2] = '\0'; // Gives us just the drive letter and colon + } + else // Assume 'C:' + strcpy (shortcut_pathA, "C:"); + + strcat (shortcut_pathA, "\\Program Files (x86)\\Jack\\Start Jack.lnk"); + + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut_pathA, -1, shortcut_pathW, MAX_PATH); + + // If it did, load the shortcut into our persistent file + if (SUCCEEDED (ppf->Load(shortcut_pathW, 0))) + { + // Read the target information from the shortcut object + if (S_OK == (pISL->GetPath (target_path, MAX_PATH, NULL, SLGP_UNCPRIORITY))) + { + char *p = strrchr (target_path, '\\'); + + if (p) + { + *p = NULL; + sp.push_back (target_path); + } + } + } + } + } + + if (ppf) + ppf->Release(); + + if (pISL) + pISL->Release(); +#endif + gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL); if (install_dir) { sp.push_back (install_dir); @@ -610,8 +613,7 @@ ARDOUR::get_jack_server_paths (const vector& server_dir_paths, vector& server_paths) { for (vector::const_iterator i = server_names.begin(); i != server_names.end(); ++i) { - Glib::PatternSpec ps (*i); - find_matching_files_in_directories (server_dir_paths, ps, server_paths); + find_files_matching_pattern (server_paths, server_dir_paths, *i); } return !server_paths.empty(); } @@ -686,17 +688,19 @@ ARDOUR::JackCommandLineOptions::JackCommandLineOptions () } bool -ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line, bool for_latency_measurement) +ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line) { vector args; args.push_back (options.server_path); -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS // must use sync mode on windows args.push_back ("-S"); +#endif - // this needs to be added now on windows +#if (defined PLATFORM_WINDOWS || defined __APPLE__) + // midi systems needs to be added before the audio driver for jack2 if (!options.midi_driver.empty () && options.midi_driver != get_none_string ()) { args.push_back ("-X"); args.push_back (options.midi_driver); @@ -738,11 +742,9 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c args.push_back ("-v"); } -#ifndef WIN32 if (options.temporary) { args.push_back ("-T"); } -#endif if (options.driver == alsa_driver_name) { if (options.midi_driver == alsa_seq_midi_driver_name) { @@ -839,7 +841,7 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c args.push_back ("-p"); args.push_back (to_string (options.period_size, std::dec)); - if (!for_latency_measurement && get_jack_audio_driver_supports_latency_adjustment (options.driver)) { + if (get_jack_audio_driver_supports_latency_adjustment (options.driver)) { if (options.input_latency) { args.push_back ("-I"); args.push_back (to_string (options.input_latency, std::dec)); @@ -878,7 +880,7 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c } } - if (options.driver == alsa_driver_name || options.driver == coreaudio_driver_name) { + if (options.driver == alsa_driver_name) { if (options.midi_driver != alsa_seq_midi_driver_name) { if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) { @@ -891,11 +893,11 @@ ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& c ostringstream oss; for (vector::const_iterator i = args.begin(); i != args.end();) { -#ifdef WIN32 - oss << quote_string (*i); -#else - oss << *i; -#endif + if (i->find_first_of(' ') != string::npos) { + oss << "\"" << *i << "\""; + } else { + oss << *i; + } if (++i != args.end()) oss << ' '; } @@ -924,20 +926,15 @@ ARDOUR::get_jack_server_user_config_file_path () bool ARDOUR::write_jack_config_file (const std::string& config_file_path, const string& command_line) { - ofstream jackdrc (config_file_path.c_str()); - - if (!jackdrc) { + if (!g_file_set_contents (config_file_path.c_str(), command_line.c_str(), -1, NULL)) { error << string_compose (_("cannot open JACK rc file %1 to store parameters"), config_file_path) << endmsg; return false; } - - jackdrc << command_line << endl; - jackdrc.close (); return true; } vector -ARDOUR::enumerate_midi_options () +ARDOUR::enumerate_midi_options () { if (midi_options.empty()) { #ifdef HAVE_ALSA @@ -946,11 +943,11 @@ ARDOUR::enumerate_midi_options () midi_options.push_back (make_pair (_("ALSA (JACK1, 0.124 and later)"), alsa_seq_midi_driver_name)); midi_options.push_back (make_pair (_("ALSA (JACK2, 1.9.8 and later)"), alsa_raw_midi_driver_name)); #endif -#ifdef HAVE_PORTAUDIO +#if (defined PLATFORM_WINDOWS && defined HAVE_PORTAUDIO) /* Windows folks: what name makes sense here? Are there other choices as well ? */ - midi_options.push_back (make_pair (_("Multimedia Extension"), winmme_midi_driver_name)); + midi_options.push_back (make_pair (_("System MIDI (MME)"), winmme_midi_driver_name)); #endif #ifdef __APPLE__ midi_options.push_back (make_pair (_("CoreMIDI"), coremidi_midi_driver_name)); @@ -959,12 +956,12 @@ ARDOUR::enumerate_midi_options () vector v; - v.push_back (get_none_string()); - for (MidiOptions::const_iterator i = midi_options.begin(); i != midi_options.end(); ++i) { v.push_back (i->first); } + v.push_back (get_none_string()); + return v; }