initial work on adding access to h/w control apps when ardour starts JACK
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 9 Sep 2013 19:17:29 +0000 (15:17 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 9 Sep 2013 19:17:43 +0000 (15:17 -0400)
gtk2_ardour/engine_dialog.cc
gtk2_ardour/engine_dialog.h
libs/ardour/ardour/audio_backend.h
libs/backends/jack/jack_audiobackend.cc
libs/backends/jack/jack_audiobackend.h

index f858f56b17696896974ece465959e4daf0ea243b..b5a59af642c752e546d79ad38f1d10fab6dd813d 100644 (file)
@@ -63,7 +63,7 @@ EngineControl::EngineControl ()
        , output_channels (output_channels_adjustment)
        , ports_adjustment (128, 8, 1024, 1, 16)
        , ports_spinner (ports_adjustment)
-       , realtime_button (_("Realtime"))
+       , control_app_button (_("Launch Control App"))
        , basic_packer (9, 3)
 {
        build_notebook ();
@@ -71,6 +71,15 @@ EngineControl::EngineControl ()
        get_vbox()->set_border_width (12);
        get_vbox()->pack_start (notebook);
 
+       Gtk::HBox* hpacker = manage (new HBox);
+       hpacker->pack_start (control_app_button, false, false);
+       hpacker->show ();
+       control_app_button.show();
+       get_vbox()->pack_start (*hpacker);
+
+       control_app_button.signal_clicked().connect (mem_fun (*this, &EngineControl::control_app_button_clicked));
+       manage_control_app_sensitivity ();
+
        add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
        add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
        add_button (Gtk::Stock::APPLY, Gtk::RESPONSE_APPLY);
@@ -347,6 +356,8 @@ EngineControl::device_changed ()
        buffer_size_combo.set_active_text (s.front());
        show_buffer_duration ();
 
+       manage_control_app_sensitivity ();
+
        maybe_set_state ();
 }      
 
@@ -700,9 +711,12 @@ EngineControl::setup_engine (bool start)
                state->active = true;
                
                if (start) {
-                       return ARDOUR::AudioEngine::instance()->start();
+                       if (ARDOUR::AudioEngine::instance()->start()) {
+                               return -1;
+                       }
                }
 
+               manage_control_app_sensitivity ();
                return 0;
 
        } catch (...) {
@@ -773,3 +787,25 @@ EngineControl::get_device_name () const
        return device_combo.get_active_text ();
 }
 
+void
+EngineControl::control_app_button_clicked ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+
+       if (!backend) {
+               return;
+       }
+
+       backend->launch_control_app();
+}
+
+void
+EngineControl::manage_control_app_sensitivity ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       if (backend && backend->have_control_app()) {
+               control_app_button.set_sensitive (true);
+       } else {
+               control_app_button.set_sensitive (false);
+       }
+}
index deaa0afa5473640c84e001a58f1eec80d99a1c06..97d41995fa2c5249f0b7f9853d8bf89b2539f001 100644 (file)
@@ -68,6 +68,8 @@ class EngineControl : public ArdourDialog {
     Gtk::Adjustment ports_adjustment;
     Gtk::SpinButton ports_spinner;
 
+    Gtk::Button     control_app_button;
+
     /* JACK specific */
     
     Gtk::CheckButton realtime_button;
@@ -80,7 +82,6 @@ class EngineControl : public ArdourDialog {
     Gtk::CheckButton hw_meter_button;
     Gtk::CheckButton verbose_output_button;
     
-    
     Gtk::ComboBoxText preset_combo;
     Gtk::ComboBoxText serverpath_combo;
     Gtk::ComboBoxText driver_combo;
@@ -150,6 +151,8 @@ class EngineControl : public ArdourDialog {
     void build_notebook ();
 
     void on_response (int);
+    void control_app_button_clicked ();
+    void manage_control_app_sensitivity ();
 };
 
 #endif /* __gtk2_ardour_engine_dialog_h__ */
index 4192f0ea8b0e93257ac8e612bd97a59f28e48584..f598f1a93a0a2d204144d2744d8eb8aa1b8a414d 100644 (file)
@@ -228,6 +228,21 @@ class AudioBackend {
     virtual uint32_t     systemic_input_latency () const = 0;
     virtual uint32_t     systemic_output_latency () const = 0;
 
+    /** Return true if it is possible to launch a control app
+     * at this time. Return false otherwise.
+     *
+     * The audio backend may not know the device for which the
+     * control app should be opened, or there may no such
+     * application. In such cases, this method should return false.
+     */
+    virtual bool have_control_app() const = 0;
+
+    /** If the device name has been set, launch an application (if any exist)
+     * to manage the hardware settings of that device. If no such application
+     * exists, do nothing.
+     */
+    virtual void launch_control_app () = 0;
+
     /* Basic state control */
 
     /** Start using the device named in the most recent call
index f452a78d4989e7d63f0d86a874199f73dd0bb958..f21440e046027f14ace0aaddf57129c2261dcba8 100644 (file)
 
 */
 
+#include <string>
+#include <list>
 #include <math.h>
 
 #include <boost/scoped_ptr.hpp>
 #include <glibmm/timer.h>
+#include <glibmm/spawn.h>
 
 #include "pbd/error.h"
 
@@ -340,7 +343,11 @@ JACKAudioBackend::set_systemic_output_latency (uint32_t l)
 std::string
 JACKAudioBackend::device_name () const
 {
-       return string();
+       if (connected()) {
+               return "???";
+       } 
+
+       return _target_device;
 }
 
 float
@@ -947,3 +954,53 @@ JACKAudioBackend::can_change_buffer_size_when_running () const
 {
        return true;
 }
+
+string
+JACKAudioBackend::control_app_name () const
+{
+       string appname;
+
+       if (_target_device.empty()) {
+               return appname;
+       }
+
+#if defined (__linux)
+       /* Linux potential control apps */
+
+       if (_target_device == "Hammerfall DSP") {
+               appname = "hdspconf";
+       }
+#else
+#if defined (__APPLE__)
+       /* OS X potential control apps */
+#else
+       /* Windows potential control apps */
+#endif
+#endif
+
+       return appname;
+}
+
+bool
+JACKAudioBackend::have_control_app () const
+{
+       return !control_app_name().empty();
+}
+
+void
+JACKAudioBackend::launch_control_app ()
+{
+       /* launch control app, don't care if it succeeds */
+
+       string appname = control_app_name ();
+
+       if (appname.empty()) {
+               return;
+       }
+       
+       std::list<string> args;
+       args.push_back (appname);
+       Glib::spawn_async ("", args, Glib::SPAWN_SEARCH_PATH);
+}
+
+       
index f47b630f49a25b43fa0524e02fab5dcb48dbbc81..15246a030566826d431a7c78af129b991f707464 100644 (file)
@@ -84,6 +84,9 @@ class JACKAudioBackend : public AudioBackend {
     uint32_t     systemic_input_latency () const;
     uint32_t     systemic_output_latency () const;
 
+    bool have_control_app() const;
+    void launch_control_app ();
+
     int start ();
     int stop ();
     int pause ();
@@ -179,6 +182,7 @@ class JACKAudioBackend : public AudioBackend {
     mutable DriverDeviceMap all_devices;
 
     PBD::ScopedConnection disconnect_connection;
+    std::string control_app_name () const;
 };
 
 } // namespace