mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of processors. There are definitely regressions here, but there's also a lot of things fixed. It's far too much work to let diverge anymore regardless, so here it is. The basic model is: A route has a fixed set of input channels (matching its JACK input ports and diskstream). The first processor takes this as input. The next processor is configured using the first processor's output as input, and is allowed to choose whatever output it wants given that input... and so on, and so on. Finally, the last processor's requested output is used to set up the panner and create whatever Jack ports are needed to output the data. All 'special' internal processors (meter, fader, amp, insert, send) are currently transparent: they read any input, and return the same set of channels back (unmodified, except for amp). User visible changes: * LV2 Instrument support (tracks with both MIDI and audio channels) * MIDI in/out plugin support * Generic plugin replication (for MIDI plugins, MIDI/audio plugins) * Movable meter point Known Bugs: * Things seem to get weird on loaded sessions * Output delivery is sketchy * 2.0 session loading was probably already broken... but it's definitely broken now :) Please test this and file bugs if you have any time... git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
97b5eb1580
commit
7183242b8c
85 changed files with 1848 additions and 2200 deletions
|
|
@ -106,7 +106,11 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
|
||||||
create_automation_child (GainAutomation, false);
|
create_automation_child (GainAutomation, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_route->panner().Changed.connect (bind (mem_fun(*this, &AudioTimeAxisView::ensure_pan_views), false));
|
if (_route->panner()) {
|
||||||
|
_route->panner()->Changed.connect (bind (
|
||||||
|
mem_fun(*this, &AudioTimeAxisView::ensure_pan_views),
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
|
||||||
/* map current state of the route */
|
/* map current state of the route */
|
||||||
|
|
||||||
|
|
@ -370,13 +374,17 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||||
void
|
void
|
||||||
AudioTimeAxisView::ensure_pan_views (bool show)
|
AudioTimeAxisView::ensure_pan_views (bool show)
|
||||||
{
|
{
|
||||||
const set<Evoral::Parameter>& params = _route->panner().what_can_be_automated();
|
if (!_route->panner()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const set<Evoral::Parameter>& params = _route->panner()->what_can_be_automated();
|
||||||
set<Evoral::Parameter>::iterator p;
|
set<Evoral::Parameter>::iterator p;
|
||||||
|
|
||||||
for (p = params.begin(); p != params.end(); ++p) {
|
for (p = params.begin(); p != params.end(); ++p) {
|
||||||
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
||||||
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
||||||
_route->panner().data().control(*p));
|
_route->panner()->data().control(*p));
|
||||||
|
|
||||||
if (pan_control->parameter().type() == NullAutomation) {
|
if (pan_control->parameter().type() == NullAutomation) {
|
||||||
error << "Pan control has NULL automation type!" << endmsg;
|
error << "Pan control has NULL automation type!" << endmsg;
|
||||||
|
|
|
||||||
|
|
@ -617,7 +617,7 @@ bool
|
||||||
Keyboard::load_keybindings (string path)
|
Keyboard::load_keybindings (string path)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
cerr << "loading bindings from " << path << endl;
|
cerr << "Loading bindings from " << path << endl;
|
||||||
|
|
||||||
Gtk::AccelMap::load (path);
|
Gtk::AccelMap::load (path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ int main (int argc, char *argv[])
|
||||||
|
|
||||||
cout << _("Ardour/GTK ")
|
cout << _("Ardour/GTK ")
|
||||||
<< VERSIONSTRING
|
<< VERSIONSTRING
|
||||||
<< _("\n (built using ")
|
<< _(" (built using ")
|
||||||
<< svn_revision
|
<< svn_revision
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
<< _(" and GCC version ") << __VERSION__
|
<< _(" and GCC version ") << __VERSION__
|
||||||
|
|
|
||||||
|
|
@ -413,20 +413,33 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
|
||||||
_("Click to Add/Edit Comments"):
|
_("Click to Add/Edit Comments"):
|
||||||
_route->comment());
|
_route->comment());
|
||||||
|
|
||||||
connections.push_back (_route->meter_change.connect (mem_fun(*this, &MixerStrip::meter_changed)));
|
connections.push_back (_route->meter_change.connect (
|
||||||
connections.push_back (_route->input_changed.connect (mem_fun(*this, &MixerStrip::input_changed)));
|
mem_fun(*this, &MixerStrip::meter_changed)));
|
||||||
connections.push_back (_route->output_changed.connect (mem_fun(*this, &MixerStrip::output_changed)));
|
connections.push_back (_route->input_changed.connect (
|
||||||
connections.push_back (_route->mix_group_changed.connect (mem_fun(*this, &MixerStrip::mix_group_changed)));
|
mem_fun(*this, &MixerStrip::input_changed)));
|
||||||
connections.push_back (_route->panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan)));
|
connections.push_back (_route->output_changed.connect (
|
||||||
|
mem_fun(*this, &MixerStrip::output_changed)));
|
||||||
|
connections.push_back (_route->mix_group_changed.connect (
|
||||||
|
mem_fun(*this, &MixerStrip::mix_group_changed)));
|
||||||
|
|
||||||
if (is_audio_track()) {
|
if (_route->panner()) {
|
||||||
connections.push_back (audio_track()->DiskstreamChanged.connect (mem_fun(*this, &MixerStrip::diskstream_changed)));
|
connections.push_back (_route->panner()->Changed.connect (
|
||||||
connections.push_back (get_diskstream()->SpeedChanged.connect (mem_fun(*this, &MixerStrip::speed_changed)));
|
mem_fun(*this, &MixerStrip::connect_to_pan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
connections.push_back (_route->NameChanged.connect (mem_fun(*this, &RouteUI::name_changed)));
|
if (is_audio_track()) {
|
||||||
connections.push_back (_route->comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed)));
|
connections.push_back (audio_track()->DiskstreamChanged.connect (
|
||||||
connections.push_back (_route->gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed)));
|
mem_fun(*this, &MixerStrip::diskstream_changed)));
|
||||||
|
connections.push_back (get_diskstream()->SpeedChanged.connect (
|
||||||
|
mem_fun(*this, &MixerStrip::speed_changed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
connections.push_back (_route->NameChanged.connect (
|
||||||
|
mem_fun(*this, &RouteUI::name_changed)));
|
||||||
|
connections.push_back (_route->comment_changed.connect (
|
||||||
|
mem_fun(*this, &MixerStrip::comment_changed)));
|
||||||
|
connections.push_back (_route->gui_changed.connect (
|
||||||
|
mem_fun(*this, &MixerStrip::route_gui_changed)));
|
||||||
|
|
||||||
set_stuff_from_route ();
|
set_stuff_from_route ();
|
||||||
|
|
||||||
|
|
@ -553,17 +566,25 @@ MixerStrip::set_width (Width w, void* owner)
|
||||||
((Gtk::Label*)solo_button->get_child())->set_text (_("Solo"));
|
((Gtk::Label*)solo_button->get_child())->set_text (_("Solo"));
|
||||||
|
|
||||||
if (_route->comment() == "") {
|
if (_route->comment() == "") {
|
||||||
comment_button.unset_bg (STATE_NORMAL);
|
comment_button.unset_bg (STATE_NORMAL);
|
||||||
((Gtk::Label*)comment_button.get_child())->set_text (_("Comments"));
|
((Gtk::Label*)comment_button.get_child())->set_text (_("Comments"));
|
||||||
} else {
|
} else {
|
||||||
comment_button.modify_bg (STATE_NORMAL, color());
|
comment_button.modify_bg (STATE_NORMAL, color());
|
||||||
((Gtk::Label*)comment_button.get_child())->set_text (_("*Comments*"));
|
((Gtk::Label*)comment_button.get_child())->set_text (_("*Comments*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (
|
||||||
|
gpm.astyle_string(gain_automation->automation_style()));
|
||||||
|
((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (
|
||||||
|
gpm.astate_string(gain_automation->automation_state()));
|
||||||
|
|
||||||
|
if (_route->panner()) {
|
||||||
|
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (
|
||||||
|
panners.astyle_string(_route->panner()->automation_style()));
|
||||||
|
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (
|
||||||
|
panners.astate_string(_route->panner()->automation_state()));
|
||||||
}
|
}
|
||||||
|
|
||||||
((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.astyle_string(gain_automation->automation_style()));
|
|
||||||
((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.astate_string(gain_automation->automation_state()));
|
|
||||||
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (panners.astyle_string(_route->panner().automation_style()));
|
|
||||||
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (panners.astate_string(_route->panner().automation_state()));
|
|
||||||
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
|
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
|
||||||
set_size_request (-1, -1);
|
set_size_request (-1, -1);
|
||||||
break;
|
break;
|
||||||
|
|
@ -583,10 +604,18 @@ MixerStrip::set_width (Width w, void* owner)
|
||||||
((Gtk::Label*)comment_button.get_child())->set_text (_("*Cmt*"));
|
((Gtk::Label*)comment_button.get_child())->set_text (_("*Cmt*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (gpm.short_astyle_string(gain_automation->automation_style()));
|
((Gtk::Label*)gpm.gain_automation_style_button.get_child())->set_text (
|
||||||
((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (gpm.short_astate_string(gain_automation->automation_state()));
|
gpm.short_astyle_string(gain_automation->automation_style()));
|
||||||
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (panners.short_astyle_string(_route->panner().automation_style()));
|
((Gtk::Label*)gpm.gain_automation_state_button.get_child())->set_text (
|
||||||
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (panners.short_astate_string(_route->panner().automation_state()));
|
gpm.short_astate_string(gain_automation->automation_state()));
|
||||||
|
|
||||||
|
if (_route->panner()) {
|
||||||
|
((Gtk::Label*)panners.pan_automation_style_button.get_child())->set_text (
|
||||||
|
panners.short_astyle_string(_route->panner()->automation_style()));
|
||||||
|
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (
|
||||||
|
panners.short_astate_string(_route->panner()->automation_state()));
|
||||||
|
}
|
||||||
|
|
||||||
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2);
|
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2);
|
||||||
set_size_request (max (50, gpm.get_gm_width()), -1);
|
set_size_request (max (50, gpm.get_gm_width()), -1);
|
||||||
break;
|
break;
|
||||||
|
|
@ -856,9 +885,13 @@ MixerStrip::connect_to_pan ()
|
||||||
panstate_connection.disconnect ();
|
panstate_connection.disconnect ();
|
||||||
panstyle_connection.disconnect ();
|
panstyle_connection.disconnect ();
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
if (!_route->panner()) {
|
||||||
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
return;
|
||||||
_route->panner().data().control(Evoral::Parameter( PanAutomation ) ));
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
||||||
|
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
||||||
|
_route->panner()->data().control(Evoral::Parameter(PanAutomation)));
|
||||||
|
|
||||||
if (pan_control) {
|
if (pan_control) {
|
||||||
panstate_connection = pan_control->alist()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
panstate_connection = pan_control->alist()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
||||||
|
|
@ -1407,7 +1440,6 @@ MixerStrip::engine_running ()
|
||||||
void
|
void
|
||||||
MixerStrip::meter_changed (void *src)
|
MixerStrip::meter_changed (void *src)
|
||||||
{
|
{
|
||||||
|
|
||||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &MixerStrip::meter_changed), src));
|
ENSURE_GUI_THREAD (bind (mem_fun(*this, &MixerStrip::meter_changed), src));
|
||||||
|
|
||||||
switch (_route->meter_point()) {
|
switch (_route->meter_point()) {
|
||||||
|
|
|
||||||
|
|
@ -65,15 +65,15 @@ Panner2d::Target::set_text (const char* txt)
|
||||||
text = strdup (txt);
|
text = strdup (txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Panner2d::Panner2d (Panner& p, int32_t h)
|
Panner2d::Panner2d (boost::shared_ptr<Panner> p, int32_t h)
|
||||||
: panner (p), width (0), height (h)
|
: panner (p), width (0), height (h)
|
||||||
{
|
{
|
||||||
allow_x = false;
|
allow_x = false;
|
||||||
allow_y = false;
|
allow_y = false;
|
||||||
allow_target = false;
|
allow_target = false;
|
||||||
|
|
||||||
panner.StateChanged.connect (mem_fun(*this, &Panner2d::handle_state_change));
|
panner->StateChanged.connect (mem_fun(*this, &Panner2d::handle_state_change));
|
||||||
panner.Changed.connect (mem_fun(*this, &Panner2d::handle_position_change));
|
panner->Changed.connect (mem_fun(*this, &Panner2d::handle_position_change));
|
||||||
|
|
||||||
drag_target = 0;
|
drag_target = 0;
|
||||||
set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
|
set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
|
||||||
|
|
@ -135,7 +135,7 @@ Panner2d::reset (uint32_t n_inputs)
|
||||||
|
|
||||||
if (existing_pucks < i) {
|
if (existing_pucks < i) {
|
||||||
float x, y;
|
float x, y;
|
||||||
panner.streampanner (i).get_position (x, y);
|
panner->streampanner (i).get_position (x, y);
|
||||||
pucks[i]->x.set_value (x);
|
pucks[i]->x.set_value (x);
|
||||||
pucks[i]->y.set_value (y);
|
pucks[i]->y.set_value (y);
|
||||||
}
|
}
|
||||||
|
|
@ -147,11 +147,11 @@ Panner2d::reset (uint32_t n_inputs)
|
||||||
|
|
||||||
/* add all outputs */
|
/* add all outputs */
|
||||||
|
|
||||||
while (targets.size() < panner.nouts()) {
|
while (targets.size() < panner->nouts()) {
|
||||||
add_target (0.0, 0.0);
|
add_target (0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (targets.size() > panner.nouts()) {
|
while (targets.size() > panner->nouts()) {
|
||||||
targets.erase (targets.begin());
|
targets.erase (targets.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,13 +159,13 @@ Panner2d::reset (uint32_t n_inputs)
|
||||||
(*x).second->visible = false;
|
(*x).second->visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t n = 0; n < panner.nouts(); ++n) {
|
for (uint32_t n = 0; n < panner->nouts(); ++n) {
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
snprintf (buf, sizeof (buf), "%d", n+1);
|
snprintf (buf, sizeof (buf), "%d", n+1);
|
||||||
targets[n]->set_text (buf);
|
targets[n]->set_text (buf);
|
||||||
targets[n]->x.set_value (panner.output(n).x);
|
targets[n]->x.set_value (panner->output(n).x);
|
||||||
targets[n]->y.set_value (panner.output(n).y);
|
targets[n]->y.set_value (panner->output(n).y);
|
||||||
targets[n]->visible = true;
|
targets[n]->visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,14 +275,14 @@ Panner2d::handle_position_change ()
|
||||||
|
|
||||||
for (n = 0; n < pucks.size(); ++n) {
|
for (n = 0; n < pucks.size(); ++n) {
|
||||||
float x, y;
|
float x, y;
|
||||||
panner.streampanner(n).get_position (x, y);
|
panner->streampanner(n).get_position (x, y);
|
||||||
pucks[n]->x.set_value (x);
|
pucks[n]->x.set_value (x);
|
||||||
pucks[n]->y.set_value (y);
|
pucks[n]->y.set_value (y);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < targets.size(); ++n) {
|
for (n = 0; n < targets.size(); ++n) {
|
||||||
targets[n]->x.set_value (panner.output(n).x);
|
targets[n]->x.set_value (panner->output(n).x);
|
||||||
targets[n]->y.set_value (panner.output(n).y);
|
targets[n]->y.set_value (panner->output(n).y);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_draw ();
|
queue_draw ();
|
||||||
|
|
@ -454,7 +454,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||||
cairo_set_line_width (cr, 1.0);
|
cairo_set_line_width (cr, 1.0);
|
||||||
|
|
||||||
cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
|
cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
|
||||||
if (!panner.bypassed()) {
|
if (!panner->bypassed()) {
|
||||||
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0);
|
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0);
|
||||||
} else {
|
} else {
|
||||||
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.2);
|
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.2);
|
||||||
|
|
@ -478,7 +478,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||||
cairo_arc (cr, height/2, height/2, height/2, 0, 2.0 * M_PI);
|
cairo_arc (cr, height/2, height/2, height/2, 0, 2.0 * M_PI);
|
||||||
cairo_stroke (cr);
|
cairo_stroke (cr);
|
||||||
|
|
||||||
if (!panner.bypassed()) {
|
if (!panner->bypassed()) {
|
||||||
float arc_radius;
|
float arc_radius;
|
||||||
|
|
||||||
cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||||
|
|
@ -715,7 +715,8 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
|
||||||
|
|
||||||
if (drag_is_puck) {
|
if (drag_is_puck) {
|
||||||
|
|
||||||
panner.streampanner(drag_index).set_position (drag_target->x.get_value(), drag_target->y.get_value(), false);
|
panner->streampanner(drag_index).set_position (
|
||||||
|
drag_target->x.get_value(), drag_target->y.get_value(), false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -745,7 +746,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
|
||||||
void
|
void
|
||||||
Panner2d::toggle_bypass ()
|
Panner2d::toggle_bypass ()
|
||||||
{
|
{
|
||||||
panner.set_bypassed (!panner.bypassed());
|
panner->set_bypassed (!panner->bypassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -766,7 +767,7 @@ Panner2d::allow_y_motion (bool yn)
|
||||||
allow_y = yn;
|
allow_y = yn;
|
||||||
}
|
}
|
||||||
|
|
||||||
Panner2dWindow::Panner2dWindow (Panner&p, int32_t h, uint32_t inputs)
|
Panner2dWindow::Panner2dWindow (boost::shared_ptr<Panner> p, int32_t h, uint32_t inputs)
|
||||||
: widget (p, h)
|
: widget (p, h)
|
||||||
, reset_button (_("Reset"))
|
, reset_button (_("Reset"))
|
||||||
, bypass_button (_("Bypass"))
|
, bypass_button (_("Bypass"))
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class Panner2dWindow;
|
||||||
class Panner2d : public Gtk::DrawingArea
|
class Panner2d : public Gtk::DrawingArea
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Panner2d (ARDOUR::Panner&, int32_t height);
|
Panner2d (boost::shared_ptr<ARDOUR::Panner>, int32_t height);
|
||||||
~Panner2d ();
|
~Panner2d ();
|
||||||
|
|
||||||
void allow_x_motion(bool);
|
void allow_x_motion(bool);
|
||||||
|
|
@ -76,7 +76,7 @@ class Panner2d : public Gtk::DrawingArea
|
||||||
|
|
||||||
Gtk::Adjustment& azimuth (uint32_t which);
|
Gtk::Adjustment& azimuth (uint32_t which);
|
||||||
|
|
||||||
ARDOUR::Panner& get_panner() const { return panner; }
|
boost::shared_ptr<ARDOUR::Panner> get_panner() const { return panner; }
|
||||||
|
|
||||||
sigc::signal<void,int> PuckMoved;
|
sigc::signal<void,int> PuckMoved;
|
||||||
sigc::signal<void,int> TargetMoved;
|
sigc::signal<void,int> TargetMoved;
|
||||||
|
|
@ -102,7 +102,7 @@ class Panner2d : public Gtk::DrawingArea
|
||||||
void set_text (const char*);
|
void set_text (const char*);
|
||||||
};
|
};
|
||||||
|
|
||||||
ARDOUR::Panner& panner;
|
boost::shared_ptr<ARDOUR::Panner> panner;
|
||||||
Glib::RefPtr<Pango::Layout> layout;
|
Glib::RefPtr<Pango::Layout> layout;
|
||||||
|
|
||||||
typedef std::map<int,Target *> Targets;
|
typedef std::map<int,Target *> Targets;
|
||||||
|
|
@ -137,7 +137,7 @@ class Panner2d : public Gtk::DrawingArea
|
||||||
class Panner2dWindow : public Gtk::Window
|
class Panner2dWindow : public Gtk::Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Panner2dWindow (ARDOUR::Panner&, int32_t height, uint32_t inputs);
|
Panner2dWindow (boost::shared_ptr<ARDOUR::Panner>, int32_t height, uint32_t inputs);
|
||||||
|
|
||||||
void reset (uint32_t n_inputs);
|
void reset (uint32_t n_inputs);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,11 @@ PannerUI::PannerUI (Session& s)
|
||||||
void
|
void
|
||||||
PannerUI::set_io (boost::shared_ptr<IO> io)
|
PannerUI::set_io (boost::shared_ptr<IO> io)
|
||||||
{
|
{
|
||||||
|
if (!io->panner()) {
|
||||||
|
cerr << "PannerUI::set_io IO has no panners" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
connections.clear ();
|
connections.clear ();
|
||||||
|
|
||||||
delete pan_astyle_menu;
|
delete pan_astyle_menu;
|
||||||
|
|
@ -142,9 +147,12 @@ PannerUI::set_io (boost::shared_ptr<IO> io)
|
||||||
|
|
||||||
_io = io;
|
_io = io;
|
||||||
|
|
||||||
connections.push_back (_io->panner().Changed.connect (mem_fun(*this, &PannerUI::panner_changed)));
|
connections.push_back (_io->panner()->Changed.connect (
|
||||||
connections.push_back (_io->panner().LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage)));
|
mem_fun(*this, &PannerUI::panner_changed)));
|
||||||
connections.push_back (_io->panner().StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state)));
|
connections.push_back (_io->panner()->LinkStateChanged.connect (
|
||||||
|
mem_fun(*this, &PannerUI::update_pan_linkage)));
|
||||||
|
connections.push_back (_io->panner()->StateChanged.connect (
|
||||||
|
mem_fun(*this, &PannerUI::update_pan_state)));
|
||||||
|
|
||||||
delete panner;
|
delete panner;
|
||||||
panner = 0;
|
panner = 0;
|
||||||
|
|
@ -185,14 +193,18 @@ PannerUI::build_astate_menu ()
|
||||||
pan_astate_menu->items().clear ();
|
pan_astate_menu->items().clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pan_astate_menu->items().push_back (MenuElem (_("Manual"),
|
pan_astate_menu->items().push_back (MenuElem (_("Manual"), bind (
|
||||||
bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Off)));
|
mem_fun (_io->panner().get(), &Panner::set_automation_state),
|
||||||
pan_astate_menu->items().push_back (MenuElem (_("Play"),
|
(AutoState) Off)));
|
||||||
bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Play)));
|
pan_astate_menu->items().push_back (MenuElem (_("Play"), bind (
|
||||||
pan_astate_menu->items().push_back (MenuElem (_("Write"),
|
mem_fun (_io->panner().get(), &Panner::set_automation_state),
|
||||||
bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Write)));
|
(AutoState) Play)));
|
||||||
pan_astate_menu->items().push_back (MenuElem (_("Touch"),
|
pan_astate_menu->items().push_back (MenuElem (_("Write"), bind (
|
||||||
bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Touch)));
|
mem_fun (_io->panner().get(), &Panner::set_automation_state),
|
||||||
|
(AutoState) Write)));
|
||||||
|
pan_astate_menu->items().push_back (MenuElem (_("Touch"), bind (
|
||||||
|
mem_fun (_io->panner().get(), &Panner::set_automation_state),
|
||||||
|
(AutoState) Touch)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,7 +240,7 @@ bool
|
||||||
PannerUI::panning_link_button_release (GdkEventButton* ev)
|
PannerUI::panning_link_button_release (GdkEventButton* ev)
|
||||||
{
|
{
|
||||||
if (!ignore_toggle) {
|
if (!ignore_toggle) {
|
||||||
_io->panner().set_linked (!_io->panner().linked());
|
_io->panner()->set_linked (!_io->panner()->linked());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -236,12 +248,12 @@ PannerUI::panning_link_button_release (GdkEventButton* ev)
|
||||||
void
|
void
|
||||||
PannerUI::panning_link_direction_clicked()
|
PannerUI::panning_link_direction_clicked()
|
||||||
{
|
{
|
||||||
switch (_io->panner().link_direction()) {
|
switch (_io->panner()->link_direction()) {
|
||||||
case Panner::SameDirection:
|
case Panner::SameDirection:
|
||||||
_io->panner().set_link_direction (Panner::OppositeDirection);
|
_io->panner()->set_link_direction (Panner::OppositeDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_io->panner().set_link_direction (Panner::SameDirection);
|
_io->panner()->set_link_direction (Panner::SameDirection);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +263,7 @@ PannerUI::update_pan_linkage ()
|
||||||
{
|
{
|
||||||
ENSURE_GUI_THREAD(mem_fun(*this, &PannerUI::update_pan_linkage));
|
ENSURE_GUI_THREAD(mem_fun(*this, &PannerUI::update_pan_linkage));
|
||||||
|
|
||||||
bool x = _io->panner().linked();
|
bool x = _io->panner()->linked();
|
||||||
bool bx = panning_link_button.get_active();
|
bool bx = panning_link_button.get_active();
|
||||||
|
|
||||||
if (x != bx) {
|
if (x != bx) {
|
||||||
|
|
@ -263,7 +275,7 @@ PannerUI::update_pan_linkage ()
|
||||||
|
|
||||||
panning_link_direction_button.set_sensitive (x);
|
panning_link_direction_button.set_sensitive (x);
|
||||||
|
|
||||||
switch (_io->panner().link_direction()) {
|
switch (_io->panner()->link_direction()) {
|
||||||
case Panner::SameDirection:
|
case Panner::SameDirection:
|
||||||
panning_link_direction_button.set_image (*(manage (new Image (get_xpm ("forwardblarrow.xpm")))));
|
panning_link_direction_button.set_image (*(manage (new Image (get_xpm ("forwardblarrow.xpm")))));
|
||||||
break;
|
break;
|
||||||
|
|
@ -325,6 +337,10 @@ PannerUI::update_pan_state ()
|
||||||
void
|
void
|
||||||
PannerUI::setup_pan ()
|
PannerUI::setup_pan ()
|
||||||
{
|
{
|
||||||
|
if (!_io->panner()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t nouts = _io->n_outputs ().n_audio();
|
uint32_t nouts = _io->n_outputs ().n_audio();
|
||||||
|
|
||||||
if (nouts == 0 || nouts == 1) {
|
if (nouts == 0 || nouts == 1) {
|
||||||
|
|
@ -346,7 +362,7 @@ PannerUI::setup_pan ()
|
||||||
} else if (nouts == 2) {
|
} else if (nouts == 2) {
|
||||||
|
|
||||||
vector<Adjustment*>::size_type asz;
|
vector<Adjustment*>::size_type asz;
|
||||||
uint32_t npans = _io->panner().npanners();
|
uint32_t npans = _io->panner()->npanners();
|
||||||
|
|
||||||
while (!pan_adjustments.empty()) {
|
while (!pan_adjustments.empty()) {
|
||||||
delete pan_bars.back();
|
delete pan_bars.back();
|
||||||
|
|
@ -363,7 +379,7 @@ PannerUI::setup_pan ()
|
||||||
/* initialize adjustment with 0.0 (L) or 1.0 (R) for the first and second panners,
|
/* initialize adjustment with 0.0 (L) or 1.0 (R) for the first and second panners,
|
||||||
which serves as a default, otherwise use current value */
|
which serves as a default, otherwise use current value */
|
||||||
|
|
||||||
rx = _io->panner().pan_control( asz)->get_value();
|
rx = _io->panner()->pan_control( asz)->get_value();
|
||||||
|
|
||||||
if (npans == 1) {
|
if (npans == 1) {
|
||||||
x = 0.5;
|
x = 0.5;
|
||||||
|
|
@ -377,13 +393,13 @@ PannerUI::setup_pan ()
|
||||||
|
|
||||||
pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
|
pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
|
||||||
bc = new PannerBar (*pan_adjustments[asz],
|
bc = new PannerBar (*pan_adjustments[asz],
|
||||||
boost::static_pointer_cast<PBD::Controllable>( _io->panner().pan_control( asz )) );
|
boost::static_pointer_cast<PBD::Controllable>( _io->panner()->pan_control( asz )) );
|
||||||
|
|
||||||
/* now set adjustment with current value of panner, then connect the signals */
|
/* now set adjustment with current value of panner, then connect the signals */
|
||||||
pan_adjustments.back()->set_value(rx);
|
pan_adjustments.back()->set_value(rx);
|
||||||
pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
|
pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
|
||||||
|
|
||||||
_io->panner().pan_control( asz )->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
|
_io->panner()->pan_control( asz )->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
|
||||||
|
|
||||||
|
|
||||||
bc->set_name ("PanSlider");
|
bc->set_name ("PanSlider");
|
||||||
|
|
@ -418,11 +434,10 @@ PannerUI::setup_pan ()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (panner == 0) {
|
if (!panner) {
|
||||||
panner = new Panner2d (_io->panner(), 61);
|
panner = new Panner2d (_io->panner(), 61);
|
||||||
panner->set_name ("MixerPanZone");
|
panner->set_name ("MixerPanZone");
|
||||||
panner->show ();
|
panner->show ();
|
||||||
|
|
||||||
|
|
||||||
panner->signal_button_press_event().connect
|
panner->signal_button_press_event().connect
|
||||||
(bind (mem_fun(*this, &PannerUI::pan_button_event), (uint32_t) 0), false);
|
(bind (mem_fun(*this, &PannerUI::pan_button_event), (uint32_t) 0), false);
|
||||||
|
|
@ -485,7 +500,7 @@ PannerUI::build_pan_menu (uint32_t which)
|
||||||
|
|
||||||
/* set state first, connect second */
|
/* set state first, connect second */
|
||||||
|
|
||||||
(dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner().streampanner(which).muted());
|
(dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner()->streampanner(which).muted());
|
||||||
(dynamic_cast<CheckMenuItem*> (&items.back()))->signal_toggled().connect
|
(dynamic_cast<CheckMenuItem*> (&items.back()))->signal_toggled().connect
|
||||||
(bind (mem_fun(*this, &PannerUI::pan_mute), which));
|
(bind (mem_fun(*this, &PannerUI::pan_mute), which));
|
||||||
|
|
||||||
|
|
@ -494,7 +509,7 @@ PannerUI::build_pan_menu (uint32_t which)
|
||||||
|
|
||||||
/* set state first, connect second */
|
/* set state first, connect second */
|
||||||
|
|
||||||
bypass_menu_item->set_active (_io->panner().bypassed());
|
bypass_menu_item->set_active (_io->panner()->bypassed());
|
||||||
bypass_menu_item->signal_toggled().connect (mem_fun(*this, &PannerUI::pan_bypass_toggle));
|
bypass_menu_item->signal_toggled().connect (mem_fun(*this, &PannerUI::pan_bypass_toggle));
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Reset"), bind (mem_fun (*this, &PannerUI::pan_reset), which)));
|
items.push_back (MenuElem (_("Reset"), bind (mem_fun (*this, &PannerUI::pan_reset), which)));
|
||||||
|
|
@ -505,34 +520,34 @@ PannerUI::build_pan_menu (uint32_t which)
|
||||||
void
|
void
|
||||||
PannerUI::pan_mute (uint32_t which)
|
PannerUI::pan_mute (uint32_t which)
|
||||||
{
|
{
|
||||||
StreamPanner& sp = _io->panner().streampanner(which);
|
StreamPanner& sp = _io->panner()->streampanner(which);
|
||||||
sp.set_muted (!sp.muted());
|
sp.set_muted (!sp.muted());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PannerUI::pan_bypass_toggle ()
|
PannerUI::pan_bypass_toggle ()
|
||||||
{
|
{
|
||||||
if (bypass_menu_item && (_io->panner().bypassed() != bypass_menu_item->get_active())) {
|
if (bypass_menu_item && (_io->panner()->bypassed() != bypass_menu_item->get_active())) {
|
||||||
_io->panner().set_bypassed (!_io->panner().bypassed());
|
_io->panner()->set_bypassed (!_io->panner()->bypassed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PannerUI::pan_reset (uint32_t which)
|
PannerUI::pan_reset (uint32_t which)
|
||||||
{
|
{
|
||||||
_io->panner().reset_streampanner (which);
|
_io->panner()->reset_streampanner (which);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PannerUI::pan_reset_all ()
|
PannerUI::pan_reset_all ()
|
||||||
{
|
{
|
||||||
_io->panner().reset_to_default ();
|
_io->panner()->reset_to_default ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PannerUI::effective_pan_display ()
|
PannerUI::effective_pan_display ()
|
||||||
{
|
{
|
||||||
if (_io->panner().empty()) {
|
if (_io->panner()->empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,7 +574,7 @@ PannerUI::pan_changed (void *src)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_io->panner().npanners()) {
|
switch (_io->panner()->npanners()) {
|
||||||
case 0:
|
case 0:
|
||||||
panning_link_direction_button.set_sensitive (false);
|
panning_link_direction_button.set_sensitive (false);
|
||||||
panning_link_button.set_sensitive (false);
|
panning_link_button.set_sensitive (false);
|
||||||
|
|
@ -595,11 +610,11 @@ PannerUI::pan_changed (void *src)
|
||||||
void
|
void
|
||||||
PannerUI::pan_adjustment_changed (uint32_t which)
|
PannerUI::pan_adjustment_changed (uint32_t which)
|
||||||
{
|
{
|
||||||
if (!in_pan_update && which < _io->panner().npanners()) {
|
if (!in_pan_update && which < _io->panner()->npanners()) {
|
||||||
|
|
||||||
float xpos;
|
float xpos;
|
||||||
float val = pan_adjustments[which]->get_value ();
|
float val = pan_adjustments[which]->get_value ();
|
||||||
xpos = _io->panner().pan_control( which )->get_value();
|
xpos = _io->panner()->pan_control( which )->get_value();
|
||||||
|
|
||||||
/* add a kinda-sorta detent for the middle */
|
/* add a kinda-sorta detent for the middle */
|
||||||
|
|
||||||
|
|
@ -616,7 +631,7 @@ PannerUI::pan_adjustment_changed (uint32_t which)
|
||||||
|
|
||||||
if (!Panner::equivalent (val, xpos)) {
|
if (!Panner::equivalent (val, xpos)) {
|
||||||
|
|
||||||
_io->panner().streampanner(which).set_position (val);
|
_io->panner()->streampanner(which).set_position (val);
|
||||||
/* XXX
|
/* XXX
|
||||||
the panner objects have no access to the session,
|
the panner objects have no access to the session,
|
||||||
so do this here. ick.
|
so do this here. ick.
|
||||||
|
|
@ -631,11 +646,11 @@ PannerUI::pan_value_changed (uint32_t which)
|
||||||
{
|
{
|
||||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which));
|
ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which));
|
||||||
|
|
||||||
if (_io->n_outputs().n_audio() > 1 && which < _io->panner().npanners()) {
|
if (_io->n_outputs().n_audio() > 1 && which < _io->panner()->npanners()) {
|
||||||
float xpos;
|
float xpos;
|
||||||
float val = pan_adjustments[which]->get_value ();
|
float val = pan_adjustments[which]->get_value ();
|
||||||
|
|
||||||
_io->panner().streampanner(which).get_position (xpos);
|
_io->panner()->streampanner(which).get_position (xpos);
|
||||||
|
|
||||||
if (!Panner::equivalent (val, xpos)) {
|
if (!Panner::equivalent (val, xpos)) {
|
||||||
in_pan_update = true;
|
in_pan_update = true;
|
||||||
|
|
@ -661,14 +676,14 @@ PannerUI::update_pan_bars (bool only_if_aplay)
|
||||||
float xpos, val;
|
float xpos, val;
|
||||||
|
|
||||||
if (only_if_aplay) {
|
if (only_if_aplay) {
|
||||||
boost::shared_ptr<AutomationList> alist (_io->panner().streampanner(n).pan_control()->alist());
|
boost::shared_ptr<AutomationList> alist (_io->panner()->streampanner(n).pan_control()->alist());
|
||||||
|
|
||||||
if (!alist->automation_playback()) {
|
if (!alist->automation_playback()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_io->panner().streampanner(n).get_effective_position (xpos);
|
_io->panner()->streampanner(n).get_effective_position (xpos);
|
||||||
val = (*i)->get_value ();
|
val = (*i)->get_value ();
|
||||||
|
|
||||||
if (!Panner::equivalent (val, xpos)) {
|
if (!Panner::equivalent (val, xpos)) {
|
||||||
|
|
@ -699,7 +714,7 @@ PannerUI::pan_printer (char *buf, uint32_t len, Adjustment* adj)
|
||||||
void
|
void
|
||||||
PannerUI::update_pan_sensitive ()
|
PannerUI::update_pan_sensitive ()
|
||||||
{
|
{
|
||||||
bool sensitive = !(_io->panner().automation_state() & Play);
|
bool sensitive = !(_io->panner()->automation_state() & Play);
|
||||||
|
|
||||||
switch (_io->n_outputs().n_audio()) {
|
switch (_io->n_outputs().n_audio()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -771,10 +786,10 @@ PannerUI::pan_automation_style_changed ()
|
||||||
|
|
||||||
switch (_width) {
|
switch (_width) {
|
||||||
case Wide:
|
case Wide:
|
||||||
pan_automation_style_button.set_label (astyle_string(_io->panner().automation_style()));
|
pan_automation_style_button.set_label (astyle_string(_io->panner()->automation_style()));
|
||||||
break;
|
break;
|
||||||
case Narrow:
|
case Narrow:
|
||||||
pan_automation_style_button.set_label (short_astyle_string(_io->panner().automation_style()));
|
pan_automation_style_button.set_label (short_astyle_string(_io->panner()->automation_style()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -788,10 +803,10 @@ PannerUI::pan_automation_state_changed ()
|
||||||
|
|
||||||
switch (_width) {
|
switch (_width) {
|
||||||
case Wide:
|
case Wide:
|
||||||
pan_automation_state_button.set_label (astate_string(_io->panner().automation_state()));
|
pan_automation_state_button.set_label (astate_string(_io->panner()->automation_state()));
|
||||||
break;
|
break;
|
||||||
case Narrow:
|
case Narrow:
|
||||||
pan_automation_state_button.set_label (short_astate_string(_io->panner().automation_state()));
|
pan_automation_state_button.set_label (short_astate_string(_io->panner()->automation_state()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -800,11 +815,11 @@ PannerUI::pan_automation_state_changed ()
|
||||||
here.
|
here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_io->panner().empty()) {
|
if (_io->panner()->empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = (_io->panner().streampanner(0).pan_control()->alist()->automation_state() != Off);
|
x = (_io->panner()->streampanner(0).pan_control()->alist()->automation_state() != Off);
|
||||||
|
|
||||||
if (pan_automation_state_button.get_active() != x) {
|
if (pan_automation_state_button.get_active() != x) {
|
||||||
ignore_toggle = true;
|
ignore_toggle = true;
|
||||||
|
|
|
||||||
|
|
@ -7312,8 +7312,7 @@ msgstr "Ardour/GTK "
|
||||||
|
|
||||||
#: gtk2_ardour/main.cc:294
|
#: gtk2_ardour/main.cc:294
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (kompiliert mit Version "
|
" (kompiliert mit Version "
|
||||||
|
|
@ -7355,7 +7354,7 @@ msgid "could not create ARDOUR GUI"
|
||||||
msgstr "konnte das grafische Ardour User Interface nicht erstellen"
|
msgstr "konnte das grafische Ardour User Interface nicht erstellen"
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:78
|
#: gtk2_ardour/ui_config.cc:78
|
||||||
msgid "loading default ui configuration file %1"
|
msgid "Loading default ui configuration file %1"
|
||||||
msgstr "lade voreingestellte UI-Konfigurationsdatei %1"
|
msgstr "lade voreingestellte UI-Konfigurationsdatei %1"
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:81
|
#: gtk2_ardour/ui_config.cc:81
|
||||||
|
|
@ -7367,8 +7366,8 @@ msgid "Ardour: default ui configuration file \"%1\" not loaded successfully."
|
||||||
msgstr "Ardour: Die voreingestellte UI-Konfigurationsdatei \"%1\" konnte nicht geladen werden."
|
msgstr "Ardour: Die voreingestellte UI-Konfigurationsdatei \"%1\" konnte nicht geladen werden."
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:104
|
#: gtk2_ardour/ui_config.cc:104
|
||||||
msgid "loading user ui configuration file %1"
|
msgid "Loading user ui configuration file %1"
|
||||||
msgstr "lade benutzerdefinierte UI-Konfigurationsdatei %1"
|
msgstr "Lade benutzerdefinierte UI-Konfigurationsdatei %1"
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:107
|
#: gtk2_ardour/ui_config.cc:107
|
||||||
msgid "Ardour: cannot read ui configuration file \"%1\""
|
msgid "Ardour: cannot read ui configuration file \"%1\""
|
||||||
|
|
|
||||||
|
|
@ -4931,8 +4931,7 @@ msgstr "Ardour/GTK "
|
||||||
|
|
||||||
#: main.cc:401
|
#: main.cc:401
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: main.cc:405
|
#: main.cc:405
|
||||||
|
|
|
||||||
|
|
@ -4900,8 +4900,7 @@ msgstr ""
|
||||||
|
|
||||||
#: main.cc:401
|
#: main.cc:401
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: main.cc:405
|
#: main.cc:405
|
||||||
|
|
|
||||||
|
|
@ -5528,8 +5528,7 @@ msgstr "Ardour/GTK"
|
||||||
|
|
||||||
#: gtk2_ardour/main.cc:314
|
#: gtk2_ardour/main.cc:314
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (construit avec "
|
" (construit avec "
|
||||||
|
|
@ -7004,7 +7003,7 @@ msgid "programming error: request for non-existent audio range (%1)!"
|
||||||
msgstr "programming error: request for non-existent audio range (%1)!"
|
msgstr "programming error: request for non-existent audio range (%1)!"
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:67
|
#: gtk2_ardour/ui_config.cc:67
|
||||||
msgid "loading default ui configuration file %1"
|
msgid "Loading default ui configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Chargement du fichier de style par défaut (%1) pour l'interface graphique"
|
"Chargement du fichier de style par défaut (%1) pour l'interface graphique"
|
||||||
|
|
||||||
|
|
@ -7021,9 +7020,9 @@ msgstr ""
|
||||||
"graphique n'a pas pu être chargé correctement."
|
"graphique n'a pas pu être chargé correctement."
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:93
|
#: gtk2_ardour/ui_config.cc:93
|
||||||
msgid "loading user ui configuration file %1"
|
msgid "Loading user ui configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"chargement du fichier utilisateur (%1) pour la configuration de l'interface "
|
"Chargement du fichier utilisateur (%1) pour la configuration de l'interface "
|
||||||
"graphique"
|
"graphique"
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:96
|
#: gtk2_ardour/ui_config.cc:96
|
||||||
|
|
|
||||||
|
|
@ -4790,8 +4790,7 @@ msgstr ""
|
||||||
|
|
||||||
#: main.cc:401
|
#: main.cc:401
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: main.cc:405
|
#: main.cc:405
|
||||||
|
|
|
||||||
|
|
@ -6147,8 +6147,7 @@ msgstr "Ardour/GTK "
|
||||||
|
|
||||||
#: gtk2_ardour/main.cc:272
|
#: gtk2_ardour/main.cc:272
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (skompilowany przy użyciu "
|
" (skompilowany przy użyciu "
|
||||||
|
|
@ -7636,7 +7635,7 @@ msgid "programming error: request for non-existent audio range (%1)!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:76
|
#: gtk2_ardour/ui_config.cc:76
|
||||||
msgid "loading default ui configuration file %1"
|
msgid "Loading default ui configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:79
|
#: gtk2_ardour/ui_config.cc:79
|
||||||
|
|
@ -7648,7 +7647,7 @@ msgid "Ardour: default ui configuration file \"%1\" not loaded successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:102
|
#: gtk2_ardour/ui_config.cc:102
|
||||||
msgid "loading user ui configuration file %1"
|
msgid "Loading user ui configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: gtk2_ardour/ui_config.cc:105
|
#: gtk2_ardour/ui_config.cc:105
|
||||||
|
|
|
||||||
|
|
@ -4852,8 +4852,7 @@ msgstr ""
|
||||||
|
|
||||||
#: main.cc:401
|
#: main.cc:401
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: main.cc:405
|
#: main.cc:405
|
||||||
|
|
|
||||||
|
|
@ -4529,8 +4529,7 @@ msgstr ""
|
||||||
|
|
||||||
#: main.cc:401
|
#: main.cc:401
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (compilado "
|
" (compilado "
|
||||||
|
|
|
||||||
|
|
@ -4761,8 +4761,7 @@ msgstr "Ardour/GTK "
|
||||||
|
|
||||||
#: gtk2_ardour/main.cc:388
|
#: gtk2_ardour/main.cc:388
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (собран с использованием "
|
" (собран с использованием "
|
||||||
|
|
|
||||||
|
|
@ -4797,8 +4797,7 @@ msgstr ""
|
||||||
|
|
||||||
#: ../main.cc:397
|
#: ../main.cc:397
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
" (built using "
|
||||||
" (built using "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" (kompilerat med "
|
" (kompilerat med "
|
||||||
|
|
|
||||||
|
|
@ -37,17 +37,19 @@
|
||||||
#include <gtkmm2ext/doi.h>
|
#include <gtkmm2ext/doi.h>
|
||||||
#include <gtkmm2ext/window_title.h>
|
#include <gtkmm2ext/window_title.h>
|
||||||
|
|
||||||
|
#include "ardour/amp.h"
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
#include "ardour/session.h"
|
|
||||||
#include "ardour/audioengine.h"
|
|
||||||
#include "ardour/route.h"
|
|
||||||
#include "ardour/audio_track.h"
|
|
||||||
#include "ardour/audio_diskstream.h"
|
#include "ardour/audio_diskstream.h"
|
||||||
#include "ardour/send.h"
|
#include "ardour/audio_track.h"
|
||||||
|
#include "ardour/audioengine.h"
|
||||||
|
#include "ardour/ladspa_plugin.h"
|
||||||
|
#include "ardour/meter.h"
|
||||||
#include "ardour/plugin_insert.h"
|
#include "ardour/plugin_insert.h"
|
||||||
#include "ardour/port_insert.h"
|
#include "ardour/port_insert.h"
|
||||||
#include "ardour/ladspa_plugin.h"
|
|
||||||
#include "ardour/profile.h"
|
#include "ardour/profile.h"
|
||||||
|
#include "ardour/route.h"
|
||||||
|
#include "ardour/send.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
|
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
#include "ardour_dialog.h"
|
#include "ardour_dialog.h"
|
||||||
|
|
@ -82,19 +84,21 @@ bool ProcessorBox::get_colors = true;
|
||||||
Gdk::Color* ProcessorBox::active_processor_color;
|
Gdk::Color* ProcessorBox::active_processor_color;
|
||||||
Gdk::Color* ProcessorBox::inactive_processor_color;
|
Gdk::Color* ProcessorBox::inactive_processor_color;
|
||||||
|
|
||||||
ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, PluginSelector &plugsel,
|
ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, PluginSelector &plugsel,
|
||||||
RouteRedirectSelection & rsel, bool owner_is_mixer)
|
RouteRedirectSelection & rsel, bool owner_is_mixer)
|
||||||
: _session(sess),
|
: _session(sess)
|
||||||
_owner_is_mixer (owner_is_mixer),
|
, _owner_is_mixer (owner_is_mixer)
|
||||||
_placement(pcmnt),
|
, _placement(pcmnt)
|
||||||
_plugin_selector(plugsel),
|
, _plugin_selector(plugsel)
|
||||||
_rr_selection(rsel)
|
, _rr_selection(rsel)
|
||||||
{
|
{
|
||||||
if (get_colors) {
|
if (get_colors) {
|
||||||
active_processor_color = new Gdk::Color;
|
active_processor_color = new Gdk::Color;
|
||||||
inactive_processor_color = new Gdk::Color;
|
inactive_processor_color = new Gdk::Color;
|
||||||
set_color (*active_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
|
set_color (*active_processor_color, rgba_from_style (
|
||||||
set_color (*inactive_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
|
"ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
|
||||||
|
set_color (*inactive_processor_color, rgba_from_style (
|
||||||
|
"ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
|
||||||
get_colors = false;
|
get_colors = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,24 +127,29 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, PluginSelector &plug
|
||||||
processor_display.signal_drop.connect (mem_fun (*this, &ProcessorBox::object_drop));
|
processor_display.signal_drop.connect (mem_fun (*this, &ProcessorBox::object_drop));
|
||||||
|
|
||||||
TreeViewColumn* name_col = processor_display.get_column(0);
|
TreeViewColumn* name_col = processor_display.get_column(0);
|
||||||
CellRendererText* renderer = dynamic_cast<CellRendererText*>(processor_display.get_column_cell_renderer (0));
|
CellRendererText* renderer = dynamic_cast<CellRendererText*>(
|
||||||
|
processor_display.get_column_cell_renderer (0));
|
||||||
name_col->add_attribute(renderer->property_foreground_gdk(), columns.color);
|
name_col->add_attribute(renderer->property_foreground_gdk(), columns.color);
|
||||||
|
|
||||||
processor_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
|
processor_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
|
||||||
|
|
||||||
model->signal_row_deleted().connect (mem_fun (*this, &ProcessorBox::row_deleted));
|
model->signal_row_deleted().connect (mem_fun (*this, &ProcessorBox::row_deleted));
|
||||||
|
|
||||||
processor_scroller.add (processor_display);
|
processor_scroller.add (processor_display);
|
||||||
processor_eventbox.add (processor_scroller);
|
processor_eventbox.add (processor_scroller);
|
||||||
|
|
||||||
processor_scroller.set_size_request (-1, 40);
|
processor_scroller.set_size_request (-1, 40);
|
||||||
|
|
||||||
pack_start (processor_eventbox, true, true);
|
pack_start (processor_eventbox, true, true);
|
||||||
|
|
||||||
processor_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (ProcessorBox::enter_box), this));
|
processor_eventbox.signal_enter_notify_event().connect (bind (
|
||||||
|
sigc::ptr_fun (ProcessorBox::enter_box),
|
||||||
|
this));
|
||||||
|
|
||||||
processor_display.signal_button_press_event().connect (mem_fun(*this, &ProcessorBox::processor_button_press_event), false);
|
processor_display.signal_button_press_event().connect (
|
||||||
processor_display.signal_button_release_event().connect (mem_fun(*this, &ProcessorBox::processor_button_release_event));
|
mem_fun(*this, &ProcessorBox::processor_button_press_event), false);
|
||||||
|
processor_display.signal_button_release_event().connect (
|
||||||
|
mem_fun(*this, &ProcessorBox::processor_button_release_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessorBox::~ProcessorBox ()
|
ProcessorBox::~ProcessorBox ()
|
||||||
|
|
@ -154,9 +163,12 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
|
||||||
|
|
||||||
_route = r;
|
_route = r;
|
||||||
|
|
||||||
connections.push_back (_route->processors_changed.connect (mem_fun(*this, &ProcessorBox::redisplay_processors)));
|
connections.push_back (_route->processors_changed.connect (
|
||||||
connections.push_back (_route->GoingAway.connect (mem_fun (*this, &ProcessorBox::route_going_away)));
|
mem_fun(*this, &ProcessorBox::redisplay_processors)));
|
||||||
connections.push_back (_route->NameChanged.connect (mem_fun(*this, &ProcessorBox::route_name_changed)));
|
connections.push_back (_route->GoingAway.connect (
|
||||||
|
mem_fun (*this, &ProcessorBox::route_going_away)));
|
||||||
|
connections.push_back (_route->NameChanged.connect (
|
||||||
|
mem_fun(*this, &ProcessorBox::route_name_changed)));
|
||||||
|
|
||||||
redisplay_processors ();
|
redisplay_processors ();
|
||||||
}
|
}
|
||||||
|
|
@ -172,8 +184,8 @@ ProcessorBox::route_going_away ()
|
||||||
void
|
void
|
||||||
ProcessorBox::object_drop (const list<boost::shared_ptr<Processor> >& procs)
|
ProcessorBox::object_drop (const list<boost::shared_ptr<Processor> >& procs)
|
||||||
{
|
{
|
||||||
for (std::list<boost::shared_ptr<Processor> >::const_iterator i = procs.begin(); i != procs.end(); ++i) {
|
for (std::list<boost::shared_ptr<Processor> >::const_iterator i = procs.begin();
|
||||||
|
i != procs.end(); ++i) {
|
||||||
XMLNode& state = (*i)->get_state ();
|
XMLNode& state = (*i)->get_state ();
|
||||||
XMLNodeList nlist;
|
XMLNodeList nlist;
|
||||||
nlist.push_back (&state);
|
nlist.push_back (&state);
|
||||||
|
|
@ -207,11 +219,9 @@ ProcessorBox::remove_processor_gui (boost::shared_ptr<Processor> processor)
|
||||||
boost::shared_ptr<PortInsert> port_insert;
|
boost::shared_ptr<PortInsert> port_insert;
|
||||||
|
|
||||||
if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
|
if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
|
||||||
|
|
||||||
PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui());
|
PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui());
|
||||||
port_insert->set_gui (0);
|
port_insert->set_gui (0);
|
||||||
delete io_selector;
|
delete io_selector;
|
||||||
|
|
||||||
} else if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
} else if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
||||||
SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui());
|
SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui());
|
||||||
send->set_gui (0);
|
send->set_gui (0);
|
||||||
|
|
@ -219,9 +229,8 @@ ProcessorBox::remove_processor_gui (boost::shared_ptr<Processor> processor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessorBox::build_send_action_menu ()
|
ProcessorBox::build_send_action_menu ()
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace Menu_Helpers;
|
using namespace Menu_Helpers;
|
||||||
|
|
||||||
|
|
@ -235,13 +244,11 @@ ProcessorBox::build_send_action_menu ()
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessorBox::show_send_controls ()
|
ProcessorBox::show_send_controls ()
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessorBox::new_send ()
|
ProcessorBox::new_send ()
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,17 +299,17 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev)
|
||||||
processor = (*iter)[columns.processor];
|
processor = (*iter)[columns.processor];
|
||||||
selected = processor_display.get_selection()->is_selected (iter);
|
selected = processor_display.get_selection()->is_selected (iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processor && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS))) {
|
if (processor && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS))) {
|
||||||
|
|
||||||
if (_session.engine().connected()) {
|
if (_session.engine().connected()) {
|
||||||
/* XXX giving an error message here is hard, because we may be in the midst of a button press */
|
/* XXX giving an error message here is hard, because we may be in the midst of a button press */
|
||||||
edit_processor (processor);
|
edit_processor (processor);
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
} else if (processor && ev->button == 1 && selected) {
|
} else if (processor && ev->button == 1 && selected) {
|
||||||
|
|
||||||
// this is purely informational but necessary
|
// this is purely informational but necessary
|
||||||
|
|
@ -314,7 +321,7 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev)
|
||||||
_plugin_selector.show_manager ();
|
_plugin_selector.show_manager ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,10 +344,12 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processor && Keyboard::is_delete_event (ev)) {
|
if (processor && Keyboard::is_delete_event (ev)) {
|
||||||
|
|
||||||
Glib::signal_idle().connect (bind (mem_fun(*this, &ProcessorBox::idle_delete_processor), boost::weak_ptr<Processor>(processor)));
|
Glib::signal_idle().connect (bind (
|
||||||
|
mem_fun(*this, &ProcessorBox::idle_delete_processor),
|
||||||
|
boost::weak_ptr<Processor>(processor)));
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
} else if (Keyboard::is_context_menu_event (ev)) {
|
} else if (Keyboard::is_context_menu_event (ev)) {
|
||||||
|
|
||||||
show_processor_menu(ev->time);
|
show_processor_menu(ev->time);
|
||||||
|
|
@ -350,7 +359,7 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
|
||||||
#ifndef GTKOSX
|
#ifndef GTKOSX
|
||||||
&& (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))
|
&& (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/* button2-click with no/appropriate modifiers */
|
/* button2-click with no/appropriate modifiers */
|
||||||
|
|
||||||
|
|
@ -361,7 +370,7 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -407,23 +416,25 @@ ProcessorBox::use_plugins (const SelectedPlugins& plugins)
|
||||||
{
|
{
|
||||||
for (SelectedPlugins::const_iterator p = plugins.begin(); p != plugins.end(); ++p) {
|
for (SelectedPlugins::const_iterator p = plugins.begin(); p != plugins.end(); ++p) {
|
||||||
|
|
||||||
boost::shared_ptr<Processor> processor (new PluginInsert (_session, *p, _placement));
|
boost::shared_ptr<Processor> processor (new PluginInsert (_session, *p));
|
||||||
|
|
||||||
Route::ProcessorStreams err_streams;
|
Route::ProcessorStreams err_streams;
|
||||||
|
|
||||||
if (Config->get_new_plugins_active()) {
|
if (Config->get_new_plugins_active()) {
|
||||||
processor->activate ();
|
processor->activate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_route->add_processor (processor, &err_streams)) {
|
if (_route->add_processor (processor, &err_streams, 0, _placement)) {
|
||||||
weird_plugin_dialog (**p, err_streams, _route);
|
weird_plugin_dialog (**p, err_streams, _route);
|
||||||
// XXX SHAREDPTR delete plugin here .. do we even need to care?
|
// XXX SHAREDPTR delete plugin here .. do we even need to care?
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (Profile->get_sae()) {
|
if (Profile->get_sae()) {
|
||||||
processor->activate ();
|
processor->activate ();
|
||||||
}
|
}
|
||||||
processor->ActiveChanged.connect (bind (mem_fun (*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
|
processor->ActiveChanged.connect (bind (
|
||||||
|
mem_fun (*this, &ProcessorBox::show_processor_active),
|
||||||
|
boost::weak_ptr<Processor>(processor)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -448,7 +459,7 @@ ProcessorBox::weird_plugin_dialog (Plugin& p, Route::ProcessorStreams streams, b
|
||||||
text += string_compose("\t%1 ", p.get_info()->n_inputs.n_audio()) + _("audio input(s)\n");
|
text += string_compose("\t%1 ", p.get_info()->n_inputs.n_audio()) + _("audio input(s)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
text += "\nBut at the insertion point, there are:\n";
|
text += _("\nBut at the insertion point, there are:\n");
|
||||||
if (has_midi) {
|
if (has_midi) {
|
||||||
text += string_compose("\t%1 ", streams.count.n_midi()) + _("MIDI channel(s)\n");
|
text += string_compose("\t%1 ", streams.count.n_midi()) + _("MIDI channel(s)\n");
|
||||||
}
|
}
|
||||||
|
|
@ -456,7 +467,7 @@ ProcessorBox::weird_plugin_dialog (Plugin& p, Route::ProcessorStreams streams, b
|
||||||
text += string_compose("\t%1 ", streams.count.n_audio()) + _("audio channel(s)\n");
|
text += string_compose("\t%1 ", streams.count.n_audio()) + _("audio channel(s)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
text += "\nArdour is unable to insert this plugin here.\n";
|
text += _("\nArdour is unable to insert this plugin here.\n");
|
||||||
label.set_text(text);
|
label.set_text(text);
|
||||||
|
|
||||||
dialog.get_vbox()->pack_start (label);
|
dialog.get_vbox()->pack_start (label);
|
||||||
|
|
@ -473,15 +484,17 @@ ProcessorBox::weird_plugin_dialog (Plugin& p, Route::ProcessorStreams streams, b
|
||||||
void
|
void
|
||||||
ProcessorBox::choose_insert ()
|
ProcessorBox::choose_insert ()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Processor> processor (new PortInsert (_session, _placement));
|
boost::shared_ptr<Processor> processor (new PortInsert (_session));
|
||||||
processor->ActiveChanged.connect (bind (mem_fun(*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
|
processor->ActiveChanged.connect (bind (
|
||||||
_route->add_processor (processor);
|
mem_fun(*this, &ProcessorBox::show_processor_active),
|
||||||
|
boost::weak_ptr<Processor>(processor)));
|
||||||
|
_route->add_processor (processor, 0, 0, _placement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessorBox::choose_send ()
|
ProcessorBox::choose_send ()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Send> send (new Send (_session, _placement));
|
boost::shared_ptr<Send> send (new Send (_session));
|
||||||
//send->set_default_type(_route->default_type());
|
//send->set_default_type(_route->default_type());
|
||||||
|
|
||||||
ChanCount outs;
|
ChanCount outs;
|
||||||
|
|
@ -502,11 +515,11 @@ ProcessorBox::choose_send ()
|
||||||
error << string_compose (_("Cannot set up new send: %1"), err.what()) << endmsg;
|
error << string_compose (_("Cannot set up new send: %1"), err.what()) << endmsg;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let the user adjust the output setup (number and connections) before passing
|
/* let the user adjust the output setup (number and connections) before passing
|
||||||
it along to the Route
|
it along to the Route
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IOSelectorWindow *ios = new IOSelectorWindow (_session, send->io(), false, true);
|
IOSelectorWindow *ios = new IOSelectorWindow (_session, send->io(), false, true);
|
||||||
|
|
||||||
ios->show_all ();
|
ios->show_all ();
|
||||||
|
|
@ -516,8 +529,10 @@ ProcessorBox::choose_send ()
|
||||||
_send_being_created = send;
|
_send_being_created = send;
|
||||||
|
|
||||||
boost::shared_ptr<Processor> r = boost::static_pointer_cast<Processor>(send);
|
boost::shared_ptr<Processor> r = boost::static_pointer_cast<Processor>(send);
|
||||||
|
|
||||||
ios->selector().Finished.connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), boost::weak_ptr<Processor>(r), ios));
|
ios->selector().Finished.connect (bind (
|
||||||
|
mem_fun(*this, &ProcessorBox::send_io_finished),
|
||||||
|
boost::weak_ptr<Processor>(r), ios));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -538,7 +553,7 @@ ProcessorBox::send_io_finished (IOSelector::Result r, boost::weak_ptr<Processor>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOSelector::Accepted:
|
case IOSelector::Accepted:
|
||||||
_route->add_processor (processor);
|
_route->add_processor (processor, 0, 0, _placement);
|
||||||
if (Profile->get_sae()) {
|
if (Profile->get_sae()) {
|
||||||
processor->activate ();
|
processor->activate ();
|
||||||
}
|
}
|
||||||
|
|
@ -556,7 +571,7 @@ ProcessorBox::redisplay_processors ()
|
||||||
if (no_processor_redisplay) {
|
if (no_processor_redisplay) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ignore_delete = true;
|
ignore_delete = true;
|
||||||
model->clear ();
|
model->clear ();
|
||||||
ignore_delete = false;
|
ignore_delete = false;
|
||||||
|
|
@ -564,7 +579,7 @@ ProcessorBox::redisplay_processors ()
|
||||||
processor_active_connections.clear ();
|
processor_active_connections.clear ();
|
||||||
processor_name_connections.clear ();
|
processor_name_connections.clear ();
|
||||||
|
|
||||||
_route->foreach_processor (mem_fun (*this, &ProcessorBox::add_processor_to_display));
|
_route->foreach_processor (_placement, mem_fun (*this, &ProcessorBox::add_processor_to_display));
|
||||||
|
|
||||||
switch (_placement) {
|
switch (_placement) {
|
||||||
case PreFader:
|
case PreFader:
|
||||||
|
|
@ -583,19 +598,23 @@ ProcessorBox::add_processor_to_display (boost::weak_ptr<Processor> p)
|
||||||
if (!processor) {
|
if (!processor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processor->placement() != _placement) {
|
if (processor == _route->amp()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gtk::TreeModel::Row row = *(model->append());
|
Gtk::TreeModel::Row row = *(model->append());
|
||||||
row[columns.text] = processor_name (processor);
|
row[columns.text] = processor_name (processor);
|
||||||
row[columns.processor] = processor;
|
row[columns.processor] = processor;
|
||||||
|
|
||||||
show_processor_active (processor);
|
show_processor_active (processor);
|
||||||
|
|
||||||
processor_active_connections.push_back (processor->ActiveChanged.connect (bind (mem_fun(*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor))));
|
processor_active_connections.push_back (processor->ActiveChanged.connect (bind (
|
||||||
processor_name_connections.push_back (processor->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::show_processor_name), boost::weak_ptr<Processor>(processor))));
|
mem_fun(*this, &ProcessorBox::show_processor_active),
|
||||||
|
boost::weak_ptr<Processor>(processor))));
|
||||||
|
processor_name_connections.push_back (processor->NameChanged.connect (bind (
|
||||||
|
mem_fun(*this, &ProcessorBox::show_processor_name),
|
||||||
|
boost::weak_ptr<Processor>(processor))));
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
|
|
@ -678,13 +697,13 @@ void
|
||||||
ProcessorBox::show_processor_active (boost::weak_ptr<Processor> weak_processor)
|
ProcessorBox::show_processor_active (boost::weak_ptr<Processor> weak_processor)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Processor> processor (weak_processor.lock());
|
boost::shared_ptr<Processor> processor (weak_processor.lock());
|
||||||
|
|
||||||
if (!processor) {
|
if (!processor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
|
ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
|
||||||
|
|
||||||
Gtk::TreeModel::Children children = model->children();
|
Gtk::TreeModel::Children children = model->children();
|
||||||
Gtk::TreeModel::Children::iterator iter = children.begin();
|
Gtk::TreeModel::Children::iterator iter = children.begin();
|
||||||
|
|
||||||
|
|
@ -694,7 +713,7 @@ ProcessorBox::show_processor_active (boost::weak_ptr<Processor> weak_processor)
|
||||||
|
|
||||||
if (r == processor) {
|
if (r == processor) {
|
||||||
(*iter)[columns.text] = processor_name (r);
|
(*iter)[columns.text] = processor_name (r);
|
||||||
|
|
||||||
if (processor->active()) {
|
if (processor->active()) {
|
||||||
(*iter)[columns.color] = *active_processor_color;
|
(*iter)[columns.color] = *active_processor_color;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -756,15 +775,15 @@ outputs do not work correctly."));
|
||||||
void
|
void
|
||||||
ProcessorBox::rename_processors ()
|
ProcessorBox::rename_processors ()
|
||||||
{
|
{
|
||||||
vector<boost::shared_ptr<Processor> > to_be_renamed;
|
ProcSelection to_be_renamed;
|
||||||
|
|
||||||
get_selected_processors (to_be_renamed);
|
get_selected_processors (to_be_renamed);
|
||||||
|
|
||||||
if (to_be_renamed.empty()) {
|
if (to_be_renamed.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) {
|
for (ProcSelection::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) {
|
||||||
rename_processor (*i);
|
rename_processor (*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +791,7 @@ ProcessorBox::rename_processors ()
|
||||||
void
|
void
|
||||||
ProcessorBox::cut_processors ()
|
ProcessorBox::cut_processors ()
|
||||||
{
|
{
|
||||||
vector<boost::shared_ptr<Processor> > to_be_removed;
|
ProcSelection to_be_removed;
|
||||||
XMLNode* node = new XMLNode (X_("cut"));
|
XMLNode* node = new XMLNode (X_("cut"));
|
||||||
|
|
||||||
get_selected_processors (to_be_removed);
|
get_selected_processors (to_be_removed);
|
||||||
|
|
@ -782,17 +801,17 @@ ProcessorBox::cut_processors ()
|
||||||
}
|
}
|
||||||
|
|
||||||
no_processor_redisplay = true;
|
no_processor_redisplay = true;
|
||||||
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
|
for (ProcSelection::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
|
||||||
// Do not cut inserts
|
// Do not cut inserts
|
||||||
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
|
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
|
||||||
(boost::dynamic_pointer_cast<Send>((*i)) != 0)) {
|
(boost::dynamic_pointer_cast<Send>((*i)) != 0)) {
|
||||||
|
|
||||||
void* gui = (*i)->get_gui ();
|
void* gui = (*i)->get_gui ();
|
||||||
|
|
||||||
if (gui) {
|
if (gui) {
|
||||||
static_cast<Gtk::Widget*>(gui)->hide ();
|
static_cast<Gtk::Widget*>(gui)->hide ();
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode& child ((*i)->get_state());
|
XMLNode& child ((*i)->get_state());
|
||||||
|
|
||||||
if (_route->remove_processor (*i) == 0) {
|
if (_route->remove_processor (*i) == 0) {
|
||||||
|
|
@ -801,7 +820,7 @@ ProcessorBox::cut_processors ()
|
||||||
} else {
|
} else {
|
||||||
delete &child;
|
delete &child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_rr_selection.set (node);
|
_rr_selection.set (node);
|
||||||
|
|
@ -813,7 +832,7 @@ ProcessorBox::cut_processors ()
|
||||||
void
|
void
|
||||||
ProcessorBox::copy_processors ()
|
ProcessorBox::copy_processors ()
|
||||||
{
|
{
|
||||||
vector<boost::shared_ptr<Processor> > to_be_copied;
|
ProcSelection to_be_copied;
|
||||||
XMLNode* node = new XMLNode (X_("copy"));
|
XMLNode* node = new XMLNode (X_("copy"));
|
||||||
|
|
||||||
get_selected_processors (to_be_copied);
|
get_selected_processors (to_be_copied);
|
||||||
|
|
@ -822,7 +841,7 @@ ProcessorBox::copy_processors ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) {
|
for (ProcSelection::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) {
|
||||||
// Do not copy inserts
|
// Do not copy inserts
|
||||||
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
|
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
|
||||||
(boost::dynamic_pointer_cast<Send>((*i)) != 0)) {
|
(boost::dynamic_pointer_cast<Send>((*i)) != 0)) {
|
||||||
|
|
@ -836,18 +855,18 @@ ProcessorBox::copy_processors ()
|
||||||
void
|
void
|
||||||
ProcessorBox::delete_processors ()
|
ProcessorBox::delete_processors ()
|
||||||
{
|
{
|
||||||
vector<boost::shared_ptr<Processor> > to_be_deleted;
|
ProcSelection to_be_deleted;
|
||||||
|
|
||||||
get_selected_processors (to_be_deleted);
|
get_selected_processors (to_be_deleted);
|
||||||
|
|
||||||
if (to_be_deleted.empty()) {
|
if (to_be_deleted.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) {
|
for (ProcSelection::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) {
|
||||||
|
|
||||||
void* gui = (*i)->get_gui ();
|
void* gui = (*i)->get_gui ();
|
||||||
|
|
||||||
if (gui) {
|
if (gui) {
|
||||||
static_cast<Gtk::Widget*>(gui)->hide ();
|
static_cast<Gtk::Widget*>(gui)->hide ();
|
||||||
}
|
}
|
||||||
|
|
@ -895,7 +914,7 @@ ProcessorBox::rename_processor (boost::shared_ptr<Processor> processor)
|
||||||
name_prompter.get_result (result);
|
name_prompter.get_result (result);
|
||||||
if (result.length()) {
|
if (result.length()) {
|
||||||
processor->set_name (result);
|
processor->set_name (result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -937,12 +956,14 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist)
|
||||||
XMLNode n (**niter);
|
XMLNode n (**niter);
|
||||||
Send::make_unique (n, _session);
|
Send::make_unique (n, _session);
|
||||||
p.reset (new Send (_session, n));
|
p.reset (new Send (_session, n));
|
||||||
|
|
||||||
|
} else if (type->value() == "meter") {
|
||||||
|
p = _route->shared_peak_meter();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p.reset (new PluginInsert (_session, **niter));
|
p.reset (new PluginInsert (_session, **niter));
|
||||||
}
|
}
|
||||||
|
|
||||||
p->set_placement (_placement);
|
|
||||||
copies.push_back (p);
|
copies.push_back (p);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
|
|
@ -950,7 +971,7 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_route->add_processors (copies)) {
|
if (_route->add_processors (copies, 0, _placement)) {
|
||||||
|
|
||||||
string msg = _(
|
string msg = _(
|
||||||
"Copying the set of processors on the clipboard failed,\n\
|
"Copying the set of processors on the clipboard failed,\n\
|
||||||
|
|
@ -974,10 +995,10 @@ ProcessorBox::deactivate_processor (boost::shared_ptr<Processor> r)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessorBox::get_selected_processors (vector<boost::shared_ptr<Processor> >& processors)
|
ProcessorBox::get_selected_processors (ProcSelection& processors)
|
||||||
{
|
{
|
||||||
vector<Gtk::TreeModel::Path> pathlist = processor_display.get_selection()->get_selected_rows();
|
vector<Gtk::TreeModel::Path> pathlist = processor_display.get_selection()->get_selected_rows();
|
||||||
|
|
||||||
for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
|
for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
|
||||||
processors.push_back ((*(model->get_iter(*iter)))[columns.processor]);
|
processors.push_back ((*(model->get_iter(*iter)))[columns.processor]);
|
||||||
}
|
}
|
||||||
|
|
@ -1056,19 +1077,19 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
||||||
|
|
||||||
if (!_session.engine().connected()) {
|
if (!_session.engine().connected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
|
boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
|
||||||
|
|
||||||
SendUIWindow *send_ui;
|
SendUIWindow *send_ui;
|
||||||
|
|
||||||
if (send->get_gui() == 0) {
|
if (send->get_gui() == 0) {
|
||||||
|
|
||||||
send_ui = new SendUIWindow (send, _session);
|
send_ui = new SendUIWindow (send, _session);
|
||||||
|
|
||||||
WindowTitle title(Glib::get_application_name());
|
WindowTitle title(Glib::get_application_name());
|
||||||
|
|
@ -1076,57 +1097,57 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
|
||||||
send_ui->set_title (title.get_string());
|
send_ui->set_title (title.get_string());
|
||||||
|
|
||||||
send->set_gui (send_ui);
|
send->set_gui (send_ui);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
send_ui = reinterpret_cast<SendUIWindow *> (send->get_gui());
|
send_ui = reinterpret_cast<SendUIWindow *> (send->get_gui());
|
||||||
}
|
}
|
||||||
|
|
||||||
gidget = send_ui;
|
gidget = send_ui;
|
||||||
|
|
||||||
} else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
|
} else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
|
||||||
|
|
||||||
PluginUIWindow *plugin_ui;
|
PluginUIWindow *plugin_ui;
|
||||||
|
|
||||||
/* these are both allowed to be null */
|
/* these are both allowed to be null */
|
||||||
|
|
||||||
Container* toplevel = get_toplevel();
|
Container* toplevel = get_toplevel();
|
||||||
Window* win = dynamic_cast<Gtk::Window*>(toplevel);
|
Window* win = dynamic_cast<Gtk::Window*>(toplevel);
|
||||||
|
|
||||||
if (plugin_insert->get_gui() == 0) {
|
if (plugin_insert->get_gui() == 0) {
|
||||||
|
|
||||||
plugin_ui = new PluginUIWindow (win, plugin_insert);
|
plugin_ui = new PluginUIWindow (win, plugin_insert);
|
||||||
|
|
||||||
WindowTitle title(Glib::get_application_name());
|
WindowTitle title(Glib::get_application_name());
|
||||||
title += generate_processor_title (plugin_insert);
|
title += generate_processor_title (plugin_insert);
|
||||||
plugin_ui->set_title (title.get_string());
|
plugin_ui->set_title (title.get_string());
|
||||||
|
|
||||||
plugin_insert->set_gui (plugin_ui);
|
plugin_insert->set_gui (plugin_ui);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
|
plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
|
||||||
plugin_ui->set_parent (win);
|
plugin_ui->set_parent (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
gidget = plugin_ui;
|
gidget = plugin_ui;
|
||||||
|
|
||||||
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
|
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
|
||||||
|
|
||||||
if (!_session.engine().connected()) {
|
if (!_session.engine().connected()) {
|
||||||
MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
|
MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
|
||||||
msg.run ();
|
msg.run ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortInsertWindow *io_selector;
|
PortInsertWindow *io_selector;
|
||||||
|
|
||||||
if (port_insert->get_gui() == 0) {
|
if (port_insert->get_gui() == 0) {
|
||||||
io_selector = new PortInsertWindow (_session, port_insert);
|
io_selector = new PortInsertWindow (_session, port_insert);
|
||||||
port_insert->set_gui (io_selector);
|
port_insert->set_gui (io_selector);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
io_selector = reinterpret_cast<PortInsertWindow *> (port_insert->get_gui());
|
io_selector = reinterpret_cast<PortInsertWindow *> (port_insert->get_gui());
|
||||||
}
|
}
|
||||||
|
|
||||||
gidget = io_selector;
|
gidget = io_selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1164,45 +1185,59 @@ ProcessorBox::register_actions ()
|
||||||
Glib::RefPtr<Action> act;
|
Glib::RefPtr<Action> act;
|
||||||
|
|
||||||
/* new stuff */
|
/* new stuff */
|
||||||
ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin"), sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
|
ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
|
||||||
|
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"), sigc::ptr_fun (ProcessorBox::rb_choose_insert));
|
act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_choose_insert));
|
||||||
ActionManager::jack_sensitive_actions.push_back (act);
|
ActionManager::jack_sensitive_actions.push_back (act);
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."), sigc::ptr_fun (ProcessorBox::rb_choose_send));
|
act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_choose_send));
|
||||||
ActionManager::jack_sensitive_actions.push_back (act);
|
ActionManager::jack_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
ActionManager::register_action (popup_act_grp, X_("clear"), _("Clear"), sigc::ptr_fun (ProcessorBox::rb_clear));
|
ActionManager::register_action (popup_act_grp, X_("clear"), _("Clear"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_clear));
|
||||||
|
|
||||||
/* standard editing stuff */
|
/* standard editing stuff */
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"), sigc::ptr_fun (ProcessorBox::rb_cut));
|
act = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_cut));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("copy"), _("Copy"), sigc::ptr_fun (ProcessorBox::rb_copy));
|
act = ActionManager::register_action (popup_act_grp, X_("copy"), _("Copy"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_copy));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
|
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("delete"), _("Delete"), sigc::ptr_fun (ProcessorBox::rb_delete));
|
act = ActionManager::register_action (popup_act_grp, X_("delete"), _("Delete"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_delete));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act); // ??
|
ActionManager::plugin_selection_sensitive_actions.push_back(act); // ??
|
||||||
|
|
||||||
paste_action = ActionManager::register_action (popup_act_grp, X_("paste"), _("Paste"), sigc::ptr_fun (ProcessorBox::rb_paste));
|
paste_action = ActionManager::register_action (popup_act_grp, X_("paste"), _("Paste"),
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("rename"), _("Rename"), sigc::ptr_fun (ProcessorBox::rb_rename));
|
sigc::ptr_fun (ProcessorBox::rb_paste));
|
||||||
|
act = ActionManager::register_action (popup_act_grp, X_("rename"), _("Rename"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_rename));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
ActionManager::register_action (popup_act_grp, X_("selectall"), _("Select All"), sigc::ptr_fun (ProcessorBox::rb_select_all));
|
ActionManager::register_action (popup_act_grp, X_("selectall"), _("Select All"),
|
||||||
ActionManager::register_action (popup_act_grp, X_("deselectall"), _("Deselect All"), sigc::ptr_fun (ProcessorBox::rb_deselect_all));
|
sigc::ptr_fun (ProcessorBox::rb_select_all));
|
||||||
|
ActionManager::register_action (popup_act_grp, X_("deselectall"), _("Deselect All"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_deselect_all));
|
||||||
|
|
||||||
/* activation */
|
/* activation */
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("activate"), _("Activate"), sigc::ptr_fun (ProcessorBox::rb_activate));
|
act = ActionManager::register_action (popup_act_grp, X_("activate"), _("Activate"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_activate));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("deactivate"), _("Deactivate"), sigc::ptr_fun (ProcessorBox::rb_deactivate));
|
act = ActionManager::register_action (popup_act_grp, X_("deactivate"), _("Deactivate"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_deactivate));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"), sigc::ptr_fun (ProcessorBox::rb_activate_all));
|
ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"),
|
||||||
ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"), sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
|
sigc::ptr_fun (ProcessorBox::rb_activate_all));
|
||||||
|
ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
|
||||||
|
|
||||||
/* show editors */
|
/* show editors */
|
||||||
act = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit"), sigc::ptr_fun (ProcessorBox::rb_edit));
|
act = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit"),
|
||||||
|
sigc::ptr_fun (ProcessorBox::rb_edit));
|
||||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||||
|
|
||||||
ActionManager::add_action_group (popup_act_grp);
|
ActionManager::add_action_group (popup_act_grp);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1373,7 +1408,7 @@ ProcessorBox::route_name_changed ()
|
||||||
Gtk::TreeModel::Row row = *iter;
|
Gtk::TreeModel::Row row = *iter;
|
||||||
|
|
||||||
processor= row[columns.processor];
|
processor= row[columns.processor];
|
||||||
|
|
||||||
void* gui = processor->get_gui();
|
void* gui = processor->get_gui();
|
||||||
|
|
||||||
if (!gui) {
|
if (!gui) {
|
||||||
|
|
@ -1383,7 +1418,7 @@ ProcessorBox::route_name_changed ()
|
||||||
/* rename editor windows for sends and plugins */
|
/* rename editor windows for sends and plugins */
|
||||||
|
|
||||||
WindowTitle title (Glib::get_application_name());
|
WindowTitle title (Glib::get_application_name());
|
||||||
|
|
||||||
if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
|
||||||
title += send->name();
|
title += send->name();
|
||||||
static_cast<Window*>(gui)->set_title (title.get_string());
|
static_cast<Window*>(gui)->set_title (title.get_string());
|
||||||
|
|
@ -1394,7 +1429,7 @@ ProcessorBox::route_name_changed ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
ProcessorBox::generate_processor_title (boost::shared_ptr<PluginInsert> pi)
|
ProcessorBox::generate_processor_title (boost::shared_ptr<PluginInsert> pi)
|
||||||
{
|
{
|
||||||
string maker = pi->plugin()->maker() ? pi->plugin()->maker() : "";
|
string maker = pi->plugin()->maker() ? pi->plugin()->maker() : "";
|
||||||
|
|
@ -1409,6 +1444,6 @@ ProcessorBox::generate_processor_title (boost::shared_ptr<PluginInsert> pi)
|
||||||
maker += " ...";
|
maker += " ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
return string_compose(_("%1: %2 (by %3)"), _route->name(), pi->name(), maker);
|
return string_compose(_("%1: %2 (by %3)"), _route->name(), pi->name(), maker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,10 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
|
||||||
void clear_processors ();
|
void clear_processors ();
|
||||||
void rename_processors ();
|
void rename_processors ();
|
||||||
|
|
||||||
|
typedef vector<boost::shared_ptr<ARDOUR::Processor> > ProcSelection;
|
||||||
|
|
||||||
void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<ARDOUR::Processor>));
|
void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<ARDOUR::Processor>));
|
||||||
void get_selected_processors (vector<boost::shared_ptr<ARDOUR::Processor> >&);
|
void get_selected_processors (ProcSelection&);
|
||||||
|
|
||||||
static Glib::RefPtr<Gtk::Action> paste_action;
|
static Glib::RefPtr<Gtk::Action> paste_action;
|
||||||
void paste_processor_state (const XMLNodeList&);
|
void paste_processor_state (const XMLNodeList&);
|
||||||
|
|
|
||||||
|
|
@ -1104,8 +1104,6 @@ TimeAxisView::compute_controls_size_info ()
|
||||||
two_row_table.show_all ();
|
two_row_table.show_all ();
|
||||||
req = two_row_table.size_request ();
|
req = two_row_table.size_request ();
|
||||||
|
|
||||||
cerr << "Normal height is " << req.height << " + " << extra_height << endl;
|
|
||||||
|
|
||||||
// height required to show all normal buttons
|
// height required to show all normal buttons
|
||||||
|
|
||||||
hNormal = /*req.height*/ 48 + extra_height;
|
hNormal = /*req.height*/ 48 + extra_height;
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ UIConfiguration::load_defaults ()
|
||||||
|
|
||||||
string rcfile = default_ui_rc_file.to_string();
|
string rcfile = default_ui_rc_file.to_string();
|
||||||
|
|
||||||
cerr << string_compose (_("loading default ui configuration file %1"), rcfile) << endl;
|
cerr << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
|
||||||
|
|
||||||
if (!tree.read (rcfile.c_str())) {
|
if (!tree.read (rcfile.c_str())) {
|
||||||
error << string_compose(_("Ardour: cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
|
error << string_compose(_("Ardour: cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
|
||||||
|
|
@ -109,7 +109,7 @@ UIConfiguration::load_state ()
|
||||||
|
|
||||||
string rcfile = default_ui_rc_file.to_string();
|
string rcfile = default_ui_rc_file.to_string();
|
||||||
|
|
||||||
cerr << string_compose (_("loading default ui configuration file %1"), rcfile) << endl;
|
cerr << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
|
||||||
|
|
||||||
if (!tree.read (rcfile.c_str())) {
|
if (!tree.read (rcfile.c_str())) {
|
||||||
error << string_compose(_("Ardour: cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
|
error << string_compose(_("Ardour: cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
|
||||||
|
|
@ -132,7 +132,7 @@ UIConfiguration::load_state ()
|
||||||
|
|
||||||
string rcfile = user_ui_rc_file.to_string();
|
string rcfile = user_ui_rc_file.to_string();
|
||||||
|
|
||||||
cerr << string_compose (_("loading user ui configuration file %1"), rcfile) << endl;
|
cerr << string_compose (_("Loading user ui configuration file %1"), rcfile) << endl;
|
||||||
|
|
||||||
if (!tree.read (rcfile)) {
|
if (!tree.read (rcfile)) {
|
||||||
error << string_compose(_("Ardour: cannot read ui configuration file \"%1\""), rcfile) << endmsg;
|
error << string_compose(_("Ardour: cannot read ui configuration file \"%1\""), rcfile) << endmsg;
|
||||||
|
|
|
||||||
|
|
@ -20,23 +20,123 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "ardour/amp.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/buffer_set.h"
|
|
||||||
#include "ardour/audio_buffer.h"
|
#include "ardour/audio_buffer.h"
|
||||||
|
#include "ardour/buffer_set.h"
|
||||||
|
#include "ardour/configuration.h"
|
||||||
|
#include "ardour/io.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
Amp::Amp(Session& s, IO& io)
|
||||||
|
: Processor(s, "Amp")
|
||||||
|
, _io(io)
|
||||||
|
, _mute(false)
|
||||||
|
, _apply_gain(true)
|
||||||
|
, _apply_gain_automation(false)
|
||||||
|
, _current_gain(1.0)
|
||||||
|
, _desired_gain(1.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||||
|
{
|
||||||
|
out = in;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Amp::configure_io (ChanCount in, ChanCount out)
|
||||||
|
{
|
||||||
|
if (out != in) { // always 1:1
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Processor::configure_io (in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Amp::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
||||||
|
{
|
||||||
|
gain_t* gab = _session.gain_automation_buffer();
|
||||||
|
|
||||||
|
if (_mute && !bufs.is_silent()) {
|
||||||
|
Amp::apply_gain (bufs, nframes, _current_mute_gain, _desired_mute_gain, false);
|
||||||
|
if (_desired_mute_gain == 0.0f) {
|
||||||
|
bufs.is_silent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_apply_gain) {
|
||||||
|
|
||||||
|
if (_apply_gain_automation) {
|
||||||
|
|
||||||
|
if (_io.phase_invert()) {
|
||||||
|
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
|
||||||
|
Sample* const sp = i->data();
|
||||||
|
for (nframes_t nx = 0; nx < nframes; ++nx) {
|
||||||
|
sp[nx] *= -gab[nx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
|
||||||
|
Sample* const sp = i->data();
|
||||||
|
for (nframes_t nx = 0; nx < nframes; ++nx) {
|
||||||
|
sp[nx] *= gab[nx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { /* manual (scalar) gain */
|
||||||
|
|
||||||
|
if (_current_gain != _desired_gain) {
|
||||||
|
|
||||||
|
Amp::apply_gain (bufs, nframes, _current_gain, _desired_gain, _io.phase_invert());
|
||||||
|
_current_gain = _desired_gain;
|
||||||
|
|
||||||
|
} else if (_current_gain != 0.0f && (_io.phase_invert() || _current_gain != 1.0f)) {
|
||||||
|
|
||||||
|
/* no need to interpolate current gain value,
|
||||||
|
but its non-unity, so apply it. if the gain
|
||||||
|
is zero, do nothing because we'll ship silence
|
||||||
|
below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gain_t this_gain;
|
||||||
|
|
||||||
|
if (_io.phase_invert()) {
|
||||||
|
this_gain = -_current_gain;
|
||||||
|
} else {
|
||||||
|
this_gain = _current_gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
|
||||||
|
Sample* const sp = i->data();
|
||||||
|
apply_gain_to_buffer(sp, nframes, this_gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (_current_gain == 0.0f) {
|
||||||
|
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
|
||||||
|
i->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Apply a declicked gain to the audio buffers of @a bufs */
|
/** Apply a declicked gain to the audio buffers of @a bufs */
|
||||||
void
|
void
|
||||||
Amp::run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity)
|
Amp::apply_gain (BufferSet& bufs, nframes_t nframes,
|
||||||
|
gain_t initial, gain_t target, bool invert_polarity)
|
||||||
{
|
{
|
||||||
if (nframes == 0)
|
if (nframes == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (bufs.count().n_audio() == 0)
|
if (bufs.count().n_audio() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes);
|
|
||||||
|
|
||||||
// if we don't need to declick, defer to apply_simple_gain
|
// if we don't need to declick, defer to apply_simple_gain
|
||||||
if (initial == target) {
|
if (initial == target) {
|
||||||
|
|
@ -98,5 +198,18 @@ Amp::apply_simple_gain (BufferSet& bufs, nframes_t nframes, gain_t target)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
Amp::state (bool full_state)
|
||||||
|
{
|
||||||
|
return get_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
Amp::get_state()
|
||||||
|
{
|
||||||
|
XMLNode* node = new XMLNode(state_node_name);
|
||||||
|
node->add_property("type", "amp");
|
||||||
|
return *node;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,63 @@
|
||||||
#define __ardour_amp_h__
|
#define __ardour_amp_h__
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
#include "ardour/chan_count.h"
|
||||||
|
#include "ardour/processor.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
class BufferSet;
|
class BufferSet;
|
||||||
|
class IO;
|
||||||
|
|
||||||
|
|
||||||
/** Applies a declick operation to all audio inputs, passing the same number of
|
/** Applies a declick operation to all audio inputs, passing the same number of
|
||||||
* audio outputs, and passing through any other types unchanged.
|
* audio outputs, and passing through any other types unchanged.
|
||||||
*
|
|
||||||
* FIXME: make this a Processor.
|
|
||||||
*/
|
*/
|
||||||
class Amp {
|
class Amp : public Processor {
|
||||||
public:
|
public:
|
||||||
static void run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity);
|
Amp(Session& s, IO& io);
|
||||||
|
|
||||||
|
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||||
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
|
void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
|
||||||
|
|
||||||
|
bool apply_gain() const { return _apply_gain; }
|
||||||
|
void apply_gain(bool yn) { _apply_gain = yn; }
|
||||||
|
|
||||||
|
bool apply_gain_automation() const { return _apply_gain_automation; }
|
||||||
|
void apply_gain_automation(bool yn) { _apply_gain_automation = yn; }
|
||||||
|
|
||||||
|
void muute(bool yn) { _mute = yn; }
|
||||||
|
|
||||||
|
void set_gain(float current, float desired) {
|
||||||
|
_current_gain = current;
|
||||||
|
_desired_gain = desired;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_mute(bool yn, float current=1.0, float desired=0.0) {
|
||||||
|
_mute = yn;
|
||||||
|
_current_mute_gain = current;
|
||||||
|
_desired_mute_gain = desired;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode& state (bool full);
|
||||||
|
XMLNode& get_state();
|
||||||
|
|
||||||
|
static void apply_gain (BufferSet& bufs, nframes_t nframes,
|
||||||
|
gain_t initial, gain_t target, bool invert_polarity);
|
||||||
|
|
||||||
static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target);
|
static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IO& _io;
|
||||||
|
bool _mute;
|
||||||
|
bool _apply_gain;
|
||||||
|
bool _apply_gain_automation;
|
||||||
|
float _current_gain;
|
||||||
|
float _desired_gain;
|
||||||
|
float _current_mute_gain;
|
||||||
|
float _desired_mute_gain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,6 @@ class AudioTrack : public Track
|
||||||
|
|
||||||
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
int declick, bool can_record, bool rec_monitors_input);
|
int declick, bool can_record, bool rec_monitors_input);
|
||||||
|
|
||||||
int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool state_changing, bool can_record, bool rec_monitors_input);
|
|
||||||
|
|
||||||
int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool can_record, bool rec_monitors_input);
|
|
||||||
|
|
||||||
boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
|
boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,10 @@ public:
|
||||||
const ChanCount& count() const { return _count; }
|
const ChanCount& count() const { return _count; }
|
||||||
ChanCount& count() { return _count; }
|
ChanCount& count() { return _count; }
|
||||||
|
|
||||||
void set_count(const ChanCount& count) { _count = count; }
|
void is_silent(bool yn) { _is_silent = yn; }
|
||||||
|
bool is_silent() const { return _is_silent; }
|
||||||
|
|
||||||
|
void set_count(const ChanCount& count) { assert(count <= _available); _count = count; }
|
||||||
|
|
||||||
size_t buffer_capacity(DataType type) const;
|
size_t buffer_capacity(DataType type) const;
|
||||||
|
|
||||||
|
|
@ -161,6 +164,9 @@ private:
|
||||||
|
|
||||||
/// Whether we (don't) 'own' the contained buffers (otherwise we mirror a PortSet)
|
/// Whether we (don't) 'own' the contained buffers (otherwise we mirror a PortSet)
|
||||||
bool _is_mirror;
|
bool _is_mirror;
|
||||||
|
|
||||||
|
/// Whether the buffer set should be considered silent
|
||||||
|
bool _is_silent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "pbd/xml++.h"
|
||||||
#include "ardour/data_type.h"
|
#include "ardour/data_type.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
@ -35,6 +36,7 @@ namespace ARDOUR {
|
||||||
*/
|
*/
|
||||||
class ChanCount {
|
class ChanCount {
|
||||||
public:
|
public:
|
||||||
|
ChanCount(const XMLNode& node);
|
||||||
ChanCount() { reset(); }
|
ChanCount() { reset(); }
|
||||||
|
|
||||||
// Convenience constructor for making single-typed streams (stereo, mono, etc)
|
// Convenience constructor for making single-typed streams (stereo, mono, etc)
|
||||||
|
|
@ -104,6 +106,14 @@ public:
|
||||||
return ( (*this > other) || (*this == other) );
|
return ( (*this > other) || (*this == other) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ChanCount min(const ChanCount& a, const ChanCount& b) {
|
||||||
|
ChanCount ret;
|
||||||
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
|
ret.set(*t, std::min(a.get(*t), b.get(*t)));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static ChanCount max(const ChanCount& a, const ChanCount& b) {
|
static ChanCount max(const ChanCount& a, const ChanCount& b) {
|
||||||
ChanCount ret;
|
ChanCount ret;
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
|
|
@ -111,6 +121,8 @@ public:
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode* state(const std::string& name) const;
|
||||||
|
|
||||||
static const ChanCount INFINITE;
|
static const ChanCount INFINITE;
|
||||||
static const ChanCount ZERO;
|
static const ChanCount ZERO;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "ardour/data_type.h"
|
#include "ardour/data_type.h"
|
||||||
|
#include "ardour/chan_count.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
|
@ -36,47 +37,26 @@ namespace ARDOUR {
|
||||||
class ChanMapping {
|
class ChanMapping {
|
||||||
public:
|
public:
|
||||||
ChanMapping() {}
|
ChanMapping() {}
|
||||||
ChanMapping(ChanCount identity) {
|
ChanMapping(ARDOUR::ChanCount identity);
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
|
||||||
for (size_t i = 0; i <= identity.get(*t); ++i)
|
uint32_t get(DataType t, uint32_t from);
|
||||||
set(*t, i, i);
|
void set(DataType t, uint32_t from, uint32_t to);
|
||||||
}
|
void offset_from(DataType t, int32_t delta);
|
||||||
}
|
void offset_to(DataType t, int32_t delta);
|
||||||
|
|
||||||
uint32_t get(DataType t, uint32_t from) {
|
|
||||||
Mappings::iterator tm = _mappings.find(t);
|
|
||||||
assert(tm != _mappings.end());
|
|
||||||
TypeMapping::iterator m = tm->second.find(from);
|
|
||||||
assert(m != tm->second.end());
|
|
||||||
return m->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(DataType t, uint32_t from, uint32_t to) {
|
|
||||||
Mappings::iterator tm = _mappings.find(t);
|
|
||||||
if (tm == _mappings.end()) {
|
|
||||||
tm = _mappings.insert(std::make_pair(t, TypeMapping())).first;
|
|
||||||
}
|
|
||||||
tm->second.insert(std::make_pair(from, to));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Increase the 'to' field of every mapping for type @a t by @a delta */
|
|
||||||
void offset(DataType t, uint32_t delta) {
|
|
||||||
Mappings::iterator tm = _mappings.find(t);
|
|
||||||
if (tm != _mappings.end()) {
|
|
||||||
for (TypeMapping::iterator m = tm->second.begin(); m != tm->second.end(); ++m) {
|
|
||||||
m->second += delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::map<uint32_t, uint32_t> TypeMapping;
|
typedef std::map<uint32_t, uint32_t> TypeMapping;
|
||||||
typedef std::map<DataType, TypeMapping> Mappings;
|
typedef std::map<DataType, TypeMapping> Mappings;
|
||||||
|
|
||||||
|
Mappings mappings() { return _mappings; }
|
||||||
|
const Mappings mappings() const { return _mappings; }
|
||||||
|
|
||||||
|
private:
|
||||||
Mappings _mappings;
|
Mappings _mappings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& m);
|
||||||
|
|
||||||
#endif // __ardour_chan_mapping_h__
|
#endif // __ardour_chan_mapping_h__
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,11 @@ namespace ARDOUR {
|
||||||
|
|
||||||
class ClickIO : public IO
|
class ClickIO : public IO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClickIO (Session& s, const string& name,
|
ClickIO (Session& s, const string& name) : IO (s, name) {}
|
||||||
|
|
||||||
int input_min = -1, int input_max = -1,
|
|
||||||
|
|
||||||
int output_min = -1, int output_max = -1)
|
|
||||||
: IO (s, name, input_min, input_max, output_min, output_max) {}
|
|
||||||
|
|
||||||
~ClickIO() {}
|
~ClickIO() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t pans_required () const { return 1; }
|
uint32_t pans_required () const { return 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
55
libs/ardour/ardour/control_outputs.h
Normal file
55
libs/ardour/ardour/control_outputs.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
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_control_outputs_h__
|
||||||
|
#define __ardour_control_outputs_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "ardour/types.h"
|
||||||
|
#include "ardour/chan_count.h"
|
||||||
|
#include "ardour/io_processor.h"
|
||||||
|
|
||||||
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
class BufferSet;
|
||||||
|
class IO;
|
||||||
|
|
||||||
|
class ControlOutputs : public IOProcessor {
|
||||||
|
public:
|
||||||
|
ControlOutputs(Session& s, IO* io);
|
||||||
|
|
||||||
|
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||||
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
|
void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
|
||||||
|
|
||||||
|
bool deliver() const { return _deliver; }
|
||||||
|
void deliver(bool yn) { _deliver = yn; }
|
||||||
|
|
||||||
|
XMLNode& state (bool full);
|
||||||
|
XMLNode& get_state();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _deliver;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ARDOUR
|
||||||
|
|
||||||
|
#endif // __ardour_control_outputs_h__
|
||||||
|
|
||||||
|
|
@ -52,32 +52,31 @@ class XMLNode;
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
class Session;
|
class Amp;
|
||||||
class AudioEngine;
|
class AudioEngine;
|
||||||
class UserBundle;
|
class AudioPort;
|
||||||
|
class BufferSet;
|
||||||
class Bundle;
|
class Bundle;
|
||||||
|
class MidiPort;
|
||||||
class Panner;
|
class Panner;
|
||||||
class PeakMeter;
|
class PeakMeter;
|
||||||
class Port;
|
class Port;
|
||||||
class AudioPort;
|
class Session;
|
||||||
class MidiPort;
|
class UserBundle;
|
||||||
class BufferSet;
|
|
||||||
|
|
||||||
/** A collection of input and output ports with connections.
|
/** A collection of input and output ports with connections.
|
||||||
*
|
*
|
||||||
* An IO can contain ports of varying types, making routes/inserts/etc with
|
* An IO can contain ports of varying types, making routes/inserts/etc with
|
||||||
* varied combinations of types (eg MIDI and audio) possible.
|
* varied combinations of types (eg MIDI and audio) possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class IO : public SessionObject, public AutomatableControls, public Latent
|
class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const string state_node_name;
|
static const string state_node_name;
|
||||||
|
|
||||||
IO (Session&, const string& name,
|
IO (Session&, const string& name, DataType default_type = DataType::AUDIO,
|
||||||
int input_min = -1, int input_max = -1,
|
ChanCount in_min=ChanCount::ZERO, ChanCount in_max=ChanCount::INFINITE,
|
||||||
int output_min = -1, int output_max = -1,
|
ChanCount out_min=ChanCount::ZERO, ChanCount out_max=ChanCount::INFINITE);
|
||||||
DataType default_type = DataType::AUDIO);
|
|
||||||
|
|
||||||
IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
|
IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
|
||||||
|
|
||||||
|
|
@ -109,7 +108,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
|
|
||||||
BufferSet& output_buffers() { return *_output_buffers; }
|
BufferSet& output_buffers() { return *_output_buffers; }
|
||||||
|
|
||||||
gain_t gain () const { return _desired_gain; }
|
gain_t gain () const { return _gain_control->user_float(); }
|
||||||
virtual gain_t effective_gain () const;
|
virtual gain_t effective_gain () const;
|
||||||
|
|
||||||
void set_denormal_protection (bool yn, void *src);
|
void set_denormal_protection (bool yn, void *src);
|
||||||
|
|
@ -118,11 +117,16 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
void set_phase_invert (bool yn, void *src);
|
void set_phase_invert (bool yn, void *src);
|
||||||
bool phase_invert() const { return _phase_invert; }
|
bool phase_invert() const { return _phase_invert; }
|
||||||
|
|
||||||
Panner& panner() { return *_panner; }
|
|
||||||
PeakMeter& peak_meter() { return *_meter; }
|
|
||||||
const Panner& panner() const { return *_panner; }
|
|
||||||
void reset_panner ();
|
void reset_panner ();
|
||||||
|
|
||||||
|
boost::shared_ptr<Amp> amp() const { return _amp; }
|
||||||
|
|
||||||
|
PeakMeter& peak_meter() { return *_meter.get(); }
|
||||||
|
const PeakMeter& peak_meter() const { return *_meter.get(); }
|
||||||
|
boost::shared_ptr<PeakMeter> shared_peak_meter() const { return _meter; }
|
||||||
|
|
||||||
|
boost::shared_ptr<Panner> panner() const { return _panner; }
|
||||||
|
|
||||||
int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
|
int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
|
||||||
|
|
||||||
int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *);
|
int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *);
|
||||||
|
|
@ -133,8 +137,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
BundleList bundles_connected_to_inputs ();
|
BundleList bundles_connected_to_inputs ();
|
||||||
BundleList bundles_connected_to_outputs ();
|
BundleList bundles_connected_to_outputs ();
|
||||||
|
|
||||||
boost::shared_ptr<Bundle> bundle_for_inputs () { return _bundle_for_inputs; }
|
boost::shared_ptr<Bundle> bundle_for_inputs () { return _bundle_for_inputs; }
|
||||||
boost::shared_ptr<Bundle> bundle_for_outputs () { return _bundle_for_outputs; }
|
boost::shared_ptr<Bundle> bundle_for_outputs () { return _bundle_for_outputs; }
|
||||||
|
|
||||||
int add_input_port (string source, void *src, DataType type = DataType::NIL);
|
int add_input_port (string source, void *src, DataType type = DataType::NIL);
|
||||||
int add_output_port (string destination, void *src, DataType type = DataType::NIL);
|
int add_output_port (string destination, void *src, DataType type = DataType::NIL);
|
||||||
|
|
@ -271,22 +275,24 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
mutable Glib::Mutex io_lock;
|
mutable Glib::Mutex io_lock;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Panner* _panner;
|
|
||||||
BufferSet* _output_buffers; //< Set directly to output port buffers
|
BufferSet* _output_buffers; //< Set directly to output port buffers
|
||||||
bool _active;
|
bool _active;
|
||||||
gain_t _gain;
|
gain_t _gain;
|
||||||
gain_t _effective_gain;
|
|
||||||
gain_t _desired_gain;
|
|
||||||
Glib::Mutex declick_lock;
|
Glib::Mutex declick_lock;
|
||||||
PortSet _outputs;
|
PortSet _outputs;
|
||||||
PortSet _inputs;
|
PortSet _inputs;
|
||||||
PeakMeter* _meter;
|
|
||||||
bool no_panner_reset;
|
bool no_panner_reset;
|
||||||
bool _phase_invert;
|
bool _phase_invert;
|
||||||
bool _denormal_protection;
|
bool _denormal_protection;
|
||||||
XMLNode* deferred_state;
|
XMLNode* deferred_state;
|
||||||
DataType _default_type;
|
DataType _default_type;
|
||||||
nframes_t _output_offset;
|
nframes_t _output_offset;
|
||||||
|
ChanCount _configured_inputs;
|
||||||
|
ChanCount _configured_outputs;
|
||||||
|
|
||||||
|
boost::shared_ptr<Amp> _amp;
|
||||||
|
boost::shared_ptr<PeakMeter> _meter;
|
||||||
|
boost::shared_ptr<Panner> _panner;
|
||||||
|
|
||||||
virtual void prepare_inputs (nframes_t nframes);
|
virtual void prepare_inputs (nframes_t nframes);
|
||||||
virtual void flush_outputs (nframes_t nframes);
|
virtual void flush_outputs (nframes_t nframes);
|
||||||
|
|
@ -301,8 +307,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
virtual void set_gain (gain_t g, void *src);
|
virtual void set_gain (gain_t g, void *src);
|
||||||
void inc_gain (gain_t delta, void *src);
|
void inc_gain (gain_t delta, void *src);
|
||||||
|
|
||||||
bool apply_gain_automation;
|
|
||||||
|
|
||||||
virtual int load_automation (std::string path);
|
virtual int load_automation (std::string path);
|
||||||
|
|
||||||
/* AudioTrack::deprecated_use_diskstream_connections() needs these */
|
/* AudioTrack::deprecated_use_diskstream_connections() needs these */
|
||||||
|
|
@ -361,6 +365,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
||||||
|
|
||||||
void bundle_changed (Bundle::Change);
|
void bundle_changed (Bundle::Change);
|
||||||
|
|
||||||
|
int get_port_counts (const XMLNode& node);
|
||||||
int create_ports (const XMLNode&);
|
int create_ports (const XMLNode&);
|
||||||
int make_connections (const XMLNode&);
|
int make_connections (const XMLNode&);
|
||||||
boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
|
boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,9 @@ class IO;
|
||||||
class IOProcessor : public Processor
|
class IOProcessor : public Processor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IOProcessor (Session&, const string& name, Placement,
|
IOProcessor (Session&, const string& proc_name, const string io_name="",
|
||||||
int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1,
|
ARDOUR::DataType default_type = DataType::AUDIO);
|
||||||
|
IOProcessor (Session&, IO* io, const string& proc_name,
|
||||||
ARDOUR::DataType default_type = DataType::AUDIO);
|
ARDOUR::DataType default_type = DataType::AUDIO);
|
||||||
virtual ~IOProcessor ();
|
virtual ~IOProcessor ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,12 @@ class Session;
|
||||||
*/
|
*/
|
||||||
class PeakMeter : public Processor {
|
class PeakMeter : public Processor {
|
||||||
public:
|
public:
|
||||||
PeakMeter(Session& s) : Processor(s, "meter", PreFader) {}
|
PeakMeter(Session& s) : Processor(s, "Meter") {}
|
||||||
|
|
||||||
void reset ();
|
void reset ();
|
||||||
void reset_max ();
|
void reset_max ();
|
||||||
|
|
||||||
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
|
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||||
bool configure_io (ChanCount in, ChanCount out);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
/** Compute peaks */
|
/** Compute peaks */
|
||||||
|
|
@ -61,11 +61,11 @@ public:
|
||||||
return minus_infinity();
|
return minus_infinity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode& state (bool full);
|
||||||
|
XMLNode& get_state();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* disallow copy construction */
|
|
||||||
PeakMeter (PeakMeter const &);
|
|
||||||
|
|
||||||
friend class IO;
|
friend class IO;
|
||||||
void meter();
|
void meter();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,17 +41,6 @@ public:
|
||||||
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
int declick, bool can_record, bool rec_monitors_input);
|
int declick, bool can_record, bool rec_monitors_input);
|
||||||
|
|
||||||
int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool state_changing, bool can_record, bool rec_monitors_input);
|
|
||||||
|
|
||||||
int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool can_record, bool rec_monitors_input);
|
|
||||||
|
|
||||||
void process_output_buffers (BufferSet& bufs,
|
|
||||||
nframes_t start_frame, nframes_t end_frame,
|
|
||||||
nframes_t nframes, bool with_redirects, int declick,
|
|
||||||
bool meter);
|
|
||||||
|
|
||||||
boost::shared_ptr<MidiDiskstream> midi_diskstream() const;
|
boost::shared_ptr<MidiDiskstream> midi_diskstream() const;
|
||||||
|
|
||||||
int use_diskstream (string name);
|
int use_diskstream (string name);
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ class Panner : public Processor
|
||||||
virtual ~Panner ();
|
virtual ~Panner ();
|
||||||
|
|
||||||
void clear_panners ();
|
void clear_panners ();
|
||||||
|
bool empty() const { return _streampanners.empty(); }
|
||||||
|
|
||||||
/// The fundamental Panner function
|
/// The fundamental Panner function
|
||||||
void set_automation_state (AutoState);
|
void set_automation_state (AutoState);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class Plugin;
|
||||||
class PluginInsert : public Processor
|
class PluginInsert : public Processor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PluginInsert (Session&, boost::shared_ptr<Plugin>, Placement);
|
PluginInsert (Session&, boost::shared_ptr<Plugin>);
|
||||||
PluginInsert (Session&, const XMLNode&);
|
PluginInsert (Session&, const XMLNode&);
|
||||||
~PluginInsert ();
|
~PluginInsert ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class Session;
|
||||||
class PortInsert : public IOProcessor
|
class PortInsert : public IOProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PortInsert (Session&, Placement);
|
PortInsert (Session&);
|
||||||
PortInsert (Session&, const XMLNode&);
|
PortInsert (Session&, const XMLNode&);
|
||||||
~PortInsert ();
|
~PortInsert ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,16 +49,21 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
|
||||||
public:
|
public:
|
||||||
static const string state_node_name;
|
static const string state_node_name;
|
||||||
|
|
||||||
Processor(Session&, const string& name, Placement p); // TODO: remove placement (use sort key)
|
Processor(Session&, const string& name);
|
||||||
|
|
||||||
virtual ~Processor() { }
|
virtual ~Processor() { }
|
||||||
|
|
||||||
|
/** Configuration of a processor on a bus
|
||||||
|
* (i.e. how to apply to a BufferSet)
|
||||||
|
*/
|
||||||
|
struct Mapping {
|
||||||
|
ChanCount in;
|
||||||
|
ChanCount out;
|
||||||
|
};
|
||||||
|
|
||||||
uint32_t sort_key() const { return _sort_key; }
|
uint32_t sort_key() const { return _sort_key; }
|
||||||
void set_sort_key (uint32_t key);
|
void set_sort_key (uint32_t key);
|
||||||
|
|
||||||
Placement placement() const { return _placement; }
|
|
||||||
void set_placement (Placement);
|
|
||||||
|
|
||||||
bool active () const { return _active; }
|
bool active () const { return _active; }
|
||||||
|
|
||||||
bool get_next_ab_is_active () const { return _next_ab_is_active; }
|
bool get_next_ab_is_active () const { return _next_ab_is_active; }
|
||||||
|
|
@ -108,7 +113,6 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
|
||||||
static sigc::signal<void,Processor*> ProcessorCreated;
|
static sigc::signal<void,Processor*> ProcessorCreated;
|
||||||
|
|
||||||
sigc::signal<void> ActiveChanged;
|
sigc::signal<void> ActiveChanged;
|
||||||
sigc::signal<void> PlacementChanged;
|
|
||||||
sigc::signal<void,ChanCount,ChanCount> ConfigurationChanged;
|
sigc::signal<void,ChanCount,ChanCount> ConfigurationChanged;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -118,9 +122,9 @@ protected:
|
||||||
bool _configured;
|
bool _configured;
|
||||||
ChanCount _configured_input;
|
ChanCount _configured_input;
|
||||||
ChanCount _configured_output;
|
ChanCount _configured_output;
|
||||||
Placement _placement;
|
|
||||||
uint32_t _sort_key;
|
uint32_t _sort_key;
|
||||||
void* _gui; /* generic, we don't know or care what this is */
|
void* _gui; /* generic, we don't know or care what this is */
|
||||||
|
Mapping _mapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,12 @@
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
class Processor;
|
class Amp;
|
||||||
|
class ControlOutputs;
|
||||||
class IOProcessor;
|
class IOProcessor;
|
||||||
class Send;
|
class Processor;
|
||||||
class RouteGroup;
|
class RouteGroup;
|
||||||
|
class Send;
|
||||||
|
|
||||||
enum mute_type {
|
enum mute_type {
|
||||||
PRE_FADER = 0x1,
|
PRE_FADER = 0x1,
|
||||||
|
|
@ -70,8 +72,10 @@ class Route : public IO
|
||||||
ControlOut = 0x4
|
ControlOut = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max,
|
Route (Session&, std::string name, Flag flags = Flag(0),
|
||||||
Flag flags = Flag(0), DataType default_type = DataType::AUDIO);
|
DataType default_type = DataType::AUDIO,
|
||||||
|
ChanCount in=ChanCount::ZERO, ChanCount out=ChanCount::ZERO);
|
||||||
|
|
||||||
Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
|
Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
|
||||||
virtual ~Route();
|
virtual ~Route();
|
||||||
|
|
||||||
|
|
@ -149,6 +153,15 @@ class Route : public IO
|
||||||
method (boost::weak_ptr<Processor> (*i));
|
method (boost::weak_ptr<Processor> (*i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void foreach_processor (Placement p, sigc::slot<void, boost::weak_ptr<Processor> > method) {
|
||||||
|
Glib::RWLock::ReaderLock lm (_processor_lock);
|
||||||
|
ProcessorList::iterator start, end;
|
||||||
|
placement_range(p, start, end);
|
||||||
|
for (ProcessorList::iterator i = start; i != end; ++i) {
|
||||||
|
method (boost::weak_ptr<Processor> (*i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Processor> nth_processor (uint32_t n) {
|
boost::shared_ptr<Processor> nth_processor (uint32_t n) {
|
||||||
Glib::RWLock::ReaderLock lm (_processor_lock);
|
Glib::RWLock::ReaderLock lm (_processor_lock);
|
||||||
|
|
@ -170,12 +183,12 @@ class Route : public IO
|
||||||
struct ProcessorStreams {
|
struct ProcessorStreams {
|
||||||
ProcessorStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {}
|
ProcessorStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {}
|
||||||
|
|
||||||
size_t index; ///< Index of processor where configuration failed
|
uint32_t index; ///< Index of processor where configuration failed
|
||||||
ChanCount count; ///< Input requested of processor
|
ChanCount count; ///< Input requested of processor
|
||||||
};
|
};
|
||||||
|
|
||||||
int add_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
|
int add_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0, ProcessorList::iterator* iter=0, Placement=PreFader);
|
||||||
int add_processors (const ProcessorList&, ProcessorStreams* err = 0);
|
int add_processors (const ProcessorList&, ProcessorStreams* err = 0, Placement placement=PreFader);
|
||||||
int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
|
int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
|
||||||
int sort_processors (ProcessorStreams* err = 0);
|
int sort_processors (ProcessorStreams* err = 0);
|
||||||
void disable_processors (Placement);
|
void disable_processors (Placement);
|
||||||
|
|
@ -226,7 +239,7 @@ class Route : public IO
|
||||||
sigc::signal<void,void*> SelectedChanged;
|
sigc::signal<void,void*> SelectedChanged;
|
||||||
|
|
||||||
int set_control_outs (const vector<std::string>& ports);
|
int set_control_outs (const vector<std::string>& ports);
|
||||||
IO* control_outs() { return _control_outs; }
|
boost::shared_ptr<ControlOutputs> control_outs() { return _control_outs; }
|
||||||
|
|
||||||
bool feeds (boost::shared_ptr<Route>);
|
bool feeds (boost::shared_ptr<Route>);
|
||||||
std::set<boost::shared_ptr<Route> > fed_by;
|
std::set<boost::shared_ptr<Route> > fed_by;
|
||||||
|
|
@ -276,12 +289,11 @@ class Route : public IO
|
||||||
nframes_t check_initial_delay (nframes_t, nframes_t&);
|
nframes_t check_initial_delay (nframes_t, nframes_t&);
|
||||||
|
|
||||||
void passthru (nframes_t start_frame, nframes_t end_frame,
|
void passthru (nframes_t start_frame, nframes_t end_frame,
|
||||||
nframes_t nframes, int declick, bool meter_inputs);
|
nframes_t nframes, int declick);
|
||||||
|
|
||||||
virtual void process_output_buffers (BufferSet& bufs,
|
virtual void process_output_buffers (BufferSet& bufs,
|
||||||
nframes_t start_frame, nframes_t end_frame,
|
nframes_t start_frame, nframes_t end_frame,
|
||||||
nframes_t nframes, bool with_processors, int declick,
|
nframes_t nframes, bool with_processors, int declick);
|
||||||
bool meter);
|
|
||||||
|
|
||||||
Flag _flags;
|
Flag _flags;
|
||||||
int _pending_declick;
|
int _pending_declick;
|
||||||
|
|
@ -296,8 +308,7 @@ class Route : public IO
|
||||||
nframes_t _roll_delay;
|
nframes_t _roll_delay;
|
||||||
ProcessorList _processors;
|
ProcessorList _processors;
|
||||||
Glib::RWLock _processor_lock;
|
Glib::RWLock _processor_lock;
|
||||||
IO *_control_outs;
|
boost::shared_ptr<ControlOutputs> _control_outs;
|
||||||
Glib::Mutex _control_outs_lock;
|
|
||||||
RouteGroup *_edit_group;
|
RouteGroup *_edit_group;
|
||||||
RouteGroup *_mix_group;
|
RouteGroup *_mix_group;
|
||||||
std::string _comment;
|
std::string _comment;
|
||||||
|
|
@ -326,8 +337,7 @@ class Route : public IO
|
||||||
virtual XMLNode& state(bool);
|
virtual XMLNode& state(bool);
|
||||||
|
|
||||||
void passthru_silence (nframes_t start_frame, nframes_t end_frame,
|
void passthru_silence (nframes_t start_frame, nframes_t end_frame,
|
||||||
nframes_t nframes, int declick,
|
nframes_t nframes, int declick);
|
||||||
bool meter);
|
|
||||||
|
|
||||||
void silence (nframes_t nframes);
|
void silence (nframes_t nframes);
|
||||||
|
|
||||||
|
|
@ -361,24 +371,18 @@ class Route : public IO
|
||||||
void input_change_handler (IOChange, void *src);
|
void input_change_handler (IOChange, void *src);
|
||||||
void output_change_handler (IOChange, void *src);
|
void output_change_handler (IOChange, void *src);
|
||||||
|
|
||||||
int reset_processor_counts (ProcessorStreams*); /* locked */
|
bool _in_configure_processors;
|
||||||
int _reset_processor_counts (ProcessorStreams*); /* unlocked */
|
|
||||||
|
|
||||||
/** processor I/O channels and plugin count handling */
|
int configure_processors (ProcessorStreams*);
|
||||||
struct ProcessorCount {
|
int configure_processors_unlocked (ProcessorStreams*);
|
||||||
boost::shared_ptr<ARDOUR::Processor> processor;
|
|
||||||
ChanCount in;
|
|
||||||
ChanCount out;
|
|
||||||
|
|
||||||
ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t apply_some_processor_counts (std::list<ProcessorCount>& iclist);
|
|
||||||
bool check_some_processor_counts (std::list<ProcessorCount>& iclist,
|
|
||||||
ChanCount required_inputs, ProcessorStreams* err_streams);
|
|
||||||
|
|
||||||
void set_deferred_state ();
|
void set_deferred_state ();
|
||||||
void add_processor_from_xml (const XMLNode&);
|
bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator* iter=0);
|
||||||
|
|
||||||
|
void placement_range(
|
||||||
|
Placement p,
|
||||||
|
ProcessorList::iterator& start,
|
||||||
|
ProcessorList::iterator& end);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace ARDOUR {
|
||||||
class Send : public IOProcessor
|
class Send : public IOProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Send (Session&, Placement);
|
Send (Session&);
|
||||||
Send (Session&, const XMLNode&);
|
Send (Session&, const XMLNode&);
|
||||||
virtual ~Send ();
|
virtual ~Send ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
||||||
void set_clean ();
|
void set_clean ();
|
||||||
bool dirty() const { return _state_of_the_state & Dirty; }
|
bool dirty() const { return _state_of_the_state & Dirty; }
|
||||||
void set_deletion_in_progress ();
|
void set_deletion_in_progress ();
|
||||||
|
void clear_deletion_in_progress ();
|
||||||
bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
|
bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
|
||||||
sigc::signal<void> DirtyChanged;
|
sigc::signal<void> DirtyChanged;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,16 +44,16 @@ class Track : public Route
|
||||||
virtual int set_mode (TrackMode m) { return false; }
|
virtual int set_mode (TrackMode m) { return false; }
|
||||||
virtual bool can_use_mode (TrackMode m, bool& bounce_required) { return false; }
|
virtual bool can_use_mode (TrackMode m, bool& bounce_required) { return false; }
|
||||||
sigc::signal<void> TrackModeChanged;
|
sigc::signal<void> TrackModeChanged;
|
||||||
|
|
||||||
|
int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
|
bool state_changing, bool can_record, bool rec_monitors_input);
|
||||||
|
|
||||||
|
int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
|
bool can_record, bool rec_monitors_input);
|
||||||
|
|
||||||
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
int declick, bool can_record, bool rec_monitors_input) = 0;
|
int declick, bool can_record, bool rec_monitors_input) = 0;
|
||||||
|
|
||||||
virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool state_changing, bool can_record, bool rec_monitors_input) = 0;
|
|
||||||
|
|
||||||
virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool can_record, bool rec_monitors_input) = 0;
|
|
||||||
|
|
||||||
void toggle_monitor_input ();
|
void toggle_monitor_input ();
|
||||||
|
|
||||||
bool can_record();
|
bool can_record();
|
||||||
|
|
|
||||||
|
|
@ -2172,7 +2172,8 @@ AudioDiskstream::set_block_size (nframes_t nframes)
|
||||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||||
|
|
||||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
||||||
if ((*chan)->speed_buffer) delete [] (*chan)->speed_buffer;
|
if ((*chan)->speed_buffer)
|
||||||
|
delete [] (*chan)->speed_buffer;
|
||||||
(*chan)->speed_buffer = new Sample[speed_buffer_size];
|
(*chan)->speed_buffer = new Sample[speed_buffer_size];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2195,9 +2196,11 @@ AudioDiskstream::allocate_temporary_buffers ()
|
||||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||||
|
|
||||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
||||||
if ((*chan)->playback_wrap_buffer) delete [] (*chan)->playback_wrap_buffer;
|
if ((*chan)->playback_wrap_buffer)
|
||||||
|
delete [] (*chan)->playback_wrap_buffer;
|
||||||
(*chan)->playback_wrap_buffer = new Sample[required_wrap_size];
|
(*chan)->playback_wrap_buffer = new Sample[required_wrap_size];
|
||||||
if ((*chan)->capture_wrap_buffer) delete [] (*chan)->capture_wrap_buffer;
|
if ((*chan)->capture_wrap_buffer)
|
||||||
|
delete [] (*chan)->capture_wrap_buffer;
|
||||||
(*chan)->capture_wrap_buffer = new Sample[required_wrap_size];
|
(*chan)->capture_wrap_buffer = new Sample[required_wrap_size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2270,7 +2273,7 @@ int
|
||||||
AudioDiskstream::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many)
|
AudioDiskstream::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many)
|
||||||
{
|
{
|
||||||
while (how_many-- && !c->empty()) {
|
while (how_many-- && !c->empty()) {
|
||||||
delete c->back();
|
//delete c->back(); // FIXME: crash (thread safe with RCU?)
|
||||||
c->pop_back();
|
c->pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,22 +26,23 @@
|
||||||
|
|
||||||
#include "evoral/Curve.hpp"
|
#include "evoral/Curve.hpp"
|
||||||
|
|
||||||
#include "ardour/audio_track.h"
|
#include "ardour/amp.h"
|
||||||
|
#include "ardour/audio_buffer.h"
|
||||||
#include "ardour/audio_diskstream.h"
|
#include "ardour/audio_diskstream.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/audio_track.h"
|
||||||
#include "ardour/io_processor.h"
|
#include "ardour/audioplaylist.h"
|
||||||
#include "ardour/audioregion.h"
|
#include "ardour/audioregion.h"
|
||||||
#include "ardour/audiosource.h"
|
#include "ardour/audiosource.h"
|
||||||
|
#include "ardour/buffer_set.h"
|
||||||
|
#include "ardour/io_processor.h"
|
||||||
|
#include "ardour/panner.h"
|
||||||
|
#include "ardour/playlist_factory.h"
|
||||||
|
#include "ardour/plugin_insert.h"
|
||||||
|
#include "ardour/processor.h"
|
||||||
#include "ardour/region_factory.h"
|
#include "ardour/region_factory.h"
|
||||||
#include "ardour/route_group_specialized.h"
|
#include "ardour/route_group_specialized.h"
|
||||||
#include "ardour/processor.h"
|
#include "ardour/session.h"
|
||||||
#include "ardour/plugin_insert.h"
|
|
||||||
#include "ardour/audioplaylist.h"
|
|
||||||
#include "ardour/playlist_factory.h"
|
|
||||||
#include "ardour/panner.h"
|
|
||||||
#include "ardour/utils.h"
|
#include "ardour/utils.h"
|
||||||
#include "ardour/buffer_set.h"
|
|
||||||
#include "ardour/audio_buffer.h"
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -145,7 +146,7 @@ AudioTrack::deprecated_use_diskstream_connections ()
|
||||||
|
|
||||||
if ((prop = node.property ("gain")) != 0) {
|
if ((prop = node.property ("gain")) != 0) {
|
||||||
set_gain (atof (prop->value().c_str()), this);
|
set_gain (atof (prop->value().c_str()), this);
|
||||||
_gain = _desired_gain;
|
_gain = _gain_control->user_float();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("input-connection")) != 0) {
|
if ((prop = node.property ("input-connection")) != 0) {
|
||||||
|
|
@ -452,91 +453,6 @@ AudioTrack::set_state_part_two ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
|
||||||
{
|
|
||||||
if (n_outputs().n_total() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_active) {
|
|
||||||
silence (nframes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_state_changing) {
|
|
||||||
|
|
||||||
/* XXX is this safe to do against transport state changes? */
|
|
||||||
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_diskstream()->check_record_status (start_frame, nframes, can_record);
|
|
||||||
|
|
||||||
bool send_silence;
|
|
||||||
|
|
||||||
if (_have_internal_generator) {
|
|
||||||
/* since the instrument has no input streams,
|
|
||||||
there is no reason to send any signal
|
|
||||||
into the route.
|
|
||||||
*/
|
|
||||||
send_silence = true;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (!Config->get_tape_machine_mode()) {
|
|
||||||
/*
|
|
||||||
ADATs work in a strange way..
|
|
||||||
they monitor input always when stopped.and auto-input is engaged.
|
|
||||||
*/
|
|
||||||
if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) {
|
|
||||||
send_silence = false;
|
|
||||||
} else {
|
|
||||||
send_silence = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
Other machines switch to input on stop if the track is record enabled,
|
|
||||||
regardless of the auto input setting (auto input only changes the
|
|
||||||
monitoring state when the transport is rolling)
|
|
||||||
*/
|
|
||||||
if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) {
|
|
||||||
send_silence = false;
|
|
||||||
} else {
|
|
||||||
send_silence = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
if (send_silence) {
|
|
||||||
|
|
||||||
/* if we're sending silence, but we want the meters to show levels for the signal,
|
|
||||||
meter right here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_have_internal_generator) {
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, true);
|
|
||||||
} else {
|
|
||||||
if (_meter_point == MeterInput) {
|
|
||||||
just_meter_input (start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* we're sending signal, but we may still want to meter the input.
|
|
||||||
*/
|
|
||||||
|
|
||||||
passthru (start_frame, end_frame, nframes, 0, (_meter_point == MeterInput));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
|
AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
|
||||||
bool can_record, bool rec_monitors_input)
|
bool can_record, bool rec_monitors_input)
|
||||||
|
|
@ -580,7 +496,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
}
|
}
|
||||||
|
|
||||||
_silent = false;
|
_silent = false;
|
||||||
apply_gain_automation = false;
|
_amp->apply_gain_automation(false);
|
||||||
|
|
||||||
if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input)) != 0) {
|
if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input)) != 0) {
|
||||||
silence (nframes);
|
silence (nframes);
|
||||||
|
|
@ -599,7 +515,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
at least potentially (depending on monitoring options)
|
at least potentially (depending on monitoring options)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
passthru (start_frame, end_frame, nframes, 0, true);
|
passthru (start_frame, end_frame, nframes, false);
|
||||||
|
|
||||||
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
||||||
|
|
||||||
|
|
@ -691,11 +607,13 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
Glib::Mutex::Lock am (data().control_lock(), Glib::TRY_LOCK);
|
Glib::Mutex::Lock am (data().control_lock(), Glib::TRY_LOCK);
|
||||||
|
|
||||||
if (am.locked() && gain_control()->automation_playback()) {
|
if (am.locked() && gain_control()->automation_playback()) {
|
||||||
apply_gain_automation = gain_control()->list()->curve().rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
|
_amp->apply_gain_automation(
|
||||||
|
gain_control()->list()->curve().rt_safe_get_vector (
|
||||||
|
start_frame, end_frame, _session.gain_automation_buffer(), nframes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_output_buffers (bufs, start_frame, end_frame, nframes, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
|
process_output_buffers (bufs, start_frame, end_frame, nframes, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* problem with the diskstream; just be quiet for a bit */
|
/* problem with the diskstream; just be quiet for a bit */
|
||||||
|
|
@ -705,36 +623,12 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool can_record, bool rec_monitors_input)
|
|
||||||
{
|
|
||||||
if (n_outputs().n_total() == 0 && _processors.empty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_active) {
|
|
||||||
silence (nframes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_silent = true;
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
silence (nframes);
|
|
||||||
|
|
||||||
return audio_diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes, bool enable_processing)
|
AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes, bool enable_processing)
|
||||||
{
|
{
|
||||||
gain_t gain_automation[nframes];
|
|
||||||
gain_t gain_buffer[nframes];
|
gain_t gain_buffer[nframes];
|
||||||
float mix_buffer[nframes];
|
float mix_buffer[nframes];
|
||||||
ProcessorList::iterator i;
|
ProcessorList::iterator i;
|
||||||
bool post_fader_work = false;
|
|
||||||
gain_t this_gain = _gain;
|
|
||||||
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
|
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
|
||||||
|
|
||||||
Glib::RWLock::ReaderLock rlock (_processor_lock);
|
Glib::RWLock::ReaderLock rlock (_processor_lock);
|
||||||
|
|
@ -767,8 +661,9 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no processing is required, there's no need to go any further.
|
// If no processing is required, there's no need to go any further.
|
||||||
if (!enable_processing)
|
if (!enable_processing) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* note: only run processors during export. other layers in the machinery
|
/* note: only run processors during export. other layers in the machinery
|
||||||
will already have checked that there are no external port processors.
|
will already have checked that there are no external port processors.
|
||||||
|
|
@ -776,57 +671,11 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
|
||||||
|
|
||||||
for (i = _processors.begin(); i != _processors.end(); ++i) {
|
for (i = _processors.begin(); i != _processors.end(); ++i) {
|
||||||
boost::shared_ptr<Processor> processor;
|
boost::shared_ptr<Processor> processor;
|
||||||
|
|
||||||
if ((processor = boost::dynamic_pointer_cast<Processor>(*i)) != 0) {
|
if ((processor = boost::dynamic_pointer_cast<Processor>(*i)) != 0) {
|
||||||
switch (processor->placement()) {
|
processor->run_in_place (buffers, start, start+nframes, nframes);
|
||||||
case PreFader:
|
|
||||||
processor->run_in_place (buffers, start, start+nframes, nframes);
|
|
||||||
break;
|
|
||||||
case PostFader:
|
|
||||||
post_fader_work = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gain_control()->automation_state() == Play) {
|
|
||||||
|
|
||||||
gain_control()->list()->curve().get_vector (start, start + nframes, gain_automation, nframes);
|
|
||||||
|
|
||||||
for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
|
|
||||||
Sample *b = bi->data();
|
|
||||||
for (nframes_t n = 0; n < nframes; ++n) {
|
|
||||||
b[n] *= gain_automation[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
|
|
||||||
Sample *b = bi->data();
|
|
||||||
for (nframes_t n = 0; n < nframes; ++n) {
|
|
||||||
b[n] *= this_gain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (post_fader_work) {
|
|
||||||
|
|
||||||
for (i = _processors.begin(); i != _processors.end(); ++i) {
|
|
||||||
boost::shared_ptr<PluginInsert> processor;
|
|
||||||
|
|
||||||
if ((processor = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
|
||||||
switch ((*i)->placement()) {
|
|
||||||
case PreFader:
|
|
||||||
break;
|
|
||||||
case PostFader:
|
|
||||||
processor->run_in_place (buffers, start, start+nframes, nframes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,8 @@ AudioEngine::jack_bufsize_callback (nframes_t nframes)
|
||||||
{
|
{
|
||||||
_buffer_size = nframes;
|
_buffer_size = nframes;
|
||||||
_raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof(float);
|
_raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof(float);
|
||||||
|
cout << "FIXME: Assuming maximum MIDI buffer size " << nframes * 4 << "bytes" << endl;
|
||||||
|
_raw_buffer_sizes[DataType::MIDI] = nframes * 4;
|
||||||
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
|
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
|
||||||
last_monitor_check = 0;
|
last_monitor_check = 0;
|
||||||
|
|
||||||
|
|
@ -604,13 +606,14 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input)
|
||||||
} else if (dtype == DataType::MIDI) {
|
} else if (dtype == DataType::MIDI) {
|
||||||
newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||||
} else {
|
} else {
|
||||||
throw unknown_type();
|
throw PortRegistrationFailure("unable to create port (unknown type)");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t& old_buffer_size = _raw_buffer_sizes[newport->type()];
|
size_t& old_buffer_size = _raw_buffer_sizes[newport->type()];
|
||||||
size_t port_buffer_size = newport->raw_buffer_size(0);
|
size_t port_buffer_size = newport->raw_buffer_size(0);
|
||||||
if (port_buffer_size > old_buffer_size)
|
if (port_buffer_size > old_buffer_size) {
|
||||||
old_buffer_size = port_buffer_size;
|
old_buffer_size = port_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
RCUWriter<Ports> writer (ports);
|
RCUWriter<Ports> writer (ports);
|
||||||
boost::shared_ptr<Ports> ps = writer.get_copy ();
|
boost::shared_ptr<Ports> ps = writer.get_copy ();
|
||||||
|
|
@ -621,8 +624,13 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input)
|
||||||
return newport;
|
return newport;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...) {
|
catch (PortRegistrationFailure& err) {
|
||||||
throw PortRegistrationFailure("unable to create port (unknown type?)");
|
throw err;
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
throw PortRegistrationFailure(string_compose(
|
||||||
|
_("unable to create port: %1"), e.what()).c_str());
|
||||||
|
} catch (...) {
|
||||||
|
throw PortRegistrationFailure("unable to create port (unknown error)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1256,6 +1264,10 @@ AudioEngine::reconnect_to_jack ()
|
||||||
nframes_t blocksize = jack_get_buffer_size (_jack);
|
nframes_t blocksize = jack_get_buffer_size (_jack);
|
||||||
session->set_block_size (blocksize);
|
session->set_block_size (blocksize);
|
||||||
session->set_frame_rate (jack_get_sample_rate (_jack));
|
session->set_frame_rate (jack_get_sample_rate (_jack));
|
||||||
|
|
||||||
|
_raw_buffer_sizes[DataType::AUDIO] = blocksize * sizeof(float);
|
||||||
|
cout << "FIXME: Assuming maximum MIDI buffer size " << blocksize * 4 << "bytes" << endl;
|
||||||
|
_raw_buffer_sizes[DataType::MIDI] = blocksize * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_monitor_check = 0;
|
last_monitor_check = 0;
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,6 @@ Automatable::set_automation_state (const XMLNode& node, Evoral::Parameter legacy
|
||||||
boost::shared_ptr<Evoral::Control> newcontrol = control_factory(param);
|
boost::shared_ptr<Evoral::Control> newcontrol = control_factory(param);
|
||||||
add_control(newcontrol);
|
add_control(newcontrol);
|
||||||
newcontrol->set_list(al);
|
newcontrol->set_list(al);
|
||||||
warning << "Control did not exist";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -268,7 +267,9 @@ Automatable::get_automation_state ()
|
||||||
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
|
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
|
||||||
boost::shared_ptr<AutomationList> l
|
boost::shared_ptr<AutomationList> l
|
||||||
= boost::dynamic_pointer_cast<AutomationList>(li->second->list());
|
= boost::dynamic_pointer_cast<AutomationList>(li->second->list());
|
||||||
node->add_child_nocopy (l->get_state ());
|
if (!l->empty()) {
|
||||||
|
node->add_child_nocopy (l->get_state ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *node;
|
return *node;
|
||||||
|
|
@ -410,7 +411,12 @@ Automatable::control_factory(const Evoral::Parameter& param)
|
||||||
} else if (param.type() == GainAutomation) {
|
} else if (param.type() == GainAutomation) {
|
||||||
control = new IO::GainControl( X_("gaincontrol"), (IO*)this, param);
|
control = new IO::GainControl( X_("gaincontrol"), (IO*)this, param);
|
||||||
} else if (param.type() == PanAutomation) {
|
} else if (param.type() == PanAutomation) {
|
||||||
control = new Panner::PanControllable( ((Panner *)this)->session(), X_("panner"), *(Panner *)this, param);
|
Panner* me = dynamic_cast<Panner*>(this);
|
||||||
|
if (me) {
|
||||||
|
control = new Panner::PanControllable(me->session(), X_("panner"), *me, param);
|
||||||
|
} else {
|
||||||
|
cerr << "ERROR: PanAutomation for non-Panner" << endl;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
control = new AutomationControl(_a_session, param);
|
control = new AutomationControl(_a_session, param);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ namespace ARDOUR {
|
||||||
/** Create a new, empty BufferSet */
|
/** Create a new, empty BufferSet */
|
||||||
BufferSet::BufferSet()
|
BufferSet::BufferSet()
|
||||||
: _is_mirror(false)
|
: _is_mirror(false)
|
||||||
|
, _is_silent(false)
|
||||||
{
|
{
|
||||||
for (size_t i=0; i < DataType::num_types; ++i) {
|
for (size_t i=0; i < DataType::num_types; ++i) {
|
||||||
_buffers.push_back(BufferVec());
|
_buffers.push_back(BufferVec());
|
||||||
|
|
@ -84,6 +85,7 @@ BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
_count = ports.count();
|
_count = ports.count();
|
||||||
|
_available = ports.count();
|
||||||
|
|
||||||
_is_mirror = true;
|
_is_mirror = true;
|
||||||
}
|
}
|
||||||
|
|
@ -97,8 +99,9 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
|
||||||
assert(type != DataType::NIL);
|
assert(type != DataType::NIL);
|
||||||
assert(type < _buffers.size());
|
assert(type < _buffers.size());
|
||||||
|
|
||||||
if (num_buffers == 0)
|
if (num_buffers == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The vector of buffers of the type we care about
|
// The vector of buffers of the type we care about
|
||||||
BufferVec& bufs = _buffers[type];
|
BufferVec& bufs = _buffers[type];
|
||||||
|
|
@ -132,7 +135,7 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
|
||||||
#ifdef HAVE_SLV2
|
#ifdef HAVE_SLV2
|
||||||
// Ensure enough low level MIDI format buffers are available for conversion
|
// Ensure enough low level MIDI format buffers are available for conversion
|
||||||
// in both directions (input & output, out-of-place)
|
// in both directions (input & output, out-of-place)
|
||||||
if (type == DataType::MIDI && _lv2_buffers.size() < _buffers[type].size() * 2) {
|
if (type == DataType::MIDI && _lv2_buffers.size() < _buffers[type].size() * 2 + 1) {
|
||||||
while (_lv2_buffers.size() < _buffers[type].size() * 2) {
|
while (_lv2_buffers.size() < _buffers[type].size() * 2) {
|
||||||
_lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
|
_lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +163,7 @@ BufferSet::buffer_capacity(DataType type) const
|
||||||
Buffer&
|
Buffer&
|
||||||
BufferSet::get(DataType type, size_t i)
|
BufferSet::get(DataType type, size_t i)
|
||||||
{
|
{
|
||||||
assert(i <= _count.get(type));
|
assert(i < _available.get(type));
|
||||||
return *_buffers[type][i];
|
return *_buffers[type][i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,28 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "ardour/chan_count.h"
|
#include "ardour/chan_count.h"
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
|
static const char* state_node_name = "Channels";
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
// infinite/zero chan count stuff, for setting minimums and maximums, etc.
|
// infinite/zero chan count stuff, for setting minimums and maximums, etc.
|
||||||
// FIXME: implement this in a less fugly way
|
// FIXME: implement this in a less fugly way
|
||||||
|
|
||||||
|
ChanCount::ChanCount(const XMLNode& node)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
XMLNodeConstIterator iter = node.children().begin();
|
||||||
|
for ( ; iter != node.children().end(); ++iter) {
|
||||||
|
if ((*iter)->name() == X_(state_node_name)) {
|
||||||
|
const string& type_str = (*iter)->property("type")->value();
|
||||||
|
const string& count_str = (*iter)->property("count")->value();
|
||||||
|
set(DataType(type_str), atol(count_str.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChanCount
|
ChanCount
|
||||||
infinity_factory()
|
infinity_factory()
|
||||||
{
|
{
|
||||||
|
|
@ -39,6 +56,21 @@ infinity_factory()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode*
|
||||||
|
ChanCount::state(const std::string& name) const
|
||||||
|
{
|
||||||
|
XMLNode* node = new XMLNode (name);
|
||||||
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
|
uint32_t count = get(*t);
|
||||||
|
if (count > 0) {
|
||||||
|
XMLNode* n = new XMLNode(X_(state_node_name));
|
||||||
|
n->add_property("type", (*t).to_string());
|
||||||
|
n->add_property("count", count);
|
||||||
|
node->add_child_nocopy(*n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
// Statics
|
// Statics
|
||||||
const ChanCount ChanCount::INFINITE = infinity_factory();
|
const ChanCount ChanCount::INFINITE = infinity_factory();
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ Configuration::load_state ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statbuf.st_size != 0) {
|
if (statbuf.st_size != 0) {
|
||||||
cerr << string_compose (_("loading system configuration file %1"), rcfile) << endl;
|
cerr << string_compose (_("Loading system configuration file %1"), rcfile) << endl;
|
||||||
|
|
||||||
if (!tree.read (rcfile.c_str())) {
|
if (!tree.read (rcfile.c_str())) {
|
||||||
error << string_compose(_("Ardour: cannot read system configuration file \"%1\""), rcfile) << endmsg;
|
error << string_compose(_("Ardour: cannot read system configuration file \"%1\""), rcfile) << endmsg;
|
||||||
|
|
@ -140,7 +140,7 @@ Configuration::load_state ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statbuf.st_size != 0) {
|
if (statbuf.st_size != 0) {
|
||||||
cerr << string_compose (_("loading user configuration file %1"), rcfile) << endl;
|
cerr << string_compose (_("Loading user configuration file %1"), rcfile) << endl;
|
||||||
|
|
||||||
if (!tree.read (rcfile)) {
|
if (!tree.read (rcfile)) {
|
||||||
error << string_compose(_("Ardour: cannot read configuration file \"%1\""), rcfile) << endmsg;
|
error << string_compose(_("Ardour: cannot read configuration file \"%1\""), rcfile) << endmsg;
|
||||||
|
|
|
||||||
79
libs/ardour/control_outputs.cc
Normal file
79
libs/ardour/control_outputs.cc
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
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 <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "ardour/control_outputs.h"
|
||||||
|
#include "ardour/audio_buffer.h"
|
||||||
|
#include "ardour/buffer_set.h"
|
||||||
|
#include "ardour/configuration.h"
|
||||||
|
#include "ardour/io.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
ControlOutputs::ControlOutputs(Session& s, IO* io)
|
||||||
|
: IOProcessor(s, io, "Control Outs")
|
||||||
|
, _deliver(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ControlOutputs::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||||
|
{
|
||||||
|
out = in;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ControlOutputs::configure_io (ChanCount in, ChanCount out)
|
||||||
|
{
|
||||||
|
if (out != in) { // always 1:1
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Processor::configure_io (in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ControlOutputs::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
||||||
|
{
|
||||||
|
if (_deliver) {
|
||||||
|
_io->deliver_output (bufs, start_frame, end_frame, nframes);
|
||||||
|
} else {
|
||||||
|
_io->silence (nframes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
ControlOutputs::state (bool full_state)
|
||||||
|
{
|
||||||
|
return get_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
ControlOutputs::get_state()
|
||||||
|
{
|
||||||
|
XMLNode* node = new XMLNode(state_node_name);
|
||||||
|
node->add_property("type", "control-outputs");
|
||||||
|
return *node;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ARDOUR
|
||||||
|
|
@ -441,17 +441,15 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<nframes_t> > const &
|
||||||
);
|
);
|
||||||
|
|
||||||
/* move panner automation */
|
/* move panner automation */
|
||||||
Panner & p = _io->panner ();
|
boost::shared_ptr<Panner> p = _io->panner ();
|
||||||
for (uint32_t i = 0; i < p.npanners (); ++i) {
|
if (p) {
|
||||||
|
for (uint32_t i = 0; i < p->npanners (); ++i) {
|
||||||
boost::shared_ptr<AutomationList> pan_alist = p.streampanner(i).pan_control()->alist();
|
boost::shared_ptr<AutomationList> pan_alist = p->streampanner(i).pan_control()->alist();
|
||||||
XMLNode & before = pan_alist->get_state ();
|
XMLNode & before = pan_alist->get_state ();
|
||||||
pan_alist->move_ranges (movements);
|
pan_alist->move_ranges (movements);
|
||||||
_session.add_command (
|
_session.add_command (new MementoCommand<AutomationList> (
|
||||||
new MementoCommand<AutomationList> (
|
*pan_alist.get(), &before, &pan_alist->get_state ()));
|
||||||
*pan_alist.get(), &before, &pan_alist->get_state ()
|
}
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move processor automation */
|
/* move processor automation */
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ int
|
||||||
ARDOUR::setup_midi ()
|
ARDOUR::setup_midi ()
|
||||||
{
|
{
|
||||||
if (Config->midi_ports.size() == 0) {
|
if (Config->midi_ports.size() == 0) {
|
||||||
warning << _("no MIDI ports specified: no MMC or MTC control possible") << endmsg;
|
//warning << _("no MIDI ports specified: no MMC or MTC control possible") << endmsg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,7 @@ Session::import_audiofiles (ImportStatus& status)
|
||||||
frame_rate(), cnt, status.total);
|
frame_rate(), cnt, status.total);
|
||||||
write_audio_data_to_new_files (source.get(), status, newfiles);
|
write_audio_data_to_new_files (source.get(), status, newfiles);
|
||||||
} else if (smf_reader.get()) { // midi
|
} else if (smf_reader.get()) { // midi
|
||||||
status.doing_what = string_compose(_("loading MIDI file %1"), *p);
|
status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
|
||||||
write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
|
write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,36 +102,27 @@ static double direct_gain_to_control (gain_t gain) {
|
||||||
* and friends if no type is explicitly requested (to avoid breakage).
|
* and friends if no type is explicitly requested (to avoid breakage).
|
||||||
*/
|
*/
|
||||||
IO::IO (Session& s, const string& name,
|
IO::IO (Session& s, const string& name,
|
||||||
int input_min, int input_max, int output_min, int output_max,
|
DataType default_type,
|
||||||
DataType default_type)
|
ChanCount in_min, ChanCount in_max, ChanCount out_min, ChanCount out_max)
|
||||||
: SessionObject(s, name),
|
: SessionObject (s, name)
|
||||||
AutomatableControls (s),
|
, AutomatableControls (s)
|
||||||
_output_buffers (new BufferSet()),
|
, _output_buffers (new BufferSet())
|
||||||
_active(true),
|
, _active (true)
|
||||||
_default_type (default_type),
|
, _default_type (default_type)
|
||||||
_input_minimum (ChanCount::ZERO),
|
, _amp (new Amp(s, *this))
|
||||||
_input_maximum (ChanCount::INFINITE),
|
, _meter (new PeakMeter(s))
|
||||||
_output_minimum (ChanCount::ZERO),
|
, _panner (new Panner(name, s))
|
||||||
_output_maximum (ChanCount::INFINITE)
|
, _input_minimum (ChanCount::ZERO)
|
||||||
|
, _input_maximum (ChanCount::INFINITE)
|
||||||
|
, _output_minimum (ChanCount::ZERO)
|
||||||
|
, _output_maximum (ChanCount::INFINITE)
|
||||||
{
|
{
|
||||||
_panner = new Panner (name, _session);
|
_input_minimum = in_min;
|
||||||
_meter = new PeakMeter (_session);
|
_output_minimum = out_min;
|
||||||
|
_input_maximum = in_max;
|
||||||
if (input_min > 0) {
|
_output_maximum = out_max;
|
||||||
_input_minimum = ChanCount(_default_type, input_min);
|
|
||||||
}
|
|
||||||
if (input_max >= 0) {
|
|
||||||
_input_maximum = ChanCount(_default_type, input_max);
|
|
||||||
}
|
|
||||||
if (output_min > 0) {
|
|
||||||
_output_minimum = ChanCount(_default_type, output_min);
|
|
||||||
}
|
|
||||||
if (output_max >= 0) {
|
|
||||||
_output_maximum = ChanCount(_default_type, output_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gain = 1.0;
|
_gain = 1.0;
|
||||||
_desired_gain = 1.0;
|
|
||||||
pending_state_node = 0;
|
pending_state_node = 0;
|
||||||
no_panner_reset = false;
|
no_panner_reset = false;
|
||||||
_phase_invert = false;
|
_phase_invert = false;
|
||||||
|
|
@ -143,8 +134,6 @@ IO::IO (Session& s, const string& name,
|
||||||
_gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
|
_gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
|
||||||
|
|
||||||
add_control(_gain_control);
|
add_control(_gain_control);
|
||||||
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// IO::Meter is emitted from another thread so the
|
// IO::Meter is emitted from another thread so the
|
||||||
|
|
@ -162,21 +151,18 @@ IO::IO (Session& s, const string& name,
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::IO (Session& s, const XMLNode& node, DataType dt)
|
IO::IO (Session& s, const XMLNode& node, DataType dt)
|
||||||
: SessionObject(s, "unnamed io"),
|
: SessionObject(s, "unnamed io")
|
||||||
AutomatableControls (s),
|
, AutomatableControls (s)
|
||||||
_output_buffers (new BufferSet()),
|
, _output_buffers (new BufferSet())
|
||||||
_active(true),
|
, _active(true)
|
||||||
_default_type (dt)
|
, _default_type (dt)
|
||||||
|
, _amp (new Amp(s, *this))
|
||||||
|
, _meter(new PeakMeter (_session))
|
||||||
{
|
{
|
||||||
_meter = new PeakMeter (_session);
|
|
||||||
_panner = 0;
|
|
||||||
deferred_state = 0;
|
deferred_state = 0;
|
||||||
no_panner_reset = false;
|
no_panner_reset = false;
|
||||||
_desired_gain = 1.0;
|
|
||||||
_gain = 1.0;
|
_gain = 1.0;
|
||||||
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
boost::shared_ptr<AutomationList> gl(
|
boost::shared_ptr<AutomationList> gl(
|
||||||
new AutomationList(Evoral::Parameter(GainAutomation)));
|
new AutomationList(Evoral::Parameter(GainAutomation)));
|
||||||
|
|
||||||
|
|
@ -218,9 +204,6 @@ IO::~IO ()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_meter_connection.disconnect();
|
m_meter_connection.disconnect();
|
||||||
|
|
||||||
delete _meter;
|
|
||||||
delete _panner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -241,50 +224,16 @@ IO::silence (nframes_t nframes)
|
||||||
void
|
void
|
||||||
IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
||||||
{
|
{
|
||||||
// FIXME: type specific code doesn't actually need to be here, it will go away in time
|
// Attach output buffers to port buffers
|
||||||
|
|
||||||
/* ********** AUDIO ********** */
|
|
||||||
|
|
||||||
// Apply gain if gain automation isn't playing
|
|
||||||
if ( ! apply_gain_automation) {
|
|
||||||
|
|
||||||
gain_t dg = _gain; // desired gain
|
|
||||||
|
|
||||||
{
|
|
||||||
Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
|
|
||||||
|
|
||||||
if (dm.locked()) {
|
|
||||||
dg = _desired_gain;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dg != _gain || dg != 1.0) {
|
|
||||||
Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert);
|
|
||||||
_gain = dg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do this so that any processing that comes after deliver_outputs()
|
|
||||||
can use the output buffers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
output_buffers().attach_buffers (_outputs, nframes, _output_offset);
|
output_buffers().attach_buffers (_outputs, nframes, _output_offset);
|
||||||
|
|
||||||
// Use the panner to distribute audio to output port buffers
|
// Use the panner to distribute audio to output port buffers
|
||||||
|
if (_panner && _panner->npanners() && !_panner->bypassed()) {
|
||||||
|
|
||||||
if (0 && _panner && _panner->npanners() && !_panner->bypassed()) {
|
|
||||||
|
|
||||||
/* blech .. we shouldn't be creating and tearing this down every process()
|
|
||||||
cycle. XXX fix me to not waste cycles and do memory allocation etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes);
|
_panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes);
|
||||||
|
|
||||||
|
// Do a 1:1 copy of data to output ports
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* do a 1:1 copy of data to output ports */
|
|
||||||
|
|
||||||
if (bufs.count().n_audio() > 0 && _outputs.count().n_audio () > 0) {
|
if (bufs.count().n_audio() > 0 && _outputs.count().n_audio () > 0) {
|
||||||
copy_to_outputs (bufs, DataType::AUDIO, nframes);
|
copy_to_outputs (bufs, DataType::AUDIO, nframes);
|
||||||
}
|
}
|
||||||
|
|
@ -292,6 +241,27 @@ IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
|
||||||
copy_to_outputs (bufs, DataType::MIDI, nframes);
|
copy_to_outputs (bufs, DataType::MIDI, nframes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply gain to output buffers if gain automation isn't playing
|
||||||
|
if ( ! _amp->apply_gain_automation()) {
|
||||||
|
|
||||||
|
gain_t dg = _gain; // desired gain
|
||||||
|
|
||||||
|
{
|
||||||
|
Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
|
||||||
|
|
||||||
|
if (dm.locked()) {
|
||||||
|
dg = _gain_control->user_float();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dg != _gain || dg != 1.0) {
|
||||||
|
Amp::apply_gain(output_buffers(), nframes, _gain, dg, _phase_invert);
|
||||||
|
_gain = dg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -302,9 +272,8 @@ IO::copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes)
|
||||||
PortSet::iterator o = _outputs.begin(type);
|
PortSet::iterator o = _outputs.begin(type);
|
||||||
BufferSet::iterator i = bufs.begin(type);
|
BufferSet::iterator i = bufs.begin(type);
|
||||||
BufferSet::iterator prev = i;
|
BufferSet::iterator prev = i;
|
||||||
|
|
||||||
while (i != bufs.end(type) && o != _outputs.end (type)) {
|
while (i != bufs.end(type) && o != _outputs.end (type)) {
|
||||||
|
|
||||||
Buffer& port_buffer (o->get_buffer (nframes));
|
Buffer& port_buffer (o->get_buffer (nframes));
|
||||||
port_buffer.read_from (*i, nframes, _output_offset);
|
port_buffer.read_from (*i, nframes, _output_offset);
|
||||||
prev = i;
|
prev = i;
|
||||||
|
|
@ -312,8 +281,7 @@ IO::copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes)
|
||||||
++o;
|
++o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extra outputs get a copy of the last buffer */
|
// Copy last buffer to any extra outputs
|
||||||
|
|
||||||
while (o != _outputs.end(type)) {
|
while (o != _outputs.end(type)) {
|
||||||
Buffer& port_buffer (o->get_buffer (nframes));
|
Buffer& port_buffer (o->get_buffer (nframes));
|
||||||
port_buffer.read_from (*prev, nframes, _output_offset);
|
port_buffer.read_from (*prev, nframes, _output_offset);
|
||||||
|
|
@ -894,14 +862,19 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
||||||
bool out_changed = false;
|
bool out_changed = false;
|
||||||
bool need_pan_reset = false;
|
bool need_pan_reset = false;
|
||||||
|
|
||||||
in = min (_input_maximum, in);
|
assert(in != ChanCount::INFINITE);
|
||||||
|
assert(out != ChanCount::INFINITE);
|
||||||
|
|
||||||
out = min (_output_maximum, out);
|
in = ChanCount::min (_input_maximum, in);
|
||||||
|
out = ChanCount::min (_output_maximum, out);
|
||||||
|
|
||||||
if (in == n_inputs() && out == n_outputs() && !clear) {
|
if (in == n_inputs() && out == n_outputs() && !clear) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_configured_inputs = in;
|
||||||
|
_configured_outputs = out;
|
||||||
|
|
||||||
{
|
{
|
||||||
BLOCK_PROCESS_CALLBACK ();
|
BLOCK_PROCESS_CALLBACK ();
|
||||||
Glib::Mutex::Lock lm (io_lock);
|
Glib::Mutex::Lock lm (io_lock);
|
||||||
|
|
@ -943,9 +916,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create any necessary new input ports */
|
/* create any necessary new input ports */
|
||||||
|
|
||||||
while (n_inputs().get(*t) < nin) {
|
while (n_inputs().get(*t) < nin) {
|
||||||
|
|
||||||
string portname = build_legal_port_name (*t, true);
|
string portname = build_legal_port_name (*t, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -959,7 +930,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
||||||
setup_peak_meters ();
|
setup_peak_meters ();
|
||||||
reset_panner ();
|
reset_panner ();
|
||||||
/* pass it on */
|
/* pass it on */
|
||||||
throw AudioEngine::PortRegistrationFailure();
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputs.add (port);
|
_inputs.add (port);
|
||||||
|
|
@ -983,7 +954,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
||||||
setup_peak_meters ();
|
setup_peak_meters ();
|
||||||
reset_panner ();
|
reset_panner ();
|
||||||
/* pass it on */
|
/* pass it on */
|
||||||
throw AudioEngine::PortRegistrationFailure ();
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
_outputs.add (port);
|
_outputs.add (port);
|
||||||
|
|
@ -1124,7 +1095,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (_output_maximum < ChanCount::INFINITE) {
|
if (_output_maximum != ChanCount::INFINITE) {
|
||||||
count = min (_output_maximum, count);
|
count = min (_output_maximum, count);
|
||||||
if (count == n_outputs() && !clear) {
|
if (count == n_outputs() && !clear) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1152,11 +1123,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
|
||||||
gain_t
|
gain_t
|
||||||
IO::effective_gain () const
|
IO::effective_gain () const
|
||||||
{
|
{
|
||||||
if (_gain_control->automation_playback()) {
|
return _gain_control->get_value();
|
||||||
return _gain_control->get_value();
|
|
||||||
} else {
|
|
||||||
return _desired_gain;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1305,16 +1272,10 @@ IO::state (bool full_state)
|
||||||
snprintf (buf, sizeof(buf), "%2.12f", gain());
|
snprintf (buf, sizeof(buf), "%2.12f", gain());
|
||||||
node->add_property ("gain", buf);
|
node->add_property ("gain", buf);
|
||||||
|
|
||||||
/* To make backwards compatibility a bit easier, write ChanCount::INFINITE to the session file
|
/* port counts */
|
||||||
as -1.
|
|
||||||
*/
|
node->add_child_nocopy(*n_inputs().state("Inputs"));
|
||||||
|
node->add_child_nocopy(*n_outputs().state("Outputs"));
|
||||||
int const in_max = _input_maximum == ChanCount::INFINITE ? -1 : _input_maximum.get(_default_type);
|
|
||||||
int const out_max = _output_maximum == ChanCount::INFINITE ? -1 : _output_maximum.get(_default_type);
|
|
||||||
|
|
||||||
snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d", _input_minimum.get(_default_type), in_max, _output_minimum.get(_default_type), out_max);
|
|
||||||
|
|
||||||
node->add_property ("iolimits", buf);
|
|
||||||
|
|
||||||
/* automation */
|
/* automation */
|
||||||
|
|
||||||
|
|
@ -1358,9 +1319,9 @@ IO::set_state (const XMLNode& node)
|
||||||
sscanf (prop->value().c_str(), "%d,%d,%d,%d",
|
sscanf (prop->value().c_str(), "%d,%d,%d,%d",
|
||||||
&in_min, &in_max, &out_min, &out_max);
|
&in_min, &in_max, &out_min, &out_max);
|
||||||
|
|
||||||
/* Correct for the difference between the way we write things to session files and the
|
// Legacy numbers:
|
||||||
way things are described by ChanCount; see comments in io.h about what the different
|
// minimum == -1 => minimum == 0
|
||||||
ChanCount values mean. */
|
// maximum == -1 => maximum == infinity
|
||||||
|
|
||||||
if (in_min < 0) {
|
if (in_min < 0) {
|
||||||
_input_minimum = ChanCount::ZERO;
|
_input_minimum = ChanCount::ZERO;
|
||||||
|
|
@ -1389,7 +1350,7 @@ IO::set_state (const XMLNode& node)
|
||||||
|
|
||||||
if ((prop = node.property ("gain")) != 0) {
|
if ((prop = node.property ("gain")) != 0) {
|
||||||
set_gain (atof (prop->value().c_str()), this);
|
set_gain (atof (prop->value().c_str()), this);
|
||||||
_gain = _desired_gain;
|
_gain = _gain_control->user_float();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) {
|
if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) {
|
||||||
|
|
@ -1400,16 +1361,16 @@ IO::set_state (const XMLNode& node)
|
||||||
|
|
||||||
// Old school Panner.
|
// Old school Panner.
|
||||||
if ((*iter)->name() == "Panner") {
|
if ((*iter)->name() == "Panner") {
|
||||||
if (_panner == 0) {
|
if (!_panner) {
|
||||||
_panner = new Panner (_name, _session);
|
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||||
}
|
}
|
||||||
_panner->set_state (**iter);
|
_panner->set_state (**iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*iter)->name() == "Processor") {
|
if ((*iter)->name() == "Processor") {
|
||||||
if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
|
if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
|
||||||
if (_panner == 0) {
|
if (!_panner) {
|
||||||
_panner = new Panner (_name, _session);
|
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||||
}
|
}
|
||||||
_panner->set_state (**iter);
|
_panner->set_state (**iter);
|
||||||
}
|
}
|
||||||
|
|
@ -1427,6 +1388,8 @@ IO::set_state (const XMLNode& node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_port_counts (node);
|
||||||
|
|
||||||
if (ports_legal) {
|
if (ports_legal) {
|
||||||
|
|
||||||
if (create_ports (node)) {
|
if (create_ports (node)) {
|
||||||
|
|
@ -1438,8 +1401,10 @@ IO::set_state (const XMLNode& node)
|
||||||
port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
|
port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !_panner )
|
if (!_panner) {
|
||||||
_panner = new Panner( _name, _session );
|
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||||
|
}
|
||||||
|
|
||||||
if (panners_legal) {
|
if (panners_legal) {
|
||||||
reset_panner ();
|
reset_panner ();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1573,6 +1538,7 @@ IO::ports_became_legal ()
|
||||||
|
|
||||||
port_legal_c.disconnect ();
|
port_legal_c.disconnect ();
|
||||||
|
|
||||||
|
get_port_counts (*pending_state_node);
|
||||||
ret = create_ports (*pending_state_node);
|
ret = create_ports (*pending_state_node);
|
||||||
|
|
||||||
if (connecting_legal) {
|
if (connecting_legal) {
|
||||||
|
|
@ -1676,48 +1642,64 @@ IO::find_possible_bundle (const string &desired_name, const string &default_name
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
IO::create_ports (const XMLNode& node)
|
IO::get_port_counts (const XMLNode& node)
|
||||||
{
|
{
|
||||||
XMLProperty const * prop;
|
XMLProperty const * prop;
|
||||||
uint32_t num_inputs = 0;
|
XMLNodeConstIterator iter;
|
||||||
uint32_t num_outputs = 0;
|
ChanCount num_inputs = n_inputs();
|
||||||
|
ChanCount num_outputs = n_outputs();
|
||||||
|
|
||||||
|
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
|
||||||
|
if ((*iter)->name() == X_("Inputs")) {
|
||||||
|
num_inputs = ChanCount::max(num_inputs, ChanCount(**iter));
|
||||||
|
} else if ((*iter)->name() == X_("Outputs")) {
|
||||||
|
num_outputs = ChanCount::max(num_inputs, ChanCount(**iter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("input-connection")) != 0) {
|
if ((prop = node.property ("input-connection")) != 0) {
|
||||||
|
|
||||||
boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
|
boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
num_inputs = c->nchannels ();
|
num_inputs = ChanCount::max(num_inputs, ChanCount(c->type(), c->nchannels()));
|
||||||
} else {
|
|
||||||
num_inputs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((prop = node.property ("inputs")) != 0) {
|
} else if ((prop = node.property ("inputs")) != 0) {
|
||||||
|
|
||||||
num_inputs = count (prop->value().begin(), prop->value().end(), '{');
|
num_inputs = ChanCount::max(num_inputs, ChanCount(_default_type,
|
||||||
|
count (prop->value().begin(), prop->value().end(), '{')));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("output-connection")) != 0) {
|
if ((prop = node.property ("output-connection")) != 0) {
|
||||||
|
|
||||||
boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
|
boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
num_outputs = c->nchannels ();
|
num_outputs = ChanCount::max(num_outputs, ChanCount(c->type(), c->nchannels()));
|
||||||
} else {
|
|
||||||
num_outputs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((prop = node.property ("outputs")) != 0) {
|
} else if ((prop = node.property ("outputs")) != 0) {
|
||||||
|
|
||||||
num_outputs = count (prop->value().begin(), prop->value().end(), '{');
|
num_outputs = ChanCount::max(num_outputs, ChanCount(_default_type,
|
||||||
|
count (prop->value().begin(), prop->value().end(), '{')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_configured_inputs = num_inputs;
|
||||||
|
_configured_outputs = num_outputs;
|
||||||
|
|
||||||
|
_input_minimum = ChanCount::min(_input_minimum, num_inputs);
|
||||||
|
_input_maximum = ChanCount::max(_input_maximum, num_inputs);
|
||||||
|
_output_minimum = ChanCount::min(_output_minimum, num_outputs);
|
||||||
|
_output_maximum = ChanCount::max(_output_maximum, num_outputs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IO::create_ports (const XMLNode& node)
|
||||||
|
{
|
||||||
no_panner_reset = true;
|
no_panner_reset = true;
|
||||||
|
|
||||||
if (ensure_io (ChanCount (_default_type, num_inputs),
|
if (ensure_io (_input_minimum, _output_minimum, true, this)) {
|
||||||
ChanCount (_default_type, num_outputs),
|
|
||||||
true, this)) {
|
|
||||||
|
|
||||||
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
|
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1730,7 +1712,6 @@ IO::create_ports (const XMLNode& node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
IO::make_connections (const XMLNode& node)
|
IO::make_connections (const XMLNode& node)
|
||||||
{
|
{
|
||||||
|
|
@ -2282,8 +2263,8 @@ IO::meter ()
|
||||||
void
|
void
|
||||||
IO::clear_automation ()
|
IO::clear_automation ()
|
||||||
{
|
{
|
||||||
data().clear (); // clears gain automation
|
data().clear_controls (); // clears gain automation
|
||||||
_panner->data().clear();
|
_panner->data().clear_controls ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2325,10 +2306,12 @@ IO::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
|
||||||
void
|
void
|
||||||
IO::inc_gain (gain_t factor, void *src)
|
IO::inc_gain (gain_t factor, void *src)
|
||||||
{
|
{
|
||||||
if (_desired_gain == 0.0f)
|
float desired_gain = _gain_control->user_float();
|
||||||
|
if (desired_gain == 0.0f) {
|
||||||
set_gain (0.000001f + (0.000001f * factor), src);
|
set_gain (0.000001f + (0.000001f * factor), src);
|
||||||
else
|
} else {
|
||||||
set_gain (_desired_gain + (_desired_gain * factor), src);
|
set_gain (desired_gain + (desired_gain * factor), src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2350,7 +2333,7 @@ IO::set_gain (gain_t val, void *src)
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock dm (declick_lock);
|
Glib::Mutex::Lock dm (declick_lock);
|
||||||
_desired_gain = val;
|
_gain_control->set_float(val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_session.transport_stopped()) {
|
if (_session.transport_stopped()) {
|
||||||
|
|
@ -2470,7 +2453,7 @@ IO::build_legal_port_name (DataType type, bool in)
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
|
snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
|
||||||
|
|
||||||
return string (buf2);
|
return string (buf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,19 @@ using namespace std;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
IOProcessor::IOProcessor (Session& s, const string& name, Placement p,
|
IOProcessor::IOProcessor (Session& s, const string& proc_name, const string io_name, DataType dtype)
|
||||||
int input_min, int input_max,
|
: Processor(s, proc_name)
|
||||||
int output_min, int output_max,
|
, _io (new IO(s, io_name != "" ? io_name : proc_name, dtype))
|
||||||
DataType dtype)
|
{
|
||||||
: Processor(s, name, p)
|
_active = false;
|
||||||
, _io (new IO(s, name, input_min, input_max, output_min, output_max, dtype))
|
_sort_key = 0;
|
||||||
|
_gui = 0;
|
||||||
|
_extra_xml = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOProcessor::IOProcessor (Session& s, IO* io, const string& proc_name, DataType dtype)
|
||||||
|
: Processor(s, proc_name)
|
||||||
|
, _io (io)
|
||||||
{
|
{
|
||||||
_active = false;
|
_active = false;
|
||||||
_sort_key = 0;
|
_sort_key = 0;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,11 @@ LV2EventBuffer::LV2EventBuffer(size_t capacity)
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (capacity == 0) {
|
||||||
|
cerr << "ERROR: LV2 event buffer of size 0 created." << endl;
|
||||||
|
capacity = 1024;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NO_POSIX_MEMALIGN
|
#ifdef NO_POSIX_MEMALIGN
|
||||||
_data = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
|
_data = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
|
||||||
int ret = (_data != NULL) ? 0 : -1;
|
int ret = (_data != NULL) ? 0 : -1;
|
||||||
|
|
@ -139,7 +144,8 @@ LV2EventBuffer::append(uint32_t frames,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*cout << "Appending event type " << type << ", size " << size
|
/*cout << "Appending event type " << type << ", size " << size
|
||||||
<< " @ " << frames << "." << subframes << endl;*/
|
<< " @ " << frames << "." << subframes << endl;
|
||||||
|
cout << "Buffer capacity " << _data->capacity << ", size " << _data->size << endl;*/
|
||||||
|
|
||||||
if (!lv2_event_write(&_iter, frames, subframes, type, size, data)) {
|
if (!lv2_event_write(&_iter, frames, subframes, type, size, data)) {
|
||||||
cerr << "ERROR: Failed to write event." << endl;
|
cerr << "ERROR: Failed to write event." << endl;
|
||||||
|
|
|
||||||
|
|
@ -268,8 +268,8 @@ LV2Plugin::get_state()
|
||||||
|
|
||||||
if (parameter_is_input(i) && parameter_is_control(i)) {
|
if (parameter_is_input(i) && parameter_is_control(i)) {
|
||||||
child = new XMLNode("Port");
|
child = new XMLNode("Port");
|
||||||
snprintf(buf, sizeof(buf), "%u", i);
|
/*snprintf(buf, sizeof(buf), "%u", i);
|
||||||
child->add_property("number", string(buf));
|
child->add_property("number", string(buf));*/
|
||||||
child->add_property("symbol", port_symbol(i));
|
child->add_property("symbol", port_symbol(i));
|
||||||
snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
|
snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
|
||||||
child->add_property("value", string(buf));
|
child->add_property("value", string(buf));
|
||||||
|
|
@ -343,8 +343,8 @@ LV2Plugin::set_state(const XMLNode& node)
|
||||||
XMLProperty *prop;
|
XMLProperty *prop;
|
||||||
XMLNodeConstIterator iter;
|
XMLNodeConstIterator iter;
|
||||||
XMLNode *child;
|
XMLNode *child;
|
||||||
const char *port;
|
const char *sym;
|
||||||
const char *data;
|
const char *value;
|
||||||
uint32_t port_id;
|
uint32_t port_id;
|
||||||
LocaleGuard lg (X_("POSIX"));
|
LocaleGuard lg (X_("POSIX"));
|
||||||
|
|
||||||
|
|
@ -359,22 +359,29 @@ LV2Plugin::set_state(const XMLNode& node)
|
||||||
|
|
||||||
child = *iter;
|
child = *iter;
|
||||||
|
|
||||||
if ((prop = child->property("number")) != 0) {
|
if ((prop = child->property("symbol")) != 0) {
|
||||||
port = prop->value().c_str();
|
sym = prop->value().c_str();
|
||||||
} else {
|
} else {
|
||||||
warning << _("LV2: no lv2 port number") << endmsg;
|
warning << _("LV2: port has no symbol, ignored") << endmsg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string,uint32_t>::iterator i = _port_indices.find(sym);
|
||||||
|
if (i != _port_indices.end()) {
|
||||||
|
port_id = i->second;
|
||||||
|
} else {
|
||||||
|
warning << _("LV2: port has unknown index, ignored") << endmsg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = child->property("value")) != 0) {
|
if ((prop = child->property("value")) != 0) {
|
||||||
data = prop->value().c_str();
|
value = prop->value().c_str();
|
||||||
} else {
|
} else {
|
||||||
warning << _("LV2: no lv2 port data") << endmsg;
|
warning << _("LV2: port has no value, ignored") << endmsg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sscanf (port, "%" PRIu32, &port_id);
|
set_parameter (port_id, atof(value));
|
||||||
set_parameter (port_id, atof(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
latency_compute_run ();
|
latency_compute_run ();
|
||||||
|
|
@ -462,9 +469,7 @@ LV2Plugin::connect_and_run (BufferSet& bufs,
|
||||||
ChanMapping in_map, ChanMapping out_map,
|
ChanMapping in_map, ChanMapping out_map,
|
||||||
nframes_t nframes, nframes_t offset)
|
nframes_t nframes, nframes_t offset)
|
||||||
{
|
{
|
||||||
cycles_t then, now;
|
cycles_t then = get_cycles ();
|
||||||
|
|
||||||
then = get_cycles ();
|
|
||||||
|
|
||||||
uint32_t audio_in_index = 0;
|
uint32_t audio_in_index = 0;
|
||||||
uint32_t audio_out_index = 0;
|
uint32_t audio_out_index = 0;
|
||||||
|
|
@ -474,25 +479,29 @@ LV2Plugin::connect_and_run (BufferSet& bufs,
|
||||||
if (parameter_is_audio(port_index)) {
|
if (parameter_is_audio(port_index)) {
|
||||||
if (parameter_is_input(port_index)) {
|
if (parameter_is_input(port_index)) {
|
||||||
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++);
|
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++);
|
||||||
|
//cerr << port_index << " : " << " AUDIO IN " << buf_index << endl;
|
||||||
slv2_instance_connect_port(_instance, port_index,
|
slv2_instance_connect_port(_instance, port_index,
|
||||||
bufs.get_audio(buf_index).data(offset));
|
bufs.get_audio(buf_index).data(offset));
|
||||||
} else if (parameter_is_output(port_index)) {
|
} else if (parameter_is_output(port_index)) {
|
||||||
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++);
|
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++);
|
||||||
|
//cerr << port_index << " : " << " AUDIO OUT " << buf_index << endl;
|
||||||
slv2_instance_connect_port(_instance, port_index,
|
slv2_instance_connect_port(_instance, port_index,
|
||||||
bufs.get_audio(buf_index).data(offset));
|
bufs.get_audio(buf_index).data(offset));
|
||||||
}
|
}
|
||||||
} else if (parameter_is_midi(port_index)) {
|
} else if (parameter_is_midi(port_index)) {
|
||||||
if (parameter_is_input(port_index)) {
|
if (parameter_is_input(port_index)) {
|
||||||
const uint32_t buf_index = in_map.get(DataType::MIDI, midi_in_index++);
|
const uint32_t buf_index = in_map.get(DataType::MIDI, midi_in_index++);
|
||||||
|
//cerr << port_index << " : " << " MIDI IN " << buf_index << endl;
|
||||||
slv2_instance_connect_port(_instance, port_index,
|
slv2_instance_connect_port(_instance, port_index,
|
||||||
bufs.get_lv2_midi(true, buf_index).data());
|
bufs.get_lv2_midi(true, buf_index).data());
|
||||||
} else if (parameter_is_output(port_index)) {
|
} else if (parameter_is_output(port_index)) {
|
||||||
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++);
|
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++);
|
||||||
|
//cerr << port_index << " : " << " MIDI OUT " << buf_index << endl;
|
||||||
slv2_instance_connect_port(_instance, port_index,
|
slv2_instance_connect_port(_instance, port_index,
|
||||||
bufs.get_lv2_midi(false, buf_index).data());
|
bufs.get_lv2_midi(false, buf_index).data());
|
||||||
}
|
}
|
||||||
} else if (!parameter_is_control(port_index)) {
|
} else if (!parameter_is_control(port_index)) {
|
||||||
std::cerr << "WARNING: Unknown LV2 port type, ignored" << endl;
|
// Optional port (it'd better be if we've made it this far...)
|
||||||
slv2_instance_connect_port(_instance, port_index, NULL);
|
slv2_instance_connect_port(_instance, port_index, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -507,7 +516,7 @@ LV2Plugin::connect_and_run (BufferSet& bufs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
now = get_cycles ();
|
cycles_t now = get_cycles ();
|
||||||
set_cycles ((uint32_t) (now - then));
|
set_cycles ((uint32_t) (now - then));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -683,7 +692,7 @@ LV2PluginInfo::discover (void* lv2_world)
|
||||||
LV2World* world = (LV2World*)lv2_world;
|
LV2World* world = (LV2World*)lv2_world;
|
||||||
SLV2Plugins plugins = slv2_world_get_all_plugins(world->world);
|
SLV2Plugins plugins = slv2_world_get_all_plugins(world->world);
|
||||||
|
|
||||||
cerr << "Discovered " << slv2_plugins_size (plugins) << " Lv2 plugins\n";
|
cerr << "LV2: Discovered " << slv2_plugins_size (plugins) << " plugins\n";
|
||||||
|
|
||||||
for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) {
|
for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) {
|
||||||
SLV2Plugin p = slv2_plugins_get_at(plugins, i);
|
SLV2Plugin p = slv2_plugins_get_at(plugins, i);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
#include "ardour/audio_buffer.h"
|
#include "ardour/audio_buffer.h"
|
||||||
#include "ardour/runtime_functions.h"
|
#include "ardour/runtime_functions.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -38,44 +40,39 @@ namespace ARDOUR {
|
||||||
void
|
void
|
||||||
PeakMeter::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
PeakMeter::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
const uint32_t n_audio = min(_configured_input.n_audio(), bufs.count().n_audio());
|
||||||
|
const uint32_t n_midi = min(_configured_input.n_midi(), bufs.count().n_midi());
|
||||||
|
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
uint32_t meterable = std::min(bufs.count().n_total(), (uint32_t)_peak_power.size());
|
|
||||||
uint32_t limit = std::min (meterable, (uint32_t)bufs.count().n_midi());
|
// Meter MIDI in to the first n_midi peaks
|
||||||
|
for (uint32_t i = 0; i < n_midi; ++i, ++n) {
|
||||||
// Meter what we have (midi)
|
float val = 0.0f;
|
||||||
for ( ; n < limit; ++n) {
|
for (MidiBuffer::iterator e = bufs.get_midi(i).begin(); e != bufs.get_midi(i).end(); ++e) {
|
||||||
float val = 0;
|
const Evoral::MIDIEvent<nframes_t> ev(*e, false);
|
||||||
|
|
||||||
// GUI needs a better MIDI meter, not much information can be
|
|
||||||
// expressed through peaks alone
|
|
||||||
for (MidiBuffer::iterator i = bufs.get_midi(n).begin(); i != bufs.get_midi(n).end(); ++i) {
|
|
||||||
const Evoral::MIDIEvent<nframes_t> ev(*i, false);
|
|
||||||
if (ev.is_note_on()) {
|
if (ev.is_note_on()) {
|
||||||
const float this_vel = log(ev.buffer()[2] / 127.0 * (M_E*M_E-M_E) + M_E) - 1.0;
|
const float this_vel = log(ev.buffer()[2] / 127.0 * (M_E*M_E-M_E) + M_E) - 1.0;
|
||||||
//printf("V %d -> %f\n", (int)((Byte)ev.buffer[2]), this_vel);
|
if (this_vel > val) {
|
||||||
if (this_vel > val)
|
|
||||||
val = this_vel;
|
val = this_vel;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val += 1.0 / bufs.get_midi(n).capacity();
|
val += 1.0 / bufs.get_midi(n).capacity();
|
||||||
if (val > 1.0)
|
if (val > 1.0) {
|
||||||
val = 1.0;
|
val = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_peak_power[n] = val;
|
_peak_power[n] = val;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
limit = std::min (meterable, bufs.count().n_audio());
|
|
||||||
|
|
||||||
// Meter what we have (audio)
|
// Meter audio in to the rest of the peaks
|
||||||
for ( ; n < limit; ++n) {
|
for (uint32_t i = 0; i < n_audio; ++i, ++n) {
|
||||||
_peak_power[n] = compute_peak (bufs.get_audio(n).data(), nframes, _peak_power[n]);
|
_peak_power[n] = compute_peak (bufs.get_audio(i).data(), nframes, _peak_power[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero any excess peaks
|
// Zero any excess peaks
|
||||||
for (size_t n = meterable; n < _peak_power.size(); ++n) {
|
for (uint32_t i = n; i < _peak_power.size(); ++i) {
|
||||||
_peak_power[n] = 0;
|
_peak_power[i] = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +80,7 @@ void
|
||||||
PeakMeter::reset ()
|
PeakMeter::reset ()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < _peak_power.size(); ++i) {
|
for (size_t i = 0; i < _peak_power.size(); ++i) {
|
||||||
_peak_power[i] = 0;
|
_peak_power[i] = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,14 +92,20 @@ PeakMeter::reset_max ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||||
|
{
|
||||||
|
out = in;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PeakMeter::configure_io (ChanCount in, ChanCount out)
|
PeakMeter::configure_io (ChanCount in, ChanCount out)
|
||||||
{
|
{
|
||||||
/* we're transparent no matter what. fight the power. */
|
if (out != in) { // always 1:1
|
||||||
if (out != in) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t limit = in.n_total();
|
uint32_t limit = in.n_total();
|
||||||
|
|
||||||
while (_peak_power.size() > limit) {
|
while (_peak_power.size() > limit) {
|
||||||
|
|
@ -165,4 +168,18 @@ PeakMeter::meter ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
PeakMeter::state (bool full_state)
|
||||||
|
{
|
||||||
|
return get_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
PeakMeter::get_state()
|
||||||
|
{
|
||||||
|
XMLNode* node = new XMLNode(state_node_name);
|
||||||
|
node->add_property("type", "meter");
|
||||||
|
return *node;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,9 @@ MidiDiskstream::~MidiDiskstream ()
|
||||||
void
|
void
|
||||||
MidiDiskstream::non_realtime_locate (nframes_t position)
|
MidiDiskstream::non_realtime_locate (nframes_t position)
|
||||||
{
|
{
|
||||||
assert(_write_source);
|
if (_write_source) {
|
||||||
_write_source->set_timeline_position (position);
|
_write_source->set_timeline_position (position);
|
||||||
|
}
|
||||||
seek(position, false);
|
seek(position, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,7 +157,10 @@ MidiDiskstream::non_realtime_input_change ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_change_pending & ConfigurationChanged) {
|
if (input_change_pending & ConfigurationChanged) {
|
||||||
assert(_io->n_inputs() == _n_channels);
|
if (_io->n_inputs().n_midi() != _n_channels.n_midi()) {
|
||||||
|
error << "Can not feed IO " << _io->n_inputs()
|
||||||
|
<< " with diskstream " << _n_channels << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_input_sources ();
|
get_input_sources ();
|
||||||
|
|
@ -547,8 +551,6 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_
|
||||||
|
|
||||||
} else if (nominally_recording) {
|
} else if (nominally_recording) {
|
||||||
|
|
||||||
cerr << "B" << endl;
|
|
||||||
|
|
||||||
/* can't do actual capture yet - waiting for latency effects to finish before we start*/
|
/* can't do actual capture yet - waiting for latency effects to finish before we start*/
|
||||||
|
|
||||||
playback_distance = nframes;
|
playback_distance = nframes;
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,16 @@
|
||||||
#include <sigc++/sigc++.h>
|
#include <sigc++/sigc++.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "pbd/compose.h"
|
||||||
#include "pbd/file_utils.h"
|
#include "pbd/file_utils.h"
|
||||||
|
#include "pbd/error.h"
|
||||||
|
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
#include "ardour/session_directory.h"
|
#include "ardour/session_directory.h"
|
||||||
#include "ardour/midi_patch_manager.h"
|
#include "ardour/midi_patch_manager.h"
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace sigc;
|
using namespace sigc;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
|
@ -55,12 +59,11 @@ MidiPatchManager::refresh()
|
||||||
|
|
||||||
path path_to_patches = _session->session_directory().midi_patch_path();
|
path path_to_patches = _session->session_directory().midi_patch_path();
|
||||||
|
|
||||||
cerr << "Path to patches: " << path_to_patches.to_string() << endl;
|
info << string_compose(_("looking for MIDI patches in %1"), path_to_patches.to_string()) << endmsg;
|
||||||
|
|
||||||
if(!exists(path_to_patches)) {
|
if (!exists(path_to_patches)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cerr << "Path to patches: " << path_to_patches.to_string() << " exists" << endl;
|
|
||||||
|
|
||||||
assert(is_directory(path_to_patches));
|
assert(is_directory(path_to_patches));
|
||||||
|
|
||||||
|
|
@ -69,17 +72,15 @@ MidiPatchManager::refresh()
|
||||||
|
|
||||||
find_matching_files_in_directory(path_to_patches, pattern, result);
|
find_matching_files_in_directory(path_to_patches, pattern, result);
|
||||||
|
|
||||||
cerr << "patchfiles result contains " << result.size() << " elements" << endl;
|
cerr << "Loading " << result.size() << " MIDI patches from " << path_to_patches.to_string() << endl;
|
||||||
|
|
||||||
for(vector<path>::iterator i = result.begin(); i != result.end(); ++i) {
|
for (vector<path>::iterator i = result.begin(); i != result.end(); ++i) {
|
||||||
cerr << "processing patchfile " << i->to_string() << endl;
|
|
||||||
|
|
||||||
boost::shared_ptr<MIDINameDocument> document(new MIDINameDocument(i->to_string()));
|
boost::shared_ptr<MIDINameDocument> document(new MIDINameDocument(i->to_string()));
|
||||||
for(MIDINameDocument::MasterDeviceNamesList::const_iterator device =
|
for (MIDINameDocument::MasterDeviceNamesList::const_iterator device =
|
||||||
document->master_device_names_by_model().begin();
|
document->master_device_names_by_model().begin();
|
||||||
device != document->master_device_names_by_model().end();
|
device != document->master_device_names_by_model().end();
|
||||||
++device) {
|
++device) {
|
||||||
cerr << "got model " << device->first << endl;
|
//cerr << "got model " << device->first << endl;
|
||||||
// have access to the documents by model name
|
// have access to the documents by model name
|
||||||
_documents[device->first] = document;
|
_documents[device->first] = document;
|
||||||
// build a list of all master devices from all documents
|
// build a list of all master devices from all documents
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ MidiSource::midi_read (MidiRingBuffer<nframes_t>& dst, sframes_t source_start,
|
||||||
Evoral::Sequence<double>::const_iterator& i = _model_iter;
|
Evoral::Sequence<double>::const_iterator& i = _model_iter;
|
||||||
|
|
||||||
if (_last_read_end == 0 || start != _last_read_end) { // || !i.valid()) {
|
if (_last_read_end == 0 || start != _last_read_end) { // || !i.valid()) {
|
||||||
cerr << "MidiSource seeking to " << start << " from " << _last_read_end << endl;
|
//cerr << "MidiSource seeking to " << start << " from " << _last_read_end << endl;
|
||||||
for (i = _model->begin(); i != _model->end(); ++i) {
|
for (i = _model->begin(); i != _model->end(); ++i) {
|
||||||
if (BEATS_TO_FRAMES(i->time()) >= start) {
|
if (BEATS_TO_FRAMES(i->time()) >= start) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -25,20 +25,20 @@
|
||||||
#include "midi++/events.h"
|
#include "midi++/events.h"
|
||||||
#include "evoral/midi_util.h"
|
#include "evoral/midi_util.h"
|
||||||
|
|
||||||
#include "ardour/midi_track.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/midi_diskstream.h"
|
#include "ardour/buffer_set.h"
|
||||||
#include "ardour/session.h"
|
|
||||||
#include "ardour/io_processor.h"
|
#include "ardour/io_processor.h"
|
||||||
|
#include "ardour/meter.h"
|
||||||
|
#include "ardour/midi_diskstream.h"
|
||||||
|
#include "ardour/midi_playlist.h"
|
||||||
#include "ardour/midi_region.h"
|
#include "ardour/midi_region.h"
|
||||||
#include "ardour/midi_source.h"
|
#include "ardour/midi_source.h"
|
||||||
#include "ardour/route_group_specialized.h"
|
#include "ardour/midi_track.h"
|
||||||
#include "ardour/processor.h"
|
|
||||||
#include "ardour/midi_playlist.h"
|
|
||||||
#include "ardour/panner.h"
|
#include "ardour/panner.h"
|
||||||
|
#include "ardour/processor.h"
|
||||||
|
#include "ardour/route_group_specialized.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
#include "ardour/utils.h"
|
#include "ardour/utils.h"
|
||||||
#include "ardour/buffer_set.h"
|
|
||||||
#include "ardour/meter.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -60,10 +60,6 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo
|
||||||
|
|
||||||
set_input_minimum(ChanCount(DataType::MIDI, 1));
|
set_input_minimum(ChanCount(DataType::MIDI, 1));
|
||||||
set_input_maximum(ChanCount(DataType::MIDI, 1));
|
set_input_maximum(ChanCount(DataType::MIDI, 1));
|
||||||
set_output_minimum(ChanCount(DataType::MIDI, 1));
|
|
||||||
set_output_maximum(ChanCount(DataType::MIDI, 1));
|
|
||||||
|
|
||||||
PortCountChanged(ChanCount(DataType::MIDI, 2)); /* EMIT SIGNAL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
|
MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
|
||||||
|
|
@ -75,10 +71,6 @@ MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
|
||||||
|
|
||||||
set_input_minimum(ChanCount(DataType::MIDI, 1));
|
set_input_minimum(ChanCount(DataType::MIDI, 1));
|
||||||
set_input_maximum(ChanCount(DataType::MIDI, 1));
|
set_input_maximum(ChanCount(DataType::MIDI, 1));
|
||||||
set_output_minimum(ChanCount(DataType::MIDI, 1));
|
|
||||||
set_output_maximum(ChanCount(DataType::MIDI, 1));
|
|
||||||
|
|
||||||
PortCountChanged(ChanCount(DataType::MIDI, 2)); /* EMIT SIGNAL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiTrack::~MidiTrack ()
|
MidiTrack::~MidiTrack ()
|
||||||
|
|
@ -370,87 +362,6 @@ MidiTrack::set_state_part_two ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
MidiTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
|
||||||
{
|
|
||||||
if (n_outputs().n_midi() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_active) {
|
|
||||||
silence (nframes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_state_changing) {
|
|
||||||
|
|
||||||
/* XXX is this safe to do against transport state changes? */
|
|
||||||
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
midi_diskstream()->check_record_status (start_frame, nframes, can_record);
|
|
||||||
|
|
||||||
bool send_silence;
|
|
||||||
|
|
||||||
if (_have_internal_generator) {
|
|
||||||
/* since the instrument has no input streams,
|
|
||||||
there is no reason to send any signal
|
|
||||||
into the route.
|
|
||||||
*/
|
|
||||||
send_silence = true;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (Config->get_auto_input()) {
|
|
||||||
if (Config->get_monitoring_model() == SoftwareMonitoring) {
|
|
||||||
send_silence = false;
|
|
||||||
} else {
|
|
||||||
send_silence = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_diskstream->record_enabled()) {
|
|
||||||
if (Config->get_monitoring_model() == SoftwareMonitoring) {
|
|
||||||
send_silence = false;
|
|
||||||
} else {
|
|
||||||
send_silence = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
send_silence = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
if (send_silence) {
|
|
||||||
|
|
||||||
/* if we're sending silence, but we want the meters to show levels for the signal,
|
|
||||||
meter right here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_have_internal_generator) {
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, true);
|
|
||||||
} else {
|
|
||||||
if (_meter_point == MeterInput) {
|
|
||||||
just_meter_input (start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
passthru_silence (start_frame, end_frame, nframes, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* we're sending signal, but we may still want to meter the input.
|
|
||||||
*/
|
|
||||||
|
|
||||||
passthru (start_frame, end_frame, nframes, 0, (_meter_point == MeterInput));
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_outputs (nframes);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
|
MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
|
||||||
bool can_record, bool rec_monitors_input)
|
bool can_record, bool rec_monitors_input)
|
||||||
|
|
@ -509,7 +420,7 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
at least potentially (depending on monitoring options)
|
at least potentially (depending on monitoring options)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
passthru (start_frame, end_frame, nframes, 0, true);
|
passthru (start_frame, end_frame, nframes, 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|
@ -529,7 +440,7 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
diskstream->get_playback(bufs.get_midi(0), start_frame, end_frame);
|
diskstream->get_playback(bufs.get_midi(0), start_frame, end_frame);
|
||||||
|
|
||||||
process_output_buffers (bufs, start_frame, end_frame, nframes,
|
process_output_buffers (bufs, start_frame, end_frame, nframes,
|
||||||
(!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
|
(!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -538,68 +449,6 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
MidiTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|
||||||
bool can_record, bool rec_monitors_input)
|
|
||||||
{
|
|
||||||
if (n_outputs().n_midi() == 0 && _processors.empty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_active) {
|
|
||||||
silence (nframes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_silent = true;
|
|
||||||
apply_gain_automation = false;
|
|
||||||
|
|
||||||
silence (nframes);
|
|
||||||
|
|
||||||
return midi_diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MidiTrack::process_output_buffers (BufferSet& bufs,
|
|
||||||
nframes_t start_frame, nframes_t end_frame,
|
|
||||||
nframes_t nframes, bool with_processors, int declick,
|
|
||||||
bool meter)
|
|
||||||
{
|
|
||||||
/* There's no such thing as a MIDI bus for the time being.
|
|
||||||
* We'll do all the MIDI route work here for now, but the long-term goal is to have
|
|
||||||
* Route::process_output_buffers handle everything */
|
|
||||||
|
|
||||||
if (meter && (_meter_point == MeterInput || _meter_point == MeterPreFader)) {
|
|
||||||
_meter->run_in_place(bufs, start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run all processors
|
|
||||||
if (with_processors) {
|
|
||||||
Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
|
|
||||||
if (rm.locked()) {
|
|
||||||
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
|
||||||
bufs.set_count(ChanCount::max(bufs.count(), (*i)->output_streams()));
|
|
||||||
(*i)->run_in_place (bufs, start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meter && (_meter_point == MeterPostFader)) {
|
|
||||||
_meter->run_in_place(bufs, start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main output stage
|
|
||||||
if (muted()) {
|
|
||||||
IO::silence (nframes);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Write 'automation' controllers (e.g. CC events from a UI slider)
|
|
||||||
write_controller_messages(bufs.get_midi(0), start_frame, end_frame, nframes);
|
|
||||||
|
|
||||||
deliver_output(bufs, start_frame, end_frame, nframes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTrack::write_controller_messages(MidiBuffer& output_buf, nframes_t start, nframes_t end, nframes_t nframes)
|
MidiTrack::write_controller_messages(MidiBuffer& output_buf, nframes_t start, nframes_t end, nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -703,7 +703,7 @@ Multi2dPanner::set_state (const XMLNode& node)
|
||||||
/*---------------------------------------------------------------------- */
|
/*---------------------------------------------------------------------- */
|
||||||
|
|
||||||
Panner::Panner (string name, Session& s)
|
Panner::Panner (string name, Session& s)
|
||||||
: Processor(s, name, PostFader)
|
: Processor(s, name)
|
||||||
{
|
{
|
||||||
//set_name_old_auto (name);
|
//set_name_old_auto (name);
|
||||||
set_name (name);
|
set_name (name);
|
||||||
|
|
@ -1012,23 +1012,30 @@ Panner::set_automation_state (AutoState state)
|
||||||
AutoState
|
AutoState
|
||||||
Panner::automation_state () const
|
Panner::automation_state () const
|
||||||
{
|
{
|
||||||
|
boost::shared_ptr<AutomationList> l;
|
||||||
if (!empty()) {
|
if (!empty()) {
|
||||||
return ((AutomationList*)_streampanners.front()->pan_control()->list().get())->automation_state ();
|
boost::shared_ptr<AutomationControl> control = _streampanners.front()->pan_control();
|
||||||
} else {
|
if (control) {
|
||||||
return Off;
|
l = boost::dynamic_pointer_cast<AutomationList>(control->list());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return l ? l->automation_state() : Off;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoStyle
|
AutoStyle
|
||||||
Panner::automation_style () const
|
Panner::automation_style () const
|
||||||
{
|
{
|
||||||
|
boost::shared_ptr<AutomationList> l;
|
||||||
if (!empty()) {
|
if (!empty()) {
|
||||||
return ((AutomationList*)_streampanners.front()->pan_control()->list().get())->automation_style ();
|
boost::shared_ptr<AutomationControl> control = _streampanners.front()->pan_control();
|
||||||
} else {
|
if (control) {
|
||||||
return Absolute;
|
l = boost::dynamic_pointer_cast<AutomationList>(control->list());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return l ? l->automation_style() : Absolute;
|
||||||
|
}
|
||||||
|
|
||||||
struct PanPlugins {
|
struct PanPlugins {
|
||||||
string name;
|
string name;
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,10 @@ using namespace PBD;
|
||||||
|
|
||||||
const string PluginInsert::port_automation_node_name = "PortAutomation";
|
const string PluginInsert::port_automation_node_name = "PortAutomation";
|
||||||
|
|
||||||
PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placement placement)
|
PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
|
||||||
: Processor (s, plug->name(), placement),
|
: Processor (s, plug->name())
|
||||||
_signal_analysis_collected_nframes(0),
|
, _signal_analysis_collected_nframes(0)
|
||||||
_signal_analysis_collect_nframes_max(0)
|
, _signal_analysis_collect_nframes_max(0)
|
||||||
{
|
{
|
||||||
/* the first is the master */
|
/* the first is the master */
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placemen
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginInsert::PluginInsert (Session& s, const XMLNode& node)
|
PluginInsert::PluginInsert (Session& s, const XMLNode& node)
|
||||||
: Processor (s, "unnamed plugin insert", PreFader),
|
: Processor (s, "unnamed plugin insert"),
|
||||||
_signal_analysis_collected_nframes(0),
|
_signal_analysis_collected_nframes(0),
|
||||||
_signal_analysis_collect_nframes_max(0)
|
_signal_analysis_collect_nframes_max(0)
|
||||||
{
|
{
|
||||||
|
|
@ -160,14 +160,10 @@ PluginInsert::output_streams() const
|
||||||
ChanCount out = _plugins.front()->get_info()->n_outputs;
|
ChanCount out = _plugins.front()->get_info()->n_outputs;
|
||||||
|
|
||||||
if (out == ChanCount::INFINITE) {
|
if (out == ChanCount::INFINITE) {
|
||||||
|
|
||||||
return _plugins.front()->output_streams ();
|
return _plugins.front()->output_streams ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
out.set_audio (out.n_audio() * _plugins.size());
|
out.set_audio (out.n_audio() * _plugins.size());
|
||||||
out.set_midi (out.n_midi() * _plugins.size());
|
out.set_midi (out.n_midi() * _plugins.size());
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +178,6 @@ PluginInsert::input_streams() const
|
||||||
} else {
|
} else {
|
||||||
in.set_audio (in.n_audio() * _plugins.size());
|
in.set_audio (in.n_audio() * _plugins.size());
|
||||||
in.set_midi (in.n_midi() * _plugins.size());
|
in.set_midi (in.n_midi() * _plugins.size());
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -323,10 +318,10 @@ PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t off
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
|
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
|
||||||
(*i)->connect_and_run (bufs, in_map, out_map, nframes, offset);
|
(*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
in_map.offset(*t, input_streams().get(*t));
|
in_map.offset_to(*t, natural_input_streams().get(*t));
|
||||||
out_map.offset(*t, output_streams().get(*t));
|
out_map.offset_to(*t, natural_output_streams().get(*t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,61 +557,60 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
|
||||||
bool
|
bool
|
||||||
PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||||
{
|
{
|
||||||
|
// Plugin has flexible I/O, so delegate to it
|
||||||
if (_plugins.front()->reconfigurable_io()) {
|
if (_plugins.front()->reconfigurable_io()) {
|
||||||
/* plugin has flexible I/O, so delegate to it */
|
|
||||||
return _plugins.front()->can_support_io_configuration (in, out);
|
return _plugins.front()->can_support_io_configuration (in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChanCount inputs = _plugins[0]->get_info()->n_inputs;
|
||||||
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
|
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
|
||||||
ChanCount inputs = _plugins[0]->get_info()->n_inputs;
|
|
||||||
|
|
||||||
if ((inputs.n_total() == 0)
|
// Plugin inputs match requested inputs exactly
|
||||||
|| (inputs.n_total() == 1 && outputs == inputs)
|
if (inputs == in) {
|
||||||
|| (inputs.n_total() == 1 && outputs == inputs
|
|
||||||
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|
|
||||||
|| (inputs.n_midi() == 0 && in.n_midi() == 0)))
|
|
||||||
|| (inputs == in)) {
|
|
||||||
out = outputs;
|
out = outputs;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_replicate = true;
|
// See if replication is possible
|
||||||
|
// We can replicate if there exists a single factor f such that, for every type,
|
||||||
/* if number of inputs is a factor of the requested input
|
// the number of plugin inputs * f = the requested number of inputs
|
||||||
configuration for every type, we can replicate.
|
uint32_t f = 0;
|
||||||
*/
|
bool can_replicate = true;
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
if (inputs.get(*t) >= in.get(*t) || (inputs.get(*t) % in.get(*t) != 0)) {
|
// No inputs of this type
|
||||||
|
if (inputs.get(*t) == 0 && in.get(*t) == 0) {
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Plugin has more inputs than requested, can not replicate
|
||||||
|
} else if (inputs.get(*t) >= in.get(*t)) {
|
||||||
|
can_replicate = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Plugin inputs is not a factor of requested inputs, can not replicate
|
||||||
|
} else if (inputs.get(*t) == 0 || in.get(*t) % inputs.get(*t) != 0) {
|
||||||
|
can_replicate = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Potential factor not set yet
|
||||||
|
} else if (f == 0) {
|
||||||
|
f = in.get(*t) / inputs.get(*t);;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Factor for this type does not match another type, can not replicate
|
||||||
|
if (f != (in.get(*t) / inputs.get(*t))) {
|
||||||
can_replicate = false;
|
can_replicate = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!can_replicate || (in.n_total() % inputs.n_total() != 0)) {
|
if (can_replicate) {
|
||||||
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
|
out.set (*t, outputs.get(*t) * f);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputs.n_total() == 0) {
|
|
||||||
/* instrument plugin, always legal, but throws away any existing streams */
|
|
||||||
out = outputs;
|
|
||||||
} else if (inputs.n_total() == 1 && outputs == inputs
|
|
||||||
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|
|
||||||
|| (inputs.n_midi() == 0 && in.n_midi() == 0))) {
|
|
||||||
/* mono, single-typed plugin, replicate as needed to match in */
|
|
||||||
out = in;
|
|
||||||
} else if (inputs == in) {
|
|
||||||
/* exact match */
|
|
||||||
out = outputs;
|
|
||||||
} else {
|
|
||||||
/* replicate - note that we've already verified that
|
|
||||||
the replication count is constant across all data types.
|
|
||||||
*/
|
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
|
||||||
out.set (*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of plugin instances required to support a given channel configuration.
|
/* Number of plugin instances required to support a given channel configuration.
|
||||||
|
|
@ -798,7 +792,7 @@ PluginInsert::set_state(const XMLNode& node)
|
||||||
|
|
||||||
cnodes = (*niter)->children ("Port");
|
cnodes = (*niter)->children ("Port");
|
||||||
|
|
||||||
for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
|
for (iter = cnodes.begin(); iter != cnodes.end(); ++iter) {
|
||||||
|
|
||||||
child = *iter;
|
child = *iter;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ PluginManager::PluginManager ()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SLV2
|
#ifdef HAVE_SLV2
|
||||||
cerr << "Creating a new lv2 world\n";
|
cerr << "LV2: Creating world" << endl;
|
||||||
_lv2_world = new LV2World();
|
_lv2_world = new LV2World();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,7 +446,7 @@ msgid "automation list: no y-coordinate stored for control point (point ignored)
|
||||||
msgstr "λίστα αυτοματισμού: καμία y-συντεταγμένη αποθηκευμένη για σημείο ελέγχου (το σημείο αγνοήθηκε)"
|
msgstr "λίστα αυτοματισμού: καμία y-συντεταγμένη αποθηκευμένη για σημείο ελέγχου (το σημείο αγνοήθηκε)"
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:80
|
#: libs/ardour/configuration.cc:80
|
||||||
msgid "loading system configuration file %1"
|
msgid "Loading system configuration file %1"
|
||||||
msgstr "Ανάκληση αρχείου ρυθμίσεων συστήματος %1"
|
msgstr "Ανάκληση αρχείου ρυθμίσεων συστήματος %1"
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:83
|
#: libs/ardour/configuration.cc:83
|
||||||
|
|
@ -458,7 +458,7 @@ msgid "Ardour: system configuration file \"%1\" not loaded successfully."
|
||||||
msgstr "Ardour: το αρχείο διαρρυθμίσεως του συστήματος \"%1\" δεν φορτώθηκε επιτυχώς."
|
msgstr "Ardour: το αρχείο διαρρυθμίσεως του συστήματος \"%1\" δεν φορτώθηκε επιτυχώς."
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:105
|
#: libs/ardour/configuration.cc:105
|
||||||
msgid "loading user configuration file %1"
|
msgid "Loading user configuration file %1"
|
||||||
msgstr "Ανάκληση αρχείου ρυθμίσεων χρήστη %1"
|
msgstr "Ανάκληση αρχείου ρυθμίσεων χρήστη %1"
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:108
|
#: libs/ardour/configuration.cc:108
|
||||||
|
|
|
||||||
|
|
@ -467,7 +467,7 @@ msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:80
|
#: libs/ardour/configuration.cc:80
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "loading system configuration file %1"
|
msgid "Loading system configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ardour: impossibile leggere il file di configurazione di sistema \"%1\""
|
"Ardour: impossibile leggere il file di configurazione di sistema \"%1\""
|
||||||
|
|
||||||
|
|
@ -484,7 +484,7 @@ msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:105
|
#: libs/ardour/configuration.cc:105
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "loading user configuration file %1"
|
msgid "Loading user configuration file %1"
|
||||||
msgstr "Ardour: impossibile la lettura del file di configurazione \"%1\""
|
msgstr "Ardour: impossibile la lettura del file di configurazione \"%1\""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:108
|
#: libs/ardour/configuration.cc:108
|
||||||
|
|
|
||||||
|
|
@ -365,7 +365,7 @@ msgid "AutomationList: passed XML node called %1, not \"AutomationList\" - ignor
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:97
|
#: libs/ardour/configuration.cc:97
|
||||||
msgid "loading system configuration file %1"
|
msgid "Loading system configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:100
|
#: libs/ardour/configuration.cc:100
|
||||||
|
|
@ -381,7 +381,7 @@ msgid "your system Ardour configuration file is empty. This probably means that
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:131
|
#: libs/ardour/configuration.cc:131
|
||||||
msgid "loading user configuration file %1"
|
msgid "Loading user configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:134
|
#: libs/ardour/configuration.cc:134
|
||||||
|
|
|
||||||
|
|
@ -430,7 +430,7 @@ msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:80
|
#: libs/ardour/configuration.cc:80
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "loading system configuration file %1"
|
msgid "Loading system configuration file %1"
|
||||||
msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÒÏÇÒÁÍÍÙ \"%1\""
|
msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÒÏÇÒÁÍÍÙ \"%1\""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:83
|
#: libs/ardour/configuration.cc:83
|
||||||
|
|
@ -443,7 +443,7 @@ msgstr "Ardour:
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:105
|
#: libs/ardour/configuration.cc:105
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "loading user configuration file %1"
|
msgid "Loading user configuration file %1"
|
||||||
msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\""
|
msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:108
|
#: libs/ardour/configuration.cc:108
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:87
|
#: libs/ardour/configuration.cc:87
|
||||||
msgid "loading system configuration file %1"
|
msgid "Loading system configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:90
|
#: libs/ardour/configuration.cc:90
|
||||||
|
|
@ -435,7 +435,7 @@ msgid "Ardour: system configuration file \"%1\" not loaded successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:111
|
#: libs/ardour/configuration.cc:111
|
||||||
msgid "loading user configuration file %1"
|
msgid "Loading user configuration file %1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: libs/ardour/configuration.cc:114
|
#: libs/ardour/configuration.cc:114
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ Port::total_latency () const
|
||||||
int
|
int
|
||||||
Port::reestablish ()
|
Port::reestablish ()
|
||||||
{
|
{
|
||||||
|
cerr << "RE-REGISTER: " << _name.c_str() << endl;
|
||||||
_jack_port = jack_port_register (_engine->jack(), _name.c_str(), type().to_jack_type(), _flags, 0);
|
_jack_port = jack_port_register (_engine->jack(), _name.c_str(), type().to_jack_type(), _flags, 0);
|
||||||
|
|
||||||
if (_jack_port == 0) {
|
if (_jack_port == 0) {
|
||||||
|
|
|
||||||
|
|
@ -40,29 +40,15 @@ using namespace std;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
PortInsert::PortInsert (Session& s, Placement p)
|
PortInsert::PortInsert (Session& s)
|
||||||
: IOProcessor (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
|
: IOProcessor (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), "")
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
ProcessorCreated (this); /* EMIT SIGNAL */
|
ProcessorCreated (this); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PortInsert::init ()
|
|
||||||
{
|
|
||||||
if (_io->add_input_port ("", this)) {
|
|
||||||
error << _("PortInsert: cannot add input port") << endmsg;
|
|
||||||
throw failed_constructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_io->add_output_port ("", this)) {
|
|
||||||
error << _("PortInsert: cannot add output port") << endmsg;
|
|
||||||
throw failed_constructor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PortInsert::PortInsert (Session& s, const XMLNode& node)
|
PortInsert::PortInsert (Session& s, const XMLNode& node)
|
||||||
: IOProcessor (s, "unnamed port insert", PreFader)
|
: IOProcessor (s, "unnamed port insert")
|
||||||
{
|
{
|
||||||
if (set_state (node)) {
|
if (set_state (node)) {
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
|
|
@ -76,6 +62,15 @@ PortInsert::~PortInsert ()
|
||||||
GoingAway ();
|
GoingAway ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PortInsert::init ()
|
||||||
|
{
|
||||||
|
if (_io->ensure_io(output_streams(), input_streams(), false, this)) { // sic
|
||||||
|
error << _("PortInsert: cannot create ports") << endmsg;
|
||||||
|
throw failed_constructor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PortInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
PortInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
|
@ -180,10 +175,10 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
|
||||||
to the number of input ports we need.
|
to the number of input ports we need.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_io->set_output_maximum (in);
|
/*_io->set_output_maximum (in);
|
||||||
_io->set_output_minimum (in);
|
_io->set_output_minimum (in);
|
||||||
_io->set_input_maximum (out);
|
_io->set_input_maximum (out);
|
||||||
_io->set_input_minimum (out);
|
_io->set_input_minimum (out);*/
|
||||||
|
|
||||||
if (_io->ensure_io (out, in, false, this) != 0) {
|
if (_io->ensure_io (out, in, false, this) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,12 @@ sigc::signal<void,Processor*> Processor::ProcessorCreated;
|
||||||
// Always saved as Processor, but may be IOProcessor or Send in legacy sessions
|
// Always saved as Processor, but may be IOProcessor or Send in legacy sessions
|
||||||
const string Processor::state_node_name = "Processor";
|
const string Processor::state_node_name = "Processor";
|
||||||
|
|
||||||
Processor::Processor(Session& session, const string& name, Placement p)
|
Processor::Processor(Session& session, const string& name)
|
||||||
: SessionObject(session, name)
|
: SessionObject(session, name)
|
||||||
, AutomatableControls(session)
|
, AutomatableControls(session)
|
||||||
, _active(false)
|
, _active(false)
|
||||||
, _next_ab_is_active(false)
|
, _next_ab_is_active(false)
|
||||||
, _configured(false)
|
, _configured(false)
|
||||||
, _placement(p)
|
|
||||||
, _gui(0)
|
, _gui(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -75,15 +74,6 @@ Processor::set_sort_key (uint32_t key)
|
||||||
_sort_key = key;
|
_sort_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Processor::set_placement (Placement p)
|
|
||||||
{
|
|
||||||
if (_placement != p) {
|
|
||||||
_placement = p;
|
|
||||||
PlacementChanged (); /* EMIT SIGNAL */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XMLNode&
|
XMLNode&
|
||||||
Processor::get_state (void)
|
Processor::get_state (void)
|
||||||
{
|
{
|
||||||
|
|
@ -120,26 +110,28 @@ Processor::state (bool full_state)
|
||||||
|
|
||||||
node->add_property("name", _name);
|
node->add_property("name", _name);
|
||||||
node->add_property("active", active() ? "yes" : "no");
|
node->add_property("active", active() ? "yes" : "no");
|
||||||
node->add_property("placement", enum_2_string (_placement));
|
|
||||||
|
|
||||||
if (_extra_xml){
|
if (_extra_xml){
|
||||||
node->add_child_copy (*_extra_xml);
|
node->add_child_copy (*_extra_xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_state) {
|
if (full_state) {
|
||||||
|
|
||||||
XMLNode& automation = Automatable::get_automation_state();
|
XMLNode& automation = Automatable::get_automation_state();
|
||||||
|
if (!automation.children().empty()
|
||||||
for (set<Evoral::Parameter>::iterator x = _visible_controls.begin(); x != _visible_controls.end(); ++x) {
|
|| !automation.properties().empty()
|
||||||
if (x != _visible_controls.begin()) {
|
|| !_visible_controls.empty()) {
|
||||||
sstr << ' ';
|
|
||||||
|
for (set<Evoral::Parameter>::iterator x = _visible_controls.begin();
|
||||||
|
x != _visible_controls.end(); ++x) {
|
||||||
|
if (x != _visible_controls.begin()) {
|
||||||
|
sstr << ' ';
|
||||||
|
}
|
||||||
|
sstr << *x;
|
||||||
}
|
}
|
||||||
sstr << *x;
|
|
||||||
|
automation.add_property ("visible", sstr.str());
|
||||||
|
node->add_child_nocopy (automation);
|
||||||
}
|
}
|
||||||
|
|
||||||
automation.add_property ("visible", sstr.str());
|
|
||||||
|
|
||||||
node->add_child_nocopy (automation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *node;
|
return *node;
|
||||||
|
|
@ -164,7 +156,6 @@ Processor::set_state (const XMLNode& node)
|
||||||
|
|
||||||
if ((*niter)->name() == X_("Automation")) {
|
if ((*niter)->name() == X_("Automation")) {
|
||||||
|
|
||||||
|
|
||||||
XMLProperty *prop;
|
XMLProperty *prop;
|
||||||
|
|
||||||
if ((prop = (*niter)->property ("path")) != 0) {
|
if ((prop = (*niter)->property ("path")) != 0) {
|
||||||
|
|
@ -203,7 +194,8 @@ Processor::set_state (const XMLNode& node)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("active")) == 0) {
|
if ((prop = node.property ("active")) == 0) {
|
||||||
warning << _("XML node describing a processor is missing the `active' field, trying legacy active flag from child node") << endmsg;
|
warning << _("XML node describing a processor is missing the `active' field,"
|
||||||
|
"trying legacy active flag from child node") << endmsg;
|
||||||
if (legacy_active) {
|
if (legacy_active) {
|
||||||
prop = legacy_active;
|
prop = legacy_active;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -217,31 +209,6 @@ Processor::set_state (const XMLNode& node)
|
||||||
ActiveChanged (); /* EMIT_SIGNAL */
|
ActiveChanged (); /* EMIT_SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("placement")) == 0) {
|
|
||||||
warning << _("XML node describing a processor is missing the `placement' field, trying legacy placement flag from child node") << endmsg;
|
|
||||||
if (legacy_placement) {
|
|
||||||
prop = legacy_placement;
|
|
||||||
} else {
|
|
||||||
error << _("No child node with placement property") << endmsg;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hack to handle older sessions before we only used EnumWriter */
|
|
||||||
|
|
||||||
string pstr;
|
|
||||||
|
|
||||||
if (prop->value() == "pre") {
|
|
||||||
pstr = "PreFader";
|
|
||||||
} else if (prop->value() == "post") {
|
|
||||||
pstr = "PostFader";
|
|
||||||
} else {
|
|
||||||
pstr = prop->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Placement p = Placement (string_2_enum (pstr, p));
|
|
||||||
set_placement (p);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1434
libs/ardour/route.cc
1434
libs/ardour/route.cc
File diff suppressed because it is too large
Load diff
|
|
@ -35,15 +35,15 @@
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
Send::Send (Session& s, Placement p)
|
Send::Send (Session& s)
|
||||||
: IOProcessor (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1), p)
|
: IOProcessor (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1))
|
||||||
{
|
{
|
||||||
_metering = false;
|
_metering = false;
|
||||||
ProcessorCreated (this); /* EMIT SIGNAL */
|
ProcessorCreated (this); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
Send::Send (Session& s, const XMLNode& node)
|
Send::Send (Session& s, const XMLNode& node)
|
||||||
: IOProcessor (s, "send", PreFader)
|
: IOProcessor (s, "send")
|
||||||
{
|
{
|
||||||
_metering = false;
|
_metering = false;
|
||||||
|
|
||||||
|
|
@ -183,10 +183,10 @@ Send::configure_io (ChanCount in, ChanCount out)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_io->set_output_maximum (in);
|
/*_io->set_output_maximum (in);
|
||||||
_io->set_output_minimum (in);
|
_io->set_output_minimum (in);
|
||||||
_io->set_input_maximum (ChanCount::ZERO);
|
_io->set_input_maximum (ChanCount::ZERO);
|
||||||
_io->set_input_minimum (ChanCount::ZERO);
|
_io->set_input_minimum (ChanCount::ZERO);*/
|
||||||
|
|
||||||
if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
|
if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,9 @@ Session::Session (AudioEngine &eng,
|
||||||
string mix_template)
|
string mix_template)
|
||||||
|
|
||||||
: _engine (eng),
|
: _engine (eng),
|
||||||
|
phi (0),
|
||||||
|
target_phi (0),
|
||||||
|
phase (0),
|
||||||
_requested_return_frame (-1),
|
_requested_return_frame (-1),
|
||||||
_scratch_buffers(new BufferSet()),
|
_scratch_buffers(new BufferSet()),
|
||||||
_silent_buffers(new BufferSet()),
|
_silent_buffers(new BufferSet()),
|
||||||
|
|
@ -196,6 +199,9 @@ Session::Session (AudioEngine &eng,
|
||||||
nframes_t initial_length)
|
nframes_t initial_length)
|
||||||
|
|
||||||
: _engine (eng),
|
: _engine (eng),
|
||||||
|
phi (0),
|
||||||
|
target_phi (0),
|
||||||
|
phase (0),
|
||||||
_requested_return_frame (-1),
|
_requested_return_frame (-1),
|
||||||
_scratch_buffers(new BufferSet()),
|
_scratch_buffers(new BufferSet()),
|
||||||
_silent_buffers(new BufferSet()),
|
_silent_buffers(new BufferSet()),
|
||||||
|
|
@ -264,14 +270,18 @@ Session::Session (AudioEngine &eng,
|
||||||
int control_id = 1;
|
int control_id = 1;
|
||||||
|
|
||||||
if (control_out_channels) {
|
if (control_out_channels) {
|
||||||
shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
|
ChanCount count(DataType::AUDIO, control_out_channels);
|
||||||
|
shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut,
|
||||||
|
DataType::AUDIO, count, count));
|
||||||
r->set_remote_control_id (control_id++);
|
r->set_remote_control_id (control_id++);
|
||||||
|
|
||||||
rl.push_back (r);
|
rl.push_back (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (master_out_channels) {
|
if (master_out_channels) {
|
||||||
shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
|
ChanCount count(DataType::AUDIO, master_out_channels);
|
||||||
|
shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut,
|
||||||
|
DataType::AUDIO, count, count));
|
||||||
r->set_remote_control_id (control_id);
|
r->set_remote_control_id (control_id);
|
||||||
|
|
||||||
rl.push_back (r);
|
rl.push_back (r);
|
||||||
|
|
@ -543,7 +553,7 @@ Session::when_engine_running ()
|
||||||
try {
|
try {
|
||||||
XMLNode* child = 0;
|
XMLNode* child = 0;
|
||||||
|
|
||||||
_click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
|
_click_io.reset (new ClickIO (*this, "click"));
|
||||||
|
|
||||||
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
|
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
|
||||||
|
|
||||||
|
|
@ -656,36 +666,20 @@ Session::when_engine_running ()
|
||||||
/* create master/control ports */
|
/* create master/control ports */
|
||||||
|
|
||||||
if (_master_out) {
|
if (_master_out) {
|
||||||
uint32_t n;
|
|
||||||
|
|
||||||
/* force the master to ignore any later call to this */
|
/* force the master to ignore any later call to this */
|
||||||
|
|
||||||
if (_master_out->pending_state_node) {
|
if (_master_out->pending_state_node) {
|
||||||
_master_out->ports_became_legal();
|
_master_out->ports_became_legal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no panner resets till we are through */
|
/* no panner resets till we are through */
|
||||||
|
|
||||||
_master_out->defer_pan_reset ();
|
_master_out->defer_pan_reset ();
|
||||||
|
|
||||||
while (_master_out->n_inputs().n_audio()
|
/* create ports */
|
||||||
< _master_out->input_maximum().n_audio()) {
|
_master_out->set_input_minimum(ChanCount(DataType::AUDIO, n_physical_inputs));
|
||||||
if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
|
_master_out->set_output_minimum(ChanCount(DataType::AUDIO, n_physical_outputs));
|
||||||
error << _("cannot setup master inputs")
|
_master_out->ensure_io (
|
||||||
<< endmsg;
|
_master_out->input_minimum (), _master_out->output_minimum (),
|
||||||
break;
|
true, this);
|
||||||
}
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
while (_master_out->n_outputs().n_audio()
|
|
||||||
< _master_out->output_maximum().n_audio()) {
|
|
||||||
if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
|
|
||||||
error << _("cannot setup master outputs")
|
|
||||||
<< endmsg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_master_out->allow_pan_reset ();
|
_master_out->allow_pan_reset ();
|
||||||
|
|
||||||
|
|
@ -765,30 +759,15 @@ Session::hookup_io ()
|
||||||
IO::enable_ports ();
|
IO::enable_ports ();
|
||||||
|
|
||||||
if (_control_out) {
|
if (_control_out) {
|
||||||
uint32_t n;
|
|
||||||
vector<string> cports;
|
vector<string> cports;
|
||||||
|
|
||||||
while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
|
_control_out->ensure_io(
|
||||||
if (_control_out->add_input_port ("", this)) {
|
_control_out->input_minimum(), _control_out->output_minimum(),
|
||||||
error << _("cannot setup control inputs")
|
false, this);
|
||||||
<< endmsg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
|
|
||||||
if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
|
|
||||||
error << _("cannot set up master outputs")
|
|
||||||
<< endmsg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
|
uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
|
||||||
|
|
||||||
for (n = 0; n < ni; ++n) {
|
for (uint32_t n = 0; n < ni; ++n) {
|
||||||
cports.push_back (_control_out->input(n)->name());
|
cports.push_back (_control_out->input(n)->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1313,7 +1292,6 @@ Session::set_block_size (nframes_t nframes)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
current_block_size = nframes;
|
current_block_size = nframes;
|
||||||
|
|
||||||
ensure_buffers(_scratch_buffers->available());
|
ensure_buffers(_scratch_buffers->available());
|
||||||
|
|
@ -1757,14 +1735,13 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||||
uint32_t nphysical_out = physoutputs.size();
|
uint32_t nphysical_out = physoutputs.size();
|
||||||
|
|
||||||
for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
|
for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
|
||||||
|
|
||||||
port = "";
|
port = "";
|
||||||
|
|
||||||
if (Config->get_output_auto_connect() & AutoConnectPhysical) {
|
if (Config->get_output_auto_connect() & AutoConnectPhysical) {
|
||||||
port = physoutputs[(channels_used+x)%nphysical_out];
|
port = physoutputs[(channels_used+x)%nphysical_out];
|
||||||
} else if (Config->get_output_auto_connect() & AutoConnectMaster) {
|
} else if (Config->get_output_auto_connect() & AutoConnectMaster) {
|
||||||
if (_master_out) {
|
if (_master_out && _master_out->n_inputs().n_audio() > 0) {
|
||||||
port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
|
port = _master_out->input (x % _master_out->n_inputs().n_audio())->name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1906,7 +1883,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
|
||||||
} while (bus_id < (UINT_MAX-1));
|
} while (bus_id < (UINT_MAX-1));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
|
shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
|
||||||
|
|
||||||
if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
|
if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
|
||||||
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
|
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
|
||||||
|
|
|
||||||
|
|
@ -339,8 +339,7 @@ Session::second_stage_init (bool new_session)
|
||||||
/* handle this one in a different way than all others, so that its clear what happened */
|
/* handle this one in a different way than all others, so that its clear what happened */
|
||||||
|
|
||||||
catch (AudioEngine::PortRegistrationFailure& err) {
|
catch (AudioEngine::PortRegistrationFailure& err) {
|
||||||
error << _("Unable to create all required ports")
|
error << err.what() << endmsg;
|
||||||
<< endmsg;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2831,7 +2830,12 @@ void
|
||||||
Session::set_deletion_in_progress ()
|
Session::set_deletion_in_progress ()
|
||||||
{
|
{
|
||||||
_state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
|
_state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::clear_deletion_in_progress ()
|
||||||
|
{
|
||||||
|
_state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& destination, sframes_t sour
|
||||||
const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
|
const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
|
||||||
|
|
||||||
if (_last_read_end == 0 || start != _last_read_end) {
|
if (_last_read_end == 0 || start != _last_read_end) {
|
||||||
cerr << "SMFSource::read_unlocked seeking to " << start << endl;
|
//cerr << "SMFSource::read_unlocked seeking to " << start << endl;
|
||||||
Evoral::SMF::seek_to_start();
|
Evoral::SMF::seek_to_start();
|
||||||
while (time < start_ticks) {
|
while (time < start_ticks) {
|
||||||
ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
|
ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
|
||||||
|
|
@ -374,10 +374,10 @@ SMFSource::load_model (bool lock, bool force_reload)
|
||||||
|
|
||||||
if (! _model) {
|
if (! _model) {
|
||||||
_model = boost::shared_ptr<MidiModel>(new MidiModel(this));
|
_model = boost::shared_ptr<MidiModel>(new MidiModel(this));
|
||||||
cerr << _name << " loaded new model " << _model.get() << endl;
|
//cerr << _name << " loaded new model " << _model.get() << endl;
|
||||||
} else {
|
} else {
|
||||||
cerr << _name << " reloading model " << _model.get()
|
/*cerr << _name << " reloading model " << _model.get()
|
||||||
<< " (" << _model->n_notes() << " notes)" <<endl;
|
<< " (" << _model->n_notes() << " notes)" << endl;*/
|
||||||
_model->clear();
|
_model->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ find_session_templates (vector<TemplateInfo>& template_names)
|
||||||
template_names.push_back (rti);
|
template_names.push_back (rti);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (templates);
|
delete templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,19 @@
|
||||||
#include <sigc++/retype_return.h>
|
#include <sigc++/retype_return.h>
|
||||||
#include <sigc++/bind.h>
|
#include <sigc++/bind.h>
|
||||||
|
|
||||||
#include "ardour/track.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/diskstream.h"
|
#include "ardour/audioplaylist.h"
|
||||||
#include "ardour/session.h"
|
|
||||||
#include "ardour/io_processor.h"
|
|
||||||
#include "ardour/audioregion.h"
|
#include "ardour/audioregion.h"
|
||||||
#include "ardour/audiosource.h"
|
#include "ardour/audiosource.h"
|
||||||
#include "ardour/route_group_specialized.h"
|
#include "ardour/diskstream.h"
|
||||||
#include "ardour/processor.h"
|
#include "ardour/io_processor.h"
|
||||||
#include "ardour/audioplaylist.h"
|
|
||||||
#include "ardour/panner.h"
|
#include "ardour/panner.h"
|
||||||
#include "ardour/utils.h"
|
|
||||||
#include "ardour/port.h"
|
#include "ardour/port.h"
|
||||||
|
#include "ardour/processor.h"
|
||||||
|
#include "ardour/route_group_specialized.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
|
#include "ardour/track.h"
|
||||||
|
#include "ardour/utils.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -40,7 +41,7 @@ using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
|
Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
|
||||||
: Route (sess, name, 1, -1, -1, -1, flag, default_type)
|
: Route (sess, name, flag, default_type)
|
||||||
, _rec_enable_control (new RecEnableControllable(*this))
|
, _rec_enable_control (new RecEnableControllable(*this))
|
||||||
{
|
{
|
||||||
_declickable = true;
|
_declickable = true;
|
||||||
|
|
@ -231,7 +232,114 @@ Track::set_latency_delay (nframes_t longest_session_latency)
|
||||||
void
|
void
|
||||||
Track::zero_diskstream_id_in_xml (XMLNode& node)
|
Track::zero_diskstream_id_in_xml (XMLNode& node)
|
||||||
{
|
{
|
||||||
if (node.property ("diskstream-id")) {
|
if (node.property ("diskstream-id")) {
|
||||||
node.add_property ("diskstream-id", "0");
|
node.add_property ("diskstream-id", "0");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Track::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
|
bool session_state_changing, bool can_record, bool rec_monitors_input)
|
||||||
|
{
|
||||||
|
if (n_outputs().n_total() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_active) {
|
||||||
|
silence (nframes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session_state_changing) {
|
||||||
|
|
||||||
|
/* XXX is this safe to do against transport state changes? */
|
||||||
|
|
||||||
|
passthru_silence (start_frame, end_frame, nframes, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diskstream()->check_record_status (start_frame, nframes, can_record);
|
||||||
|
|
||||||
|
bool send_silence;
|
||||||
|
|
||||||
|
if (_have_internal_generator) {
|
||||||
|
/* since the instrument has no input streams,
|
||||||
|
there is no reason to send any signal
|
||||||
|
into the route.
|
||||||
|
*/
|
||||||
|
send_silence = true;
|
||||||
|
} else {
|
||||||
|
if (!Config->get_tape_machine_mode()) {
|
||||||
|
/*
|
||||||
|
ADATs work in a strange way..
|
||||||
|
they monitor input always when stopped.and auto-input is engaged.
|
||||||
|
*/
|
||||||
|
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
||||||
|
&& (Config->get_auto_input () || _diskstream->record_enabled())) {
|
||||||
|
send_silence = false;
|
||||||
|
} else {
|
||||||
|
send_silence = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
Other machines switch to input on stop if the track is record enabled,
|
||||||
|
regardless of the auto input setting (auto input only changes the
|
||||||
|
monitoring state when the transport is rolling)
|
||||||
|
*/
|
||||||
|
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
||||||
|
&& _diskstream->record_enabled()) {
|
||||||
|
send_silence = false;
|
||||||
|
} else {
|
||||||
|
send_silence = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_amp->apply_gain_automation(false);
|
||||||
|
|
||||||
|
if (send_silence) {
|
||||||
|
|
||||||
|
/* if we're sending silence, but we want the meters to show levels for the signal,
|
||||||
|
meter right here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_have_internal_generator) {
|
||||||
|
passthru_silence (start_frame, end_frame, nframes, 0);
|
||||||
|
} else {
|
||||||
|
if (_meter_point == MeterInput) {
|
||||||
|
just_meter_input (start_frame, end_frame, nframes);
|
||||||
|
}
|
||||||
|
passthru_silence (start_frame, end_frame, nframes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* we're sending signal, but we may still want to meter the input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
passthru (start_frame, end_frame, nframes, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Track::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||||
|
bool can_record, bool rec_monitors_input)
|
||||||
|
{
|
||||||
|
if (n_outputs().n_total() == 0 && _processors.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_active) {
|
||||||
|
silence (nframes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_silent = true;
|
||||||
|
_amp->apply_gain_automation(false);
|
||||||
|
|
||||||
|
silence (nframes);
|
||||||
|
|
||||||
|
return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,9 @@ def build(bld):
|
||||||
buffer_set.cc
|
buffer_set.cc
|
||||||
bundle.cc
|
bundle.cc
|
||||||
chan_count.cc
|
chan_count.cc
|
||||||
|
chan_mapping.cc
|
||||||
configuration.cc
|
configuration.cc
|
||||||
|
control_outputs.cc
|
||||||
control_protocol_manager.cc
|
control_protocol_manager.cc
|
||||||
control_protocol_search_path.cc
|
control_protocol_search_path.cc
|
||||||
crossfade.cc
|
crossfade.cc
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,15 @@ public:
|
||||||
|
|
||||||
virtual void set_float(float val, bool to_list=false, FrameTime frame=0);
|
virtual void set_float(float val, bool to_list=false, FrameTime frame=0);
|
||||||
virtual float get_float(bool from_list=false, FrameTime frame=0) const;
|
virtual float get_float(bool from_list=false, FrameTime frame=0) const;
|
||||||
virtual float user_float() const;
|
|
||||||
|
|
||||||
|
/** Get the latest user-set value
|
||||||
|
* (which may not equal get_value() when automation is playing back).
|
||||||
|
*
|
||||||
|
* Automation write/touch works by periodically sampling this value
|
||||||
|
* and adding it to the ControlList.
|
||||||
|
*/
|
||||||
|
float user_float() const { return _user_value; }
|
||||||
|
|
||||||
void set_list(boost::shared_ptr<ControlList>);
|
void set_list(boost::shared_ptr<ControlList>);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ public:
|
||||||
|
|
||||||
bool find_next_event(FrameTime start, FrameTime end, ControlEvent& ev) const;
|
bool find_next_event(FrameTime start, FrameTime end, ControlEvent& ev) const;
|
||||||
|
|
||||||
virtual bool empty() const { return _controls.size() == 0; }
|
virtual bool controls_empty() const { return _controls.size() == 0; }
|
||||||
virtual void clear();
|
virtual void clear_controls();
|
||||||
|
|
||||||
void what_has_data(std::set<Parameter>&) const;
|
void what_has_data(std::set<Parameter>&) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public:
|
||||||
inline const boost::shared_ptr< Note<Time> > note_at(size_t i) { return _notes[i]; }
|
inline const boost::shared_ptr< Note<Time> > note_at(size_t i) { return _notes[i]; }
|
||||||
|
|
||||||
inline size_t n_notes() const { return _notes.size(); }
|
inline size_t n_notes() const { return _notes.size(); }
|
||||||
inline bool empty() const { return _notes.size() == 0 && ControlSet::empty(); }
|
inline bool empty() const { return _notes.size() == 0 && ControlSet::controls_empty(); }
|
||||||
|
|
||||||
inline static bool note_time_comparator(const boost::shared_ptr< const Note<Time> >& a,
|
inline static bool note_time_comparator(const boost::shared_ptr< const Note<Time> >& a,
|
||||||
const boost::shared_ptr< const Note<Time> >& b) {
|
const boost::shared_ptr< const Note<Time> >& b) {
|
||||||
|
|
|
||||||
|
|
@ -54,19 +54,6 @@ Control::set_float(float value, bool to_list, FrameTime frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Get the latest user-set value, which may not equal get_value() when automation
|
|
||||||
* is playing back, etc.
|
|
||||||
*
|
|
||||||
* Automation write/touch works by periodically sampling this value and adding it
|
|
||||||
* to the AutomationList.
|
|
||||||
*/
|
|
||||||
float
|
|
||||||
Control::user_float() const
|
|
||||||
{
|
|
||||||
return _user_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Control::set_list(boost::shared_ptr<ControlList> list)
|
Control::set_list(boost::shared_ptr<ControlList> list)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ ControlSet::find_next_event (FrameTime now, FrameTime end, ControlEvent& next_ev
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ControlSet::clear ()
|
ControlSet::clear_controls ()
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (_control_lock);
|
Glib::Mutex::Lock lm (_control_lock);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue