X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fengine_dialog.cc;h=d6e6a52f4606e2cc6e5168b1f78b255a3ed9dc59;hb=153ee4e441eeebc9aceaa3121e4a785c6011a962;hp=7d8f29cce46c3c5f2a11b27e2033c03fa4b97884;hpb=68e943265edf04e63a8e8b8f62bab20f99d9c637;p=ardour.git diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 7d8f29cce4..d6e6a52f46 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -1,11 +1,34 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include #include #include +#include + #include #include -#include + +#include "pbd/epa.h" +#include "pbd/xml++.h" #ifdef __APPLE__ #include @@ -16,15 +39,15 @@ #include #endif -#include +#include "ardour/profile.h" #include #include #include -#include -#include -#include +#include "pbd/convert.h" +#include "pbd/error.h" +#include "pbd/pathscanner.h" #ifdef __APPLE #include @@ -46,6 +69,10 @@ EngineControl::EngineControl () priority_spinner (priority_adjustment), ports_adjustment (128, 8, 1024, 1, 16), ports_spinner (ports_adjustment), + input_latency_adjustment (0, 0, 99999, 1), + input_latency (input_latency_adjustment), + output_latency_adjustment (0, 0, 99999, 1), + output_latency (output_latency_adjustment), realtime_button (_("Realtime")), no_memory_lock_button (_("Do not lock memory")), unlock_memory_button (_("Unlock memory")), @@ -65,7 +92,7 @@ EngineControl::EngineControl () basic_packer (8, 2), options_packer (14, 2), device_packer (6, 2) -#endif +#endif { using namespace Notebook_Helpers; Label* label; @@ -115,6 +142,7 @@ EngineControl::EngineControl () #else strings.push_back (X_("ALSA")); strings.push_back (X_("OSS")); + strings.push_back (X_("FreeBoB")); strings.push_back (X_("FFADO")); #endif strings.push_back (X_("NetJACK")); @@ -122,73 +150,86 @@ EngineControl::EngineControl () set_popdown_strings (driver_combo, strings); driver_combo.set_active_text (strings.front()); - driver_combo.signal_changed().connect (mem_fun (*this, &EngineControl::driver_changed)); + driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed)); driver_changed (); strings.clear (); - strings.push_back (_("Playback/Recording on 1 Device")); - strings.push_back (_("Playback/Recording on 2 Devices")); + strings.push_back (_("Playback/recording on 1 device")); + strings.push_back (_("Playback/recording on 2 devices")); strings.push_back (_("Playback only")); strings.push_back (_("Recording only")); set_popdown_strings (audio_mode_combo, strings); audio_mode_combo.set_active_text (strings.front()); - audio_mode_combo.signal_changed().connect (mem_fun (*this, &EngineControl::audio_mode_changed)); + audio_mode_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::audio_mode_changed)); audio_mode_changed (); + strings.clear (); + strings.push_back (_("None")); + strings.push_back (_("seq")); + strings.push_back (_("raw")); + set_popdown_strings (midi_driver_combo, strings); + midi_driver_combo.set_active_text (strings.front ()); + row = 0; - label = manage (new Label (_("Driver"))); + label = manage (new Label (_("Driver:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (driver_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; - label = manage (new Label (_("Interface"))); + label = manage (new Label (_("Interface:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (interface_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; - label = manage (new Label (_("Sample Rate"))); + label = manage (new Label (_("Sample rate:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; - label = manage (new Label (_("Buffer size"))); + label = manage (new Label (_("Buffer size:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (period_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; #ifndef __APPLE__ - label = manage (new Label (_("Number of buffers"))); + label = manage (new Label (_("Number of buffers:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (periods_spinner, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); periods_spinner.set_value (2); row++; #endif - label = manage (new Label (_("Approximate latency"))); - label->set_alignment (0.0, 0.5); + label = manage (new Label (_("Approximate latency:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (latency_label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; - sample_rate_combo.signal_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency)); - periods_adjustment.signal_value_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency)); - period_size_combo.signal_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency)); + sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); + periods_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); + period_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); redisplay_latency(); row++; /* no audio mode with CoreAudio, its duplex or nuthin' */ #ifndef __APPLE__ - label = manage (new Label (_("Audio Mode"))); + label = manage (new Label (_("Audio mode:"))); + label->set_alignment (0, 0.5); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (audio_mode_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; #endif - interface_combo.set_size_request (125, -1); - input_device_combo.set_size_request (125, -1); - output_device_combo.set_size_request (125, -1); + interface_combo.set_size_request (250, -1); + input_device_combo.set_size_request (250, -1); + output_device_combo.set_size_request (250, -1); /* @@ -198,8 +239,8 @@ EngineControl::EngineControl () stop_button.set_sensitive (false); } - start_button.signal_clicked().connect (mem_fun (*this, &EngineControl::start_engine)); - stop_button.signal_clicked().connect (mem_fun (*this, &EngineControl::start_engine)); + start_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine)); + stop_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine)); */ button_box.pack_start (start_button, false, false); @@ -215,9 +256,12 @@ EngineControl::EngineControl () options_packer.attach (realtime_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; - realtime_button.signal_toggled().connect (mem_fun (*this, &EngineControl::realtime_changed)); + realtime_button.set_active (true); + realtime_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::realtime_changed)); realtime_changed (); +#if PROVIDE_TOO_MANY_OPTIONS + #ifndef __APPLE__ label = manage (new Label (_("Realtime Priority"))); label->set_alignment (1.0, 0.5); @@ -242,7 +286,7 @@ EngineControl::EngineControl () ++row; options_packer.attach (verbose_output_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; -#else +#else options_packer.attach (verbose_output_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; #endif @@ -262,15 +306,22 @@ EngineControl::EngineControl () options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; - label = manage (new Label (_("Number of ports"))); - label->set_alignment (1.0, 0.5); +#endif /* PROVIDE_TOO_MANY_OPTIONS */ + label = manage (new Label (_("Number of ports:"))); + label->set_alignment (0, 0.5); options_packer.attach (ports_spinner, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0)); options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; + label = manage (new Label (_("MIDI driver:"))); + label->set_alignment (0, 0.5); + options_packer.attach (midi_driver_combo, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0)); + options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + #ifndef __APPLE__ - label = manage (new Label (_("Dither"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Dither:"))); + label->set_alignment (0, 0.5); options_packer.attach (dither_mode_combo, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0)); options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); ++row; @@ -282,7 +333,7 @@ EngineControl::EngineControl () fatal << _("No JACK server found anywhere on this system. Please install JACK and restart") << endmsg; /*NOTREACHED*/ } - + set_popdown_strings (serverpath_combo, server_strings); serverpath_combo.set_active_text (server_strings.front()); @@ -300,36 +351,42 @@ EngineControl::EngineControl () row = 0; #ifndef __APPLE__ - label = manage (new Label (_("Input device"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Input device:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_device_combo, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; - label = manage (new Label (_("Output device"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Output device:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); - device_packer.attach (output_device_combo, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); + device_packer.attach (output_device_combo, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; #endif - label = manage (new Label (_("Input channels"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Input channels:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_channels, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; - label = manage (new Label (_("Output channels"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Output channels:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (output_channels, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; - label = manage (new Label (_("Hardware input latency (samples)"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Hardware input latency:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); + label = manage (new Label (_("samples"))); + label->set_alignment (0, 0.5); + device_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; - label = manage (new Label (_("Hardware output latency (samples)"))); - label->set_alignment (1.0, 0.5); + label = manage (new Label (_("Hardware output latency:"))); + label->set_alignment (0, 0.5); device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (output_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); + label = manage (new Label (_("samples"))); + label->set_alignment (0, 0.5); + device_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; basic_hbox.pack_start (basic_packer, false, false); @@ -358,33 +415,36 @@ EngineControl::build_command_line (vector& cmd) { string str; string driver; - bool using_oss = false; bool using_alsa = false; bool using_coreaudio = false; - bool using_netjack = false; - bool using_ffado = false; bool using_dummy = false; + bool using_ffado = false; /* first, path to jackd */ cmd.push_back (serverpath_combo.get_active_text ()); - + /* now jackd arguments */ str = timeout_combo.get_active_text (); + if (str != _("Ignore")) { + double secs = 0; uint32_t msecs; - atof (str); + secs = atof (str); msecs = (uint32_t) floor (secs * 1000.0); - cmd.push_back ("-t"); - cmd.push_back (to_string (msecs, std::dec)); + + if (msecs > 0) { + cmd.push_back ("-t"); + cmd.push_back (to_string (msecs, std::dec)); + } } if (no_memory_lock_button.get_active()) { cmd.push_back ("-m"); /* no munlock */ } - + cmd.push_back ("-p"); /* port max */ cmd.push_back (to_string ((uint32_t) floor (ports_spinner.get_value()), std::dec)); @@ -392,6 +452,8 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-R"); cmd.push_back ("-P"); cmd.push_back (to_string ((uint32_t) floor (priority_spinner.get_value()), std::dec)); + } else { + cmd.push_back ("-r"); /* override jackd's default --realtime */ } if (unlock_memory_button.get_active()) { @@ -401,7 +463,7 @@ EngineControl::build_command_line (vector& cmd) if (verbose_output_button.get_active()) { cmd.push_back ("-v"); } - + /* now add fixed arguments (not user-selectable) */ cmd.push_back ("-T"); // temporary */ @@ -411,31 +473,22 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-d"); driver = driver_combo.get_active_text (); + if (driver == X_("ALSA")) { using_alsa = true; cmd.push_back ("alsa"); } else if (driver == X_("OSS")) { - using_oss = true; cmd.push_back ("oss"); } else if (driver == X_("CoreAudio")) { using_coreaudio = true; cmd.push_back ("coreaudio"); } else if (driver == X_("NetJACK")) { - using_netjack = true; cmd.push_back ("netjack"); + } else if (driver == X_("FreeBoB")) { + cmd.push_back ("freebob"); } else if (driver == X_("FFADO")) { using_ffado = true; - - /* do this until FFADO becomes the standard */ - - char* hack = getenv ("ARDOUR_FIREWIRE_DRIVER_NAME"); - - if (hack) { - cmd.push_back (hack); - } else { - cmd.push_back ("freebob"); - } - + cmd.push_back ("firewire"); } else if ( driver == X_("Dummy")) { using_dummy = true; cmd.push_back ("dummy"); @@ -445,13 +498,13 @@ EngineControl::build_command_line (vector& cmd) if (!using_coreaudio) { str = audio_mode_combo.get_active_text(); - + if (str == _("Playback/Recording on 1 Device")) { - + /* relax */ - + } else if (str == _("Playback/Recording on 2 Devices")) { - + string input_device = get_device_name (driver, input_device_combo.get_active_text()); string output_device = get_device_name (driver, output_device_combo.get_active_text()); @@ -462,6 +515,7 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-C"); cmd.push_back (input_device); + cmd.push_back ("-P"); cmd.push_back (output_device); @@ -471,7 +525,7 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-C"); } - if (! using_dummy ) { + if (!using_dummy) { cmd.push_back ("-n"); cmd.push_back (to_string ((uint32_t) floor (periods_spinner.get_value()), std::dec)); } @@ -479,12 +533,29 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-r"); cmd.push_back (to_string (get_rate(), std::dec)); - + cmd.push_back ("-p"); cmd.push_back (period_size_combo.get_active_text()); + if (using_alsa || using_ffado || using_coreaudio) { + + double val = input_latency_adjustment.get_value(); + + if (val) { + cmd.push_back ("-I"); + cmd.push_back (to_string ((uint32_t) val, std::dec)); + } + + val = output_latency_adjustment.get_value(); + + if (val) { + cmd.push_back ("-O"); + cmd.push_back (to_string ((uint32_t) val, std::dec)); + } + } + if (using_alsa) { - + if (audio_mode_combo.get_active_text() != _("Playback/Recording on 2 Devices")) { string device = get_device_name (driver, interface_combo.get_active_text()); @@ -495,12 +566,12 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back ("-d"); cmd.push_back (device); - } + } if (hw_meter_button.get_active()) { cmd.push_back ("-M"); } - + if (hw_monitor_button.get_active()) { cmd.push_back ("-H"); } @@ -519,16 +590,23 @@ EngineControl::build_command_line (vector& cmd) if (force16bit_button.get_active()) { cmd.push_back ("-S"); } - + if (soft_mode_button.get_active()) { cmd.push_back ("-s"); } + str = midi_driver_combo.get_active_text (); + + if (str == _("seq")) { + cmd.push_back ("-X seq"); + } else if (str == _("raw")) { + cmd.push_back ("-X raw"); + } } else if (using_coreaudio) { #ifdef __APPLE__ // note: older versions of the CoreAudio JACK backend use -n instead of -d here - + string device = get_device_name (driver, interface_combo.get_active_text()); if (device.empty()) { cmd.clear (); @@ -539,16 +617,23 @@ EngineControl::build_command_line (vector& cmd) cmd.push_back (device); #endif - } else if (using_oss) { - - } else if (using_netjack) { - } } bool EngineControl::engine_running () { + EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa (); + boost::scoped_ptr current_epa; + + /* revert all environment settings back to whatever they were when ardour started + */ + + if (global_epa) { + current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */ + global_epa->restore (); + } + jack_status_t status; jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status); @@ -566,12 +651,12 @@ EngineControl::setup_engine () std::string cwd = "/tmp"; build_command_line (args); - + if (args.empty()) { return 1; // try again } - Glib::ustring jackdrc_path = Glib::get_home_dir(); + std::string jackdrc_path = Glib::get_home_dir(); jackdrc_path += "/.jackdrc"; ofstream jackdrc (jackdrc_path.c_str()); @@ -607,13 +692,15 @@ EngineControl::enumerate_devices (const string& driver) /* note: case matters for the map keys */ if (driver == "CoreAudio") { -#ifdef __APPLE__ +#ifdef __APPLE__ devices[driver] = enumerate_coreaudio_devices (); #endif #ifndef __APPLE__ } else if (driver == "ALSA") { devices[driver] = enumerate_alsa_devices (); + } else if (driver == "FreeBOB") { + devices[driver] = enumerate_freebob_devices (); } else if (driver == "FFADO") { devices[driver] = enumerate_ffado_devices (); } else if (driver == "OSS") { @@ -629,14 +716,14 @@ EngineControl::enumerate_devices (const string& driver) } #ifdef __APPLE__ -static OSStatus +static OSStatus getDeviceUIDFromID( AudioDeviceID id, char *name, size_t nsize) { UInt32 size = sizeof(CFStringRef); CFStringRef UI; OSStatus res = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UI); - if (res == noErr) + if (res == noErr) CFStringGetCString(UI,name,nsize,CFStringGetSystemEncoding()); CFRelease(UI); return res; @@ -646,7 +733,7 @@ vector EngineControl::enumerate_coreaudio_devices () { vector devs; - + // Find out how many Core Audio devices are there, if any... // (code snippet gently "borrowed" from St?hane Letz jackdmp;) OSStatus err; @@ -703,11 +790,11 @@ EngineControl::enumerate_coreaudio_devices () // this returns the unique id for the device // that must be used on the commandline for jack - + if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) { devs.push_back (coreDeviceName); backend_devs.push_back (drivername); - } + } } } } @@ -728,7 +815,7 @@ have no duplex audio device.\n\n\ Alternatively, if you really want just playback\n\ or recording but not both, start JACK before running\n\ Ardour and choose the relevant device then." - ), + ), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK); msg.set_title (_("No suitable audio devices")); msg.set_position (Gtk::WIN_POS_MOUSE); @@ -765,28 +852,11 @@ EngineControl::enumerate_alsa_devices () while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) { - bool have_playback = false; - bool have_capture = false; - - /* find duplex devices only */ - - 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) { - have_capture = true; - } - 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) { - have_playback = true; - } - - if (have_capture && have_playback) { devs.push_back (snd_pcm_info_get_name (pcminfo)); devname += ','; devname += to_string (device, std::dec); @@ -815,6 +885,7 @@ EngineControl::enumerate_freebob_devices () vector devs; return devs; } + vector EngineControl::enumerate_oss_devices () { @@ -840,22 +911,19 @@ EngineControl::driver_changed () { string driver = driver_combo.get_active_text(); string::size_type maxlen = 0; - int maxindex = -1; int n = 0; enumerate_devices (driver); vector& strings = devices[driver]; - if (strings.empty() && driver != "FFADO" && driver != "Dummy") { - error << string_compose (_("No devices found for driver \"%1\""), driver) << endmsg; + if (strings.empty() && driver != "FreeBoB" && driver != "FFADO" && driver != "Dummy") { return; } - + for (vector::iterator i = strings.begin(); i != strings.end(); ++i, ++n) { if ((*i).length() > maxlen) { maxlen = (*i).length(); - maxindex = n; } } @@ -867,8 +935,8 @@ EngineControl::driver_changed () interface_combo.set_active_text (strings.front()); input_device_combo.set_active_text (strings.front()); output_device_combo.set_active_text (strings.front()); - } - + } + if (driver == "ALSA") { soft_mode_button.set_sensitive (true); force16bit_button.set_sensitive (true); @@ -905,12 +973,13 @@ EngineControl::redisplay_latency () snprintf (buf, sizeof(buf), "%.1fmsec", (periods * period_size) / (rate/1000.0)); latency_label.set_text (buf); + latency_label.set_alignment (0, 0.5); } void EngineControl::audio_mode_changed () { - Glib::ustring str = audio_mode_combo.get_active_text(); + std::string str = audio_mode_combo.get_active_text(); if (str == _("Playback/Recording on 1 Device")) { input_device_combo.set_sensitive (false); @@ -925,7 +994,7 @@ EngineControl::audio_mode_changed () } } -static bool jack_server_filter(const string& str, void *arg) +static bool jack_server_filter(const string& str, void */*arg*/) { return str == "jackd" || str == "jackdmp"; } @@ -937,23 +1006,23 @@ EngineControl::find_jack_servers (vector& strings) /* this magic lets us finds the path to the OSX bundle, and then we infer JACK's location from there */ - + char execpath[MAXPATHLEN+1]; uint32_t pathsz = sizeof (execpath); _NSGetExecutablePath (execpath, &pathsz); - + string path (Glib::path_get_dirname (execpath)); path += "/jackd"; if (Glib::file_test (path, FILE_TEST_EXISTS)) { strings.push_back (path); - } + } if (getenv ("ARDOUR_WITH_JACK")) { /* no other options - only use the JACK we supply */ if (strings.empty()) { - fatal << _("JACK appears to be missing from the Ardour bundle") << endmsg; + fatal << string_compose (_("JACK appears to be missing from the %1 bundle"), PROGRAM_NAME) << endmsg; /*NOTREACHED*/ } return; @@ -961,7 +1030,7 @@ EngineControl::find_jack_servers (vector& strings) #else string path; #endif - + PathScanner scanner; vector *jack_servers; std::map un; @@ -997,12 +1066,12 @@ EngineControl::find_jack_servers (vector& strings) #endif jack_servers = scanner (path, jack_server_filter, 0, false, true); - + vector::iterator iter; - + for (iter = jack_servers->begin(); iter != jack_servers->end(); iter++) { string p = **iter; - + if (un[p]++ == 0) { strings.push_back(p); } @@ -1028,13 +1097,13 @@ EngineControl::get_device_name (const string& driver, const string& human_readab if (backend_devs.empty()) { return human_readable; } - + for (i = devices[driver].begin(), n = backend_devs.begin(); i != devices[driver].end(); ++i, ++n) { if (human_readable == (*i)) { return (*n); } } - + if (i == devices[driver].end()) { warning << string_compose (_("Audio device \"%1\" not known on this computer."), human_readable) << endmsg; } @@ -1047,7 +1116,7 @@ EngineControl::get_state () { XMLNode* root = new XMLNode ("AudioSetup"); XMLNode* child; - Glib::ustring path; + std::string path; child = new XMLNode ("periods"); child->add_property ("val", to_string (periods_adjustment.get_value(), std::dec)); @@ -1148,7 +1217,11 @@ EngineControl::get_state () child = new XMLNode ("outputdevice"); child->add_property ("val", output_device_combo.get_active_text()); root->add_child_nocopy (*child); - + + child = new XMLNode ("mididriver"); + child->add_property ("val", midi_driver_combo.get_active_text()); + root->add_child_nocopy (*child); + return *root; } @@ -1160,34 +1233,46 @@ EngineControl::set_state (const XMLNode& root) XMLNode* child; XMLProperty* prop = NULL; bool using_dummy = false; - + bool using_ffado = false; + int val; string strval; - + if ( (child = root.child ("driver"))){ prop = child->property("val"); + if (prop && (prop->value() == "Dummy") ) { using_dummy = true; } + if (prop && (prop->value() == "FFADO") ) { + using_ffado = true; + } + } - + clist = root.children(); for (citer = clist.begin(); citer != clist.end(); ++citer) { - if ( prop && (prop->value() == "FFADO" )) - continue; + child = *citer; prop = child->property ("val"); if (!prop || prop->value().empty()) { - if ( using_dummy && ( child->name() == "interface" || child->name() == "inputdevice" || child->name() == "outputdevice" )) + if (((using_dummy || using_ffado) + && ( child->name() == "interface" + || child->name() == "inputdevice" + || child->name() == "outputdevice")) + || child->name() == "timeout") + { continue; + } + error << string_compose (_("AudioSetup value for %1 is missing data"), child->name()) << endmsg; continue; } - + strval = prop->value(); /* adjustments/spinners */ @@ -1250,24 +1335,34 @@ EngineControl::set_state (const XMLNode& root) } else if (child->name() == "periodsize") { period_size_combo.set_active_text(strval); } else if (child->name() == "serverpath") { - /* do not allow us to use a server path that doesn't - exist on this system. this handles cases where - the user has an RC file listing a serverpath - from some other machine. - */ - vector::iterator x; - for (x = server_strings.begin(); x != server_strings.end(); ++x) { - if (*x == strval) { - break; - } - } - if (x != server_strings.end()) { - serverpath_combo.set_active_text (strval); - } else { - warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"), - strval) - << endmsg; - } + + /* only attempt to set this if we have bothered to look + up server names already. otherwise this is all + redundant (actually, all of this dialog/widget + is redundant in that case ...) + */ + + if (!server_strings.empty()) { + /* do not allow us to use a server path that doesn't + exist on this system. this handles cases where + the user has an RC file listing a serverpath + from some other machine. + */ + vector::iterator x; + for (x = server_strings.begin(); x != server_strings.end(); ++x) { + if (*x == strval) { + break; + } + } + if (x != server_strings.end()) { + serverpath_combo.set_active_text (strval); + } else { + warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"), + strval) + << endmsg; + } + } + } else if (child->name() == "driver") { driver_combo.set_active_text(strval); } else if (child->name() == "interface") { @@ -1282,6 +1377,8 @@ EngineControl::set_state (const XMLNode& root) input_device_combo.set_active_text(strval); } else if (child->name() == "outputdevice") { output_device_combo.set_active_text(strval); + } else if (child->name() == "mididriver") { + midi_driver_combo.set_active_text(strval); } } }