2 * Copyright (C) 1999-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2007 Jesse Chappell <jesse@essej.net>
4 * Copyright (C) 2006-2009 Sampo Savolainen <v2@iki.fi>
5 * Copyright (C) 2006-2015 David Robillard <d@drobilla.net>
6 * Copyright (C) 2006-2016 Tim Mayberry <mojofunk@gmail.com>
7 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
8 * Copyright (C) 2008-2009 Hans Baier <hansfbaier@googlemail.com>
9 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
10 * Copyright (C) 2013-2017 Nick Mainsbridge <mainsbridge@gmail.com>
11 * Copyright (C) 2014-2019 Ben Loftis <ben@harrisonconsoles.com>
12 * Copyright (C) 2015 GZharun <grygoriiz@wavesglobal.com>
13 * Copyright (C) 2016-2018 Len Ovens <len@ovenwerks.net>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <boost/algorithm/string/erase.hpp>
36 #include "ardour/audioengine.h"
37 #include "ardour/bundle.h"
38 #include "ardour/session.h"
39 #include "ardour/user_bundle.h"
41 using namespace ARDOUR;
45 Session::add_bundle (boost::shared_ptr<Bundle> bundle, bool emit_signal)
48 RCUWriter<BundleList> writer (_bundles);
49 boost::shared_ptr<BundleList> b = writer.get_copy ();
50 b->push_back (bundle);
54 BundleAddedOrRemoved (); /* EMIT SIGNAL */
61 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
66 RCUWriter<BundleList> writer (_bundles);
67 boost::shared_ptr<BundleList> b = writer.get_copy ();
68 BundleList::iterator i = find (b->begin(), b->end(), bundle);
77 BundleAddedOrRemoved (); /* EMIT SIGNAL */
83 boost::shared_ptr<Bundle>
84 Session::bundle_by_name (string name) const
86 boost::shared_ptr<BundleList> b = _bundles.reader ();
88 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
89 if ((*i)->name() == name) {
94 return boost::shared_ptr<Bundle> ();
98 Session::setup_bundles ()
102 RCUWriter<BundleList> writer (_bundles);
103 boost::shared_ptr<BundleList> b = writer.get_copy ();
104 for (BundleList::iterator i = b->begin(); i != b->end();) {
105 if (boost::dynamic_pointer_cast<UserBundle>(*i)) {
113 std::vector<string> inputs[DataType::num_types];
114 std::vector<string> outputs[DataType::num_types];
116 for (uint32_t i = 0; i < DataType::num_types; ++i) {
117 get_physical_ports (inputs[i], outputs[i], DataType (DataType::Symbol (i)),
118 MidiPortFlags (0), /* no specific inclusions */
119 MidiPortFlags (MidiPortControl|MidiPortVirtual) /* exclude control & virtual ports */
123 /* Create a set of Bundle objects that map
124 to the physical I/O currently available. We create both
125 mono and stereo bundles, so that the common cases of mono
126 and stereo tracks get bundles to put in their mixer strip
127 in / out menus. There may be a nicer way of achieving that;
128 it doesn't really scale that well to higher channel counts
131 /* mono output bundles */
133 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
135 std::string pn = _engine.get_pretty_name_by_name (outputs[DataType::AUDIO][np]);
137 snprintf (buf, sizeof (buf), _("out %s"), pn.c_str());
139 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
142 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
143 c->add_channel (_("mono"), DataType::AUDIO);
144 c->set_port (0, outputs[DataType::AUDIO][np]);
146 add_bundle (c, false);
149 /* stereo output bundles */
151 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
152 if (np + 1 < outputs[DataType::AUDIO].size()) {
154 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
155 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
156 c->add_channel (_("L"), DataType::AUDIO);
157 c->set_port (0, outputs[DataType::AUDIO][np]);
158 c->add_channel (_("R"), DataType::AUDIO);
159 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
161 add_bundle (c, false);
165 /* mono input bundles */
167 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
169 std::string pn = _engine.get_pretty_name_by_name (inputs[DataType::AUDIO][np]);
171 snprintf (buf, sizeof (buf), _("in %s"), pn.c_str());
173 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
176 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
177 c->add_channel (_("mono"), DataType::AUDIO);
178 c->set_port (0, inputs[DataType::AUDIO][np]);
180 add_bundle (c, false);
183 /* stereo input bundles */
185 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
186 if (np + 1 < inputs[DataType::AUDIO].size()) {
188 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
190 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
191 c->add_channel (_("L"), DataType::AUDIO);
192 c->set_port (0, inputs[DataType::AUDIO][np]);
193 c->add_channel (_("R"), DataType::AUDIO);
194 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
196 add_bundle (c, false);
200 /* MIDI input bundles */
202 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
203 string n = inputs[DataType::MIDI][np];
205 std::string pn = _engine.get_pretty_name_by_name (n);
209 boost::erase_first (n, X_("alsa_pcm:"));
211 boost::shared_ptr<Bundle> c (new Bundle (n, false));
212 c->add_channel ("", DataType::MIDI);
213 c->set_port (0, inputs[DataType::MIDI][np]);
214 add_bundle (c, false);
217 /* MIDI output bundles */
219 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
220 string n = outputs[DataType::MIDI][np];
221 std::string pn = _engine.get_pretty_name_by_name (n);
225 boost::erase_first (n, X_("alsa_pcm:"));
227 boost::shared_ptr<Bundle> c (new Bundle (n, true));
228 c->add_channel ("", DataType::MIDI);
229 c->set_port (0, outputs[DataType::MIDI][np]);
230 add_bundle (c, false);
233 // we trust the backend to only calls us if there's a change
234 BundleAddedOrRemoved (); /* EMIT SIGNAL */