Midi Busses? why yes!
authorRobin Gareus <robin@gareus.org>
Wed, 16 Mar 2016 03:41:19 +0000 (04:41 +0100)
committerRobin Gareus <robin@gareus.org>
Wed, 16 Mar 2016 03:41:19 +0000 (04:41 +0100)
gtk2_ardour/add_route_dialog.cc
gtk2_ardour/add_route_dialog.h
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
libs/ardour/ardour/session.h
libs/ardour/session.cc

index 1127ab2da770312bb2eb89778c7b7905942ee292..14dda03d08580fb500d694bfc4ae1d7ef65170e7 100644 (file)
@@ -77,7 +77,8 @@ AddRouteDialog::AddRouteDialog ()
        track_bus_combo.append_text (_("Audio Tracks"));
        track_bus_combo.append_text (_("MIDI Tracks"));
        track_bus_combo.append_text (_("Audio+MIDI Tracks"));
-       track_bus_combo.append_text (_("Busses"));
+       track_bus_combo.append_text (_("Audio Busses"));
+       track_bus_combo.append_text (_("MIDI Busses"));
        track_bus_combo.set_active (0);
 
        insert_at_combo.append_text (_("First"));
@@ -198,8 +199,10 @@ AddRouteDialog::TypeWanted
 AddRouteDialog::type_wanted() const
 {
        std::string str = track_bus_combo.get_active_text();
-       if (str == _("Busses")) {
+       if (str == _("Audio Busses")) {
                return AudioBus;
+       } else if (str == _("MIDI Busses")){
+               return MidiBus;
        } else if (str == _("MIDI Tracks")){
                return MidiTrack;
        } else if (str == _("Audio+MIDI Tracks")) {
@@ -232,6 +235,7 @@ AddRouteDialog::maybe_update_name_template_entry ()
                name_template_entry.set_text (_("Audio+MIDI"));
                break;
        case AudioBus:
+       case MidiBus:
                name_template_entry.set_text (_("Bus"));
                break;
        }
@@ -280,6 +284,14 @@ AddRouteDialog::track_type_chosen ()
                mode_label.set_sensitive (true);
                instrument_label.set_sensitive (false);
                break;
+       case MidiBus:
+               mode_combo.set_sensitive (false);
+               channel_combo.set_sensitive (false);
+               instrument_combo.set_sensitive (true);
+               configuration_label.set_sensitive (false);
+               mode_label.set_sensitive (true);
+               instrument_label.set_sensitive (true);
+               break;
        }
 
        maybe_update_name_template_entry ();
index eb38338f1f73d8ab8721a56484ddf85567a884ce..08359c2000420ef5853141bf5743f9ff8f0780b6 100644 (file)
@@ -49,19 +49,20 @@ class AddRouteDialog : public ArdourDialog
        AddRouteDialog ();
        ~AddRouteDialog ();
 
-        enum TypeWanted {
+       enum TypeWanted {
                AudioTrack,
                MidiTrack,
                MixedTrack,
-               AudioBus
+               AudioBus,
+               MidiBus
        };
-        TypeWanted type_wanted() const;
+       TypeWanted type_wanted() const;
 
-        ARDOUR::ChanCount channels ();
+       ARDOUR::ChanCount channels ();
        int count ();
 
-        std::string name_template () const;
-        bool name_template_is_default () const;
+       std::string name_template () const;
+       bool name_template_is_default () const;
        std::string track_template ();
        ARDOUR::PluginInfoPtr requested_instrument ();
 
index a01f2edaed5d9ad688f6a0980ef3f83bbadcea30..e1bcd06b7c48817e8916f6c297fc49dcfdc2d988 100644 (file)
@@ -1806,6 +1806,31 @@ restart with more ports."), PROGRAM_NAME));
        }
 }
 
+void
+ARDOUR_UI::session_add_midi_bus (RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
+{
+
+       if (_session == 0) {
+               warning << _("You cannot add a track without a session already loaded.") << endmsg;
+               return;
+       }
+
+       try {
+               RouteList routes = _session->new_midi_route (route_group, how_many, name_template, instrument);
+               if (routes.size() != how_many) {
+                       error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
+               }
+
+       }
+       catch (...) {
+               MessageDialog msg (_main_window,
+                                  string_compose (_("There are insufficient ports available\n\
+to create a new track or bus.\n\
+You should save %1, exit and\n\
+restart with more ports."), PROGRAM_NAME));
+               msg.run ();
+       }
+}
 
 void
 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
@@ -1815,6 +1840,8 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t
 
        if (disk) {
                session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, instrument);
+       } else {
+               session_add_midi_bus (route_group, how_many, name_template, instrument);
        }
 }
 
@@ -3939,6 +3966,9 @@ ARDOUR_UI::add_route (Gtk::Window* /* ignored */)
        case AddRouteDialog::AudioBus:
                session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template);
                break;
+       case AddRouteDialog::MidiBus:
+               session_add_midi_bus (route_group, count, name_template, instrument);
+               break;
        }
 }
 
index bc58341ec70101cb2491182d72656f353cc794b3..09baa2c9eeca6d136f3e54b375972d69c1c5ce05 100644 (file)
@@ -289,19 +289,18 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
                session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, route_group, how_many, name_template);
        }
 
+
        void session_add_midi_track (ARDOUR::RouteGroup* route_group, uint32_t how_many, std::string const & name_template,
-                                    ARDOUR::PluginInfoPtr instrument) {
+                       ARDOUR::PluginInfoPtr instrument) {
                session_add_midi_route (true, route_group, how_many, name_template, instrument);
        }
 
-        void session_add_mixed_track (const ARDOUR::ChanCount& input, const ARDOUR::ChanCount& output, ARDOUR::RouteGroup* route_group, uint32_t how_many, std::string const & name_template,
-                                     ARDOUR::PluginInfoPtr instrument);
+       void session_add_mixed_track (const ARDOUR::ChanCount& input, const ARDOUR::ChanCount& output, ARDOUR::RouteGroup* route_group, uint32_t how_many, std::string const & name_template,
+                       ARDOUR::PluginInfoPtr instrument);
 
-       /*void session_add_midi_bus () {
-               session_add_midi_route (false);
-       }*/
+       void session_add_midi_bus (ARDOUR::RouteGroup* route_group, uint32_t how_many, std::string const & name_template, ARDOUR::PluginInfoPtr instrument);
 
-        void attach_to_engine ();
+       void attach_to_engine ();
        void post_engine ();
 
        gint exit_on_main_window_close (GdkEventAny *);
index 0651eb69bf0e6ef56be2bb2f2885d4d7a5c272bf..a650bfdb1a2a83a9754095811a508642df706a5b 100644 (file)
@@ -585,6 +585,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
                RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = ""
                );
 
+       RouteList new_midi_route (RouteGroup* route_group, uint32_t how_many, std::string name_template = "", boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>());
+
        void remove_routes (boost::shared_ptr<RouteList>);
        void remove_route (boost::shared_ptr<Route>);
 
index f58994a0d3f48d8c9d131d4db79afb8fc77f4eb8..d668fb46e768cf32707ddde67be8785a0c9fb72b 100644 (file)
@@ -2435,6 +2435,92 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
        return ret;
 }
 
+RouteList
+Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument)
+{
+       string bus_name;
+       uint32_t bus_id = 0;
+       string port;
+       RouteList ret;
+
+       bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Midi Bus");
+
+       while (how_many) {
+               if (!find_route_name (name_template.empty () ? _("Midi Bus") : name_template, ++bus_id, bus_name, use_number)) {
+                       error << "cannot find name for new midi bus" << endmsg;
+                       goto failure;
+               }
+
+               try {
+                       boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
+
+                       if (bus->init ()) {
+                               goto failure;
+                       }
+
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+                       // boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
+#endif
+                       {
+                               Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+
+                               if (bus->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
+                                       error << _("cannot configure new midi bus input") << endmsg;
+                                       goto failure;
+                               }
+
+
+                               if (bus->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
+                                       error << _("cannot configure new midi bus output") << endmsg;
+                                       goto failure;
+                               }
+                       }
+
+                       if (route_group) {
+                               route_group->add (bus);
+                       }
+                       if (Config->get_remote_model() == UserOrdered) {
+                               bus->set_remote_control_id (next_control_id());
+                       }
+
+                       ret.push_back (bus);
+                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
+                       ARDOUR::GUIIdle ();
+               }
+
+               catch (failed_constructor &err) {
+                       error << _("Session: could not create new audio route.") << endmsg;
+                       goto failure;
+               }
+
+               catch (AudioEngine::PortRegistrationFailure& pfe) {
+                       error << pfe.what() << endmsg;
+                       goto failure;
+               }
+
+
+               --how_many;
+       }
+
+  failure:
+       if (!ret.empty()) {
+               StateProtector sp (this);
+               add_routes (ret, false, false, false);
+
+               if (instrument) {
+                       for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
+                               PluginPtr plugin = instrument->load (*this);
+                               boost::shared_ptr<Processor> p (new PluginInsert (*this, plugin));
+                               (*r)->add_processor (p, PreFader);
+                       }
+               }
+       }
+
+       return ret;
+
+}
+
+
 void
 Session::midi_output_change_handler (IOChange change, void * /*src*/, boost::weak_ptr<Route> wmt)
 {