2 Copyright (C) 2000-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
28 #include <glibmm/thread.h>
30 #include <pbd/xml++.h>
31 #include <pbd/replace_all.h>
32 #include <pbd/unknown_type.h>
34 #include <ardour/audioengine.h>
35 #include <ardour/io.h>
36 #include <ardour/route.h>
37 #include <ardour/port.h>
38 #include <ardour/audio_port.h>
39 #include <ardour/midi_port.h>
40 #include <ardour/auto_bundle.h>
41 #include <ardour/session.h>
42 #include <ardour/cycle_timer.h>
43 #include <ardour/panner.h>
44 #include <ardour/buffer_set.h>
45 #include <ardour/meter.h>
46 #include <ardour/amp.h>
53 A bug in OS X's cmath that causes isnan() and isinf() to be
54 "undeclared". the following works around that
57 #if defined(__APPLE__) && defined(__MACH__)
58 extern "C" int isnan (double);
59 extern "C" int isinf (double);
62 #define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock())
65 using namespace ARDOUR;
68 const string IO::state_node_name = "IO";
69 bool IO::connecting_legal = false;
70 bool IO::ports_legal = false;
71 bool IO::panners_legal = false;
72 sigc::signal<void> IO::Meter;
73 sigc::signal<int> IO::ConnectingLegal;
74 sigc::signal<int> IO::PortsLegal;
75 sigc::signal<int> IO::PannersLegal;
76 sigc::signal<void,ChanCount> IO::PortCountChanged;
77 sigc::signal<int> IO::PortsCreated;
79 Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
81 /* this is a default mapper of [0 .. 1.0] control values to a gain coefficient.
82 others can be imagined.
86 static gain_t direct_control_to_gain (double fract) {
87 /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
88 /* this maxes at +6dB */
89 return pow (2.0,(sqrt(sqrt(sqrt(fract)))*198.0-192.0)/6.0);
92 static double direct_gain_to_control (gain_t gain) {
93 /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
94 if (gain == 0) return 0.0;
96 return pow((6.0*log(gain)/log(2.0)+192.0)/198.0, 8.0);
100 /** @param default_type The type of port that will be created by ensure_io
101 * and friends if no type is explicitly requested (to avoid breakage).
103 IO::IO (Session& s, const string& name,
104 int input_min, int input_max, int output_min, int output_max,
105 DataType default_type, bool public_ports)
106 : SessionObject(s, name),
107 AutomatableControls (s),
108 _output_buffers (new BufferSet()),
110 _default_type (default_type),
111 _public_ports (public_ports),
112 _input_minimum (ChanCount::ZERO),
113 _input_maximum (ChanCount::INFINITE),
114 _output_minimum (ChanCount::ZERO),
115 _output_maximum (ChanCount::INFINITE)
117 _panner = new Panner (name, _session);
118 _meter = new PeakMeter (_session);
121 _input_minimum = ChanCount(_default_type, input_min);
123 if (input_max >= 0) {
124 _input_maximum = ChanCount(_default_type, input_max);
126 if (output_min > 0) {
127 _output_minimum = ChanCount(_default_type, output_min);
129 if (output_max >= 0) {
130 _output_maximum = ChanCount(_default_type, output_max);
135 pending_state_node = 0;
136 no_panner_reset = false;
137 _phase_invert = false;
140 boost::shared_ptr<AutomationList> gl(
141 new AutomationList(Evoral::Parameter(GainAutomation)));
143 _gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
145 add_control(_gain_control);
147 apply_gain_automation = false;
150 // IO::Meter is emitted from another thread so the
151 // Meter signal must be protected.
152 Glib::Mutex::Lock guard (m_meter_signal_lock);
153 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
156 // Connect to our own PortCountChanged signal to connect output buffers
157 IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
159 _session.add_controllable (_gain_control);
161 create_bundles_for_inputs_and_outputs ();
164 IO::IO (Session& s, const XMLNode& node, DataType dt)
165 : SessionObject(s, "unnamed io"),
166 AutomatableControls (s),
167 _output_buffers (new BufferSet()),
171 _meter = new PeakMeter (_session);
172 _public_ports = true; // XXX get this from node
175 no_panner_reset = false;
179 apply_gain_automation = false;
181 boost::shared_ptr<AutomationList> gl(
182 new AutomationList(Evoral::Parameter(GainAutomation)));
184 _gain_control = boost::shared_ptr<GainControl>(
185 new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl));
187 add_control(_gain_control);
192 // IO::Meter is emitted from another thread so the
193 // Meter signal must be protected.
194 Glib::Mutex::Lock guard (m_meter_signal_lock);
195 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
198 // Connect to our own PortCountChanged signal to connect output buffers
199 IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
201 _session.add_controllable (_gain_control);
203 create_bundles_for_inputs_and_outputs ();
208 Glib::Mutex::Lock guard (m_meter_signal_lock);
209 Glib::Mutex::Lock lm (io_lock);
211 BLOCK_PROCESS_CALLBACK ();
213 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
214 _session.engine().unregister_port (*i);
217 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
218 _session.engine().unregister_port (*i);
221 m_meter_connection.disconnect();
225 delete _output_buffers;
229 IO::silence (nframes_t nframes, nframes_t offset)
231 /* io_lock, not taken: function must be called from Session::process() calltree */
233 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
234 i->get_buffer(nframes,offset).silence (nframes, offset);
238 /** Deliver bufs to the IO's output ports
240 * This function should automatically do whatever it necessary to correctly deliver bufs
241 * to the outputs, eg applying gain or pan or whatever else needs to be done.
244 IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
246 // FIXME: type specific code doesn't actually need to be here, it will go away in time
248 /* ********** AUDIO ********** */
250 // Apply gain if gain automation isn't playing
251 if ( ! apply_gain_automation) {
253 gain_t dg = _gain; // desired gain
256 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
264 if (dg != _gain || dg != 1.0)
265 Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert);
268 // Use the panner to distribute audio to output port buffers
269 if( _panner && _panner->npanners() && !_panner->bypassed()) {
270 _panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
272 const DataType type = DataType::AUDIO;
274 // Copy any audio 1:1 to outputs
276 BufferSet::iterator o = output_buffers().begin(type);
277 BufferSet::iterator i = bufs.begin(type);
278 BufferSet::iterator prev = i;
280 while (i != bufs.end(type) && o != output_buffers().end (type)) {
281 o->read_from(*i, nframes, offset);
287 /* extra outputs get a copy of the last buffer */
289 while (o != output_buffers().end(type)) {
290 o->read_from(*prev, nframes, offset);
295 /* ********** MIDI ********** */
297 // No MIDI, we're done here
298 if (bufs.count().n_midi() == 0) {
302 const DataType type = DataType::MIDI;
304 // Copy any MIDI 1:1 to outputs
305 assert(bufs.count().n_midi() == output_buffers().count().n_midi());
306 BufferSet::iterator o = output_buffers().begin(type);
307 for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) {
308 o->read_from(*i, nframes, offset);
313 IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
315 assert(outs.available() >= n_inputs());
317 if (n_inputs() == ChanCount::ZERO)
320 outs.set_count(n_inputs());
322 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
324 BufferSet::iterator o = outs.begin(*t);
325 for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
326 o->read_from(i->get_buffer(nframes,offset), nframes, offset);
333 IO::just_meter_input (nframes_t start_frame, nframes_t end_frame,
334 nframes_t nframes, nframes_t offset)
336 BufferSet& bufs = _session.get_scratch_buffers (n_inputs());
338 collect_input (bufs, nframes, offset);
340 _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset);
345 IO::check_bundles_connected_to_inputs ()
347 check_bundles (_bundles_connected_to_inputs, inputs());
351 IO::check_bundles_connected_to_outputs ()
353 check_bundles (_bundles_connected_to_outputs, outputs());
357 IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
359 std::vector<UserBundleInfo> new_list;
361 for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) {
363 ChanCount const N = i->bundle->nchannels ();
365 if (ports.num_ports (default_type()) < N.get (default_type())) {
370 uint32_t n = N.get (default_type());
372 for (uint32_t j = 0; j < n; ++j) {
373 /* Every port on bundle channel j must be connected to our input j */
374 PortList const pl = i->bundle->channel_ports (j);
375 for (uint32_t k = 0; k < pl.size(); ++k) {
376 if (ports.port(j)->connected_to (pl[k]) == false) {
388 new_list.push_back (*i);
390 i->configuration_will_change.disconnect ();
391 i->configuration_has_changed.disconnect ();
392 i->ports_will_change.disconnect ();
393 i->ports_have_changed.disconnect ();
402 IO::disconnect_input (Port* our_port, string other_port, void* src)
404 if (other_port.length() == 0 || our_port == 0) {
409 BLOCK_PROCESS_CALLBACK ();
412 Glib::Mutex::Lock lm (io_lock);
414 /* check that our_port is really one of ours */
416 if ( ! _inputs.contains(our_port)) {
420 /* disconnect it from the source */
422 if (_session.engine().disconnect (other_port, our_port->name())) {
423 error << string_compose(_("IO: cannot disconnect input port %1 from %2"), our_port->name(), other_port) << endmsg;
427 check_bundles_connected_to_inputs ();
431 input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
432 _session.set_dirty ();
438 IO::connect_input (Port* our_port, string other_port, void* src)
440 if (other_port.length() == 0 || our_port == 0) {
445 BLOCK_PROCESS_CALLBACK ();
448 Glib::Mutex::Lock lm (io_lock);
450 /* check that our_port is really one of ours */
452 if ( ! _inputs.contains(our_port) ) {
456 /* connect it to the source */
458 if (_session.engine().connect (other_port, our_port->name())) {
464 input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
465 _session.set_dirty ();
470 IO::disconnect_output (Port* our_port, string other_port, void* src)
472 if (other_port.length() == 0 || our_port == 0) {
477 BLOCK_PROCESS_CALLBACK ();
480 Glib::Mutex::Lock lm (io_lock);
482 /* check that our_port is really one of ours */
484 if ( ! _outputs.contains(our_port) ) {
488 /* disconnect it from the destination */
490 if (_session.engine().disconnect (our_port->name(), other_port)) {
491 error << string_compose(_("IO: cannot disconnect output port %1 from %2"), our_port->name(), other_port) << endmsg;
495 check_bundles_connected_to_outputs ();
499 output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
500 _session.set_dirty ();
505 IO::connect_output (Port* our_port, string other_port, void* src)
507 if (other_port.length() == 0 || our_port == 0) {
512 BLOCK_PROCESS_CALLBACK ();
516 Glib::Mutex::Lock lm (io_lock);
518 /* check that our_port is really one of ours */
520 if ( ! _outputs.contains(our_port) ) {
524 /* connect it to the destination */
526 if (_session.engine().connect (our_port->name(), other_port)) {
532 output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
533 _session.set_dirty ();
538 IO::set_input (Port* other_port, void* src)
540 /* this removes all but one ports, and connects that one port
541 to the specified source.
544 if (_input_minimum.n_total() > 1) {
545 /* sorry, you can't do this */
549 if (other_port == 0) {
550 if (_input_minimum == ChanCount::ZERO) {
551 return ensure_inputs (ChanCount::ZERO, false, true, src);
557 if (ensure_inputs (ChanCount(other_port->type(), 1), true, true, src)) {
561 return connect_input (_inputs.port(0), other_port->name(), src);
565 IO::remove_output_port (Port* port, void* src)
567 IOChange change (NoChange);
570 BLOCK_PROCESS_CALLBACK ();
574 Glib::Mutex::Lock lm (io_lock);
576 if (n_outputs() <= _output_minimum) {
577 /* sorry, you can't do this */
581 if (_outputs.remove(port)) {
582 change = IOChange (change|ConfigurationChanged);
584 if (port->connected()) {
585 change = IOChange (change|ConnectionsChanged);
588 _session.engine().unregister_port (*port);
589 check_bundles_connected_to_outputs ();
591 setup_peak_meters ();
596 PortCountChanged (n_outputs()); /* EMIT SIGNAL */
599 if (change == ConnectionsChanged) {
600 setup_bundles_for_inputs_and_outputs ();
603 if (change != NoChange) {
604 output_changed (change, src);
605 _session.set_dirty ();
612 /** Add an output port.
614 * @param destination Name of input port to connect new port to.
615 * @param src Source for emitted ConfigurationChanged signal.
616 * @param type Data type of port. Default value (NIL) will use this IO's default type.
619 IO::add_output_port (string destination, void* src, DataType type)
623 if (type == DataType::NIL)
624 type = _default_type;
627 BLOCK_PROCESS_CALLBACK ();
631 Glib::Mutex::Lock lm (io_lock);
633 if (n_outputs() >= _output_maximum) {
637 /* Create a new output port */
639 string portname = build_legal_port_name (type, false);
641 if ((our_port = _session.engine().register_output_port (type, portname, _public_ports)) == 0) {
642 error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
646 _outputs.add (our_port);
647 setup_peak_meters ();
651 PortCountChanged (n_outputs()); /* EMIT SIGNAL */
654 if (destination.length()) {
655 if (_session.engine().connect (our_port->name(), destination)) {
660 // pan_changed (src); /* EMIT SIGNAL */
661 output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
662 setup_bundles_for_inputs_and_outputs ();
663 _session.set_dirty ();
669 IO::remove_input_port (Port* port, void* src)
671 IOChange change (NoChange);
674 BLOCK_PROCESS_CALLBACK ();
678 Glib::Mutex::Lock lm (io_lock);
680 if (n_inputs() <= _input_minimum) {
681 /* sorry, you can't do this */
685 if (_inputs.remove(port)) {
686 change = IOChange (change|ConfigurationChanged);
688 if (port->connected()) {
689 change = IOChange (change|ConnectionsChanged);
692 _session.engine().unregister_port (*port);
693 check_bundles_connected_to_inputs ();
695 setup_peak_meters ();
700 PortCountChanged (n_inputs ()); /* EMIT SIGNAL */
703 if (change == ConfigurationChanged) {
704 setup_bundles_for_inputs_and_outputs ();
707 if (change != NoChange) {
708 input_changed (change, src);
709 _session.set_dirty ();
717 /** Add an input port.
719 * @param type Data type of port. The appropriate port type, and @ref Port will be created.
720 * @param destination Name of input port to connect new port to.
721 * @param src Source for emitted ConfigurationChanged signal.
724 IO::add_input_port (string source, void* src, DataType type)
728 if (type == DataType::NIL)
729 type = _default_type;
732 BLOCK_PROCESS_CALLBACK ();
735 Glib::Mutex::Lock lm (io_lock);
737 if (_input_maximum.get(type) >= 0 && n_inputs().get (type) >= _input_maximum.get (type)) {
741 /* Create a new input port */
743 string portname = build_legal_port_name (type, true);
745 if ((our_port = _session.engine().register_input_port (type, portname, _public_ports)) == 0) {
746 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
750 _inputs.add (our_port);
751 setup_peak_meters ();
755 PortCountChanged (n_inputs()); /* EMIT SIGNAL */
758 if (source.length()) {
760 if (_session.engine().connect (source, our_port->name())) {
765 // pan_changed (src); /* EMIT SIGNAL */
766 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
767 setup_bundles_for_inputs_and_outputs ();
768 _session.set_dirty ();
774 IO::disconnect_inputs (void* src)
777 BLOCK_PROCESS_CALLBACK ();
780 Glib::Mutex::Lock lm (io_lock);
782 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
783 _session.engine().disconnect (*i);
786 check_bundles_connected_to_inputs ();
790 input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
796 IO::disconnect_outputs (void* src)
799 BLOCK_PROCESS_CALLBACK ();
802 Glib::Mutex::Lock lm (io_lock);
804 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
805 _session.engine().disconnect (*i);
808 check_bundles_connected_to_outputs ();
812 output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
813 _session.set_dirty ();
819 IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
821 Port* input_port = 0;
822 bool changed = false;
825 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
827 const size_t n = count.get(*t);
829 /* remove unused ports */
830 for (size_t i = n_inputs().get(*t); i > n; --i) {
831 input_port = _inputs.port(*t, i-1);
834 _inputs.remove(input_port);
835 _session.engine().unregister_port (*input_port);
840 /* create any necessary new ports */
841 while (n_inputs().get(*t) < n) {
843 string portname = build_legal_port_name (*t, true);
847 if ((input_port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) {
848 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
853 catch (AudioEngine::PortRegistrationFailure& err) {
854 setup_peak_meters ();
857 throw AudioEngine::PortRegistrationFailure();
860 _inputs.add (input_port);
866 check_bundles_connected_to_inputs ();
867 setup_peak_meters ();
869 PortCountChanged (n_inputs()); /* EMIT SIGNAL */
870 _session.set_dirty ();
874 /* disconnect all existing ports so that we get a fresh start */
875 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
876 _session.engine().disconnect (*i);
883 /** Attach output_buffers to port buffers.
885 * Connected to IO's own PortCountChanged signal.
888 IO::attach_buffers(ChanCount ignored)
890 _output_buffers->attach_buffers(_outputs);
894 IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
896 bool in_changed = false;
897 bool out_changed = false;
898 bool need_pan_reset = false;
900 in = min (_input_maximum, in);
902 out = min (_output_maximum, out);
904 if (in == n_inputs() && out == n_outputs() && !clear) {
909 BLOCK_PROCESS_CALLBACK ();
910 Glib::Mutex::Lock lm (io_lock);
914 if (n_outputs() != out) {
915 need_pan_reset = true;
918 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
920 const size_t nin = in.get(*t);
921 const size_t nout = out.get(*t);
923 Port* output_port = 0;
924 Port* input_port = 0;
926 /* remove unused output ports */
927 for (size_t i = n_outputs().get(*t); i > nout; --i) {
928 output_port = _outputs.port(*t, i-1);
931 _outputs.remove(output_port);
932 _session.engine().unregister_port (*output_port);
937 /* remove unused input ports */
938 for (size_t i = n_inputs().get(*t); i > nin; --i) {
939 input_port = _inputs.port(*t, i-1);
942 _inputs.remove(input_port);
943 _session.engine().unregister_port (*input_port);
948 /* create any necessary new input ports */
950 while (n_inputs().get(*t) < nin) {
952 string portname = build_legal_port_name (*t, true);
955 if ((port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) {
956 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
961 catch (AudioEngine::PortRegistrationFailure& err) {
962 setup_peak_meters ();
965 throw AudioEngine::PortRegistrationFailure();
972 /* create any necessary new output ports */
974 while (n_outputs().get(*t) < nout) {
976 string portname = build_legal_port_name (*t, false);
979 if ((port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) {
980 error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
985 catch (AudioEngine::PortRegistrationFailure& err) {
986 setup_peak_meters ();
989 throw AudioEngine::PortRegistrationFailure ();
999 /* disconnect all existing ports so that we get a fresh start */
1001 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1002 _session.engine().disconnect (*i);
1005 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1006 _session.engine().disconnect (*i);
1010 if (in_changed || out_changed) {
1011 setup_peak_meters ();
1017 check_bundles_connected_to_outputs ();
1018 output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1022 check_bundles_connected_to_inputs ();
1023 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1026 if (in_changed || out_changed) {
1027 PortCountChanged (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */
1028 setup_bundles_for_inputs_and_outputs ();
1029 _session.set_dirty ();
1036 IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
1038 bool changed = false;
1040 count = min (_input_maximum, count);
1042 if (count == n_inputs() && !clear) {
1047 BLOCK_PROCESS_CALLBACK ();
1048 Glib::Mutex::Lock im (io_lock);
1049 changed = ensure_inputs_locked (count, clear, src);
1051 changed = ensure_inputs_locked (count, clear, src);
1055 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1056 setup_bundles_for_inputs_and_outputs ();
1057 _session.set_dirty ();
1063 IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
1065 Port* output_port = 0;
1066 bool changed = false;
1067 bool need_pan_reset = false;
1069 if (n_outputs() != count) {
1070 need_pan_reset = true;
1073 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1075 const size_t n = count.get(*t);
1077 /* remove unused ports */
1078 for (size_t i = n_outputs().get(*t); i > n; --i) {
1079 output_port = _outputs.port(*t, i-1);
1081 assert(output_port);
1082 _outputs.remove(output_port);
1083 _session.engine().unregister_port (*output_port);
1088 /* create any necessary new ports */
1089 while (n_outputs().get(*t) < n) {
1091 string portname = build_legal_port_name (*t, false);
1093 if ((output_port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) {
1094 error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
1098 _outputs.add (output_port);
1100 setup_peak_meters ();
1102 if (need_pan_reset) {
1109 check_bundles_connected_to_outputs ();
1110 PortCountChanged (n_outputs()); /* EMIT SIGNAL */
1111 _session.set_dirty ();
1115 /* disconnect all existing ports so that we get a fresh start */
1116 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1117 _session.engine().disconnect (*i);
1125 IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
1127 bool changed = false;
1129 if (_output_maximum < ChanCount::INFINITE) {
1130 count = min (_output_maximum, count);
1131 if (count == n_outputs() && !clear) {
1136 /* XXX caller should hold io_lock, but generally doesn't */
1139 BLOCK_PROCESS_CALLBACK ();
1140 Glib::Mutex::Lock im (io_lock);
1141 changed = ensure_outputs_locked (count, clear, src);
1143 changed = ensure_outputs_locked (count, clear, src);
1147 output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1148 setup_bundles_for_inputs_and_outputs ();
1155 IO::effective_gain () const
1157 if (_gain_control->automation_playback()) {
1158 return _gain_control->get_value();
1160 return _desired_gain;
1167 if (panners_legal) {
1168 if (!no_panner_reset) {
1169 _panner->reset (n_outputs().n_audio(), pans_required());
1172 panner_legal_c.disconnect ();
1173 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1178 IO::panners_became_legal ()
1180 _panner->reset (n_outputs().n_audio(), pans_required());
1181 _panner->load (); // automation
1182 panner_legal_c.disconnect ();
1187 IO::defer_pan_reset ()
1189 no_panner_reset = true;
1193 IO::allow_pan_reset ()
1195 no_panner_reset = false;
1201 IO::get_state (void)
1203 return state (true);
1207 IO::state (bool full_state)
1209 XMLNode* node = new XMLNode (state_node_name);
1212 vector<string>::iterator ci;
1214 LocaleGuard lg (X_("POSIX"));
1215 Glib::Mutex::Lock lm (io_lock);
1217 node->add_property("name", _name);
1218 id().print (buf, sizeof (buf));
1219 node->add_property("id", buf);
1222 std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin();
1223 i != _bundles_connected_to_inputs.end();
1227 XMLNode* n = new XMLNode ("InputBundle");
1228 n->add_property ("name", i->bundle->name ());
1229 node->add_child_nocopy (*n);
1233 std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin();
1234 i != _bundles_connected_to_outputs.end();
1238 XMLNode* n = new XMLNode ("OutputBundle");
1239 n->add_property ("name", i->bundle->name ());
1240 node->add_child_nocopy (*n);
1245 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1247 vector<string> connections;
1249 if (i->get_connections (connections)) {
1253 for (n = 0, ci = connections.begin(); ci != connections.end(); ++ci, ++n) {
1258 /* if its a connection to our own port,
1259 return only the port name, not the
1260 whole thing. this allows connections
1261 to be re-established even when our
1262 client name is different.
1265 str += _session.engine().make_port_name_relative (*ci);
1275 node->add_property ("inputs", str);
1279 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1281 vector<string> connections;
1283 if (i->get_connections (connections)) {
1287 for (n = 0, ci = connections.begin(); ci != connections.end(); ++ci, ++n) {
1292 str += _session.engine().make_port_name_relative (*ci);
1302 node->add_property ("outputs", str);
1304 node->add_child_nocopy (_panner->state (full_state));
1305 node->add_child_nocopy (_gain_control->get_state ());
1307 snprintf (buf, sizeof(buf), "%2.12f", gain());
1308 node->add_property ("gain", buf);
1310 /* To make backwards compatibility a bit easier, write ChanCount::INFINITE to the session file
1314 int const in_max = _input_maximum == ChanCount::INFINITE ? -1 : _input_maximum.get(_default_type);
1315 int const out_max = _output_maximum == ChanCount::INFINITE ? -1 : _output_maximum.get(_default_type);
1317 snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d", _input_minimum.get(_default_type), in_max, _output_minimum.get(_default_type), out_max);
1319 node->add_property ("iolimits", buf);
1324 node->add_child_nocopy (get_automation_state());
1330 IO::set_state (const XMLNode& node)
1332 const XMLProperty* prop;
1333 XMLNodeConstIterator iter;
1334 LocaleGuard lg (X_("POSIX"));
1336 /* force use of non-localized representation of decimal point,
1337 since we use it a lot in XML files and so forth.
1340 if (node.name() != state_node_name) {
1341 error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg;
1345 if ((prop = node.property ("name")) != 0) {
1346 _name = prop->value();
1347 /* used to set panner name with this, but no more */
1350 if ((prop = node.property ("id")) != 0) {
1351 _id = prop->value ();
1359 if ((prop = node.property ("iolimits")) != 0) {
1360 sscanf (prop->value().c_str(), "%d,%d,%d,%d",
1361 &in_min, &in_max, &out_min, &out_max);
1363 /* Correct for the difference between the way we write things to session files and the
1364 way things are described by ChanCount; see comments in io.h about what the different
1365 ChanCount values mean. */
1368 _input_minimum = ChanCount::ZERO;
1370 _input_minimum = ChanCount (_default_type, in_min);
1374 _input_maximum = ChanCount::INFINITE;
1376 _input_maximum = ChanCount (_default_type, in_max);
1380 _output_minimum = ChanCount::ZERO;
1382 _output_minimum = ChanCount (_default_type, out_min);
1386 _output_maximum = ChanCount::INFINITE;
1388 _output_maximum = ChanCount (_default_type, out_max);
1392 if ((prop = node.property ("gain")) != 0) {
1393 set_gain (atof (prop->value().c_str()), this);
1394 _gain = _desired_gain;
1397 if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) {
1398 /* old school automation handling */
1401 for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
1403 // Old school Panner.
1404 if ((*iter)->name() == "Panner") {
1406 _panner = new Panner (_name, _session);
1408 _panner->set_state (**iter);
1411 if ((*iter)->name() == "Processor") {
1412 if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
1414 _panner = new Panner (_name, _session);
1416 _panner->set_state (**iter);
1420 if ((*iter)->name() == X_("Automation")) {
1422 set_automation_state (*(*iter), Evoral::Parameter(GainAutomation));
1425 if ((*iter)->name() == X_("controllable")) {
1426 if ((prop = (*iter)->property("name")) != 0 && prop->value() == "gaincontrol") {
1427 _gain_control->set_state (**iter);
1434 if (create_ports (node)) {
1440 port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
1444 _panner = new Panner( _name, _session );
1445 if (panners_legal) {
1448 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1451 if (connecting_legal) {
1453 if (make_connections (node)) {
1459 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
1462 if (!ports_legal || !connecting_legal) {
1463 pending_state_node = new XMLNode (node);
1470 IO::load_automation (string path)
1475 uint32_t linecnt = 0;
1477 LocaleGuard lg (X_("POSIX"));
1479 fullpath = Glib::build_filename(_session.automation_dir(), path);
1481 in.open (fullpath.c_str());
1484 fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
1486 in.open (fullpath.c_str());
1489 error << string_compose(_("%1: cannot open automation event file \"%2\""), _name, fullpath) << endmsg;
1494 clear_automation ();
1496 while (in.getline (line, sizeof(line), '\n')) {
1501 if (++linecnt == 1) {
1502 if (memcmp (line, "version", 7) == 0) {
1503 if (sscanf (line, "version %f", &version) != 1) {
1504 error << string_compose(_("badly formed version number in automation event file \"%1\""), path) << endmsg;
1508 error << string_compose(_("no version information in automation event file \"%1\""), path) << endmsg;
1515 if (sscanf (line, "%c %" PRIu32 " %lf", &type, &when, &value) != 3) {
1516 warning << string_compose(_("badly formatted automation event record at line %1 of %2 (ignored)"), linecnt, path) << endmsg;
1522 _gain_control->list()->fast_simple_add (when, value);
1532 /* older (pre-1.0) versions of ardour used this */
1536 warning << _("dubious automation event found (and ignored)") << endmsg;
1544 IO::connecting_became_legal ()
1548 if (pending_state_node == 0) {
1549 fatal << _("IO::connecting_became_legal() called without a pending state node") << endmsg;
1554 connection_legal_c.disconnect ();
1556 ret = make_connections (*pending_state_node);
1559 delete pending_state_node;
1560 pending_state_node = 0;
1566 IO::ports_became_legal ()
1570 if (pending_state_node == 0) {
1571 fatal << _("IO::ports_became_legal() called without a pending state node") << endmsg;
1576 port_legal_c.disconnect ();
1578 ret = create_ports (*pending_state_node);
1580 if (connecting_legal) {
1581 delete pending_state_node;
1582 pending_state_node = 0;
1588 boost::shared_ptr<Bundle>
1589 IO::find_possible_bundle (const string &desired_name, const string &default_name, const string &bundle_type_name)
1591 static const string digits = "0123456789";
1593 boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
1596 int bundle_number, mask;
1597 string possible_name;
1598 bool stereo = false;
1599 string::size_type last_non_digit_pos;
1601 error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
1604 // find numeric suffix of desired name
1607 last_non_digit_pos = desired_name.find_last_not_of(digits);
1609 if (last_non_digit_pos != string::npos) {
1611 s << desired_name.substr(last_non_digit_pos);
1615 // see if it's a stereo connection e.g. "in 3+4"
1617 if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
1618 int left_bundle_number = 0;
1619 string::size_type left_last_non_digit_pos;
1621 left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
1623 if (left_last_non_digit_pos != string::npos) {
1625 s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
1626 s >> left_bundle_number;
1628 if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
1639 // find highest set bit
1641 while ((mask <= bundle_number) && (mask <<= 1));
1643 // "wrap" bundle number into largest possible power of 2
1648 if (bundle_number & mask) {
1649 bundle_number &= ~mask;
1652 s << default_name << " " << bundle_number + 1;
1655 s << "+" << bundle_number + 2;
1658 possible_name = s.str();
1660 if ((c = _session.bundle_by_name (possible_name)) != 0) {
1667 info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
1670 error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
1681 IO::create_ports (const XMLNode& node)
1683 XMLProperty const * prop;
1684 ChanCount num_inputs;
1685 ChanCount num_outputs;
1687 if ((prop = node.property ("input-connection")) != 0) {
1689 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
1695 num_inputs = c->nchannels();
1697 } else if ((prop = node.property ("inputs")) != 0) {
1699 num_inputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
1702 if ((prop = node.property ("output-connection")) != 0) {
1704 boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
1710 num_outputs = c->nchannels ();
1712 } else if ((prop = node.property ("outputs")) != 0) {
1714 num_outputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
1717 no_panner_reset = true;
1719 if (ensure_io (num_inputs, num_outputs, true, this)) {
1720 error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
1724 no_panner_reset = false;
1726 set_deferred_state ();
1734 IO::make_connections (const XMLNode& node)
1737 const XMLProperty* prop;
1739 if ((prop = node.property ("input-connection")) != 0) {
1740 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
1746 connect_input_ports_to_bundle (c, this);
1748 } else if ((prop = node.property ("inputs")) != 0) {
1749 if (set_inputs (prop->value())) {
1750 error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
1755 if ((prop = node.property ("output-connection")) != 0) {
1756 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
1762 connect_output_ports_to_bundle (c, this);
1764 } else if ((prop = node.property ("outputs")) != 0) {
1765 if (set_outputs (prop->value())) {
1766 error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
1771 for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) {
1773 if ((*i)->name() == "InputBundle") {
1774 XMLProperty const * prop = (*i)->property ("name");
1776 boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("in"), _("input"));
1778 connect_input_ports_to_bundle (b, this);
1782 } else if ((*i)->name() == "OutputBundle") {
1783 XMLProperty const * prop = (*i)->property ("name");
1785 boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("out"), _("output"));
1787 connect_output_ports_to_bundle (b, this);
1797 IO::set_inputs (const string& str)
1799 vector<string> ports;
1804 if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1808 // FIXME: audio-only
1809 if (ensure_inputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1813 string::size_type start, end, ostart;
1820 while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1823 if ((end = str.find_first_of ('}', start)) == string::npos) {
1824 error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
1828 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1829 error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
1835 for (int x = 0; x < n; ++x) {
1836 connect_input (input (i), ports[x], this);
1848 IO::set_outputs (const string& str)
1850 vector<string> ports;
1855 if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1859 // FIXME: audio-only
1860 if (ensure_outputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1864 string::size_type start, end, ostart;
1871 while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1874 if ((end = str.find_first_of ('}', start)) == string::npos) {
1875 error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg;
1879 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1880 error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg;
1886 for (int x = 0; x < n; ++x) {
1887 connect_output (output (i), ports[x], this);
1899 IO::parse_io_string (const string& str, vector<string>& ports)
1901 string::size_type pos, opos;
1903 if (str.length() == 0) {
1912 while ((pos = str.find_first_of (',', opos)) != string::npos) {
1913 ports.push_back (str.substr (opos, pos - opos));
1917 if (opos < str.length()) {
1918 ports.push_back (str.substr(opos));
1921 return ports.size();
1925 IO::parse_gain_string (const string& str, vector<string>& ports)
1927 string::size_type pos, opos;
1933 while ((pos = str.find_first_of (',', opos)) != string::npos) {
1934 ports.push_back (str.substr (opos, pos - opos));
1938 if (opos < str.length()) {
1939 ports.push_back (str.substr(opos));
1942 return ports.size();
1946 IO::set_name (const string& requested_name)
1948 if (requested_name == _name) {
1954 if ( (rt = dynamic_cast<Route *>(this))) {
1955 name = Route::ensure_track_or_route_name(requested_name, _session);
1957 name = requested_name;
1961 /* replace all colons in the name. i wish we didn't have to do this */
1963 if (replace_all (name, ":", "-")) {
1964 warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
1967 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1968 string current_name = i->short_name();
1969 current_name.replace (current_name.find (_name), _name.length(), name);
1970 i->set_name (current_name);
1973 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1974 string current_name = i->short_name();
1975 current_name.replace (current_name.find (_name), _name.length(), name);
1976 i->set_name (current_name);
1979 bool const r = SessionObject::set_name(name);
1981 setup_bundles_for_inputs_and_outputs ();
1987 IO::set_input_minimum (ChanCount n)
1993 IO::set_input_maximum (ChanCount n)
1999 IO::set_output_minimum (ChanCount n)
2001 _output_minimum = n;
2005 IO::set_output_maximum (ChanCount n)
2007 _output_maximum = n;
2011 IO::set_port_latency (nframes_t nframes)
2013 Glib::Mutex::Lock lm (io_lock);
2015 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2016 i->set_latency (nframes);
2021 IO::output_latency () const
2023 nframes_t max_latency;
2028 /* io lock not taken - must be protected by other means */
2030 for (PortSet::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2031 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
2032 max_latency = latency;
2040 IO::input_latency () const
2042 nframes_t max_latency;
2047 /* io lock not taken - must be protected by other means */
2049 for (PortSet::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2050 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
2051 max_latency = latency;
2059 IO::connect_input_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
2062 BLOCK_PROCESS_CALLBACK ();
2063 Glib::Mutex::Lock lm2 (io_lock);
2065 /* Connect to the bundle, not worrying about any connections
2066 that are already made. */
2068 ChanCount const channels = c->nchannels ();
2069 uint32_t cnt = channels.get (default_type());
2071 for (uint32_t n = 0; n < cnt; ++n) {
2072 const PortList& pl = c->channel_ports (n);
2074 for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2076 if (!_inputs.port(n)->connected_to (*i)) {
2078 if (_session.engine().connect (*i, _inputs.port(n)->name())) {
2086 /* If this is a UserBundle, make a note of what we've done */
2088 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
2091 /* See if we already know about this one */
2092 std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin();
2093 while (i != _bundles_connected_to_inputs.end() && i->bundle != ub) {
2097 if (i == _bundles_connected_to_inputs.end()) {
2098 /* We don't, so make a note */
2099 _bundles_connected_to_inputs.push_back (UserBundleInfo (this, ub));
2104 input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
2109 IO::connect_output_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
2112 BLOCK_PROCESS_CALLBACK ();
2113 Glib::Mutex::Lock lm2 (io_lock);
2115 /* Connect to the bundle, not worrying about any connections
2116 that are already made. */
2118 ChanCount const channels = c->nchannels ();
2119 uint32_t cnt = channels.get (default_type());
2121 for (uint32_t n = 0; n < cnt; ++n) {
2123 const PortList& pl = c->channel_ports (n);
2125 for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2127 if (!_outputs.port(n)->connected_to (*i)) {
2129 if (_session.engine().connect (_outputs.port(n)->name(), *i)) {
2136 /* If this is a UserBundle, make a note of what we've done */
2138 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
2141 /* See if we already know about this one */
2142 std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin();
2143 while (i != _bundles_connected_to_outputs.end() && i->bundle != ub) {
2147 if (i == _bundles_connected_to_outputs.end()) {
2148 /* We don't, so make a note */
2149 _bundles_connected_to_outputs.push_back (UserBundleInfo (this, ub));
2154 output_changed (IOChange (ConnectionsChanged|ConfigurationChanged), src); /* EMIT SIGNAL */
2160 IO::disable_connecting ()
2162 connecting_legal = false;
2167 IO::enable_connecting ()
2169 connecting_legal = true;
2170 return ConnectingLegal ();
2174 IO::disable_ports ()
2176 ports_legal = false;
2184 return PortsLegal ();
2188 IO::disable_panners (void)
2190 panners_legal = false;
2195 IO::reset_panners ()
2197 panners_legal = true;
2198 return PannersLegal ();
2202 IO::bundle_configuration_will_change ()
2205 // connect_input_ports_to_bundle (_input_bundle, this);
2209 IO::bundle_configuration_has_changed ()
2212 // connect_input_ports_to_bundle (_input_bundle, this);
2216 IO::bundle_ports_will_change (int ignored)
2219 // connect_output_ports_to_bundle (_output_bundle, this);
2223 IO::bundle_ports_have_changed (int ignored)
2226 // connect_output_ports_to_bundle (_output_bundle, this);
2230 IO::GainControl::set_value (float val)
2232 // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2233 if (val > 1.99526231f)
2236 _io->set_gain (val, this);
2238 AutomationControl::set_value(val);
2242 IO::GainControl::get_value (void) const
2244 return AutomationControl::get_value();
2248 IO::setup_peak_meters()
2250 ChanCount max_streams = std::max (_inputs.count(), _outputs.count());
2251 _meter->configure_io (max_streams, max_streams);
2255 Update the peak meters.
2257 The meter signal lock is taken to prevent modification of the
2258 Meter signal while updating the meters, taking the meter signal
2259 lock prior to taking the io_lock ensures that all IO will remain
2260 valid while metering.
2265 Glib::Mutex::Lock guard (m_meter_signal_lock);
2266 Meter(); /* EMIT SIGNAL */
2272 // FIXME: Ugly. Meter should manage the lock, if it's necessary
2274 Glib::Mutex::Lock lm (io_lock); // READER: meter thread.
2279 IO::clear_automation ()
2281 data().clear (); // clears gain automation
2282 _panner->data().clear();
2286 IO::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
2288 // XXX: would be nice to get rid of this special hack
2290 if (param.type() == GainAutomation) {
2292 bool changed = false;
2295 Glib::Mutex::Lock lm (control_lock());
2297 boost::shared_ptr<AutomationList> gain_auto
2298 = boost::dynamic_pointer_cast<AutomationList>(_gain_control->list());
2300 if (state != gain_auto->automation_state()) {
2302 _last_automation_snapshot = 0;
2303 gain_auto->set_automation_state (state);
2306 // FIXME: shouldn't this use Curve?
2307 set_gain (gain_auto->eval (_session.transport_frame()), this);
2313 _session.set_dirty ();
2317 AutomatableControls::set_parameter_automation_state(param, state);
2322 IO::inc_gain (gain_t factor, void *src)
2324 if (_desired_gain == 0.0f)
2325 set_gain (0.000001f + (0.000001f * factor), src);
2327 set_gain (_desired_gain + (_desired_gain * factor), src);
2331 IO::set_gain (gain_t val, void *src)
2333 // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2334 if (val > 1.99526231f)
2337 if (src != _gain_control.get()) {
2338 _gain_control->set_value(val);
2339 // bit twisty, this will come back and call us again
2340 // (this keeps control in sync with reality)
2345 Glib::Mutex::Lock dm (declick_lock);
2346 _desired_gain = val;
2349 if (_session.transport_stopped()) {
2354 if (_session.transport_stopped() && src != 0 && src != this && _gain_control->automation_write()) {
2355 _gain_control->list()->add (_session.transport_frame(), val);
2360 _session.set_dirty();
2364 IO::start_pan_touch (uint32_t which)
2366 if (which < _panner->npanners()) {
2367 (*_panner).pan_control(which)->start_touch();
2372 IO::end_pan_touch (uint32_t which)
2374 if (which < _panner->npanners()) {
2375 (*_panner).pan_control(which)->stop_touch();
2381 IO::automation_snapshot (nframes_t now, bool force)
2383 AutomatableControls::automation_snapshot (now, force);
2384 // XXX: This seems to be wrong.
2385 // drobilla: shouldnt automation_snapshot for panner be called
2386 // "automagically" because its an Automatable now ?
2388 // we could dump this whole method then. <3
2390 if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
2391 _panner->automation_snapshot (now, force);
2394 _panner->automation_snapshot (now, force);
2395 _last_automation_snapshot = now;
2399 IO::transport_stopped (nframes_t frame)
2401 _gain_control->list()->reposition_for_rt_add (frame);
2403 if (_gain_control->automation_state() != Off) {
2405 /* the src=0 condition is a special signal to not propagate
2406 automation gain changes into the mix group when locating.
2409 // FIXME: shouldn't this use Curve?
2410 set_gain (_gain_control->list()->eval (frame), 0);
2413 _panner->transport_stopped (frame);
2417 IO::build_legal_port_name (DataType type, bool in)
2419 const int name_size = jack_port_name_size();
2424 if (type == DataType::AUDIO) {
2425 suffix = _("audio");
2426 } else if (type == DataType::MIDI) {
2429 throw unknown_type();
2434 maxports = _input_maximum.get(type);
2436 suffix += _("_out");
2437 maxports = _output_maximum.get(type);
2440 if (maxports == 1) {
2441 // allow space for the slash + the suffix
2442 limit = name_size - _session.engine().client_name().length() - (suffix.length() + 1);
2443 char buf[name_size+1];
2444 snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
2445 return string (buf);
2448 // allow up to 4 digits for the output port number, plus the slash, suffix and extra space
2450 limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
2452 char buf1[name_size+1];
2453 char buf2[name_size+1];
2455 snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
2460 port_number = find_input_port_hole (buf1);
2462 port_number = find_output_port_hole (buf1);
2465 snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
2467 return string (buf2);
2471 IO::find_input_port_hole (const char* base)
2473 /* CALLER MUST HOLD IO LOCK */
2477 if (_inputs.empty()) {
2481 /* we only allow up to 4 characters for the port number
2484 for (n = 1; n < 9999; ++n) {
2485 char buf[jack_port_name_size()];
2486 PortSet::iterator i = _inputs.begin();
2488 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2490 for ( ; i != _inputs.end(); ++i) {
2491 if (i->short_name() == buf) {
2496 if (i == _inputs.end()) {
2504 IO::find_output_port_hole (const char* base)
2506 /* CALLER MUST HOLD IO LOCK */
2510 if (_outputs.empty()) {
2514 /* we only allow up to 4 characters for the port number
2517 for (n = 1; n < 9999; ++n) {
2518 char buf[jack_port_name_size()];
2519 PortSet::iterator i = _outputs.begin();
2521 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2523 for ( ; i != _outputs.end(); ++i) {
2524 if (i->short_name() == buf) {
2529 if (i == _outputs.end()) {
2538 IO::set_active (bool yn)
2541 active_changed(); /* EMIT SIGNAL */
2546 IO::audio_input(uint32_t n) const
2548 return dynamic_cast<AudioPort*>(input(n));
2552 IO::audio_output(uint32_t n) const
2554 return dynamic_cast<AudioPort*>(output(n));
2558 IO::midi_input(uint32_t n) const
2560 return dynamic_cast<MidiPort*>(input(n));
2564 IO::midi_output(uint32_t n) const
2566 return dynamic_cast<MidiPort*>(output(n));
2570 IO::set_phase_invert (bool yn, void *src)
2572 if (_phase_invert != yn) {
2574 // phase_invert_changed (src); /* EMIT SIGNAL */
2579 IO::set_denormal_protection (bool yn, void *src)
2581 if (_denormal_protection != yn) {
2582 _denormal_protection = yn;
2583 // denormal_protection_changed (src); /* EMIT SIGNAL */
2588 IO::update_port_total_latencies ()
2590 /* io_lock, not taken: function must be called from Session::process() calltree */
2592 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2593 _session.engine().update_total_latency (*i);
2596 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2597 _session.engine().update_total_latency (*i);
2603 * Setup bundles that describe our inputs and outputs.
2607 IO::setup_bundles_for_inputs_and_outputs ()
2611 snprintf(buf, sizeof (buf), _("%s in"), _name.c_str());
2612 _bundle_for_inputs->set_name (buf);
2613 uint32_t const ni = inputs().num_ports();
2614 _bundle_for_inputs->set_channels (ni);
2615 for (uint32_t i = 0; i < ni; ++i) {
2616 _bundle_for_inputs->set_port (i, inputs().port(i)->name());
2619 snprintf(buf, sizeof (buf), _("%s out"), _name.c_str());
2620 _bundle_for_outputs->set_name (buf);
2621 uint32_t const no = outputs().num_ports();
2622 _bundle_for_outputs->set_channels (no);
2623 for (uint32_t i = 0; i < no; ++i) {
2624 _bundle_for_outputs->set_port (i, outputs().port(i)->name());
2630 * Create and setup bundles that describe our inputs and outputs.
2634 IO::create_bundles_for_inputs_and_outputs ()
2636 _bundle_for_inputs = boost::shared_ptr<AutoBundle> (new AutoBundle (true));
2637 _bundle_for_outputs = boost::shared_ptr<AutoBundle> (new AutoBundle (false));
2638 setup_bundles_for_inputs_and_outputs ();
2641 /** Add a bundle to a list if is connected to our inputs.
2642 * @param b Bundle to check.
2643 * @param bundles List to add to.
2646 IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
2648 boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
2650 if (ab == 0 || ab->ports_are_outputs() == false) {
2654 if (ab->nchannels().get (default_type()) != n_inputs().n_total ()) {
2658 for (uint32_t i = 0; i < n_inputs().n_total (); ++i) {
2660 PortList const & pl = b->channel_ports (i);
2666 if (!input(i)->connected_to (pl[0])) {
2671 bundles->push_back (b);
2674 /** @return Bundles connected to our inputs */
2675 std::vector<boost::shared_ptr<Bundle> >
2676 IO::bundles_connected_to_inputs ()
2678 std::vector<boost::shared_ptr<Bundle> > bundles;
2681 for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); i != _bundles_connected_to_inputs.end(); ++i) {
2682 bundles.push_back (i->bundle);
2686 _session.foreach_bundle (
2687 sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_input_bundle_to_list), &bundles)
2694 /** Add a bundle to a list if is connected to our outputs.
2695 * @param b Bundle to check.
2696 * @param bundles List to add to.
2699 IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
2701 boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
2702 if (ab == 0 || ab->ports_are_inputs() == false) {
2706 if (ab->nchannels ().get (default_type()) != n_outputs().n_total ()) {
2710 for (uint32_t i = 0; i < n_outputs().n_total (); ++i) {
2712 PortList const & pl = b->channel_ports (i);
2718 if (!output(i)->connected_to (pl[0])) {
2723 bundles->push_back (b);
2727 /* @return Bundles connected to our outputs */
2728 std::vector<boost::shared_ptr<Bundle> >
2729 IO::bundles_connected_to_outputs ()
2731 std::vector<boost::shared_ptr<Bundle> > bundles;
2734 for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); i != _bundles_connected_to_outputs.end(); ++i) {
2735 bundles.push_back (i->bundle);
2739 _session.foreach_bundle (
2740 sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_output_bundle_to_list), &bundles)
2747 IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
2750 configuration_will_change = b->ConfigurationWillChange.connect (
2751 sigc::mem_fun (*io, &IO::bundle_configuration_will_change)
2753 configuration_has_changed = b->ConfigurationHasChanged.connect (
2754 sigc::mem_fun (*io, &IO::bundle_configuration_has_changed)
2756 ports_will_change = b->PortsWillChange.connect (
2757 sigc::mem_fun (*io, &IO::bundle_ports_will_change)
2759 ports_have_changed = b->PortsHaveChanged.connect (
2760 sigc::mem_fun (*io, &IO::bundle_ports_have_changed)
2765 IO::prepare_inputs (nframes_t nframes, nframes_t offset)
2767 /* io_lock, not taken: function must be called from Session::process() calltree */
2771 IO::flush_outputs (nframes_t nframes, nframes_t offset)
2773 /* io_lock, not taken: function must be called from Session::process() calltree */
2774 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2776 /* Only run cycle_start() on output ports, because
2777 inputs must be done in the correct processing order,
2778 which requires interleaving with route processing.
2781 (*i).flush_buffers (nframes, offset);