summaryrefslogtreecommitdiff
path: root/libs/ardour/io.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/io.cc')
-rw-r--r--libs/ardour/io.cc189
1 files changed, 112 insertions, 77 deletions
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 9a41d74cee..80eeaa1f19 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -14,8 +14,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
*/
#include <fstream>
@@ -62,19 +60,19 @@ using namespace PBD;
static float current_automation_version_number = 1.0;
-jack_nframes_t IO::_automation_interval = 0;
-const string IO::state_node_name = "IO";
-bool IO::connecting_legal = false;
-bool IO::ports_legal = false;
-bool IO::panners_legal = false;
+jack_nframes_t IO::_automation_interval = 0;
+const string IO::state_node_name = "IO";
+bool IO::connecting_legal = false;
+bool IO::ports_legal = false;
+bool IO::panners_legal = false;
sigc::signal<void> IO::Meter;
sigc::signal<int> IO::ConnectingLegal;
sigc::signal<int> IO::PortsLegal;
sigc::signal<int> IO::PannersLegal;
-sigc::signal<void,uint32_t> IO::MoreOutputs;
+sigc::signal<void,ChanCount> IO::MoreOutputs;
sigc::signal<int> IO::PortsCreated;
-Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
+Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
/* this is a default mapper of [0 .. 1.0] control values to a gain coefficient.
others can be imagined.
@@ -112,10 +110,10 @@ IO::IO (Session& s, string name,
_default_type(default_type),
_gain_control (*this),
_gain_automation_curve (0.0, 2.0, 1.0),
- _input_minimum (input_min),
- _input_maximum (input_max),
- _output_minimum (output_min),
- _output_maximum (output_max)
+ _input_minimum (_default_type, input_min),
+ _input_maximum (_default_type, input_max),
+ _output_minimum (_default_type, output_min),
+ _output_maximum (_default_type, output_max)
{
_panner = new Panner (name, _session);
_gain = 1.0;
@@ -228,11 +226,11 @@ IO::pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start,
/* io_lock, not taken: function must be called from Session::process() calltree */
- if (n_outputs() == 0) {
+ if (n_outputs().get(DataType::AUDIO) == 0) {
return;
}
- if (n_outputs() == 1) {
+ if (n_outputs().get(DataType::AUDIO) == 1) {
dst = audio_output(0)->get_audio_buffer().data (nframes, offset);
@@ -250,7 +248,7 @@ IO::pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start,
uint32_t o = 0;
vector<Sample *>::iterator in;
Panner::iterator pan;
- Sample* obufs[n_outputs()];
+ Sample* obufs[n_outputs().get(DataType::AUDIO)];
/* the terrible silence ... */
for (PortSet::audio_iterator out = _outputs.audio_begin(); out != _outputs.audio_end(); ++out, ++o) {
@@ -273,7 +271,7 @@ IO::pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nfr
/* io_lock, not taken: function must be called from Session::process() calltree */
- if (n_outputs() == 0) {
+ if (n_outputs().get(DataType::AUDIO) == 0) {
return;
}
@@ -286,7 +284,7 @@ IO::pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nfr
return;
}
- if (n_outputs() == 1) {
+ if (n_outputs().get(DataType::AUDIO) == 1) {
dst = audio_output(0)->get_audio_buffer().data(nframes, offset);
@@ -343,7 +341,7 @@ IO::pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nfr
uint32_t o = 0;
vector<Sample *>::iterator in;
Panner::iterator pan;
- Sample* obufs[n_outputs()];
+ Sample* obufs[n_outputs().get(DataType::AUDIO)];
/* the terrible silence ... */
@@ -376,7 +374,7 @@ IO::deliver_output (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nfram
{
/* io_lock, not taken: function must be called from Session::process() calltree */
- if (n_outputs() == 0) {
+ if (n_outputs().get(DataType::AUDIO) == 0) {
return;
}
@@ -419,7 +417,7 @@ IO::deliver_output_no_pan (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_
{
/* io_lock, not taken: function must be called from Session::process() calltree */
- if (n_outputs() == 0) {
+ if (n_outputs().get(DataType::AUDIO) == 0) {
return;
}
@@ -520,7 +518,7 @@ IO::collect_input (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframe
have to do.
Hack? Why yes .. we only need to read nframes-worth of
- data, but the data we want is at `offset' within the
+ data, but the data we want is at 'offset' within the
buffer.
*/
@@ -716,13 +714,13 @@ IO::set_input (Port* other_port, void* src)
to the specified source.
*/
- if (_input_minimum > 1 || _input_minimum == 0) {
+ if (_input_minimum.get_total() > 1) {
/* sorry, you can't do this */
return -1;
}
if (other_port == 0) {
- if (_input_minimum < 0) {
+ if (_input_minimum == ChanCount::ZERO) {
return ensure_inputs (0, false, true, src);
} else {
return -1;
@@ -807,14 +805,14 @@ IO::add_output_port (string destination, void* src, DataType type)
{
Glib::Mutex::Lock lm (io_lock);
- if (_output_maximum >= 0 && (int) n_outputs() == _output_maximum) {
+ if (n_outputs() >= _output_maximum) {
return -1;
}
/* Create a new output port */
// FIXME: naming scheme for differently typed ports?
- if (_output_maximum == 1) {
+ if (_output_maximum.get_total() == 1) {
snprintf (name, sizeof (name), _("%s/out"), _name.c_str());
} else {
snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
@@ -920,14 +918,14 @@ IO::add_input_port (string source, void* src, DataType type)
{
Glib::Mutex::Lock lm (io_lock);
- if (_input_maximum >= 0 && (int) n_inputs() == _input_maximum) {
+ if (n_inputs() >= _input_maximum) {
return -1;
}
/* Create a new input port */
// FIXME: naming scheme for differently typed ports?
- if (_input_maximum == 1) {
+ if (_input_maximum.get_total() == 1) {
snprintf (name, sizeof (name), _("%s/in"), _name.c_str());
} else {
snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
@@ -1014,7 +1012,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
/* remove unused ports */
- while (n_inputs() > n) {
+ while (n_inputs().get(_default_type) > n) {
throw; // FIXME
/*
_session.engine().unregister_port (_inputs.back());
@@ -1026,13 +1024,13 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
/* create any necessary new ports */
- while (n_inputs() < n) {
+ while (n_inputs().get(_default_type) < n) {
char buf[64];
/* Create a new input port (of the default type) */
- if (_input_maximum == 1) {
+ if (_input_maximum.get_total() == 1) {
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
}
else {
@@ -1084,15 +1082,11 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
bool out_changed = false;
bool need_pan_reset;
- if (_input_maximum >= 0) {
- nin = min (_input_maximum, (int) nin);
- }
+ nin = min (_input_maximum.get(_default_type), static_cast<size_t>(nin));
- if (_output_maximum >= 0) {
- nout = min (_output_maximum, (int) nout);
- }
+ nout = min (_output_maximum.get(_default_type), static_cast<size_t>(nout));
- if (nin == n_inputs() && nout == n_outputs() && !clear) {
+ if (nin == n_inputs().get(_default_type) && nout == n_outputs().get(_default_type) && !clear) {
return 0;
}
@@ -1102,7 +1096,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
Port* port;
- if (n_outputs() == nout) {
+ if (n_outputs().get(_default_type) == nout) {
need_pan_reset = false;
} else {
need_pan_reset = true;
@@ -1110,7 +1104,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
/* remove unused ports */
- while (n_inputs() > nin) {
+ while (n_inputs().get(_default_type) > nin) {
throw; // FIXME
/*
_session.engine().unregister_port (_inputs.back());
@@ -1119,7 +1113,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
in_changed = true;*/
}
- while (n_outputs() > nout) {
+ while (n_outputs().get(_default_type) > nout) {
throw; // FIXME
/*
_session.engine().unregister_port (_outputs.back());
@@ -1130,13 +1124,13 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
/* create any necessary new ports (of the default type) */
- while (n_inputs() < nin) {
+ while (n_inputs().get(_default_type) < nin) {
char buf[64];
/* Create a new input port */
- if (_input_maximum == 1) {
+ if (_input_maximum.get_total() == 1) {
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
}
else {
@@ -1163,13 +1157,13 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
/* create any necessary new ports */
- while (n_outputs() < nout) {
+ while (n_outputs().get(_default_type) < nout) {
char buf[64];
/* Create a new output port */
- if (_output_maximum == 1) {
+ if (_output_maximum.get_total() == 1) {
snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
} else {
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
@@ -1235,14 +1229,12 @@ IO::ensure_inputs (uint32_t n, bool clear, bool lockit, void* src)
{
bool changed = false;
- if (_input_maximum >= 0) {
- n = min (_input_maximum, (int) n);
-
- if (n == n_inputs() && !clear) {
- return 0;
- }
+ n = min (_input_maximum.get(_default_type), static_cast<size_t>(n));
+
+ if (n == n_inputs().get(_default_type) && !clear) {
+ return 0;
}
-
+
if (lockit) {
Glib::Mutex::Lock em (_session.engine().process_lock());
Glib::Mutex::Lock im (io_lock);
@@ -1265,7 +1257,7 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
bool changed = false;
bool need_pan_reset;
- if (n_outputs() == n) {
+ if (n_outputs().get(_default_type) == n) {
need_pan_reset = false;
} else {
need_pan_reset = true;
@@ -1273,7 +1265,7 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
/* remove unused ports */
- while (n_outputs() > n) {
+ while (n_outputs().get(_default_type) > n) {
throw; // FIXME
/*
_session.engine().unregister_port (_outputs.back());
@@ -1285,13 +1277,13 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
/* create any necessary new ports */
- while (n_outputs() < n) {
+ while (n_outputs().get(_default_type) < n) {
char buf[64];
/* Create a new output port */
- if (_output_maximum == 1) {
+ if (_output_maximum.get(_default_type) == 1) {
snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
} else {
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
@@ -1333,9 +1325,9 @@ IO::ensure_outputs (uint32_t n, bool clear, bool lockit, void* src)
{
bool changed = false;
- if (_output_maximum >= 0) {
- n = min (_output_maximum, (int) n);
- if (n == n_outputs() && !clear) {
+ if (_output_maximum < ChanCount::INFINITE) {
+ n = min (_output_maximum.get(_default_type), static_cast<size_t>(n));
+ if (n == n_outputs().get(_default_type) && !clear) {
return 0;
}
}
@@ -1371,7 +1363,7 @@ IO::reset_panner ()
{
if (panners_legal) {
if (!no_panner_reset) {
- _panner->reset (n_outputs(), pans_required());
+ _panner->reset (n_outputs().get(_default_type), pans_required());
}
} else {
panner_legal_c.disconnect ();
@@ -1382,7 +1374,7 @@ IO::reset_panner ()
int
IO::panners_became_legal ()
{
- _panner->reset (n_outputs(), pans_required());
+ _panner->reset (n_outputs().get(_default_type), pans_required());
_panner->load (); // automation
panner_legal_c.disconnect ();
return 0;
@@ -1506,11 +1498,12 @@ IO::state (bool full_state)
snprintf (buf, sizeof(buf), "%2.12f", gain());
node->add_property ("gain", buf);
- snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d",
- _input_minimum,
- _input_maximum,
- _output_minimum,
- _output_maximum);
+ const int in_min = (_input_minimum == ChanCount::ZERO) ? -1 : _input_minimum.get(_default_type);
+ const int in_max = (_input_maximum == ChanCount::INFINITE) ? -1 : _input_maximum.get(_default_type);
+ const int out_min = (_output_minimum == ChanCount::ZERO) ? -1 : _output_minimum.get(_default_type);
+ const int out_max = (_output_maximum == ChanCount::INFINITE) ? -1 : _output_maximum.get(_default_type);
+
+ snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d", in_min, in_max, out_min, out_max);
node->add_property ("iolimits", buf);
@@ -1602,12 +1595,18 @@ IO::set_state (const XMLNode& node)
_id = prop->value ();
}
+ size_t in_min = -1;
+ size_t in_max = -1;
+ size_t out_min = -1;
+ size_t out_max = -1;
+
if ((prop = node.property ("iolimits")) != 0) {
- sscanf (prop->value().c_str(), "%d,%d,%d,%d",
- &_input_minimum,
- &_input_maximum,
- &_output_minimum,
- &_output_maximum);
+ sscanf (prop->value().c_str(), "%zd,%zd,%zd,%zd",
+ &in_min, &in_max, &out_min, &out_max);
+ _input_minimum = ChanCount(_default_type, in_min);
+ _input_maximum = ChanCount(_default_type, in_max);
+ _output_minimum = ChanCount(_default_type, out_min);
+ _output_maximum = ChanCount(_default_type, out_max);
}
if ((prop = node.property ("gain")) != 0) {
@@ -1972,24 +1971,60 @@ IO::set_name (string name, void* src)
void
IO::set_input_minimum (int n)
{
- _input_minimum = n;
+ if (n < 0)
+ _input_minimum = ChanCount::ZERO;
+ else
+ _input_minimum = ChanCount(_default_type, n);
}
void
IO::set_input_maximum (int n)
{
- _input_maximum = n;
+ if (n < 0)
+ _input_maximum = ChanCount::INFINITE;
+ else
+ _input_maximum = ChanCount(_default_type, n);
}
void
IO::set_output_minimum (int n)
{
- _output_minimum = n;
+ if (n < 0)
+ _output_minimum = ChanCount::ZERO;
+ else
+ _output_minimum = ChanCount(_default_type, n);
}
void
IO::set_output_maximum (int n)
{
+ if (n < 0)
+ _output_maximum = ChanCount::INFINITE;
+ else
+ _output_maximum = ChanCount(_default_type, n);
+}
+
+void
+IO::set_input_minimum (ChanCount n)
+{
+ _input_minimum = n;
+}
+
+void
+IO::set_input_maximum (ChanCount n)
+{
+ _input_maximum = n;
+}
+
+void
+IO::set_output_minimum (ChanCount n)
+{
+ _output_minimum = n;
+}
+
+void
+IO::set_output_maximum (ChanCount n)
+{
_output_maximum = n;
}
@@ -2279,7 +2314,7 @@ IO::GainControllable::get_value (void) const
void
IO::reset_peak_meters ()
{
- uint32_t limit = max (n_inputs(), n_outputs());
+ uint32_t limit = max (n_inputs().get(DataType::AUDIO), n_outputs().get(DataType::AUDIO));
for (uint32_t i = 0; i < limit; ++i) {
_peak_power[i] = 0;
@@ -2289,7 +2324,7 @@ IO::reset_peak_meters ()
void
IO::setup_peak_meters ()
{
- uint32_t limit = max (n_inputs(), n_outputs());
+ uint32_t limit = max (n_inputs().get(DataType::AUDIO), n_outputs().get(DataType::AUDIO));
while (_peak_power.size() < limit) {
_peak_power.push_back (0);
@@ -2336,7 +2371,7 @@ void
IO::meter ()
{
Glib::Mutex::Lock lm (io_lock); // READER: meter thread.
- uint32_t limit = max (n_inputs(), n_outputs());
+ uint32_t limit = max (n_inputs().get(DataType::AUDIO), n_outputs().get(DataType::AUDIO));
for (uint32_t n = 0; n < limit; ++n) {