- Replaced integer port counts (and input/output maximum/minimum) with ChanCount, which can count multiple types and does the reasonable thing for all comparison operators
- Removed the fader/meters from MIDI mixer strips, at least until they do something - Made the Add Route dialog refuse to create MIDI busses, Spifftacular warning dialog and all Changes a bit more widespread than I was hoping, but worked out really well - lots of code will continue to work fine even when multi-typed (eg instrument) IOs come around, just ignoring the types it doesn't care about. Most all changes related to counts are little search/replace deals, logic doesn't need to change. Hopefully SVN can handle (automatic) merging with the other SoC projects if the buffer change goes as well. Next step: do for buffers what the last two commits did for ports. git-svn-id: svn://localhost/ardour2/branches/midi@787 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -159,11 +159,16 @@ AddRouteDialog::track ()
|
||||
return track_button.get_active ();
|
||||
}
|
||||
|
||||
bool
|
||||
AddRouteDialog::midi ()
|
||||
ARDOUR::DataType
|
||||
AddRouteDialog::type ()
|
||||
{
|
||||
// FIXME: ew
|
||||
|
||||
const string str = channel_combo.get_active_text();
|
||||
return (str == _("MIDI"));
|
||||
if (str == _("MIDI"))
|
||||
return ARDOUR::DataType::MIDI;
|
||||
else
|
||||
return ARDOUR::DataType::AUDIO;
|
||||
}
|
||||
|
||||
string
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <gtkmm/comboboxtext.h>
|
||||
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/data_type.h>
|
||||
|
||||
class AddRouteDialog : public Gtk::Dialog
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class AddRouteDialog : public Gtk::Dialog
|
||||
~AddRouteDialog ();
|
||||
|
||||
bool track ();
|
||||
bool midi ();
|
||||
ARDOUR::DataType type();
|
||||
std::string name_template ();
|
||||
int channels ();
|
||||
int count ();
|
||||
|
||||
@@ -1414,7 +1414,7 @@ ARDOUR_UI::name_io_setup (AudioEngine& engine,
|
||||
bool in)
|
||||
{
|
||||
if (in) {
|
||||
if (io.n_inputs() == 0) {
|
||||
if (io.n_inputs().get_total() == 0) {
|
||||
buf = _("none");
|
||||
return;
|
||||
}
|
||||
@@ -1433,7 +1433,7 @@ ARDOUR_UI::name_io_setup (AudioEngine& engine,
|
||||
|
||||
} else {
|
||||
|
||||
if (io.n_outputs() == 0) {
|
||||
if (io.n_outputs().get_total() == 0) {
|
||||
buf = _("none");
|
||||
return;
|
||||
}
|
||||
@@ -2103,7 +2103,7 @@ ARDOUR_UI::add_route ()
|
||||
Session::AutoConnectOption oac = session->get_output_auto_connect();
|
||||
|
||||
if (oac & Session::AutoConnectMaster) {
|
||||
output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
|
||||
output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
|
||||
} else {
|
||||
output_chan = input_chan;
|
||||
}
|
||||
@@ -2111,10 +2111,15 @@ ARDOUR_UI::add_route ()
|
||||
/* XXX do something with name template */
|
||||
|
||||
while (count) {
|
||||
if (track && add_route_dialog->midi()) {
|
||||
session_add_midi_track();
|
||||
} else if (add_route_dialog->midi()) {
|
||||
session_add_midi_bus();
|
||||
if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
|
||||
if (track) {
|
||||
session_add_midi_track();
|
||||
} else {
|
||||
MessageDialog msg (*editor,
|
||||
_("Sorry, MIDI Busses are not supported at this time."));
|
||||
msg.run ();
|
||||
//session_add_midi_bus();
|
||||
}
|
||||
} else if (track) {
|
||||
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
|
||||
} else {
|
||||
|
||||
@@ -406,7 +406,7 @@ AudioTimeAxisView::update_pans ()
|
||||
/* we don't draw lines for "greater than stereo" panning.
|
||||
*/
|
||||
|
||||
if (_route->n_outputs() > 2) {
|
||||
if (_route->n_outputs().get(DataType::AUDIO) > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
|
||||
input_chan = finfo.channels;
|
||||
|
||||
if (session->get_output_auto_connect() & Session::AutoConnectMaster) {
|
||||
output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
|
||||
output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
|
||||
} else {
|
||||
output_chan = input_chan;
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ ExportDialog::set_state()
|
||||
}
|
||||
|
||||
TreeModel::Children rows = master_selector.get_model()->children();
|
||||
for (uint32_t r = 0; r < session->master_out()->n_outputs(); ++r) {
|
||||
for (uint32_t r = 0; r < session->master_out()->n_outputs().get(DataType::AUDIO); ++r) {
|
||||
if (nchns == 2) {
|
||||
if (r % 2) {
|
||||
rows[r][exp_cols.right] = true;
|
||||
@@ -1092,9 +1092,9 @@ ExportDialog::fill_lists ()
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t i=0; i < route->n_outputs(); ++i) {
|
||||
for (uint32_t i=0; i < route->n_outputs().get(DataType::AUDIO); ++i) {
|
||||
string name;
|
||||
if (route->n_outputs() == 1) {
|
||||
if (route->n_outputs().get(DataType::AUDIO) == 1) {
|
||||
name = route->name();
|
||||
} else {
|
||||
name = string_compose("%1: out-%2", route->name(), i+1);
|
||||
|
||||
@@ -141,13 +141,16 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
|
||||
gain_automation_state_button.set_size_request(15, 15);
|
||||
gain_automation_style_button.set_size_request(15, 15);
|
||||
|
||||
|
||||
fader_vbox = manage (new Gtk::VBox());
|
||||
fader_vbox->set_spacing (0);
|
||||
fader_vbox->pack_start (*gain_slider, false, false, 0);
|
||||
|
||||
hbox.set_spacing (0);
|
||||
hbox.pack_start (*fader_vbox, false, false, 2);
|
||||
|
||||
if (_io->default_type() == ARDOUR::DataType::AUDIO)
|
||||
hbox.pack_start (*fader_vbox, false, false, 2);
|
||||
|
||||
set_width(Narrow);
|
||||
|
||||
Route* r;
|
||||
@@ -382,7 +385,7 @@ GainMeter::hide_all_meters ()
|
||||
void
|
||||
GainMeter::setup_meters ()
|
||||
{
|
||||
uint32_t nmeters = _io->n_outputs();
|
||||
uint32_t nmeters = _io->n_outputs().get(DataType::AUDIO);
|
||||
guint16 width;
|
||||
|
||||
hide_all_meters ();
|
||||
@@ -394,16 +397,16 @@ GainMeter::setup_meters ()
|
||||
switch (r->meter_point()) {
|
||||
case MeterPreFader:
|
||||
case MeterInput:
|
||||
nmeters = r->n_inputs();
|
||||
nmeters = r->n_inputs().get(DataType::AUDIO);
|
||||
break;
|
||||
case MeterPostFader:
|
||||
nmeters = r->n_outputs();
|
||||
nmeters = r->n_outputs().get(DataType::AUDIO);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
nmeters = _io->n_outputs();
|
||||
nmeters = _io->n_outputs().get(DataType::AUDIO);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -183,15 +183,18 @@ IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input)
|
||||
|
||||
port_button_box.pack_start (add_port_button, false, false);
|
||||
|
||||
// The IO selector only works for single typed IOs
|
||||
const ARDOUR::DataType t = io->default_type();
|
||||
|
||||
if (for_input) {
|
||||
if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) {
|
||||
if (io->input_maximum().get(t) < 0 || io->input_maximum().get(t) > (size_t) io->n_inputs().get(t)) {
|
||||
add_port_button.set_sensitive (true);
|
||||
} else {
|
||||
add_port_button.set_sensitive (false);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) {
|
||||
if (io->output_maximum().get(t) < 0 || io->output_maximum().get(t) > (size_t) io->n_outputs().get(t)) {
|
||||
add_port_button.set_sensitive (true);
|
||||
} else {
|
||||
add_port_button.set_sensitive (false);
|
||||
@@ -202,14 +205,14 @@ IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input)
|
||||
port_button_box.pack_start (remove_port_button, false, false);
|
||||
|
||||
if (for_input) {
|
||||
if (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs()) {
|
||||
if (io->input_minimum().get(t) < 0 || io->input_minimum().get(t) < (size_t) io->n_inputs().get(t)) {
|
||||
remove_port_button.set_sensitive (true);
|
||||
} else {
|
||||
remove_port_button.set_sensitive (false);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs()) {
|
||||
if (io->output_minimum().get(t) < 0 || io->output_minimum().get(t) < (size_t) io->n_outputs().get(t)) {
|
||||
remove_port_button.set_sensitive (true);
|
||||
} else {
|
||||
remove_port_button.set_sensitive (false);
|
||||
@@ -373,10 +376,13 @@ IOSelector::display_ports ()
|
||||
Port *port;
|
||||
uint32_t limit;
|
||||
|
||||
// The IO selector only works for single typed IOs
|
||||
const ARDOUR::DataType t = io->default_type();
|
||||
|
||||
if (for_input) {
|
||||
limit = io->n_inputs();
|
||||
limit = io->n_inputs().get(t);
|
||||
} else {
|
||||
limit = io->n_outputs();
|
||||
limit = io->n_outputs().get(t);
|
||||
}
|
||||
|
||||
for (slist<TreeView *>::iterator i = port_displays.begin(); i != port_displays.end(); ) {
|
||||
@@ -443,7 +449,7 @@ IOSelector::display_ports ()
|
||||
|
||||
if (for_input) {
|
||||
|
||||
if (io->input_maximum() == 1) {
|
||||
if (io->input_maximum().get(io->default_type()) == 1) {
|
||||
selected_port = port;
|
||||
selected_port_tview = tview;
|
||||
} else {
|
||||
@@ -454,7 +460,7 @@ IOSelector::display_ports ()
|
||||
|
||||
} else {
|
||||
|
||||
if (io->output_maximum() == 1) {
|
||||
if (io->output_maximum().get(t) == 1) {
|
||||
selected_port = port;
|
||||
selected_port_tview = tview;
|
||||
} else {
|
||||
@@ -545,6 +551,9 @@ IOSelector::add_port ()
|
||||
{
|
||||
/* add a new port, then hide the button if we're up to the maximum allowed */
|
||||
|
||||
// The IO selector only works for single typed IOs
|
||||
const ARDOUR::DataType t = io->default_type();
|
||||
|
||||
if (for_input) {
|
||||
|
||||
try {
|
||||
@@ -556,11 +565,11 @@ IOSelector::add_port ()
|
||||
msg.run ();
|
||||
}
|
||||
|
||||
if (io->input_maximum() >= 0 && io->input_maximum() <= (int) io->n_inputs()) {
|
||||
if (io->input_maximum().get(t) >= 0 && io->input_maximum().get(t) <= (size_t) io->n_inputs().get(t)) {
|
||||
add_port_button.set_sensitive (false);
|
||||
}
|
||||
|
||||
if (io->input_minimum() < (int) io->n_inputs()) {
|
||||
if (io->input_minimum().get(t) < (size_t) io->n_inputs().get(t)) {
|
||||
remove_port_button.set_sensitive (true);
|
||||
}
|
||||
|
||||
@@ -575,7 +584,7 @@ IOSelector::add_port ()
|
||||
msg.run ();
|
||||
}
|
||||
|
||||
if (io->output_maximum() >= 0 && io->output_maximum() <= (int) io->n_outputs()) {
|
||||
if (io->output_maximum().get(t) >= 0 && io->output_maximum().get(t) <= (size_t) io->n_outputs().get(t)) {
|
||||
add_port_button.set_sensitive (false);
|
||||
}
|
||||
}
|
||||
@@ -586,17 +595,20 @@ IOSelector::remove_port ()
|
||||
{
|
||||
uint32_t nports;
|
||||
|
||||
// The IO selector only works for single typed IOs
|
||||
const ARDOUR::DataType t = io->default_type();
|
||||
|
||||
// always remove last port
|
||||
|
||||
if (for_input) {
|
||||
if ((nports = io->n_inputs()) > 0) {
|
||||
if ((nports = io->n_inputs().get(t)) > 0) {
|
||||
io->remove_input_port (io->input(nports-1), this);
|
||||
}
|
||||
if (io->input_minimum() == (int) io->n_inputs()) {
|
||||
if (io->input_minimum().get(t) == (size_t) io->n_inputs().get(t)) {
|
||||
remove_port_button.set_sensitive (false);
|
||||
}
|
||||
} else {
|
||||
if ((nports = io->n_outputs()) > 0) {
|
||||
if ((nports = io->n_outputs().get(t)) > 0) {
|
||||
io->remove_output_port (io->output(nports-1), this);
|
||||
}
|
||||
}
|
||||
@@ -749,11 +761,11 @@ IOSelector::redisplay ()
|
||||
display_ports ();
|
||||
|
||||
if (for_input) {
|
||||
if (io->input_maximum() != 0) {
|
||||
if (io->input_maximum().get(io->default_type()) != 0) {
|
||||
rescan ();
|
||||
}
|
||||
} else {
|
||||
if (io->output_maximum() != 0) {
|
||||
if (io->output_maximum().get(io->default_type()) != 0) {
|
||||
rescan();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ MixerStrip::add_connection_to_input_menu (ARDOUR::Connection* c)
|
||||
|
||||
MenuList& citems = input_menu.items();
|
||||
|
||||
if (c->nports() == _route->n_inputs()) {
|
||||
if (c->nports() == _route->n_inputs().get_total()) {
|
||||
|
||||
citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_input_chosen), c)));
|
||||
|
||||
@@ -637,7 +637,7 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c)
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->nports() == _route->n_outputs()) {
|
||||
if (c->nports() == _route->n_outputs().get_total()) {
|
||||
|
||||
MenuList& citems = output_menu.items();
|
||||
citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_output_chosen), c)));
|
||||
@@ -1129,8 +1129,6 @@ MixerStrip::route_active_changed ()
|
||||
{
|
||||
RouteUI::route_active_changed ();
|
||||
|
||||
// FIXME: MIDI/Audio bus distinction
|
||||
|
||||
if (is_midi_track()) {
|
||||
if (_route->active()) {
|
||||
set_name ("MidiTrackStripBase");
|
||||
@@ -1139,7 +1137,6 @@ MixerStrip::route_active_changed ()
|
||||
set_name ("MidiTrackStripBaseInactive");
|
||||
gpm.set_meter_strip_name ("MidiTrackStripBaseInactive");
|
||||
}
|
||||
gpm.set_fader_name ("MidiTrackFader");
|
||||
} else if (is_audio_track()) {
|
||||
if (_route->active()) {
|
||||
set_name ("AudioTrackStripBase");
|
||||
|
||||
@@ -276,7 +276,7 @@ PannerUI::update_pan_state ()
|
||||
void
|
||||
PannerUI::setup_pan ()
|
||||
{
|
||||
uint32_t nouts = _io->n_outputs ();
|
||||
uint32_t nouts = _io->n_outputs ().get(ARDOUR::DataType::AUDIO);
|
||||
|
||||
if (nouts == 0 || nouts == 1) {
|
||||
|
||||
@@ -375,7 +375,7 @@ PannerUI::setup_pan ()
|
||||
}
|
||||
|
||||
update_pan_sensitive ();
|
||||
panner->reset (_io->n_inputs());
|
||||
panner->reset (_io->n_inputs().get(ARDOUR::DataType::AUDIO));
|
||||
panner->set_size_request (w, 61);
|
||||
|
||||
/* and finally, add it to the panner frame */
|
||||
@@ -462,7 +462,7 @@ PannerUI::effective_pan_display ()
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_io->n_outputs()) {
|
||||
switch (_io->n_outputs().get(ARDOUR::DataType::AUDIO)) {
|
||||
case 0:
|
||||
case 1:
|
||||
/* relax */
|
||||
@@ -473,7 +473,7 @@ PannerUI::effective_pan_display ()
|
||||
break;
|
||||
|
||||
default:
|
||||
//panner->move_puck (pan_value (v, right), 0.5);
|
||||
//panner->move_puck (pan_value (v, right), 0.5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -499,7 +499,7 @@ PannerUI::pan_changed (void *src)
|
||||
panning_link_button.set_sensitive (true);
|
||||
}
|
||||
|
||||
uint32_t nouts = _io->n_outputs();
|
||||
uint32_t nouts = _io->n_outputs().get(ARDOUR::DataType::AUDIO);
|
||||
|
||||
switch (nouts) {
|
||||
case 0:
|
||||
@@ -556,7 +556,7 @@ PannerUI::pan_value_changed (uint32_t which)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which));
|
||||
|
||||
if (_io->n_outputs() > 1 && which < _io->panner().size()) {
|
||||
if (_io->n_outputs().get(ARDOUR::DataType::AUDIO) > 1 && which < _io->panner().size()) {
|
||||
float xpos;
|
||||
float val = pan_adjustments[which]->get_value ();
|
||||
|
||||
@@ -626,7 +626,7 @@ PannerUI::update_pan_sensitive ()
|
||||
{
|
||||
bool sensitive = !(_io->panner().automation_state() & Play);
|
||||
|
||||
switch (_io->n_outputs()) {
|
||||
switch (_io->n_outputs().get(ARDOUR::DataType::AUDIO)) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
|
||||
@@ -417,8 +417,8 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr
|
||||
p.name(),
|
||||
p.get_info()->n_inputs,
|
||||
p.get_info()->n_outputs,
|
||||
io->n_inputs(),
|
||||
io->n_outputs(),
|
||||
io->n_inputs().get_total(),
|
||||
io->n_outputs().get_total(),
|
||||
streams));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ ardour.Append(POTFILE = domain + '.pot')
|
||||
ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
|
||||
|
||||
ardour_files=Split("""
|
||||
chan_count.cc
|
||||
diskstream.cc
|
||||
track.cc
|
||||
audio_diskstream.cc
|
||||
@@ -39,6 +40,7 @@ audio_port.cc
|
||||
midi_port.cc
|
||||
port_set.cc
|
||||
buffer.cc
|
||||
buffer_set.cc
|
||||
audiofilesource.cc
|
||||
audiofilter.cc
|
||||
audioregion.cc
|
||||
|
||||
110
libs/ardour/ardour/buffer_set.h
Normal file
110
libs/ardour/ardour/buffer_set.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_buffer_set_h__
|
||||
#define __ardour_buffer_set_h__
|
||||
|
||||
#include <vector>
|
||||
#include <ardour/buffer.h>
|
||||
#include <ardour/chan_count.h>
|
||||
#include <ardour/data_type.h>
|
||||
#include <ardour/port_set.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
|
||||
/** A set of buffers of various types.
|
||||
*
|
||||
* These are mainly accessed from Session and passed around as scratch buffers
|
||||
* (eg as parameters to run() methods) to do in-place signal processing.
|
||||
*
|
||||
* There are two types of counts associated with a BufferSet - available,
|
||||
* and the 'use count'. Available is the actual number of allocated buffers
|
||||
* (and so is the maximum acceptable value for the use counts).
|
||||
*
|
||||
* The use counts are how things determine the form of their input and inform
|
||||
* others the form of their output (eg what they did to the BufferSet).
|
||||
* Setting the use counts is realtime safe.
|
||||
*/
|
||||
class BufferSet
|
||||
{
|
||||
public:
|
||||
BufferSet(const PortSet& ports);
|
||||
BufferSet();
|
||||
~BufferSet();
|
||||
|
||||
void clear();
|
||||
|
||||
void ensure_buffers(const ChanCount& chan_count, size_t buffer_capacity);
|
||||
void ensure_buffers(size_t num_buffers, DataType type, size_t buffer_capacity);
|
||||
|
||||
// FIXME: add these
|
||||
//const ChanCount& available() const { return _count; }
|
||||
//ChanCount& available() { return _count; }
|
||||
|
||||
const ChanCount& count() const { return _count; }
|
||||
ChanCount& count() { return _count; }
|
||||
|
||||
size_t available_buffers(DataType type) const;
|
||||
size_t buffer_capacity(DataType type) const;
|
||||
|
||||
Buffer& buffer(DataType type, size_t i)
|
||||
{
|
||||
assert(i <= _count.get(type));
|
||||
return *_buffers[type.to_index()][i];
|
||||
}
|
||||
|
||||
AudioBuffer& audio_buffer(size_t i)
|
||||
{
|
||||
return (AudioBuffer&)buffer(DataType::AUDIO, i);
|
||||
}
|
||||
#if 0
|
||||
/** See PortInsert::run for an example of usage */
|
||||
class IndexSet {
|
||||
public:
|
||||
IndexSet() { reset(); }
|
||||
|
||||
void reset() { _is[0] = 0; _is[1] = 0; }
|
||||
|
||||
size_t index(DataType type) { return _is[type.to_index()]; }
|
||||
void increment(DataType type) { _is[type.to_index()] += 1; }
|
||||
|
||||
private:
|
||||
int _is[2];
|
||||
};
|
||||
#endif
|
||||
|
||||
const ChanCount& chan_count() const { return _count; }
|
||||
|
||||
private:
|
||||
typedef std::vector<Buffer*> BufferVec;
|
||||
|
||||
/// Vector of vectors, indexed by DataType::to_index()
|
||||
std::vector<BufferVec> _buffers;
|
||||
|
||||
/// Use counts (there may be more actual buffers than this)
|
||||
ChanCount _count;
|
||||
|
||||
/// Whether we (don't) 'own' the contained buffers (are a mirror of a PortSet)
|
||||
bool _is_mirror;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif // __ardour_buffer_set_h__
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
ChanCount(DataType type, size_t channels)
|
||||
{
|
||||
reset();
|
||||
set_count(type, channels);
|
||||
set(type, channels);
|
||||
}
|
||||
|
||||
void reset()
|
||||
@@ -44,10 +44,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void set_count(DataType type, size_t count) { _counts[type.to_index()] = count; }
|
||||
size_t get_count(DataType type) const { return _counts[type.to_index()]; }
|
||||
void set(DataType type, size_t count) { _counts[type.to_index()] = count; }
|
||||
size_t get(DataType type) const { return _counts[type.to_index()]; }
|
||||
|
||||
size_t get_total_count() const
|
||||
size_t get_total() const
|
||||
{
|
||||
size_t ret = 0;
|
||||
for (size_t i=0; i < DataType::num_types; ++i)
|
||||
@@ -70,7 +70,51 @@ public:
|
||||
return ! (*this == other);
|
||||
}
|
||||
|
||||
bool operator<(const ChanCount& other) const
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
if (_counts[(*t).to_index()] >= other._counts[(*t).to_index()]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<=(const ChanCount& other) const
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
if (_counts[(*t).to_index()] > other._counts[(*t).to_index()]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator>(const ChanCount& other) const
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
if (_counts[(*t).to_index()] <= other._counts[(*t).to_index()]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator>=(const ChanCount& other) const
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
if (_counts[(*t).to_index()] < other._counts[(*t).to_index()]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const ChanCount INFINITE;
|
||||
static const ChanCount ZERO;
|
||||
|
||||
private:
|
||||
|
||||
size_t _counts[DataType::num_types];
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/data_type.h>
|
||||
#include <ardour/port_set.h>
|
||||
#include <ardour/chan_count.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@@ -72,14 +73,20 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
int input_min = -1, int input_max = -1,
|
||||
int output_min = -1, int output_max = -1,
|
||||
DataType default_type = DataType::AUDIO);
|
||||
|
||||
|
||||
virtual ~IO();
|
||||
|
||||
int input_minimum() const { return _input_minimum; }
|
||||
int input_maximum() const { return _input_maximum; }
|
||||
int output_minimum() const { return _output_minimum; }
|
||||
int output_maximum() const { return _output_maximum; }
|
||||
ChanCount input_minimum() const { return _input_minimum; }
|
||||
ChanCount input_maximum() const { return _input_maximum; }
|
||||
ChanCount output_minimum() const { return _output_minimum; }
|
||||
ChanCount output_maximum() const { return _output_maximum; }
|
||||
|
||||
void set_input_minimum (ChanCount n);
|
||||
void set_input_maximum (ChanCount n);
|
||||
void set_output_minimum (ChanCount n);
|
||||
void set_output_maximum (ChanCount n);
|
||||
|
||||
// Do not write any new code using these
|
||||
void set_input_minimum (int n);
|
||||
void set_input_maximum (int n);
|
||||
void set_output_minimum (int n);
|
||||
@@ -162,8 +169,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
MidiPort* midi_input(uint32_t n) const;
|
||||
MidiPort* midi_output(uint32_t n) const;
|
||||
|
||||
uint32_t n_inputs () const { return _inputs.num_ports(); }
|
||||
uint32_t n_outputs () const { return _outputs.num_ports(); }
|
||||
const ChanCount& n_inputs () const { return _inputs.chan_count(); }
|
||||
const ChanCount& n_outputs () const { return _outputs.chan_count(); }
|
||||
|
||||
sigc::signal<void,IOChange,void*> input_changed;
|
||||
sigc::signal<void,IOChange,void*> output_changed;
|
||||
@@ -193,7 +200,7 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
static sigc::signal<int> PortsLegal;
|
||||
static sigc::signal<int> PannersLegal;
|
||||
static sigc::signal<int> ConnectingLegal;
|
||||
static sigc::signal<void,uint32_t> MoreOutputs;
|
||||
static sigc::signal<void,ChanCount> MoreOutputs;
|
||||
static sigc::signal<int> PortsCreated;
|
||||
|
||||
PBD::Controllable& gain_control() {
|
||||
@@ -203,7 +210,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
/* Peak metering */
|
||||
|
||||
float peak_input_power (uint32_t n) {
|
||||
if (n < std::max (n_inputs(), n_outputs())) {
|
||||
if (n < std::max (_inputs.chan_count().get(DataType::AUDIO),
|
||||
_outputs.chan_count().get(DataType::AUDIO))) {
|
||||
return _visible_peak_power[n];
|
||||
} else {
|
||||
return minus_infinity();
|
||||
@@ -300,7 +308,8 @@ public:
|
||||
void reset_peak_meters();
|
||||
void reset_panner ();
|
||||
|
||||
virtual uint32_t pans_required() const { return n_inputs(); }
|
||||
virtual uint32_t pans_required() const
|
||||
{ return _inputs.chan_count().get(DataType::AUDIO); }
|
||||
|
||||
static void apply_declick (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes,
|
||||
gain_t initial, gain_t target, bool invert_polarity);
|
||||
@@ -363,10 +372,10 @@ public:
|
||||
sigc::connection port_legal_c;
|
||||
sigc::connection panner_legal_c;
|
||||
|
||||
int _input_minimum;
|
||||
int _input_maximum;
|
||||
int _output_minimum;
|
||||
int _output_maximum;
|
||||
ChanCount _input_minimum;
|
||||
ChanCount _input_maximum;
|
||||
ChanCount _output_minimum;
|
||||
ChanCount _output_maximum;
|
||||
|
||||
|
||||
static int parse_io_string (const string&, vector<string>& chns);
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
const ChanCount& chan_count() const { return _chan_count; }
|
||||
|
||||
bool empty() const { return (_chan_count.get_total_count() == 0); }
|
||||
bool empty() const { return (_chan_count.get_total() == 0); }
|
||||
|
||||
// ITERATORS
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(*this, 0); }
|
||||
iterator end() { return iterator(*this, _chan_count.get_total_count()); }
|
||||
iterator end() { return iterator(*this, _chan_count.get_total()); }
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
};
|
||||
|
||||
const_iterator begin() const { return const_iterator(*this, 0); }
|
||||
const_iterator end() const { return const_iterator(*this, _chan_count.get_total_count()); }
|
||||
const_iterator end() const { return const_iterator(*this, _chan_count.get_total()); }
|
||||
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
};
|
||||
|
||||
audio_iterator audio_begin() { return audio_iterator(*this, 0); }
|
||||
audio_iterator audio_end() { return audio_iterator(*this, _chan_count.get_count(DataType::AUDIO)); }
|
||||
audio_iterator audio_end() { return audio_iterator(*this, _chan_count.get(DataType::AUDIO)); }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ class Redirect : public IO
|
||||
bool active () const { return _active; }
|
||||
void set_active (bool yn, void *src);
|
||||
|
||||
virtual uint32_t output_streams() const { return n_outputs(); }
|
||||
virtual uint32_t input_streams () const { return n_inputs(); }
|
||||
virtual uint32_t natural_output_streams() const { return n_outputs(); }
|
||||
virtual uint32_t natural_input_streams () const { return n_inputs(); }
|
||||
virtual uint32_t output_streams() const { return n_outputs().get(_default_type); }
|
||||
virtual uint32_t input_streams () const { return n_inputs().get(_default_type); }
|
||||
virtual uint32_t natural_output_streams() const { return n_outputs().get(_default_type); }
|
||||
virtual uint32_t natural_input_streams () const { return n_inputs().get(_default_type); }
|
||||
|
||||
uint32_t sort_key() const { return _sort_key; }
|
||||
void set_sort_key (uint32_t key);
|
||||
|
||||
@@ -1091,7 +1091,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
|
||||
void update_latency_compensation_proxy (void* ignored);
|
||||
|
||||
void ensure_passthru_buffers (uint32_t howmany);
|
||||
void ensure_passthru_buffers (ChanCount howmany);
|
||||
|
||||
void process_scrub (jack_nframes_t);
|
||||
void process_without_events (jack_nframes_t);
|
||||
|
||||
@@ -212,21 +212,21 @@ AudioDiskstream::non_realtime_input_change ()
|
||||
|
||||
if (input_change_pending & ConfigurationChanged) {
|
||||
|
||||
if (_io->n_inputs() > _n_channels) {
|
||||
if (_io->n_inputs().get(DataType::AUDIO) > _n_channels) {
|
||||
|
||||
// we need to add new channel infos
|
||||
|
||||
int diff = _io->n_inputs() - channels.size();
|
||||
int diff = _io->n_inputs().get(DataType::AUDIO) - channels.size();
|
||||
|
||||
for (int i = 0; i < diff; ++i) {
|
||||
add_channel ();
|
||||
}
|
||||
|
||||
} else if (_io->n_inputs() < _n_channels) {
|
||||
} else if (_io->n_inputs().get(DataType::AUDIO) < _n_channels) {
|
||||
|
||||
// we need to get rid of channels
|
||||
|
||||
int diff = channels.size() - _io->n_inputs();
|
||||
int diff = channels.size() - _io->n_inputs().get(DataType::AUDIO);
|
||||
|
||||
for (int i = 0; i < diff; ++i) {
|
||||
remove_channel ();
|
||||
@@ -264,7 +264,7 @@ AudioDiskstream::non_realtime_input_change ()
|
||||
void
|
||||
AudioDiskstream::get_input_sources ()
|
||||
{
|
||||
uint32_t ni = _io->n_inputs();
|
||||
uint32_t ni = _io->n_inputs().get(DataType::AUDIO);
|
||||
|
||||
for (uint32_t n = 0; n < ni; ++n) {
|
||||
|
||||
|
||||
@@ -417,7 +417,7 @@ int
|
||||
AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
|
||||
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
if (n_outputs() == 0) {
|
||||
if (n_outputs().get_total() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
}
|
||||
}
|
||||
|
||||
if (n_outputs() == 0 && _redirects.empty()) {
|
||||
if (n_outputs().get_total() == 0 && _redirects.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -609,7 +609,7 @@ int
|
||||
AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
|
||||
bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
if (n_outputs() == 0 && _redirects.empty()) {
|
||||
if (n_outputs().get_total() == 0 && _redirects.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Auditioner::audition_current_playlist ()
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
_panner->reset (n_outputs().get(DataType::AUDIO), _diskstream->n_channels());
|
||||
|
||||
g_atomic_int_set (&_active, 1);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ Auditioner::audition_region (AudioRegion& region)
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
_panner->reset (n_outputs().get(DataType::AUDIO), _diskstream->n_channels());
|
||||
|
||||
length = the_region->length();
|
||||
_diskstream->seek (0);
|
||||
|
||||
141
libs/ardour/buffer_set.cc
Normal file
141
libs/ardour/buffer_set.cc
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <ardour/buffer_set.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
|
||||
/** Create a BufferSet to mirror a PortSet */
|
||||
BufferSet::BufferSet(const PortSet& ports)
|
||||
: _count(ports.chan_count())
|
||||
, _is_mirror(true)
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
BufferVec v;
|
||||
|
||||
for (size_t j=0; j < ports.num_ports(*t); ++j) {
|
||||
v.push_back(&ports.nth_port_of_type(*t, j)->get_buffer());
|
||||
}
|
||||
|
||||
_buffers.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new, empty BufferSet */
|
||||
BufferSet::BufferSet()
|
||||
: _is_mirror(false)
|
||||
{
|
||||
for (size_t i=0; i < DataType::num_types; ++i)
|
||||
_buffers.push_back( BufferVec() );
|
||||
|
||||
_count.reset();
|
||||
}
|
||||
|
||||
|
||||
BufferSet::~BufferSet()
|
||||
{
|
||||
if (!_is_mirror)
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
/** Destroy all contained buffers.
|
||||
*/
|
||||
void
|
||||
BufferSet::clear()
|
||||
{
|
||||
for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) {
|
||||
for (BufferVec::iterator j = (*i).begin(); j != (*i).end(); ++j) {
|
||||
delete *j;
|
||||
}
|
||||
(*i).clear();
|
||||
}
|
||||
_buffers.clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BufferSet::ensure_buffers(const ChanCount& chan_count, size_t buffer_capacity)
|
||||
{
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
ensure_buffers(chan_count.get(*t), *t, buffer_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Ensure that there are @a num_buffers buffers of type @a type available,
|
||||
* each of size at least @a buffer_size
|
||||
*/
|
||||
void
|
||||
BufferSet::ensure_buffers(size_t num_buffers, DataType type, size_t buffer_capacity)
|
||||
{
|
||||
assert(type != DataType::NIL);
|
||||
assert(type.to_index() < _buffers.size());
|
||||
|
||||
if (num_buffers == 0)
|
||||
return;
|
||||
|
||||
// The vector of buffers of the type we care about
|
||||
BufferVec& bufs = _buffers[type.to_index()];
|
||||
|
||||
// If there's not enough or they're too small, just nuke the whole thing and
|
||||
// rebuild it (so I'm lazy..)
|
||||
if (bufs.size() < num_buffers
|
||||
|| (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
|
||||
|
||||
// Nuke it
|
||||
for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
|
||||
delete (*i);
|
||||
}
|
||||
bufs.clear();
|
||||
|
||||
// Rebuild it
|
||||
for (size_t i=0; i < num_buffers; ++i) {
|
||||
bufs.push_back(Buffer::create(type, buffer_capacity));
|
||||
}
|
||||
}
|
||||
|
||||
// Post-conditions
|
||||
assert(bufs.size() >= num_buffers);
|
||||
assert((bufs[0])->type() == type);
|
||||
assert(bufs[0]->capacity() >= buffer_capacity);
|
||||
}
|
||||
|
||||
size_t
|
||||
BufferSet::available_buffers(DataType type) const
|
||||
{
|
||||
return _buffers[type.to_symbol()-1].size();
|
||||
}
|
||||
|
||||
|
||||
/** Get the capacity (size) of the available buffers of the given type.
|
||||
*
|
||||
* All buffers of a certain type always have the same capacity.
|
||||
*/
|
||||
size_t
|
||||
BufferSet::buffer_capacity(DataType type) const
|
||||
{
|
||||
assert(available_buffers(type) > 0);
|
||||
return _buffers[type.to_index()][0]->capacity();
|
||||
}
|
||||
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
48
libs/ardour/chan_count.cc
Normal file
48
libs/ardour/chan_count.cc
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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: insert.cc 712 2006-07-28 01:08:57Z drobilla $
|
||||
*/
|
||||
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#include <stdint.h>
|
||||
#include <ardour/chan_count.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
// infinite/zero chan count stuff, for setting minimums and maximums, etc.
|
||||
// FIXME: implement this in a less fugly way
|
||||
|
||||
ChanCount
|
||||
infinity_factory()
|
||||
{
|
||||
ChanCount ret;
|
||||
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
ret.set(*t, SIZE_MAX);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Statics
|
||||
const ChanCount ChanCount::INFINITE = infinity_factory();
|
||||
const ChanCount ChanCount::ZERO = ChanCount();
|
||||
|
||||
|
||||
} // namespace ARDOUR
|
||||
@@ -85,7 +85,7 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placemen
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em (_session.engine().process_lock());
|
||||
IO::MoreOutputs (output_streams ());
|
||||
IO::MoreOutputs (ChanCount(_default_type, output_streams()));
|
||||
}
|
||||
|
||||
RedirectCreated (this); /* EMIT SIGNAL */
|
||||
@@ -106,7 +106,7 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node)
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em (_session.engine().process_lock());
|
||||
IO::MoreOutputs (output_streams());
|
||||
IO::MoreOutputs (ChanCount(_default_type, output_streams()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,7 +903,7 @@ PortInsert::~PortInsert ()
|
||||
void
|
||||
PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset)
|
||||
{
|
||||
if (n_outputs() == 0) {
|
||||
if (n_outputs().get(_default_type) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -999,7 +999,7 @@ PortInsert::latency()
|
||||
int32_t
|
||||
PortInsert::can_support_input_configuration (int32_t in) const
|
||||
{
|
||||
if (input_maximum() == -1 && output_maximum() == -1) {
|
||||
if (input_maximum() == ChanCount::INFINITE && output_maximum() == ChanCount::INFINITE) {
|
||||
|
||||
/* not configured yet */
|
||||
|
||||
@@ -1011,7 +1011,7 @@ PortInsert::can_support_input_configuration (int32_t in) const
|
||||
many output ports it will have.
|
||||
*/
|
||||
|
||||
if (output_maximum() == in) {
|
||||
if (output_maximum().get(_default_type) == static_cast<uint32_t>(in)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1042,11 +1042,11 @@ PortInsert::configure_io (int32_t ignored_magic, int32_t in, int32_t out)
|
||||
set_input_minimum (out);
|
||||
|
||||
if (in < 0) {
|
||||
in = n_outputs ();
|
||||
in = n_outputs ().get(_default_type);
|
||||
}
|
||||
|
||||
if (out < 0) {
|
||||
out = n_inputs ();
|
||||
out = n_inputs ().get(_default_type);
|
||||
}
|
||||
|
||||
return ensure_io (out, in, false, this);
|
||||
@@ -1056,17 +1056,17 @@ int32_t
|
||||
PortInsert::compute_output_streams (int32_t cnt) const
|
||||
{
|
||||
/* puzzling, eh? think about it ... */
|
||||
return n_inputs ();
|
||||
return n_inputs ().get(_default_type);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PortInsert::output_streams() const
|
||||
{
|
||||
return n_inputs ();
|
||||
return n_inputs ().get(_default_type);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PortInsert::input_streams() const
|
||||
{
|
||||
return n_outputs ();
|
||||
return n_outputs ().get(_default_type);
|
||||
}
|
||||
|
||||
@@ -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,23 +1971,59 @@ 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) {
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ MidiDiskstream::non_realtime_input_change ()
|
||||
|
||||
if (input_change_pending & ConfigurationChanged) {
|
||||
|
||||
assert(_io->n_inputs() == _n_channels);
|
||||
assert(_io->n_inputs().get(DataType::MIDI) == _n_channels);
|
||||
}
|
||||
|
||||
get_input_sources ();
|
||||
|
||||
@@ -403,7 +403,7 @@ int
|
||||
MidiTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
|
||||
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
if (n_outputs() == 0) {
|
||||
if (n_outputs().get(DataType::MIDI) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ int
|
||||
MidiTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
|
||||
bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
if (n_outputs() == 0 && _redirects.empty()) {
|
||||
if (n_outputs().get(DataType::MIDI) == 0 && _redirects.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ PortSet::add_port(Port* port)
|
||||
v.push_back(port);
|
||||
sort(v.begin(), v.end(), sort_ports_by_name);
|
||||
|
||||
_chan_count.set_count(port->type(), _chan_count.get_count(port->type()) + 1);
|
||||
_chan_count.set(port->type(), _chan_count.get(port->type()) + 1);
|
||||
|
||||
assert(_chan_count.get_count(port->type()) == _ports[port->type().to_index()].size());
|
||||
assert(_chan_count.get(port->type()) == _ports[port->type().to_index()].size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -587,7 +587,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
|
||||
solo_audible = dsg > 0;
|
||||
mute_audible = dmg > 0 || !_mute_affects_main_outs;
|
||||
|
||||
if (n_outputs() == 0) {
|
||||
if (n_outputs().get(_default_type) == 0) {
|
||||
|
||||
/* relax */
|
||||
|
||||
@@ -647,12 +647,12 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
|
||||
// cerr << "meter post" << endl;
|
||||
|
||||
if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
|
||||
uint32_t no = n_outputs();
|
||||
uint32_t no = n_outputs().get(DataType::AUDIO);
|
||||
for (n = 0; n < no; ++n) {
|
||||
_peak_power[n] = 0;
|
||||
}
|
||||
} else {
|
||||
uint32_t no = n_outputs();
|
||||
uint32_t no = n_outputs().get(DataType::AUDIO);
|
||||
for (n = 0; n < no; ++n) {
|
||||
_peak_power[n] = Session::compute_peak (audio_output(n)->get_audio_buffer ().data(nframes, offset), nframes, _peak_power[n]);
|
||||
}
|
||||
@@ -663,7 +663,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
|
||||
uint32_t
|
||||
Route::n_process_buffers ()
|
||||
{
|
||||
return max (n_inputs(), redirect_max_outs);
|
||||
return max (n_inputs().get(_default_type), static_cast<size_t>(redirect_max_outs));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -801,7 +801,7 @@ Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t*
|
||||
|
||||
*/
|
||||
|
||||
porti->ensure_io (n_outputs (), n_inputs(), false, this);
|
||||
porti->ensure_io (n_outputs ().get(DataType::AUDIO), n_inputs().get(DataType::AUDIO), false, this);
|
||||
}
|
||||
|
||||
// Ensure peak vector sizes before the plugin is activated
|
||||
@@ -1074,7 +1074,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
|
||||
|
||||
/* A: PreFader */
|
||||
|
||||
if (check_some_plugin_counts (insert_map[PreFader], n_inputs (), err_streams)) {
|
||||
if (check_some_plugin_counts (insert_map[PreFader], n_inputs ().get(_default_type), err_streams)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
|
||||
InsertCount& ic (insert_map[PreFader].back());
|
||||
initial_streams = ic.insert->compute_output_streams (ic.cnt);
|
||||
} else {
|
||||
initial_streams = n_inputs ();
|
||||
initial_streams = n_inputs ().get(_default_type);
|
||||
}
|
||||
|
||||
/* B: PostFader */
|
||||
@@ -1110,13 +1110,13 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
|
||||
|
||||
if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
|
||||
if (r == _redirects.begin()) {
|
||||
s->expect_inputs (n_inputs());
|
||||
s->expect_inputs (n_inputs().get(_default_type));
|
||||
} else {
|
||||
s->expect_inputs ((*prev)->output_streams());
|
||||
}
|
||||
}
|
||||
|
||||
redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
|
||||
redirect_max_outs = max ((*r)->output_streams(), redirect_max_outs);
|
||||
}
|
||||
|
||||
/* we're done */
|
||||
@@ -1761,7 +1761,7 @@ Route::set_control_outs (const vector<string>& ports)
|
||||
have outputs. we track the changes in ::output_change_handler().
|
||||
*/
|
||||
|
||||
_control_outs->ensure_io (0, n_outputs(), true, this);
|
||||
_control_outs->ensure_io (0, n_outputs().get(DataType::AUDIO), true, this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1836,8 +1836,8 @@ Route::feeds (boost::shared_ptr<Route> other)
|
||||
uint32_t i, j;
|
||||
|
||||
IO& self = *this;
|
||||
uint32_t no = self.n_outputs();
|
||||
uint32_t ni = other->n_inputs ();
|
||||
uint32_t no = self.n_outputs().get_total();
|
||||
uint32_t ni = other->n_inputs ().get_total();
|
||||
|
||||
for (i = 0; i < no; ++i) {
|
||||
for (j = 0; j < ni; ++j) {
|
||||
@@ -1851,7 +1851,7 @@ Route::feeds (boost::shared_ptr<Route> other)
|
||||
|
||||
for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); r++) {
|
||||
|
||||
no = (*r)->n_outputs();
|
||||
no = (*r)->n_outputs().get_total();
|
||||
|
||||
for (i = 0; i < no; ++i) {
|
||||
for (j = 0; j < ni; ++j) {
|
||||
@@ -1866,7 +1866,7 @@ Route::feeds (boost::shared_ptr<Route> other)
|
||||
|
||||
if (_control_outs) {
|
||||
|
||||
no = _control_outs->n_outputs();
|
||||
no = _control_outs->n_outputs().get_total();
|
||||
|
||||
for (i = 0; i < no; ++i) {
|
||||
for (j = 0; j < ni; ++j) {
|
||||
@@ -1990,7 +1990,7 @@ Route::output_change_handler (IOChange change, void *ignored)
|
||||
{
|
||||
if (change & ConfigurationChanged) {
|
||||
if (_control_outs) {
|
||||
_control_outs->ensure_io (0, n_outputs(), true, this);
|
||||
_control_outs->ensure_io (0, n_outputs().get(DataType::AUDIO), true, this);
|
||||
}
|
||||
|
||||
reset_plugin_counts (0);
|
||||
@@ -2000,18 +2000,18 @@ Route::output_change_handler (IOChange change, void *ignored)
|
||||
uint32_t
|
||||
Route::pans_required () const
|
||||
{
|
||||
if (n_outputs() < 2) {
|
||||
if (n_outputs().get(DataType::AUDIO) < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return max (n_inputs (), redirect_max_outs);
|
||||
return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs));
|
||||
}
|
||||
|
||||
int
|
||||
Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
|
||||
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
if (n_outputs() == 0) {
|
||||
if (n_outputs().get(_default_type) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2022,7 +2022,7 @@ Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes
|
||||
|
||||
apply_gain_automation = false;
|
||||
|
||||
if (n_inputs()) {
|
||||
if (n_inputs().get(_default_type)) {
|
||||
passthru (start_frame, end_frame, nframes, offset, 0, false);
|
||||
} else {
|
||||
silence (nframes, offset);
|
||||
@@ -2069,7 +2069,7 @@ Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t
|
||||
}
|
||||
}
|
||||
|
||||
if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
|
||||
if ((n_outputs().get_total() == 0 && _redirects.empty()) || n_inputs().get_total() == 0 || !_active) {
|
||||
silence (nframes, offset);
|
||||
return 0;
|
||||
}
|
||||
@@ -2126,7 +2126,7 @@ Route::has_external_redirects () const
|
||||
for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
|
||||
if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
|
||||
|
||||
uint32_t no = pi->n_outputs();
|
||||
uint32_t no = pi->n_outputs().get(_default_type);
|
||||
|
||||
for (uint32_t n = 0; n < no; ++n) {
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ Send::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_
|
||||
|
||||
if (_metering) {
|
||||
uint32_t n;
|
||||
uint32_t no = n_outputs();
|
||||
uint32_t no = n_outputs().get(DataType::AUDIO);
|
||||
|
||||
if (_gain == 0) {
|
||||
|
||||
@@ -144,7 +144,7 @@ Send::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_
|
||||
|
||||
if (_metering) {
|
||||
uint32_t n;
|
||||
uint32_t no = n_outputs();
|
||||
uint32_t no = n_outputs().get(DataType::AUDIO);
|
||||
|
||||
for (n = 0; n < no; ++n) {
|
||||
_peak_power[n] = 0;
|
||||
|
||||
@@ -719,7 +719,8 @@ Session::when_engine_running ()
|
||||
|
||||
_master_out->defer_pan_reset ();
|
||||
|
||||
while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
|
||||
while (_master_out->n_inputs().get(DataType::AUDIO)
|
||||
< _master_out->input_maximum().get(DataType::AUDIO)) {
|
||||
if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
|
||||
error << _("cannot setup master inputs")
|
||||
<< endmsg;
|
||||
@@ -727,7 +728,8 @@ Session::when_engine_running ()
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
|
||||
while (_master_out->n_outputs().get(DataType::AUDIO)
|
||||
< _master_out->output_maximum().get(DataType::AUDIO)) {
|
||||
if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
|
||||
error << _("cannot setup master outputs")
|
||||
<< endmsg;
|
||||
@@ -742,7 +744,7 @@ Session::when_engine_running ()
|
||||
|
||||
Connection* c = new OutputConnection (_("Master Out"), true);
|
||||
|
||||
for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
|
||||
for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
|
||||
c->add_port ();
|
||||
c->add_connection ((int) n, _master_out->input(n)->name());
|
||||
}
|
||||
@@ -810,7 +812,7 @@ Session::hookup_io ()
|
||||
if (_control_out) {
|
||||
uint32_t n;
|
||||
|
||||
while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
|
||||
while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
|
||||
if (_control_out->add_input_port ("", this)) {
|
||||
error << _("cannot setup control inputs")
|
||||
<< endmsg;
|
||||
@@ -818,7 +820,7 @@ Session::hookup_io ()
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
|
||||
while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
|
||||
if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
|
||||
error << _("cannot set up master outputs")
|
||||
<< endmsg;
|
||||
@@ -1458,7 +1460,7 @@ Session::set_block_size (jack_nframes_t nframes)
|
||||
_passthru_buffers.clear ();
|
||||
_silent_buffers.clear ();
|
||||
|
||||
ensure_passthru_buffers (np);
|
||||
ensure_passthru_buffers (ChanCount(DataType::AUDIO, np));
|
||||
|
||||
for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
|
||||
free(*i);
|
||||
@@ -1685,7 +1687,7 @@ Session::new_midi_track (TrackMode mode)
|
||||
if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
|
||||
if (!(*i)->hidden()) {
|
||||
n++;
|
||||
channels_used += (*i)->n_inputs();
|
||||
channels_used += (*i)->n_inputs().get(DataType::MIDI);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1880,7 +1882,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
|
||||
if (!(*i)->hidden()) {
|
||||
n++;
|
||||
channels_used += (*i)->n_inputs();
|
||||
channels_used += (*i)->n_inputs().get(DataType::AUDIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1923,7 +1925,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
}
|
||||
|
||||
if (nphysical_in) {
|
||||
for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
|
||||
for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
@@ -1937,7 +1939,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t x = 0; x < track->n_outputs(); ++x) {
|
||||
for (uint32_t x = 0; x < track->n_outputs().get(DataType::AUDIO); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
@@ -1945,7 +1947,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
port = _engine.get_nth_physical_output (DataType::AUDIO, (channels_used+x)%nphysical_out);
|
||||
} else if (output_auto_connect & AutoConnectMaster) {
|
||||
if (_master_out) {
|
||||
port = _master_out->input (x%_master_out->n_inputs())->name();
|
||||
port = _master_out->audio_input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1956,10 +1958,10 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
|
||||
if (_control_out) {
|
||||
vector<string> cports;
|
||||
uint32_t ni = _control_out->n_inputs();
|
||||
uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
|
||||
|
||||
for (n = 0; n < ni; ++n) {
|
||||
cports.push_back (_control_out->input(n)->name());
|
||||
cports.push_back (_control_out->audio_input(n)->name());
|
||||
}
|
||||
|
||||
track->set_control_outs (cports);
|
||||
@@ -2018,7 +2020,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
<< endmsg;
|
||||
}
|
||||
|
||||
for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
|
||||
for (uint32_t x = 0; x < bus->n_inputs().get(DataType::AUDIO); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
@@ -2031,7 +2033,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
|
||||
for (uint32_t x = 0; x < bus->n_outputs().get(DataType::AUDIO); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
@@ -2039,7 +2041,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
port = _engine.get_nth_physical_input (DataType::AUDIO, (n+x)%n_physical_outputs);
|
||||
} else if (output_auto_connect & AutoConnectMaster) {
|
||||
if (_master_out) {
|
||||
port = _master_out->input (x%_master_out->n_inputs())->name();
|
||||
port = _master_out->audio_input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2050,7 +2052,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
|
||||
if (_control_out) {
|
||||
vector<string> cports;
|
||||
uint32_t ni = _control_out->n_inputs();
|
||||
uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
|
||||
|
||||
for (uint32_t n = 0; n < ni; ++n) {
|
||||
cports.push_back (_control_out->input(n)->name());
|
||||
@@ -3656,9 +3658,11 @@ Session::tempo_map_changed (Change ignored)
|
||||
}
|
||||
|
||||
void
|
||||
Session::ensure_passthru_buffers (uint32_t howmany)
|
||||
Session::ensure_passthru_buffers (ChanCount howmany)
|
||||
{
|
||||
while (howmany > _passthru_buffers.size()) {
|
||||
// FIXME: temporary hack
|
||||
|
||||
while (howmany.get(DataType::AUDIO) > _passthru_buffers.size()) {
|
||||
Sample *p;
|
||||
#ifdef NO_POSIX_MEMALIGN
|
||||
p = (Sample *) malloc(current_block_size * sizeof(Sample));
|
||||
@@ -3688,7 +3692,7 @@ Session::ensure_passthru_buffers (uint32_t howmany)
|
||||
_send_buffers.push_back (p);
|
||||
|
||||
}
|
||||
allocate_pan_automation_buffers (current_block_size, howmany, false);
|
||||
allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
|
||||
}
|
||||
|
||||
string
|
||||
|
||||
Reference in New Issue
Block a user