diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-08-17 15:53:59 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-08-17 15:53:59 +0000 |
commit | f5d5974b9807f169f0555537fe3a95e3cc60693b (patch) | |
tree | 74b704c5cdb8afb690a23a2f1e6a5983b460d332 | |
parent | 327275f4c9381575021be96f2c67e23b378bd98c (diff) |
continue cleanup+improvements to audio setup dialog; add save+restore to said dialog
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2321 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/ardour-sae.menus | 5 | ||||
-rw-r--r-- | gtk2_ardour/ardour2_ui_dark.rc.in | 18 | ||||
-rw-r--r-- | gtk2_ardour/ardour2_ui_light.rc.in | 18 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.cc | 497 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.h | 16 | ||||
-rw-r--r-- | gtk2_ardour/new_session_dialog.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/option_editor.cc | 6 |
9 files changed, 472 insertions, 105 deletions
diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index 83245b879b..d9827a38dd 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -127,7 +127,9 @@ <menuitem action='set-mouse-mode-gain'/> <menuitem action='set-mouse-mode-zoom'/> <menuitem action='set-mouse-mode-timefx'/> - </menu> + </menu> + <separator/> + <menuitem action='ToggleOptionsEditor'/> </menu> <menu name='Regions' action='Regions'> <menuitem action='crop'/> @@ -215,7 +217,6 @@ <separator/> <menuitem action='goto-editor'/> <menuitem action='goto-mixer'/> - <menuitem action='ToggleOptionsEditor'/> <menuitem action='ToggleInspector'/> <menuitem action='ToggleLocations'/> <menuitem action='ToggleThemeManager'/> diff --git a/gtk2_ardour/ardour2_ui_dark.rc.in b/gtk2_ardour/ardour2_ui_dark.rc.in index 2549506299..1510b1c1bd 100644 --- a/gtk2_ardour/ardour2_ui_dark.rc.in +++ b/gtk2_ardour/ardour2_ui_dark.rc.in @@ -454,7 +454,7 @@ style "ardour_progressbars" = "default_buttons_menus" bg[PRELIGHT] = { 0.00, 0.36, 0.40 } } -style "options_window" = "default_base" +style "preferences" = "default_base" { font_name = "%FONT_NORMAL%" fg[PRELIGHT] = { 0.80, 0.80, 0.80 } @@ -1208,15 +1208,15 @@ widget "*MixerMonitorInputButton.*" style:highest "very_small_button" widget "*MixerIOButton" style:highest "very_small_button" widget "*MixerIOButtonLabel" style:highest "very_small_button" widget "*AddRouteDialogSpinner" style:highest "ardour_adjusters" -widget "*AddRouteDialogRadioButton*" style:highest "options_window" -widget "*OptionsNotebook" style:highest "options_window" -widget "*OptionEditorToggleButton*" style:highest "options_window" -widget "*OptionsLabel" style:highest "options_window" -widget "*OptionEditorAuditionerLabel" style:highest "options_window" +widget "*AddRouteDialogRadioButton*" style:highest "preferences" +widget "*OptionsNotebook" style:highest "preferences" +widget "*OptionEditorToggleButton*" style:highest "preferences" +widget "*OptionsLabel" style:highest "preferences" +widget "*OptionEditorAuditionerLabel" style:highest "preferences" widget "*OptionsEntry" style:highest "option_entry" -widget "*InspectorNotebook" style:highest "options_window" -widget "*NewSessionDialog" style:highest "options_window" -widget "*NewSessionDialogButton*" style:highest "options_window" +widget "*InspectorNotebook" style:highest "preferences" +widget "*NewSessionDialog" style:highest "preferences" +widget "*NewSessionDialogButton*" style:highest "preferences" widget "*MixerSendSwitch*" style:highest "very_small_red_active_and_selected_button" widget "*OptionEditorToggleButton" style:highest "small_red_active_and_selected_button" widget "*NewSessionDialogButton" style:highest "small_red_active_and_selected_button" diff --git a/gtk2_ardour/ardour2_ui_light.rc.in b/gtk2_ardour/ardour2_ui_light.rc.in index dec884f41f..c9c054783a 100644 --- a/gtk2_ardour/ardour2_ui_light.rc.in +++ b/gtk2_ardour/ardour2_ui_light.rc.in @@ -457,7 +457,7 @@ style "ardour_progressbars" = "default_buttons_menus" bg[PRELIGHT] = { 0.00, 0.36, 0.40 } } -style "options_window" = "default_base" +style "preferences" = "default_base" { font_name = "%FONT_NORMAL%" fg[PRELIGHT] = { 0.80, 0.80, 0.80 } @@ -1212,15 +1212,15 @@ widget "*MixerMonitorInputButton.*" style:highest "very_small_button" widget "*MixerIOButton" style:highest "very_small_button" widget "*MixerIOButtonLabel" style:highest "very_small_button" widget "*AddRouteDialogSpinner" style:highest "ardour_adjusters" -widget "*AddRouteDialogRadioButton*" style:highest "options_window" -widget "*OptionsNotebook" style:highest "options_window" -widget "*OptionEditorToggleButton*" style:highest "options_window" -widget "*OptionsLabel" style:highest "options_window" -widget "*OptionEditorAuditionerLabel" style:highest "options_window" +widget "*AddRouteDialogRadioButton*" style:highest "preferences" +widget "*OptionsNotebook" style:highest "preferences" +widget "*OptionEditorToggleButton*" style:highest "preferences" +widget "*OptionsLabel" style:highest "preferences" +widget "*OptionEditorAuditionerLabel" style:highest "preferences" widget "*OptionsEntry" style:highest "option_entry" -widget "*InspectorNotebook" style:highest "options_window" -widget "*NewSessionDialog" style:highest "options_window" -widget "*NewSessionDialogButton*" style:highest "options_window" +widget "*InspectorNotebook" style:highest "preferences" +widget "*NewSessionDialog" style:highest "preferences" +widget "*NewSessionDialogButton*" style:highest "preferences" widget "*MixerSendSwitch*" style:highest "very_small_red_active_and_selected_button" widget "*OptionEditorToggleButton" style:highest "small_red_active_and_selected_button" widget "*NewSessionDialogButton" style:highest "small_red_active_and_selected_button" diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 99a8c072f6..8c5ddd752b 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -475,6 +475,11 @@ ARDOUR_UI::save_ardour_state () XMLNode* node = new XMLNode (keyboard->get_state()); Config->add_extra_xml (*node); Config->add_extra_xml (get_transport_controllable_state()); + if (new_session_dialog) { + if (new_session_dialog->engine_control.was_used()) { + Config->add_extra_xml (new_session_dialog->engine_control.get_state()); + } + } Config->save_state(); XMLNode enode(static_cast<Stateful*>(editor)->get_state()); @@ -562,7 +567,7 @@ ARDOUR_UI::startup () bool isnew; new_session_dialog = new NewSessionDialog(); - + /* If no session name is given: we're not loading a session yet, nor creating a new one */ if (session_name.length()) { @@ -609,7 +614,13 @@ ARDOUR_UI::startup () } } else { + + XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); + if (audio_setup) { + new_session_dialog->engine_control.set_state (*audio_setup); + } + /* no backend audio, must bring up NSD to check configuration */ need_nsd = true; diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 98cf2b42ac..ca0d3d58fb 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -201,7 +201,7 @@ ARDOUR_UI::install_actions () ActionManager::register_action (common_actions, X_("goto-editor"), _("Show Editor"), mem_fun(*this, &ARDOUR_UI::goto_editor_window)); ActionManager::register_action (common_actions, X_("goto-mixer"), _("Show Mixer"), mem_fun(*this, &ARDOUR_UI::goto_mixer_window)); - ActionManager::register_toggle_action (common_actions, X_("ToggleOptionsEditor"), _("Options Editor"), mem_fun(*this, &ARDOUR_UI::toggle_options_window)); + ActionManager::register_toggle_action (common_actions, X_("ToggleOptionsEditor"), _("Preferences"), mem_fun(*this, &ARDOUR_UI::toggle_options_window)); act = ActionManager::register_toggle_action (common_actions, X_("ToggleInspector"), _("Track/Bus Inspector"), mem_fun(*this, &ARDOUR_UI::toggle_route_params_window)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_toggle_action (common_actions, X_("ToggleConnections"), _("Connections"), mem_fun(*this, &ARDOUR_UI::toggle_connection_editor)); diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 5cb7a0d0ff..75d950051f 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -3,11 +3,14 @@ #include <fstream> #include <glibmm.h> +#include <pbd/xml++.h> #ifdef __APPLE__ #include <CoreAudio/CoreAudio.h> #include <CoreFoundation/CFString.h> -#endif __APPLE__ +#else +#include <alsa/asoundlib.h> +#endif #include <ardour/profile.h> #include <jack/jack.h> @@ -50,13 +53,19 @@ EngineControl::EngineControl () start_button (_("Start")), stop_button (_("Stop")), basic_packer (8, 2), - options_packer (12, 2), +#ifdef __APPLE__ + options_packer (4, 2), +#else + options_packer (14, 2), +#endif device_packer (3, 2) { using namespace Notebook_Helpers; Label* label; vector<string> strings; + _used = false; + strings.push_back (_("8000Hz")); strings.push_back (_("22050Hz")); strings.push_back (_("44100Hz")); @@ -80,6 +89,14 @@ EngineControl::EngineControl () set_popdown_strings (period_size_combo, strings); period_size_combo.set_active_text ("1024"); + strings.clear (); + strings.push_back (_("None")); + strings.push_back (_("Triangular")); + strings.push_back (_("Rectangular")); + strings.push_back (_("Shaped")); + set_popdown_strings (dither_mode_combo, strings); + dither_mode_combo.set_active_text (_("None")); + /* basic parameters */ basic_packer.set_spacings (6); @@ -104,9 +121,10 @@ EngineControl::EngineControl () driver_changed (); strings.clear (); - strings.push_back (_("Duplex")); + strings.push_back (_("Playback/Recording on 1 Device")); + strings.push_back (_("Playback/Recording on 2 Devices")); strings.push_back (_("Playback only")); - strings.push_back (_("Capture only")); + strings.push_back (_("Recording only")); set_popdown_strings (audio_mode_combo, strings); audio_mode_combo.set_active_text (strings.front()); @@ -135,6 +153,7 @@ EngineControl::EngineControl () periods_spinner.set_value (2); label = manage (new Label (_("Approximate latency"))); + label->set_alignment (0.0, 0.5); basic_packer.attach (*label, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (latency_label, 1, 2, 5, 6, FILL|EXPAND, (AttachOptions) 0); @@ -145,9 +164,14 @@ EngineControl::EngineControl () label = manage (new Label (_("Audio Mode"))); basic_packer.attach (*label, 0, 1, 6, 7, FILL|EXPAND, (AttachOptions) 0); + + /* no audio mode with CoreAudio, its duplex or nuthin' */ + +#ifndef __APPLE__ basic_packer.attach (audio_mode_combo, 1, 2, 6, 7, FILL|EXPAND, (AttachOptions) 0); +#endif - /* + /* if (engine_running()) { start_button.set_sensitive (false); @@ -166,26 +190,41 @@ EngineControl::EngineControl () /* options */ - options_packer.attach (realtime_button, 0, 1, 0, 1, FILL|EXPAND, (AttachOptions) 0); + int row = 0; + options_packer.set_spacings (6); + + options_packer.attach (realtime_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; label = manage (new Label (_("Realtime Priority"))); - options_packer.attach (*label, 0, 1, 1, 2, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (priority_spinner, 1, 2, 1, 2, FILL|EXPAND, (AttachOptions) 0); + label->set_alignment (0.0, 0.5); + options_packer.attach (priority_spinner, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + options_packer.attach (*label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; priority_spinner.set_value (60); realtime_button.signal_toggled().connect (mem_fun (*this, &EngineControl::realtime_changed)); realtime_changed (); #ifndef __APPLE__ - options_packer.attach (no_memory_lock_button, 0, 1, 2, 3, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (unlock_memory_button, 0, 1, 3, 4, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (soft_mode_button, 0, 1, 4, 5, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (monitor_button, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (force16bit_button, 0, 1, 6, 7, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (hw_monitor_button, 0, 1, 7, 8, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (hw_meter_button, 0, 1, 8, 9, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (verbose_output_button, 0, 1, 9, 10, FILL|EXPAND, (AttachOptions) 0); + options_packer.attach (no_memory_lock_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (unlock_memory_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (soft_mode_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (monitor_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (force16bit_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (hw_monitor_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (hw_meter_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + options_packer.attach (verbose_output_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; #else - options_packer.attach (verbose_output_button, 0, 1, 2, 3, FILL|EXPAND, (AttachOptions) 0); + options_packer.attach (verbose_output_button, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; #endif strings.clear (); @@ -198,12 +237,24 @@ EngineControl::EngineControl () timeout_combo.set_active_text (strings.front ()); label = manage (new Label (_("Client timeout"))); - options_packer.attach (*label, 0, 1, 11, 12, (AttachOptions) 0, (AttachOptions) 0); - options_packer.attach (timeout_combo, 1, 2, 11, 12, FILL|EXPAND, AttachOptions(0)); + label->set_alignment (0.0, 0.5); + options_packer.attach (timeout_combo, 0, 1, row, row + 1, FILL|EXPAND, AttachOptions(0)); + options_packer.attach (*label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; label = manage (new Label (_("Number of ports"))); - options_packer.attach (*label, 0, 1, 12, 13, (AttachOptions) 0, (AttachOptions) 0); - options_packer.attach (ports_spinner, 1, 2, 12, 13, FILL|EXPAND, AttachOptions(0)); + label->set_alignment (0.0, 0.5); + options_packer.attach (ports_spinner, 0, 1, row, row + 1, FILL|EXPAND, AttachOptions(0)); + options_packer.attach (*label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; + +#ifndef __APPLE__ + label = manage (new Label (_("Dither"))); + label->set_alignment (0.0, 0.5); + options_packer.attach (dither_mode_combo, 0, 1, row, row + 1, FILL|EXPAND, AttachOptions(0)); + options_packer.attach (*label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; +#endif strings.clear (); @@ -217,12 +268,12 @@ EngineControl::EngineControl () set_popdown_strings (serverpath_combo, strings); serverpath_combo.set_active_text (strings.front()); - cerr << "we have " << strings.size() << " possible Jack servers\n"; - if (strings.size() > 1) { label = manage (new Label (_("Server:"))); - options_packer.attach (*label, 0, 1, 11, 12, (AttachOptions) 0, (AttachOptions) 0); - options_packer.attach (serverpath_combo, 1, 2, 11, 12, FILL|EXPAND, (AttachOptions) 0); + options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + label->set_alignment (0.0, 0.5); + options_packer.attach (serverpath_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + ++row; } /* device settings */ @@ -230,25 +281,33 @@ EngineControl::EngineControl () device_packer.set_spacings (6); label = manage (new Label (_("Input device"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 0, 1, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_device_combo, 1, 2, 0, 1, FILL|EXPAND, (AttachOptions) 0); label = manage (new Label (_("Output device"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 1, 2, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (output_device_combo, 1, 2, 1, 2, FILL|EXPAND, (AttachOptions) 0); label = manage (new Label (_("Input channels"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 2, 3, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_channels, 1, 2, 2, 3, FILL|EXPAND, (AttachOptions) 0); label = manage (new Label (_("Output channels"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 3, 4, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (output_channels, 1, 2, 3, 4, FILL|EXPAND, (AttachOptions) 0); - label = manage (new Label (_("Input latency (samples)"))); + label = manage (new Label (_("Hardware input latency (samples)"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 4, 5, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (input_latency, 1, 2, 4, 5, FILL|EXPAND, (AttachOptions) 0); - label = manage (new Label (_("Output latency (samples)"))); + label = manage (new Label (_("Hardware output latency (samples)"))); + label->set_alignment (1.0, 0.5); device_packer.attach (*label, 0, 1, 5, 6, FILL|EXPAND, (AttachOptions) 0); device_packer.attach (output_latency, 1, 2, 5, 6, FILL|EXPAND, (AttachOptions) 0); - notebook.pages().push_back (TabElem (basic_packer, _("Basics"))); + basic_hbox.pack_start (basic_packer, false, false); + + notebook.pages().push_back (TabElem (basic_hbox, _("Basics"))); notebook.pages().push_back (TabElem (options_packer, _("Options"))); notebook.pages().push_back (TabElem (device_packer, _("Device Parameters"))); @@ -338,16 +397,26 @@ EngineControl::build_command_line (vector<string>& cmd) /* driver arguments */ - str = audio_mode_combo.get_active_text(); - if (str == _("Duplex")) { - /* relax */ - } else if (str == _("Playback only")) { - cmd.push_back ("-P"); - } else if (str == _("Capture only")) { - cmd.push_back ("-C"); - } - 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")) { + + cmd.push_back ("-C"); + cmd.push_back (get_device_name (driver, input_device_combo.get_active_text())); + cmd.push_back ("-P"); + cmd.push_back (get_device_name (driver, output_device_combo.get_active_text())); + + } else if (str == _("Playback only")) { + cmd.push_back ("-P"); + } else if (str == _("Recording only")) { + cmd.push_back ("-C"); + } + cmd.push_back ("-n"); cmd.push_back (to_string ((uint32_t) floor (periods_spinner.get_value()), std::dec)); } @@ -359,9 +428,11 @@ EngineControl::build_command_line (vector<string>& cmd) cmd.push_back (period_size_combo.get_active_text()); if (using_alsa) { - - cmd.push_back ("-d"); - cmd.push_back (interface_combo.get_active_text()); + + if (audio_mode_combo.get_active_text() != _("Playback/Recording on 2 Devices")) { + cmd.push_back ("-d"); + cmd.push_back (get_device_name (driver, interface_combo.get_active_text())); + } if (hw_meter_button.get_active()) { cmd.push_back ("-M"); @@ -372,6 +443,7 @@ EngineControl::build_command_line (vector<string>& cmd) } str = dither_mode_combo.get_active_text(); + if (str == _("None")) { } else if (str == _("Triangular")) { cmd.push_back ("-z triangular"); @@ -393,23 +465,7 @@ EngineControl::build_command_line (vector<string>& cmd) #ifdef __APPLE__ cmd.push_back ("-n"); - - Glib::ustring str = interface_combo.get_active_text(); - vector<string>::iterator n; - vector<string>::iterator i; - - for (i = devices[driver].begin(), n = coreaudio_devs.begin(); i != devices[driver].end(); ++i, ++n) { - if (str == (*i)) { - cerr << "for " << str << " use " << (*n) << endl; - cmd.push_back (*n); - break; - } - } - - if (i == devices[driver].end()) { - fatal << string_compose (_("programming error: %1"), "coreaudio device ID missing") << endmsg; - /*NOTREACHED*/ - } + cmd.push_back (get_device_name (driver, interface_combo.get_active_text())); #endif } else if (using_oss) { @@ -458,6 +514,8 @@ EngineControl::start_engine () jackdrc << endl; cerr << endl; jackdrc.close (); + + _used = true; #if 0 @@ -477,10 +535,6 @@ EngineControl::start_engine () int EngineControl::stop_engine () { - close (engine_stdin); - close (engine_stderr); - close (engine_stdout); - spawn_close_pid (engine_pid); return 0; } @@ -531,7 +585,7 @@ EngineControl::enumerate_coreaudio_devices () Boolean isWritable; size_t outSize = sizeof(isWritable); - coreaudio_devs.clear (); + backend_devs.clear (); err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &outSize, &isWritable); @@ -563,7 +617,7 @@ EngineControl::enumerate_coreaudio_devices () if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) { devs.push_back (coreDeviceName); - coreaudio_devs.push_back (drivername); + backend_devs.push_back (drivername); } } } @@ -579,12 +633,63 @@ vector<string> EngineControl::enumerate_alsa_devices () { vector<string> devs; - devs.push_back ("hw:0"); - devs.push_back ("hw:1"); - devs.push_back ("plughw:0"); - devs.push_back ("plughw:1"); + + 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; + + backend_devs.clear (); + + while (snd_card_next (&cardnum) >= 0 && cardnum >= 0) { + + devname = "hw:"; + devname += to_string (cardnum, std::dec); + + if (snd_ctl_open (&handle, devname.c_str(), 0) >= 0 && snd_ctl_card_info (handle, info) >= 0) { + + 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); + backend_devs.push_back (devname); + } + } + + snd_ctl_close(handle); + } + } + return devs; } + vector<string> EngineControl::enumerate_ffado_devices () { @@ -618,9 +723,13 @@ EngineControl::driver_changed () vector<string>& strings = devices[driver]; set_popdown_strings (interface_combo, strings); + set_popdown_strings (input_device_combo, strings); + set_popdown_strings (output_device_combo, strings); if (!strings.empty()) { 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") { @@ -662,19 +771,23 @@ EngineControl::audio_mode_changed () { Glib::ustring str = audio_mode_combo.get_active_text(); - if (str == _("Duplex")) { + if (str == _("Playback/Recording on 1 Device")) { input_device_combo.set_sensitive (false); output_device_combo.set_sensitive (false); - } else { + } else if (str == _("Playback/Recording on 2 Devices")) { input_device_combo.set_sensitive (true); output_device_combo.set_sensitive (true); + } else if (str == _("Playback only")) { + output_device_combo.set_sensitive (true); + } else if (str == _("Recording only")) { + input_device_combo.set_sensitive (true); } } void EngineControl::find_jack_servers (vector<string>& strings) { -#ifdef __APPLE +#ifdef __APPLE__ if (Profile->get_single_package()) { /* this magic lets us finds the path to the OSX bundle, and then @@ -696,8 +809,9 @@ EngineControl::find_jack_servers (vector<string>& strings) } else { warning << _("JACK appears to be missing from the Ardour bundle") << endmsg; } + } #endif - + if (Glib::file_test ("/usr/bin/jackd", FILE_TEST_EXISTS)) { strings.push_back ("/usr/bin/jackd"); } @@ -718,3 +832,244 @@ EngineControl::find_jack_servers (vector<string>& strings) } } + +string +EngineControl::get_device_name (const string& driver, const string& human_readable) +{ + vector<string>::iterator n; + vector<string>::iterator i; + + 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()) { + fatal << string_compose (_("programming error: %1"), "true hardware name for ID missing") << endmsg; + /*NOTREACHED*/ + } + + /* keep gcc happy */ + + return string(); +} + +XMLNode& +EngineControl::get_state () +{ + XMLNode* root = new XMLNode ("AudioSetup"); + XMLNode* child; + Glib::ustring path; + + child = new XMLNode ("periods"); + child->add_property ("val", to_string (periods_adjustment.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("priority"); + child->add_property ("val", to_string (priority_adjustment.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("ports"); + child->add_property ("val", to_string (ports_adjustment.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("inchannels"); + child->add_property ("val", to_string (input_channels.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("outchannels"); + child->add_property ("val", to_string (output_channels.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("inlatency"); + child->add_property ("val", to_string (input_latency.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("outlatency"); + child->add_property ("val", to_string (output_latency.get_value(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("realtime"); + child->add_property ("val", to_string (realtime_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("nomemorylock"); + child->add_property ("val", to_string (no_memory_lock_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("unlockmemory"); + child->add_property ("val", to_string (unlock_memory_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("softmode"); + child->add_property ("val", to_string (soft_mode_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("force16bit"); + child->add_property ("val", to_string (force16bit_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("hwmonitor"); + child->add_property ("val", to_string (hw_monitor_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("hwmeter"); + child->add_property ("val", to_string (hw_meter_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("verbose"); + child->add_property ("val", to_string (verbose_output_button.get_active(), std::dec)); + root->add_child_nocopy (*child); + + child = new XMLNode ("samplerate"); + child->add_property ("val", sample_rate_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("periodsize"); + child->add_property ("val", period_size_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("serverpath"); + child->add_property ("val", serverpath_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("driver"); + child->add_property ("val", driver_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("interface"); + child->add_property ("val", interface_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("timeout"); + child->add_property ("val", timeout_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("dither"); + child->add_property ("val", dither_mode_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("audiomode"); + child->add_property ("val", audio_mode_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("inputdevice"); + child->add_property ("val", input_device_combo.get_active_text()); + root->add_child_nocopy (*child); + + child = new XMLNode ("outputdevice"); + child->add_property ("val", output_device_combo.get_active_text()); + root->add_child_nocopy (*child); + + return *root; +} + +void +EngineControl::set_state (const XMLNode& root) +{ + XMLNodeList clist; + XMLNodeConstIterator citer; + XMLNode* child; + XMLProperty* prop; + + int val; + string strval; + + clist = root.children(); + + for (citer = clist.begin(); citer != clist.end(); ++citer) { + + child = *citer; + + prop = child->property ("val"); + + if (!prop || prop->value().empty()) { + error << string_compose (_("AudioSetup value for %1 is missing data"), child->name()) << endmsg; + continue; + } + + strval = prop->value(); + + /* adjustments/spinners */ + + if (child->name() == "periods") { + val = atoi (strval); + periods_adjustment.set_value(val); + } else if (child->name() == "priority") { + val = atoi (strval); + priority_adjustment.set_value(val); + } else if (child->name() == "ports") { + val = atoi (strval); + ports_adjustment.set_value(val); + } else if (child->name() == "inchannels") { + val = atoi (strval); + input_channels.set_value(val); + } else if (child->name() == "outchannels") { + val = atoi (strval); + output_channels.set_value(val); + } else if (child->name() == "inlatency") { + val = atoi (strval); + input_latency.set_value(val); + } else if (child->name() == "outlatency") { + val = atoi (strval); + output_latency.set_value(val); + } + + /* buttons */ + + else if (child->name() == "realtime") { + val = atoi (strval); + realtime_button.set_active(val); + } else if (child->name() == "nomemorylock") { + val = atoi (strval); + no_memory_lock_button.set_active(val); + } else if (child->name() == "unlockmemory") { + val = atoi (strval); + unlock_memory_button.set_active(val); + } else if (child->name() == "softmode") { + val = atoi (strval); + soft_mode_button.set_active(val); + } else if (child->name() == "force16bit") { + val = atoi (strval); + force16bit_button.set_active(val); + } else if (child->name() == "hwmonitor") { + val = atoi (strval); + hw_monitor_button.set_active(val); + } else if (child->name() == "hwmeter") { + val = atoi (strval); + hw_meter_button.set_active(val); + } else if (child->name() == "verbose") { + val = atoi (strval); + verbose_output_button.set_active(val); + } + + /* combos */ + + else if (child->name() == "samplerate") { + sample_rate_combo.set_active_text(strval); + } else if (child->name() == "periodsize") { + period_size_combo.set_active_text(strval); + } else if (child->name() == "serverpath") { + serverpath_combo.set_active_text(strval); + } else if (child->name() == "driver") { + driver_combo.set_active_text(strval); + } else if (child->name() == "interface") { + interface_combo.set_active_text(strval); + } else if (child->name() == "timeout") { + timeout_combo.set_active_text(strval); + } else if (child->name() == "dither") { + dither_mode_combo.set_active_text(strval); + } else if (child->name() == "audiomode") { + audio_mode_combo.set_active_text(strval); + } else if (child->name() == "inputdevice") { + input_device_combo.set_active_text(strval); + } else if (child->name() == "outputdevice") { + output_device_combo.set_active_text(strval); + } + } +} diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h index 2115538679..e3623d2d76 100644 --- a/gtk2_ardour/engine_dialog.h +++ b/gtk2_ardour/engine_dialog.h @@ -24,6 +24,10 @@ class EngineControl : public Gtk::VBox { int start_engine (); int stop_engine (); + bool was_used() const { return _used; } + XMLNode& get_state (); + void set_state (const XMLNode&); + private: Gtk::Adjustment periods_adjustment; Gtk::SpinButton periods_spinner; @@ -67,24 +71,21 @@ class EngineControl : public Gtk::VBox { Gtk::Table basic_packer; Gtk::Table options_packer; Gtk::Table device_packer; - + Gtk::HBox basic_hbox; Gtk::Notebook notebook; + + bool _used; void realtime_changed (); void driver_changed (); - void build_command_line (std::vector<std::string>&); - Glib::Pid engine_pid; - int engine_stdin; - int engine_stdout; - int engine_stderr; std::map<std::string,std::vector<std::string> > devices; + std::vector<std::string> backend_devs; void enumerate_devices (); #ifdef __APPLE__ std::vector<std::string> enumerate_coreaudio_devices (); - std::vector<std::string> coreaudio_devs; #else std::vector<std::string> enumerate_alsa_devices (); std::vector<std::string> enumerate_oss_devices (); @@ -97,6 +98,7 @@ class EngineControl : public Gtk::VBox { uint32_t get_rate(); void audio_mode_changed (); void find_jack_servers (std::vector<std::string>&); + std::string get_device_name (const std::string& driver, const std::string& human_readable_name); }; #endif /* __gtk2_ardour_engine_dialog_h__ */ diff --git a/gtk2_ardour/new_session_dialog.cc b/gtk2_ardour/new_session_dialog.cc index d48a332cbc..65fdc35903 100644 --- a/gtk2_ardour/new_session_dialog.cc +++ b/gtk2_ardour/new_session_dialog.cc @@ -452,10 +452,8 @@ void NewSessionDialog::set_have_engine (bool yn) { if (yn) { - cerr << "removing audio page\n"; m_notebook->remove_page (engine_control); } else { - cerr << "appending audio page\n"; m_notebook->append_page (engine_control, _("Audio Setup")); m_notebook->show_all_children(); } diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index e68be7149c..2ef7c43d4f 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -106,13 +106,13 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) session = 0; WindowTitle title(Glib::get_application_name()); - title += _("Options Editor"); + title += _("Preferences"); set_title(title.get_string()); set_default_size (300, 300); - set_wmclass (X_("ardour_option_editor"), "Ardour"); + set_wmclass (X_("ardour_preferences"), "Ardour"); - set_name ("OptionsWindow"); + set_name ("Preferences"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); VBox *vbox = get_vbox(); |