mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
Another not-quite-there-but-better commit.
Brought plugin automation into the fold of new automation system. Fixed plugin automation, broke panner automation :] (pending Panner work). Made AutomationController better at automatically following it's controller value (mimic what gain meter does). Fixed some visible automation track bugs (but still broken WRT serialization). git-svn-id: svn://localhost/ardour2/trunk@2092 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
685fa95e72
commit
bbf4175713
49 changed files with 728 additions and 2065 deletions
|
|
@ -96,10 +96,7 @@ ardour_ui_options.cc
|
|||
audio_clock.cc
|
||||
audio_time_axis.cc
|
||||
audio_region_editor.cc
|
||||
automation_gain_line.cc
|
||||
automation_midi_cc_line.cc
|
||||
automation_line.cc
|
||||
automation_pan_line.cc
|
||||
automation_time_axis.cc
|
||||
automation_controller.cc
|
||||
midi_time_axis.cc
|
||||
|
|
@ -144,8 +141,6 @@ export_dialog.cc
|
|||
export_session_dialog.cc
|
||||
export_region_dialog.cc
|
||||
export_range_markers_dialog.cc
|
||||
gain_automation_time_axis.cc
|
||||
midi_controller_time_axis.cc
|
||||
gain_meter.cc
|
||||
ghostregion.cc
|
||||
gtk-custom-hruler.c
|
||||
|
|
@ -162,7 +157,6 @@ mixer_ui.cc
|
|||
new_session_dialog.cc
|
||||
option_editor.cc
|
||||
opts.cc
|
||||
pan_automation_time_axis.cc
|
||||
panner.cc
|
||||
panner2d.cc
|
||||
panner_ui.cc
|
||||
|
|
@ -171,8 +165,6 @@ plugin_selector.cc
|
|||
plugin_ui.cc
|
||||
prompter.cc
|
||||
public_editor.cc
|
||||
processor_automation_line.cc
|
||||
processor_automation_time_axis.cc
|
||||
processor_box.cc
|
||||
region_gain_line.cc
|
||||
region_selection.cc
|
||||
|
|
|
|||
|
|
@ -49,14 +49,12 @@
|
|||
|
||||
#include "ardour_ui.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "automation_gain_line.h"
|
||||
#include "automation_pan_line.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "enums.h"
|
||||
#include "gain_automation_time_axis.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "keyboard.h"
|
||||
#include "pan_automation_time_axis.h"
|
||||
#include "playlist_selector.h"
|
||||
#include "prompter.h"
|
||||
#include "public_editor.h"
|
||||
|
|
@ -291,38 +289,19 @@ AudioTimeAxisView::create_automation_child (ParamID param)
|
|||
return;
|
||||
}
|
||||
|
||||
GainAutomationTimeAxisView* gain_track = new GainAutomationTimeAxisView (_session,
|
||||
_route,
|
||||
boost::shared_ptr<AutomationTimeAxisView> gain_track(new AutomationTimeAxisView (_session,
|
||||
_route, _route, c,
|
||||
editor,
|
||||
*this,
|
||||
parent_canvas,
|
||||
_route->describe_parameter(param),
|
||||
c);
|
||||
|
||||
AutomationLine* line = new AutomationGainLine ("automation gain",
|
||||
*gain_track,
|
||||
*gain_track->canvas_display,
|
||||
c->list());
|
||||
|
||||
line->set_line_color (ARDOUR_UI::config()->canvasvar_AutomationLine.get());
|
||||
|
||||
gain_track->add_line (*line);
|
||||
c->list()->param_id().to_string() /* FIXME: correct state name? */));
|
||||
|
||||
add_automation_child(ParamID(GainAutomation), gain_track);
|
||||
|
||||
} else if (param.type() == PanAutomation) {
|
||||
|
||||
PanAutomationTimeAxisView* pan_track = new PanAutomationTimeAxisView (_session,
|
||||
_route,
|
||||
editor,
|
||||
*this,
|
||||
parent_canvas,
|
||||
_route->describe_parameter(param));
|
||||
|
||||
ensure_xml_node ();
|
||||
|
||||
add_automation_child(ParamID(PanAutomation), pan_track);
|
||||
|
||||
update_pans ();
|
||||
|
||||
} else {
|
||||
|
|
@ -334,41 +313,33 @@ void
|
|||
AudioTimeAxisView::update_pans ()
|
||||
{
|
||||
Panner::iterator p;
|
||||
|
||||
RouteAutomationNode* ran = automation_track(PanAutomation);
|
||||
if (!ran) {
|
||||
warning << _route << " has no pan automation track" << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
AutomationTimeAxisView* pan_track = ran->track;
|
||||
|
||||
pan_track->clear_lines ();
|
||||
|
||||
/* we don't draw lines for "greater than stereo" panning.
|
||||
*/
|
||||
/* This is a filthy kludge until the panner stuff gets up to speed. */
|
||||
|
||||
if (_route->n_outputs().n_audio() > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = _route->panner().begin(); p != _route->panner().end(); ++p) {
|
||||
|
||||
AutomationLine* line;
|
||||
|
||||
line = new AutomationPanLine ("automation pan", *pan_track,
|
||||
*pan_track->canvas_display,
|
||||
(*p)->automation());
|
||||
|
||||
if (p == _route->panner().begin()) {
|
||||
/* first line is a nice orange */
|
||||
line->set_line_color (ARDOUR_UI::config()->canvasvar_AutomationLine.get());
|
||||
} else {
|
||||
/* second line is a nice blue */
|
||||
line->set_line_color (ARDOUR_UI::config()->canvasvar_AutomationLine.get());
|
||||
/* Remove all our old automation tracks. Slowly. */
|
||||
while (true) {
|
||||
bool found = false;
|
||||
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
||||
if (i->first.type() == PanAutomation) {
|
||||
_automation_tracks.erase(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pan_track->add_line (*line);
|
||||
if ( ! found)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Man I hate that damn stereo->stereo panner */
|
||||
for (p = _route->panner().begin(); p != _route->panner().end(); ++p) {
|
||||
boost::shared_ptr<AutomationTimeAxisView> pan_track(new AutomationTimeAxisView (_session,
|
||||
_route, _route/*FIXME*/, (*p)->pan_control(),
|
||||
editor,
|
||||
*this,
|
||||
parent_canvas,
|
||||
_route->describe_parameter((*p)->pan_control()->list()->param_id()),
|
||||
(*p)->pan_control()->list()->param_id().to_string() /* FIXME: correct state name? */));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@
|
|||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include "automation_controller.h"
|
||||
#include "ardour/automation_event.h"
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "utils.h"
|
||||
#include "automation_controller.h"
|
||||
#include "gui_thread.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -51,6 +52,8 @@ AutomationController::AutomationController(boost::shared_ptr<AutomationControl>
|
|||
|
||||
_screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
|
||||
mem_fun (*this, &AutomationController::display_effective_value));
|
||||
|
||||
ac->Changed.connect (mem_fun(*this, &AutomationController::value_changed));
|
||||
}
|
||||
|
||||
AutomationController::~AutomationController()
|
||||
|
|
@ -71,14 +74,15 @@ AutomationController::create(Session& s, boost::shared_ptr<AutomationList> al, b
|
|||
void
|
||||
AutomationController::update_label(char* label, int label_len)
|
||||
{
|
||||
//cerr << "Controller label: " << label << endl;
|
||||
if (label && label_len)
|
||||
snprintf(label, label_len, "%.3f", _controllable->get_value());
|
||||
}
|
||||
|
||||
void
|
||||
AutomationController::display_effective_value()
|
||||
{
|
||||
if ( ! _controllable->list()->automation_playback())
|
||||
return;
|
||||
//if ( ! _controllable->list()->automation_playback())
|
||||
// return;
|
||||
|
||||
float value = _controllable->get_value();
|
||||
|
||||
|
|
@ -108,3 +112,28 @@ AutomationController::end_touch()
|
|||
{
|
||||
_controllable->list()->stop_touch();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationController::automation_state_changed ()
|
||||
{
|
||||
ENSURE_GUI_THREAD(mem_fun(*this, &AutomationController::automation_state_changed));
|
||||
|
||||
bool x = (_controllable->list()->automation_state() != Off);
|
||||
|
||||
/* start watching automation so that things move */
|
||||
|
||||
_screen_update_connection.disconnect();
|
||||
|
||||
if (x) {
|
||||
_screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
|
||||
mem_fun (*this, &AutomationController::display_effective_value));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutomationController::value_changed ()
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (
|
||||
mem_fun(*this, &AutomationController::display_effective_value));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public:
|
|||
~AutomationController();
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> controllable() { return _controllable; }
|
||||
|
||||
Gtk::Adjustment* adjustment() { return _adjustment; }
|
||||
|
||||
void update_label(char* label, int label_len);
|
||||
void display_effective_value();
|
||||
|
|
@ -52,6 +54,9 @@ private:
|
|||
void start_touch();
|
||||
void end_touch();
|
||||
|
||||
void value_changed();
|
||||
void automation_state_changed();
|
||||
|
||||
bool _ignore_change;
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
|
||||
Gtk::Adjustment* _adjustment;
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2003 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 <sigc++/signal.h>
|
||||
|
||||
#include <ardour/curve.h>
|
||||
#include <pbd/fastlog.h>
|
||||
|
||||
#include "public_editor.h"
|
||||
#include "automation_gain_line.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AutomationGainLine::AutomationGainLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> l)
|
||||
|
||||
: AutomationLine (name, tv, parent, l)
|
||||
{
|
||||
set_verbose_cursor_uses_gain_mapping (true);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationGainLine::view_to_model_y (double& y)
|
||||
{
|
||||
y = slider_position_to_gain (y);
|
||||
y = max (0.0, y);
|
||||
y = min (2.0, y);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationGainLine::model_to_view_y (double& y)
|
||||
{
|
||||
y = gain_to_slider_position (y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_automation_gain_line_h__
|
||||
#define __ardour_gtk_automation_gain_line_h__
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_line.h"
|
||||
|
||||
class TimeAxisView;
|
||||
|
||||
class AutomationGainLine : public AutomationLine
|
||||
{
|
||||
public:
|
||||
AutomationGainLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
||||
|
||||
void view_to_model_y (double&);
|
||||
void model_to_view_y (double&);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ardour_gtk_automation_gain_line_h__ */
|
||||
|
||||
|
||||
|
|
@ -248,6 +248,9 @@ AutomationLine::AutomationLine (const string & name, TimeAxisView& tv, ArdourCan
|
|||
alist->StateChanged.connect (mem_fun(*this, &AutomationLine::list_changed));
|
||||
|
||||
trackview.session().register_with_memento_command_factory(alist->id(), this);
|
||||
|
||||
if (alist->param_id().type() == GainAutomation)
|
||||
set_verbose_cursor_uses_gain_mapping (true);
|
||||
}
|
||||
|
||||
AutomationLine::~AutomationLine ()
|
||||
|
|
@ -1290,3 +1293,34 @@ AutomationLine::set_state (const XMLNode &node)
|
|||
/* function as a proxy for the model */
|
||||
return alist->set_state (node);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationLine::view_to_model_y (double& y)
|
||||
{
|
||||
if (alist->param_id().type() == GainAutomation) {
|
||||
y = slider_position_to_gain (y);
|
||||
y = max (0.0, y);
|
||||
y = min (2.0, y);
|
||||
} else if (alist->param_id().type() == PanAutomation) {
|
||||
// vertical coordinate axis reversal
|
||||
y = 1.0 - y;
|
||||
} else if (alist->param_id().type() == MidiCCAutomation) {
|
||||
y = (int)(y * 127.0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutomationLine::model_to_view_y (double& y)
|
||||
{
|
||||
if (alist->param_id().type() == GainAutomation) {
|
||||
y = gain_to_slider_position (y);
|
||||
} else if (alist->param_id().type() == PanAutomation) {
|
||||
// vertical coordinate axis reversal
|
||||
y = 1.0 - y;
|
||||
} else if (alist->param_id().type() == MidiCCAutomation) {
|
||||
y = y / 127.0;
|
||||
} else if (alist->param_id().type() == PluginAutomation) {
|
||||
y = (y - alist->get_min_y()) / (double)(alist->get_max_y()- alist->get_min_y());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,8 +147,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
|
|||
void hide_selection ();
|
||||
|
||||
virtual string get_verbose_cursor_string (float);
|
||||
virtual void view_to_model_y (double&) = 0;
|
||||
virtual void model_to_view_y (double&) = 0;
|
||||
virtual void view_to_model_y (double&);
|
||||
virtual void model_to_view_y (double&);
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationList> the_list() const { return alist; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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 <sigc++/signal.h>
|
||||
|
||||
#include <ardour/curve.h>
|
||||
|
||||
#include "automation_midi_cc_line.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AutomationMidiCCLine::AutomationMidiCCLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> l)
|
||||
|
||||
: AutomationLine (name, tv, parent, l)
|
||||
{
|
||||
set_verbose_cursor_uses_gain_mapping (true);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationMidiCCLine::view_to_model_y (double& y)
|
||||
{
|
||||
assert(y >= 0);
|
||||
assert(y <= 1);
|
||||
|
||||
y = (int)(y * 127.0);
|
||||
|
||||
assert(y >= 0);
|
||||
assert(y <= 127);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationMidiCCLine::model_to_view_y (double& y)
|
||||
{
|
||||
assert(y >= 0);
|
||||
assert(y <= 127);
|
||||
|
||||
y = y / 127.0;
|
||||
|
||||
assert(y >= 0);
|
||||
assert(y <= 1);
|
||||
}
|
||||
|
||||
string
|
||||
AutomationMidiCCLine::get_verbose_cursor_string (float fraction)
|
||||
{
|
||||
static const size_t MAX_VAL_LEN = 4; // 4 for "127\0"
|
||||
char buf[MAX_VAL_LEN];
|
||||
|
||||
double cc_val = fraction;
|
||||
view_to_model_y(cc_val); // 0..127
|
||||
|
||||
snprintf (buf, MAX_VAL_LEN, "%u", (unsigned)cc_val);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_automation_midi_cc_line_h__
|
||||
#define __ardour_gtk_automation_midi_cc_line_h__
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_line.h"
|
||||
|
||||
class TimeAxisView;
|
||||
|
||||
class AutomationMidiCCLine : public AutomationLine
|
||||
{
|
||||
public:
|
||||
AutomationMidiCCLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
||||
|
||||
void view_to_model_y (double&);
|
||||
void model_to_view_y (double&);
|
||||
|
||||
string get_verbose_cursor_string (float);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ardour_gtk_automation_midi_cc_line_h__ */
|
||||
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2003 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 <sigc++/signal.h>
|
||||
|
||||
#include <ardour/curve.h>
|
||||
|
||||
#include "canvas_impl.h"
|
||||
#include "public_editor.h"
|
||||
#include "automation_pan_line.h"
|
||||
#include "utils.h"
|
||||
#include <cmath>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AutomationPanLine::AutomationPanLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> l)
|
||||
|
||||
: AutomationLine (name, tv, parent, l)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AutomationPanLine::view_to_model_y (double& y)
|
||||
{
|
||||
// vertical coordinate axis reversal
|
||||
y = 1.0 - y;
|
||||
}
|
||||
|
||||
void
|
||||
AutomationPanLine::model_to_view_y (double& y)
|
||||
{
|
||||
// vertical coordinate axis reversal
|
||||
y = 1.0 - y;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_automation_pan_line_h__
|
||||
#define __ardour_gtk_automation_pan_line_h__
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_line.h"
|
||||
|
||||
class TimeAxisView;
|
||||
|
||||
class AutomationPanLine : public AutomationLine
|
||||
{
|
||||
public:
|
||||
AutomationPanLine (const string & name, TimeAxisView&, ArdourCanvas::Group& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
||||
|
||||
void view_to_model_y (double&);
|
||||
void model_to_view_y (double&);
|
||||
|
||||
private:
|
||||
vector<ArdourCanvas::Item*> lines;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ardour_gtk_automation_pan_line_h__ */
|
||||
|
||||
|
||||
|
|
@ -47,13 +47,20 @@ using namespace Editing;
|
|||
Pango::FontDescription AutomationTimeAxisView::name_font;
|
||||
bool AutomationTimeAxisView::have_name_font = false;
|
||||
|
||||
AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e, TimeAxisView& rent,
|
||||
ArdourCanvas::Canvas& canvas, const string & nom,
|
||||
const string & state_name, const string & nomparent)
|
||||
AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
|
||||
boost::shared_ptr<Automatable> a, boost::shared_ptr<AutomationControl> c,
|
||||
PublicEditor& e, TimeAxisView& rent,
|
||||
ArdourCanvas::Canvas& canvas, const string & nom,
|
||||
const string & state_name, const string & nomparent)
|
||||
|
||||
: AxisView (s),
|
||||
TimeAxisView (s, e, &rent, canvas),
|
||||
route (r),
|
||||
_route (r),
|
||||
_control (c),
|
||||
_automatable (a),
|
||||
_controller(AutomationController::create(s, c->list(), c)),
|
||||
_base_rect (0),
|
||||
_xml_node (0),
|
||||
_name (nom),
|
||||
_state_name (state_name),
|
||||
height_button (_("h")),
|
||||
|
|
@ -74,20 +81,20 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
ignore_state_request = false;
|
||||
first_call_to_set_height = true;
|
||||
|
||||
base_rect = new SimpleRect(*canvas_display);
|
||||
base_rect->property_x1() = 0.0;
|
||||
base_rect->property_y1() = 0.0;
|
||||
base_rect->property_x2() = editor.frame_to_pixel (max_frames);
|
||||
base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackOutline.get();
|
||||
/* outline ends and bottom */
|
||||
base_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);
|
||||
base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackFill.get();
|
||||
//base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EnteredControlPoint.get();
|
||||
_base_rect = new SimpleRect(*canvas_display);
|
||||
_base_rect->property_x1() = 0.0;
|
||||
_base_rect->property_y1() = 0.0;
|
||||
_base_rect->property_x2() = editor.frame_to_pixel (max_frames);
|
||||
_base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackOutline.get();
|
||||
|
||||
base_rect->set_data ("trackview", this);
|
||||
/* outline ends and bottom */
|
||||
_base_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);
|
||||
_base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackFill.get();
|
||||
|
||||
_base_rect->set_data ("trackview", this);
|
||||
|
||||
base_rect->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_automation_track_event),
|
||||
base_rect, this));
|
||||
_base_rect->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_automation_track_event),
|
||||
_base_rect, this));
|
||||
|
||||
hide_button.add (*(manage (new Gtk::Image (::get_icon("hide")))));
|
||||
|
||||
|
|
@ -182,6 +189,16 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
if (xml_node) {
|
||||
set_state (*xml_node);
|
||||
}
|
||||
|
||||
boost::shared_ptr<AutomationLine> line(new AutomationLine (
|
||||
_control->list()->param_id().to_string(),
|
||||
*this,
|
||||
*canvas_display,
|
||||
_control->list()));
|
||||
|
||||
line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
|
||||
line->queue_reset ();
|
||||
add_line (line);
|
||||
|
||||
/* make sure labels etc. are correct */
|
||||
|
||||
|
|
@ -225,11 +242,14 @@ void
|
|||
AutomationTimeAxisView::set_automation_state (AutoState state)
|
||||
{
|
||||
if (!ignore_state_request) {
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
route->set_parameter_automation_state (
|
||||
i->second->controllable()->list()->param_id(),
|
||||
if (_route == _automatable) { // FIXME: ew
|
||||
_route->set_parameter_automation_state (
|
||||
_control->list()->param_id(),
|
||||
state);
|
||||
}
|
||||
|
||||
_control->list()->set_automation_state(state);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,10 +260,10 @@ AutomationTimeAxisView::automation_state_changed ()
|
|||
|
||||
/* update button label */
|
||||
|
||||
if (lines.empty()) {
|
||||
if (!_line) {
|
||||
state = Off;
|
||||
} else {
|
||||
state = lines.front().first->the_list()->automation_state ();
|
||||
state = _control->list()->automation_state ();
|
||||
}
|
||||
|
||||
switch (state & (Off|Play|Touch|Write)) {
|
||||
|
|
@ -307,9 +327,7 @@ void
|
|||
AutomationTimeAxisView::clear_clicked ()
|
||||
{
|
||||
_session.begin_reversible_command (_("clear automation"));
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->clear ();
|
||||
}
|
||||
_line->clear ();
|
||||
_session.commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
|
@ -325,11 +343,10 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
|
|||
XMLNode* xml_node = state_parent->get_child_xml_node (_state_name);
|
||||
|
||||
TimeAxisView::set_height (ht);
|
||||
base_rect->property_y2() = h;
|
||||
_base_rect->property_y2() = h;
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->set_y_position_and_height (0, h);
|
||||
}
|
||||
if (_line)
|
||||
_line->set_y_position_and_height (0, h);
|
||||
|
||||
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
(*i)->set_height ();
|
||||
|
|
@ -364,17 +381,13 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
|
|||
|
||||
//if (changed_between_small_and_normal || first_call_to_set_height) {
|
||||
first_call_to_set_height = false;
|
||||
unsigned control_cnt = 0;
|
||||
switch (ht) {
|
||||
case Largest:
|
||||
case Large:
|
||||
case Larger:
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->second->show ();
|
||||
controls_table.attach (*i->second.get(), 0, 8, 2 + control_cnt, 3 + control_cnt, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
++control_cnt;
|
||||
}
|
||||
_controller->show ();
|
||||
controls_table.attach (*_controller.get(), 0, 8, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
|
||||
case Normal:
|
||||
|
||||
|
|
@ -427,7 +440,7 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
|
|||
|
||||
if (changed) {
|
||||
/* only emit the signal if the height really changed */
|
||||
route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,9 +449,7 @@ AutomationTimeAxisView::set_samples_per_unit (double spu)
|
|||
{
|
||||
TimeAxisView::set_samples_per_unit (editor.get_current_zoom());
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->reset ();
|
||||
}
|
||||
_line->reset ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -504,16 +515,37 @@ AutomationTimeAxisView::build_display_menu ()
|
|||
automation_state_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
|
||||
{
|
||||
double x = 0;
|
||||
|
||||
canvas_display->w2i (x, y);
|
||||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
y = 1.0 - (y / height);
|
||||
|
||||
/* map using line */
|
||||
|
||||
_line->view_to_model_y (y);
|
||||
|
||||
_session.begin_reversible_command (_("add automation event"));
|
||||
XMLNode& before = _control->list()->get_state();
|
||||
|
||||
_control->list()->add (when, y);
|
||||
|
||||
XMLNode& after = _control->list()->get_state();
|
||||
_session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->list().get(), &before, &after));
|
||||
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
ret = cut_copy_clear_one (*i->first, selection, op);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cut_copy_clear_one (*_line, selection, op);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -563,9 +595,7 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
|||
void
|
||||
AutomationTimeAxisView::reset_objects (PointSelection& selection)
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
reset_objects_one (*i->first, selection);
|
||||
}
|
||||
reset_objects_one (*_line, selection);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -588,13 +618,7 @@ AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection&
|
|||
bool
|
||||
AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
ret = cut_copy_clear_objects_one (*i->first, selection, op);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cut_copy_clear_objects_one (*_line, selection, op);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -653,13 +677,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
|
|||
bool
|
||||
AutomationTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size_t nth)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
ret = paste_one (*i->first, pos, times, selection, nth);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return paste_one (*_line, pos, times, selection, nth);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -721,7 +739,7 @@ AutomationTimeAxisView::remove_ghost (GhostRegion* gr)
|
|||
void
|
||||
AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable*>& results)
|
||||
{
|
||||
if (!lines.empty() && touched (top, bot)) {
|
||||
if (_line && touched (top, bot)) {
|
||||
double topfrac;
|
||||
double botfrac;
|
||||
|
||||
|
|
@ -748,78 +766,60 @@ AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double
|
|||
botfrac = 1.0 - ((bot - y_position) / height);
|
||||
}
|
||||
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->get_selectables (start, end, botfrac, topfrac, results);
|
||||
}
|
||||
_line->get_selectables (start, end, botfrac, topfrac, results);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& result)
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->get_inverted_selectables (sel, result);
|
||||
}
|
||||
_line->get_inverted_selectables (sel, result);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::set_selected_points (PointSelection& points)
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->set_selected_points (points);
|
||||
}
|
||||
_line->set_selected_points (points);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::clear_lines ()
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i)
|
||||
delete i->first;
|
||||
|
||||
lines.clear ();
|
||||
_line.reset();
|
||||
automation_connection.disconnect ();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::add_line (AutomationLine& line)
|
||||
AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
|
||||
{
|
||||
bool get = false;
|
||||
assert(line);
|
||||
assert(!_line);
|
||||
assert(line->the_list() == _control->list());
|
||||
|
||||
if (lines.empty()) {
|
||||
/* first line is the Model for automation state */
|
||||
automation_connection = line.the_list()->automation_state_changed.connect
|
||||
(mem_fun(*this, &AutomationTimeAxisView::automation_state_changed));
|
||||
get = true;
|
||||
}
|
||||
automation_connection = _control->list()->automation_state_changed.connect
|
||||
(mem_fun(*this, &AutomationTimeAxisView::automation_state_changed));
|
||||
|
||||
lines.push_back (std::make_pair(&line,
|
||||
AutomationController::create(_session, line.the_list(),
|
||||
route->control(line.the_list()->param_id()))));
|
||||
_line = line;
|
||||
//_controller = AutomationController::create(_session, line->the_list(), _control);
|
||||
|
||||
line.set_y_position_and_height (0, height);
|
||||
line->set_y_position_and_height (0, height);
|
||||
|
||||
if (get) {
|
||||
/* pick up the current state */
|
||||
automation_state_changed ();
|
||||
}
|
||||
/* pick up the current state */
|
||||
automation_state_changed ();
|
||||
|
||||
line.show();
|
||||
line->show();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::show_all_control_points ()
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->show_all_control_points ();
|
||||
}
|
||||
_line->show_all_control_points ();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::hide_all_but_selected_control_points ()
|
||||
{
|
||||
for (Lines::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
i->first->hide_all_but_selected_control_points ();
|
||||
}
|
||||
_line->hide_all_but_selected_control_points ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -841,9 +841,7 @@ AutomationTimeAxisView::set_colors ()
|
|||
(*i)->set_colors();
|
||||
}
|
||||
|
||||
for (Lines::iterator i=lines.begin(); i != lines.end(); i++ ) {
|
||||
i->first->set_colors();
|
||||
}
|
||||
_line->set_colors();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -856,6 +854,31 @@ void
|
|||
AutomationTimeAxisView::set_state (const XMLNode& node)
|
||||
{
|
||||
TimeAxisView::set_state (node);
|
||||
|
||||
XMLNodeList kids;
|
||||
XMLNodeConstIterator iter;
|
||||
|
||||
kids = node.children ();
|
||||
|
||||
//snprintf (buf, sizeof(buf), "Port_%" PRIu32, param.id());
|
||||
|
||||
for (iter = kids.begin(); iter != kids.end(); ++iter) {
|
||||
if ((*iter)->name() == _control->list()->param_id().to_string()) {
|
||||
|
||||
XMLProperty *shown = (*iter)->property("shown_editor");
|
||||
|
||||
if (shown && shown->value() == "yes") {
|
||||
set_marked_for_display(true);
|
||||
canvas_display->show(); /* FIXME: necessary? show_at? */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_marked_for_display)
|
||||
hide();
|
||||
|
||||
// FIXME: _xml_node = &node?
|
||||
}
|
||||
|
||||
XMLNode*
|
||||
|
|
@ -869,3 +892,64 @@ AutomationTimeAxisView::get_state_node ()
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::ensure_xml_node ()
|
||||
{
|
||||
if ((_automatable != _route) && _xml_node == 0) {
|
||||
if ((_xml_node = _automatable->extra_xml ("GUI")) == 0) {
|
||||
_xml_node = new XMLNode ("GUI");
|
||||
_automatable->add_extra_xml (*_xml_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
|
||||
{
|
||||
if (_automatable == _route)
|
||||
return;
|
||||
|
||||
char buf[32];
|
||||
|
||||
ensure_xml_node ();
|
||||
|
||||
XMLNodeList nlist = _xml_node->children ();
|
||||
XMLNodeConstIterator i;
|
||||
XMLNode * port_node = 0;
|
||||
|
||||
/* FIXME: these parsed XML node names need to go */
|
||||
//snprintf (buf, sizeof(buf), "Port_%" PRIu32, _param.id());
|
||||
|
||||
for (i = nlist.begin(); i != nlist.end(); ++i) {
|
||||
/* FIXME: legacy session loading */
|
||||
if ((*i)->name() == _control->list()->param_id().to_string()) {
|
||||
port_node = (*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!port_node) {
|
||||
port_node = new XMLNode(buf);
|
||||
_xml_node->add_child_nocopy(*port_node);
|
||||
}
|
||||
|
||||
port_node->add_property ("shown_editor", editor_shown ? "yes": "no");
|
||||
}
|
||||
|
||||
guint32
|
||||
AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
|
||||
{
|
||||
update_extra_xml_shown (true);
|
||||
|
||||
return TimeAxisView::show_at (y, nth, parent);
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::hide ()
|
||||
{
|
||||
update_extra_xml_shown (false);
|
||||
|
||||
TimeAxisView::hide ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/automatable.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "time_axis_view.h"
|
||||
|
|
@ -52,12 +53,13 @@ class GhostRegion;
|
|||
class Selection;
|
||||
class Selectable;
|
||||
|
||||
/** TODO: All the derived types of this can probably be merged into this cleanly.
|
||||
*/
|
||||
|
||||
class AutomationTimeAxisView : public TimeAxisView {
|
||||
public:
|
||||
AutomationTimeAxisView (ARDOUR::Session&,
|
||||
boost::shared_ptr<ARDOUR::Route>,
|
||||
boost::shared_ptr<ARDOUR::Automatable>,
|
||||
boost::shared_ptr<ARDOUR::AutomationControl>,
|
||||
PublicEditor&,
|
||||
TimeAxisView& parent,
|
||||
ArdourCanvas::Canvas& canvas,
|
||||
|
|
@ -67,17 +69,14 @@ class AutomationTimeAxisView : public TimeAxisView {
|
|||
|
||||
~AutomationTimeAxisView();
|
||||
|
||||
virtual void set_height (TimeAxisView::TrackHeight);
|
||||
void set_height (TimeAxisView::TrackHeight);
|
||||
void set_samples_per_unit (double);
|
||||
std::string name() const { return _name; }
|
||||
|
||||
virtual void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double) = 0;
|
||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
|
||||
|
||||
virtual void clear_lines ();
|
||||
virtual void add_line (AutomationLine&);
|
||||
|
||||
typedef vector<std::pair<AutomationLine*,boost::shared_ptr<AutomationController> > > Lines;
|
||||
Lines lines;
|
||||
void clear_lines ();
|
||||
boost::shared_ptr<AutomationLine> line() { return _line; }
|
||||
|
||||
void set_selected_points (PointSelection&);
|
||||
void get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable *>&);
|
||||
|
|
@ -100,10 +99,22 @@ class AutomationTimeAxisView : public TimeAxisView {
|
|||
void hide_all_but_selected_control_points ();
|
||||
void set_state (const XMLNode&);
|
||||
XMLNode* get_state_node ();
|
||||
|
||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||
void hide ();
|
||||
|
||||
protected:
|
||||
boost::shared_ptr<ARDOUR::Route> route;
|
||||
ArdourCanvas::SimpleRect* base_rect;
|
||||
boost::shared_ptr<ARDOUR::Route> _route; ///< Parent route
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> _control; ///< Control
|
||||
boost::shared_ptr<ARDOUR::Automatable> _automatable; ///< Control owner, maybe = _route
|
||||
|
||||
boost::shared_ptr<AutomationController> _controller;
|
||||
|
||||
ArdourCanvas::SimpleRect* _base_rect;
|
||||
boost::shared_ptr<AutomationLine> _line;
|
||||
|
||||
XMLNode* _xml_node;
|
||||
|
||||
string _name;
|
||||
string _state_name;
|
||||
bool in_destructor;
|
||||
|
|
@ -124,12 +135,14 @@ class AutomationTimeAxisView : public TimeAxisView {
|
|||
Gtk::CheckMenuItem* auto_touch_item;
|
||||
Gtk::CheckMenuItem* auto_write_item;
|
||||
|
||||
void add_line (boost::shared_ptr<AutomationLine>);
|
||||
|
||||
void clear_clicked ();
|
||||
void height_clicked ();
|
||||
void hide_clicked ();
|
||||
void auto_clicked ();
|
||||
|
||||
virtual void build_display_menu ();
|
||||
void build_display_menu ();
|
||||
|
||||
list<GhostRegion*> ghosts;
|
||||
|
||||
|
|
@ -144,6 +157,9 @@ class AutomationTimeAxisView : public TimeAxisView {
|
|||
void automation_state_changed ();
|
||||
sigc::connection automation_connection;
|
||||
|
||||
void ensure_xml_node ();
|
||||
void update_extra_xml_shown (bool editor_shown);
|
||||
|
||||
void entered ();
|
||||
void exited ();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,9 @@
|
|||
#include "crossfade_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "region_gain_line.h"
|
||||
#include "automation_gain_line.h"
|
||||
#include "automation_pan_line.h"
|
||||
#include "automation_midi_cc_line.h"
|
||||
#include "automation_line.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "processor_automation_line.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "simplerect.h"
|
||||
|
||||
|
|
@ -563,8 +561,6 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
|
|||
bool
|
||||
Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
|
||||
{
|
||||
ItemType type;
|
||||
|
||||
switch (event->type) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
|
|
@ -585,21 +581,7 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
|
|||
break;
|
||||
}
|
||||
|
||||
if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
|
||||
type = GainControlPointItem;
|
||||
} else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
|
||||
type = GainAutomationControlPointItem;
|
||||
} else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
|
||||
type = PanAutomationControlPointItem;
|
||||
} else if (dynamic_cast<ProcessorAutomationLine*> (&cp->line) != 0) {
|
||||
type = RedirectAutomationControlPointItem;
|
||||
} else if (dynamic_cast<AutomationMidiCCLine*> (&cp->line) != 0) {
|
||||
type = MidiCCAutomationControlPointItem;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return typed_event (item, event, type);
|
||||
return typed_event (item, event, ControlPointItem);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -609,16 +591,8 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation
|
|||
|
||||
if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
|
||||
type = GainLineItem;
|
||||
} else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
|
||||
type = GainAutomationLineItem;
|
||||
} else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
|
||||
type = PanAutomationLineItem;
|
||||
} else if (dynamic_cast<ProcessorAutomationLine*> (al) != 0) {
|
||||
type = ProcessorAutomationLineItem;
|
||||
} else if (dynamic_cast<AutomationMidiCCLine*> (al) != 0) {
|
||||
type = MidiCCAutomationLineItem;
|
||||
} else {
|
||||
return false;
|
||||
type = AutomationLineItem;
|
||||
}
|
||||
|
||||
return typed_event (item, event, type);
|
||||
|
|
|
|||
|
|
@ -30,16 +30,9 @@ enum ItemType {
|
|||
RangeMarkerBarItem,
|
||||
TransportMarkerBarItem,
|
||||
SelectionItem,
|
||||
GainControlPointItem,
|
||||
ControlPointItem,
|
||||
GainLineItem,
|
||||
GainAutomationControlPointItem,
|
||||
GainAutomationLineItem,
|
||||
PanAutomationControlPointItem,
|
||||
PanAutomationLineItem,
|
||||
RedirectAutomationControlPointItem,
|
||||
ProcessorAutomationLineItem,
|
||||
MidiCCAutomationControlPointItem,
|
||||
MidiCCAutomationLineItem,
|
||||
AutomationLineItem,
|
||||
MeterMarkerItem,
|
||||
TempoMarkerItem,
|
||||
MeterBarItem,
|
||||
|
|
|
|||
|
|
@ -347,10 +347,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
|
|||
commit = set_selected_track_from_click (press, op, false);
|
||||
break;
|
||||
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
commit = set_selected_track_from_click (press, op, true);
|
||||
if (mouse_mode != MouseRange) {
|
||||
commit |= set_selected_control_point_from_click (op, false);
|
||||
|
|
@ -537,18 +534,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||
return true;
|
||||
break;
|
||||
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
start_control_point_grab (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
||||
case GainAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
start_line_grab_from_line (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
|
@ -600,18 +591,11 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||
// start_line_grab_from_regionview (item, event);
|
||||
break;
|
||||
|
||||
case GainControlPointItem:
|
||||
start_control_point_grab (item, event);
|
||||
return true;
|
||||
|
||||
case GainLineItem:
|
||||
start_line_grab_from_line (item, event);
|
||||
return true;
|
||||
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
start_control_point_grab (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
|
@ -623,17 +607,11 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||
break;
|
||||
|
||||
switch (item_type) {
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
start_control_point_grab (item, event);
|
||||
break;
|
||||
|
||||
case GainAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
start_line_grab_from_line (item, event);
|
||||
break;
|
||||
|
||||
|
|
@ -685,10 +663,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||
}
|
||||
|
||||
break;
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
start_control_point_grab (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
|
@ -894,19 +869,14 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
}
|
||||
break;
|
||||
|
||||
case GainControlPointItem:
|
||||
case ControlPointItem:
|
||||
if (mouse_mode == MouseGain) {
|
||||
remove_gain_control_point (item, event);
|
||||
} else {
|
||||
remove_control_point (item, event);
|
||||
}
|
||||
break;
|
||||
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
remove_control_point (item, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -922,10 +892,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
case PlayheadCursorItem:
|
||||
case MarkerItem:
|
||||
case GainLineItem:
|
||||
case GainAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
case StartSelectionTrimItem:
|
||||
case EndSelectionTrimItem:
|
||||
return true;
|
||||
|
|
@ -1044,33 +1011,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
double fraction;
|
||||
|
||||
switch (item_type) {
|
||||
case GainControlPointItem:
|
||||
if (mouse_mode == MouseGain) {
|
||||
cp = static_cast<ControlPoint*>(item->get_data ("control_point"));
|
||||
cp->set_visible (true);
|
||||
|
||||
double at_x, at_y;
|
||||
at_x = cp->get_x();
|
||||
at_y = cp->get_y ();
|
||||
cp->item->i2w (at_x, at_y);
|
||||
at_x += 20.0;
|
||||
at_y += 20.0;
|
||||
|
||||
fraction = 1.0 - ((cp->get_y() - cp->line.y_position()) / cp->line.height());
|
||||
|
||||
set_verbose_canvas_cursor (cp->line.get_verbose_cursor_string (fraction), at_x, at_y);
|
||||
show_verbose_canvas_cursor ();
|
||||
|
||||
if (is_drawable()) {
|
||||
track_canvas.get_window()->set_cursor (*fader_cursor);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
|
||||
cp = static_cast<ControlPoint*>(item->get_data ("control_point"));
|
||||
cp->set_visible (true);
|
||||
|
|
@ -1104,10 +1045,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
}
|
||||
break;
|
||||
|
||||
case GainAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
|
||||
{
|
||||
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
||||
|
|
@ -1227,15 +1165,8 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
|
||||
switch (item_type) {
|
||||
case GainLineItem:
|
||||
case GainAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case GainControlPointItem:
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case AutomationLineItem:
|
||||
case ControlPointItem:
|
||||
/* these do not affect the current entered track state */
|
||||
clear_entered_track = false;
|
||||
break;
|
||||
|
|
@ -1263,11 +1194,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
bool is_start;
|
||||
|
||||
switch (item_type) {
|
||||
case GainControlPointItem:
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
cp = reinterpret_cast<ControlPoint*>(item->get_data ("control_point"));
|
||||
if (cp->line.npoints() > 1) {
|
||||
if (!cp->selected) {
|
||||
|
|
@ -1301,10 +1228,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
break;
|
||||
|
||||
case GainLineItem:
|
||||
case GainAutomationLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
al = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
|
||||
{
|
||||
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
||||
|
|
@ -1445,11 +1369,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
|
|||
case PlayheadCursorItem:
|
||||
case EditCursorItem:
|
||||
case MarkerItem:
|
||||
case GainControlPointItem:
|
||||
case RedirectAutomationControlPointItem:
|
||||
case MidiCCAutomationControlPointItem:
|
||||
case GainAutomationControlPointItem:
|
||||
case PanAutomationControlPointItem:
|
||||
case ControlPointItem:
|
||||
case TempoMarkerItem:
|
||||
case MeterMarkerItem:
|
||||
case RegionViewNameHighlight:
|
||||
|
|
@ -1457,10 +1377,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
|
|||
case EndSelectionTrimItem:
|
||||
case SelectionItem:
|
||||
case GainLineItem:
|
||||
case ProcessorAutomationLineItem:
|
||||
case MidiCCAutomationLineItem:
|
||||
case GainAutomationLineItem:
|
||||
case PanAutomationLineItem:
|
||||
case AutomationLineItem:
|
||||
case FadeInHandleItem:
|
||||
case FadeOutHandleItem:
|
||||
|
||||
|
|
@ -2823,7 +2740,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
TimeAxisView *tracklist_timeview;
|
||||
tracklist_timeview = (*i);
|
||||
RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tracklist_timeview);
|
||||
list<TimeAxisView*> children_list;
|
||||
TimeAxisView::Children children_list;
|
||||
|
||||
/* zeroes are audio tracks. ones are other types. */
|
||||
|
||||
|
|
@ -2843,7 +2760,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
height_list[rtv2->order] = (*i)->height;
|
||||
children = 1;
|
||||
if ((children_list = rtv2->get_child_list()).size() > 0) {
|
||||
for (list<TimeAxisView*>::iterator j = children_list.begin(); j != children_list.end(); ++j) {
|
||||
for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) {
|
||||
tracks = tracks |= (0x01 << (rtv2->order + children));
|
||||
height_list[rtv2->order + children] = (*j)->height;
|
||||
numtracks++;
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 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 <ardour/automation_event.h>
|
||||
#include <ardour/route.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "gain_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
|
||||
GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
|
||||
PublicEditor& e, TimeAxisView& parent,
|
||||
ArdourCanvas::Canvas& canvas, const string & n,
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> c)
|
||||
|
||||
: AxisView (s),
|
||||
AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("gain"), ""),
|
||||
_control (c)
|
||||
{
|
||||
}
|
||||
|
||||
GainAutomationTimeAxisView::~GainAutomationTimeAxisView ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GainAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
|
||||
{
|
||||
double x = 0;
|
||||
|
||||
canvas_display->w2i (x, y);
|
||||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
y = 1.0 - (y / height);
|
||||
|
||||
/* map using line */
|
||||
|
||||
lines.front().first->view_to_model_y (y);
|
||||
|
||||
_session.begin_reversible_command (_("add gain automation event"));
|
||||
XMLNode& before = _control->list()->get_state();
|
||||
_control->list()->add (when, y);
|
||||
XMLNode& after = _control->list()->get_state();
|
||||
_session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->list(), &before, &after));
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_gain_automation_time_axis_h__
|
||||
#define __ardour_gtk_gain_automation_time_axis_h__
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_time_axis.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class AutomationList;
|
||||
class AutomationControl;
|
||||
}
|
||||
|
||||
class GainAutomationTimeAxisView : public AutomationTimeAxisView
|
||||
{
|
||||
public:
|
||||
GainAutomationTimeAxisView (ARDOUR::Session&,
|
||||
boost::shared_ptr<ARDOUR::Route>,
|
||||
PublicEditor&,
|
||||
TimeAxisView& parent_axis,
|
||||
ArdourCanvas::Canvas& canvas,
|
||||
const string & name,
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control);
|
||||
|
||||
~GainAutomationTimeAxisView();
|
||||
|
||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> _control;
|
||||
|
||||
void automation_changed ();
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_gain_automation_time_axis_h__ */
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
#include "plugin_ui.h"
|
||||
#include "utils.h"
|
||||
#include "gui_thread.h"
|
||||
#include "automation_controller.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ LadspaPluginUI::build ()
|
|||
}
|
||||
}
|
||||
|
||||
if ((cui = build_control_ui (i, plugin->get_nth_control (i))) == 0) {
|
||||
if ((cui = build_control_ui (i, insert->control(ParamID(PluginAutomation, i)))) == 0) {
|
||||
error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -305,18 +306,12 @@ LadspaPluginUI::ControlUI::ControlUI ()
|
|||
ignore_change = 0;
|
||||
display = 0;
|
||||
button = 0;
|
||||
control = 0;
|
||||
clickbox = 0;
|
||||
adjustment = 0;
|
||||
meterinfo = 0;
|
||||
}
|
||||
|
||||
LadspaPluginUI::ControlUI::~ControlUI()
|
||||
{
|
||||
if (adjustment) {
|
||||
delete adjustment;
|
||||
}
|
||||
|
||||
if (meterinfo) {
|
||||
delete meterinfo->meter;
|
||||
delete meterinfo;
|
||||
|
|
@ -328,7 +323,9 @@ LadspaPluginUI::automation_state_changed (ControlUI* cui)
|
|||
{
|
||||
/* update button label */
|
||||
|
||||
switch (insert->get_parameter_automation_state (ParamID(PluginAutomation, cui->port_index))
|
||||
// don't lock to avoid deadlock because we're triggered by
|
||||
// AutomationControl::Changed() while the automation lock is taken
|
||||
switch (insert->get_parameter_automation_state (cui->param_id(), false)
|
||||
& (Off|Play|Touch|Write)) {
|
||||
case Off:
|
||||
cui->automate_button.set_label (_("Manual"));
|
||||
|
|
@ -361,8 +358,7 @@ LadspaPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
|
|||
}
|
||||
|
||||
LadspaPluginUI::ControlUI*
|
||||
LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontrol)
|
||||
|
||||
LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<AutomationControl> mcontrol)
|
||||
{
|
||||
ControlUI* control_ui;
|
||||
Plugin::ParameterDescriptor desc;
|
||||
|
|
@ -370,10 +366,9 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
|
|||
plugin->get_parameter_descriptor (port_index, desc);
|
||||
|
||||
control_ui = manage (new ControlUI ());
|
||||
control_ui->adjustment = 0;
|
||||
control_ui->combo = 0;
|
||||
control_ui->combo_map = 0;
|
||||
control_ui->port_index = port_index;
|
||||
control_ui->control = mcontrol;
|
||||
control_ui->update_pending = false;
|
||||
control_ui->label.set_text (desc.label);
|
||||
control_ui->label.set_alignment (0.0, 0.5);
|
||||
|
|
@ -397,7 +392,7 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
|
|||
//control_ui->combo->set_value_in_list(true, false);
|
||||
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
|
||||
control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_combo_changed), control_ui));
|
||||
plugin->ParameterChanged.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
control_ui->pack_start(control_ui->label, true, true);
|
||||
control_ui->pack_start(*control_ui->combo, false, true);
|
||||
|
||||
|
|
@ -429,52 +424,53 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
|
|||
return control_ui;
|
||||
}
|
||||
|
||||
control_ui->adjustment = new Adjustment (0, 0, 0, 0, 0);
|
||||
|
||||
/* XXX this code is not right yet, because it doesn't handle
|
||||
the absence of bounds in any sensible fashion.
|
||||
*/
|
||||
|
||||
control_ui->adjustment->set_lower (desc.lower);
|
||||
control_ui->adjustment->set_upper (desc.upper);
|
||||
#if 0
|
||||
control_ui->controller->adjustment()->set_lower (desc.lower);
|
||||
control_ui->controller->adjustment()->set_upper (desc.upper);
|
||||
|
||||
control_ui->logarithmic = desc.logarithmic;
|
||||
if (control_ui->logarithmic) {
|
||||
if (control_ui->adjustment->get_lower() == 0.0) {
|
||||
control_ui->adjustment->set_lower (control_ui->adjustment->get_upper()/10000);
|
||||
if (control_ui->controller->adjustment()->get_lower() == 0.0) {
|
||||
control_ui->controller->adjustment()->set_lower (control_ui->controller->adjustment()->get_upper()/10000);
|
||||
}
|
||||
control_ui->adjustment->set_upper (log(control_ui->adjustment->get_upper()));
|
||||
control_ui->adjustment->set_lower (log(control_ui->adjustment->get_lower()));
|
||||
control_ui->controller->adjustment()->set_upper (log(control_ui->controller->adjustment()->get_upper()));
|
||||
control_ui->controller->adjustment()->set_lower (log(control_ui->controller->adjustment()->get_lower()));
|
||||
}
|
||||
|
||||
|
||||
float delta = desc.upper - desc.lower;
|
||||
|
||||
control_ui->adjustment->set_page_size (delta/100.0);
|
||||
control_ui->adjustment->set_step_increment (desc.step);
|
||||
control_ui->adjustment->set_page_increment (desc.largestep);
|
||||
control_ui->controller->adjustment()->set_page_size (delta/100.0);
|
||||
control_ui->controller->adjustment()->set_step_increment (desc.step);
|
||||
control_ui->controller->adjustment()->set_page_increment (desc.largestep);
|
||||
#endif
|
||||
|
||||
if (desc.integer_step) {
|
||||
control_ui->clickbox = new ClickBox (control_ui->adjustment, "PluginUIClickBox");
|
||||
control_ui->clickbox = new ClickBox (control_ui->controller->adjustment(), "PluginUIClickBox");
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2);
|
||||
control_ui->clickbox->set_print_func (integer_printer, 0);
|
||||
} else {
|
||||
sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &LadspaPluginUI::print_parameter), (uint32_t) port_index);
|
||||
//sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &LadspaPluginUI::print_parameter), (uint32_t) port_index);
|
||||
|
||||
control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot);
|
||||
control_ui->control->set_size_request (200, req.height);
|
||||
control_ui->control->set_name (X_("PluginSlider"));
|
||||
control_ui->control->set_style (BarController::LeftToRight);
|
||||
control_ui->control->set_use_parent (true);
|
||||
control_ui->controller = AutomationController::create(insert->session(), mcontrol->list(), mcontrol);
|
||||
control_ui->controller->set_size_request (200, req.height);
|
||||
control_ui->controller->set_name (X_("PluginSlider"));
|
||||
control_ui->controller->set_style (BarController::LeftToRight);
|
||||
control_ui->controller->set_use_parent (true);
|
||||
|
||||
control_ui->control->StartGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::start_touch), control_ui));
|
||||
control_ui->control->StopGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::stop_touch), control_ui));
|
||||
control_ui->controller->StartGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::start_touch), control_ui));
|
||||
control_ui->controller->StopGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::stop_touch), control_ui));
|
||||
|
||||
}
|
||||
|
||||
if (control_ui->logarithmic) {
|
||||
control_ui->adjustment->set_value(log(plugin->get_parameter(port_index)));
|
||||
control_ui->controller->adjustment()->set_value(log(plugin->get_parameter(port_index)));
|
||||
} else{
|
||||
control_ui->adjustment->set_value(plugin->get_parameter(port_index));
|
||||
control_ui->controller->adjustment()->set_value(plugin->get_parameter(port_index));
|
||||
}
|
||||
|
||||
/* XXX memory leak: SliderController not destroyed by ControlUI
|
||||
|
|
@ -486,17 +482,16 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
|
|||
if (desc.integer_step) {
|
||||
control_ui->pack_start (*control_ui->clickbox, false, false);
|
||||
} else {
|
||||
control_ui->pack_start (*control_ui->control, false, false);
|
||||
control_ui->pack_start (*control_ui->controller, false, false);
|
||||
}
|
||||
|
||||
control_ui->pack_start (control_ui->automate_button, false, false);
|
||||
control_ui->adjustment->signal_value_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_adjustment_changed), control_ui));
|
||||
control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
|
||||
|
||||
automation_state_changed (control_ui);
|
||||
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
insert->control (ParamID(PluginAutomation, port_index))->list()->automation_state_changed.connect
|
||||
mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
mcontrol->list()->automation_state_changed.connect
|
||||
(bind (mem_fun(*this, &LadspaPluginUI::automation_state_changed), control_ui));
|
||||
|
||||
} else if (plugin->parameter_is_output (port_index)) {
|
||||
|
|
@ -546,20 +541,21 @@ LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontro
|
|||
output_controls.push_back (control_ui);
|
||||
}
|
||||
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
|
||||
return control_ui;
|
||||
}
|
||||
|
||||
void
|
||||
LadspaPluginUI::start_touch (LadspaPluginUI::ControlUI* cui)
|
||||
{
|
||||
insert->control (ParamID(PluginAutomation, cui->port_index))->list()->start_touch ();
|
||||
cui->control->list()->start_touch ();
|
||||
}
|
||||
|
||||
void
|
||||
LadspaPluginUI::stop_touch (LadspaPluginUI::ControlUI* cui)
|
||||
{
|
||||
insert->control (ParamID(PluginAutomation, cui->port_index))->list()->stop_touch ();
|
||||
cui->control->list()->stop_touch ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -590,33 +586,15 @@ LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
|
|||
void
|
||||
LadspaPluginUI::set_automation_state (AutoState state, ControlUI* cui)
|
||||
{
|
||||
insert->set_parameter_automation_state (ParamID(PluginAutomation, cui->port_index), state);
|
||||
insert->set_parameter_automation_state (cui->param_id(), state);
|
||||
}
|
||||
|
||||
void
|
||||
LadspaPluginUI::control_adjustment_changed (ControlUI* cui)
|
||||
LadspaPluginUI::parameter_changed (ControlUI* cui)
|
||||
{
|
||||
if (cui->ignore_change) {
|
||||
return;
|
||||
}
|
||||
|
||||
double value = cui->adjustment->get_value();
|
||||
|
||||
if (cui->logarithmic) {
|
||||
value = exp(value);
|
||||
}
|
||||
|
||||
insert->set_parameter (ParamID(PluginAutomation, cui->port_index), (float) value);
|
||||
}
|
||||
|
||||
void
|
||||
LadspaPluginUI::parameter_changed (uint32_t abs_port_id, float val, ControlUI* cui)
|
||||
{
|
||||
if (cui->port_index == abs_port_id) {
|
||||
if (!cui->update_pending) {
|
||||
cui->update_pending = true;
|
||||
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &LadspaPluginUI::update_control_display), cui));
|
||||
}
|
||||
if (!cui->update_pending) {
|
||||
cui->update_pending = true;
|
||||
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &LadspaPluginUI::update_control_display), cui));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -627,7 +605,7 @@ LadspaPluginUI::update_control_display (ControlUI* cui)
|
|||
|
||||
cui->update_pending = false;
|
||||
|
||||
float val = plugin->get_parameter (cui->port_index);
|
||||
float val = cui->control->get_value();
|
||||
|
||||
cui->ignore_change++;
|
||||
if (cui->combo) {
|
||||
|
|
@ -638,22 +616,26 @@ LadspaPluginUI::update_control_display (ControlUI* cui)
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else if (cui->adjustment == 0) {
|
||||
} else if (cui->button) {
|
||||
|
||||
if (val > 0.5) {
|
||||
cui->button->set_active (true);
|
||||
} else {
|
||||
cui->button->set_active (false);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cui->controller->display_effective_value();
|
||||
|
||||
|
||||
/*} else {
|
||||
if (cui->logarithmic) {
|
||||
val = log(val);
|
||||
}
|
||||
if (val != cui->adjustment->get_value()) {
|
||||
cui->adjustment->set_value (val);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
cui->ignore_change--;
|
||||
}
|
||||
|
||||
|
|
@ -661,7 +643,7 @@ void
|
|||
LadspaPluginUI::control_port_toggled (ControlUI* cui)
|
||||
{
|
||||
if (!cui->ignore_change) {
|
||||
insert->set_parameter (ParamID(PluginAutomation, cui->port_index), cui->button->get_active());
|
||||
insert->set_parameter (cui->param_id(), cui->button->get_active());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -671,7 +653,7 @@ LadspaPluginUI::control_combo_changed (ControlUI* cui)
|
|||
if (!cui->ignore_change) {
|
||||
string value = cui->combo->get_active_text();
|
||||
std::map<string,float> mapping = *cui->combo_map;
|
||||
insert->set_parameter (ParamID(PluginAutomation, cui->port_index), mapping[value]);
|
||||
insert->set_parameter (cui->param_id(), mapping[value]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -710,7 +692,7 @@ void
|
|||
LadspaPluginUI::output_update ()
|
||||
{
|
||||
for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) {
|
||||
float val = plugin->get_parameter ((*i)->port_index);
|
||||
float val = plugin->get_parameter ((*i)->param_id().id());
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof(buf), "%.2f", val);
|
||||
(*i)->display_label->set_text (buf);
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 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 <ardour/automation_event.h>
|
||||
#include <ardour/route.h>
|
||||
#include <pbd/memento_command.h>
|
||||
#include <pbd/controllable.h>
|
||||
|
||||
#include "midi_controller_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
|
||||
MidiControllerTimeAxisView::MidiControllerTimeAxisView (Session& s, boost::shared_ptr<Route> r,
|
||||
PublicEditor& e, TimeAxisView& parent,
|
||||
ArdourCanvas::Canvas& canvas, const string & n,
|
||||
boost::shared_ptr<AutomationControl> c)
|
||||
: AxisView (s),
|
||||
AutomationTimeAxisView (s, r, e, parent, canvas, n, c->list()->param_id().to_string(), ""),
|
||||
_control (c)
|
||||
{
|
||||
}
|
||||
|
||||
MidiControllerTimeAxisView::~MidiControllerTimeAxisView ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MidiControllerTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
|
||||
{
|
||||
double x = 0;
|
||||
|
||||
canvas_display->w2i (x, y);
|
||||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
y = 1.0 - (y / height);
|
||||
|
||||
/* map using line */
|
||||
|
||||
lines.front().first->view_to_model_y (y);
|
||||
|
||||
_session.begin_reversible_command (_("add midi controller automation event"));
|
||||
XMLNode& before = _control->list()->get_state();
|
||||
_control->list()->add (when, y);
|
||||
XMLNode& after = _control->list()->get_state();
|
||||
_session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->list().get(), &before, &after));
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_midi_controller_time_axis_h__
|
||||
#define __ardour_gtk_midi_controller_time_axis_h__
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_time_axis.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class AutomationList;
|
||||
}
|
||||
|
||||
class MidiControllerTimeAxisView : public AutomationTimeAxisView
|
||||
{
|
||||
public:
|
||||
MidiControllerTimeAxisView (ARDOUR::Session&,
|
||||
boost::shared_ptr<ARDOUR::Route>,
|
||||
PublicEditor&,
|
||||
TimeAxisView& parent_axis,
|
||||
ArdourCanvas::Canvas& canvas,
|
||||
const string & name,
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> c);
|
||||
|
||||
~MidiControllerTimeAxisView();
|
||||
|
||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> _control;
|
||||
|
||||
void automation_changed ();
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_midi_controller_time_axis_h__ */
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
#include "ardour_ui.h"
|
||||
#include "midi_time_axis.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "automation_midi_cc_line.h"
|
||||
#include "automation_line.h"
|
||||
#include "add_midi_cc_track_dialog.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "crossfade_view.h"
|
||||
|
|
@ -61,9 +61,6 @@
|
|||
#include "point_selection.h"
|
||||
#include "prompter.h"
|
||||
#include "public_editor.h"
|
||||
#include "processor_automation_line.h"
|
||||
#include "processor_automation_time_axis.h"
|
||||
#include "midi_controller_time_axis.h"
|
||||
#include "region_view.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "selection.h"
|
||||
|
|
@ -193,23 +190,13 @@ MidiTimeAxisView::create_automation_child (ParamID param)
|
|||
_route->add_control(c);
|
||||
}
|
||||
|
||||
MidiControllerTimeAxisView* track = new MidiControllerTimeAxisView (_session,
|
||||
_route,
|
||||
boost::shared_ptr<AutomationTimeAxisView> track(new AutomationTimeAxisView (_session,
|
||||
_route, _route, c,
|
||||
editor,
|
||||
*this,
|
||||
parent_canvas,
|
||||
_route->describe_parameter(param),
|
||||
c);
|
||||
|
||||
AutomationMidiCCLine* line = new AutomationMidiCCLine (param.to_string(),
|
||||
*track,
|
||||
*track->canvas_display,
|
||||
c->list());
|
||||
|
||||
line->set_line_color (ARDOUR_UI::config()->canvasvar_AutomationLine.get());
|
||||
|
||||
track->add_line(*line);
|
||||
|
||||
c->list()->param_id().to_string() /* FIXME: correct state name? */));
|
||||
add_automation_child(param, track);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -701,8 +701,8 @@ MixerStrip::connect_to_pan ()
|
|||
if (!_route->panner().empty()) {
|
||||
StreamPanner* sp = _route->panner().front();
|
||||
|
||||
panstate_connection = sp->automation()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
||||
panstyle_connection = sp->automation()->automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed));
|
||||
panstate_connection = sp->pan_control()->list()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
||||
panstyle_connection = sp->pan_control()->list()->automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed));
|
||||
}
|
||||
|
||||
panners.pan_changed (this);
|
||||
|
|
|
|||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 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 <ardour/curve.h>
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/panner.h>
|
||||
|
||||
#include <gtkmm2ext/popup.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "pan_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "route_ui.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
|
||||
PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e,
|
||||
TimeAxisView& parent, Canvas& canvas, std::string n)
|
||||
|
||||
: AxisView (s),
|
||||
AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("pan"), "")
|
||||
{
|
||||
multiline_selector.set_name ("PanAutomationLineSelector");
|
||||
|
||||
controls_table.attach (multiline_selector, 1, 5, 1, 2, Gtk::EXPAND, Gtk::EXPAND);
|
||||
}
|
||||
|
||||
PanAutomationTimeAxisView::~PanAutomationTimeAxisView ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
|
||||
{
|
||||
if (lines.empty()) {
|
||||
/* no data, possibly caused by no outputs/inputs */
|
||||
Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true);
|
||||
|
||||
msg->set_text (_("Pan automation track has no lines, unable to add point\n(is track pannable?)"));
|
||||
msg->touch ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int line_index = 0;
|
||||
|
||||
if (lines.size() > 1) {
|
||||
line_index = multiline_selector.get_active_row_number();
|
||||
|
||||
if (line_index < 0 || line_index >= (int)lines.size()) {
|
||||
Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true);
|
||||
|
||||
msg->set_text (_("You need to select which line to edit"));
|
||||
msg->touch ();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double x = 0;
|
||||
|
||||
canvas_display->w2i (x, y);
|
||||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
y = 1.0 - (y / height);
|
||||
|
||||
/* map using line */
|
||||
|
||||
lines.front().first->view_to_model_y (y);
|
||||
|
||||
boost::shared_ptr<AutomationList> alist (lines[line_index].first->the_list());
|
||||
|
||||
_session.begin_reversible_command (_("add pan automation event"));
|
||||
XMLNode &before = alist->get_state();
|
||||
alist->add (when, y);
|
||||
XMLNode &after = alist->get_state();
|
||||
_session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
|
||||
_session.commit_reversible_command ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
void
|
||||
PanAutomationTimeAxisView::clear_lines ()
|
||||
{
|
||||
AutomationTimeAxisView::clear_lines();
|
||||
multiline_selector.clear();
|
||||
}
|
||||
|
||||
void
|
||||
PanAutomationTimeAxisView::add_line (AutomationLine& line)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf,32,"Line %zu",lines.size()+1);
|
||||
multiline_selector.append_text(buf);
|
||||
|
||||
if (lines.empty()) {
|
||||
multiline_selector.set_active(0);
|
||||
}
|
||||
|
||||
if (lines.size() + 1 > 1 && (height_style != Small && height_style != Smaller)) {
|
||||
multiline_selector.show();
|
||||
} else {
|
||||
multiline_selector.hide();
|
||||
|
||||
}
|
||||
|
||||
AutomationTimeAxisView::add_line(line);
|
||||
}
|
||||
|
||||
void
|
||||
PanAutomationTimeAxisView::set_height (TimeAxisView::TrackHeight th)
|
||||
{
|
||||
AutomationTimeAxisView::set_height(th);
|
||||
|
||||
switch (th) {
|
||||
case Largest:
|
||||
case Large:
|
||||
case Larger:
|
||||
case Normal:
|
||||
if (lines.size() > 1) {
|
||||
multiline_selector.show();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
multiline_selector.hide();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_pan_automation_time_axis_h__
|
||||
#define __ardour_gtk_pan_automation_time_axis_h__
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_time_axis.h"
|
||||
|
||||
#include <gtkmm/comboboxtext.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
class IOProcessor;
|
||||
}
|
||||
|
||||
class PanAutomationTimeAxisView : public AutomationTimeAxisView
|
||||
{
|
||||
public:
|
||||
PanAutomationTimeAxisView (ARDOUR::Session&,
|
||||
boost::shared_ptr<ARDOUR::Route>,
|
||||
PublicEditor&,
|
||||
TimeAxisView& parent_axis,
|
||||
ArdourCanvas::Canvas& canvas,
|
||||
std::string name);
|
||||
|
||||
~PanAutomationTimeAxisView();
|
||||
|
||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
|
||||
|
||||
void clear_lines ();
|
||||
void add_line (AutomationLine&);
|
||||
void set_height (TimeAxisView::TrackHeight);
|
||||
|
||||
protected:
|
||||
Gtk::ComboBoxText multiline_selector;
|
||||
|
||||
private:
|
||||
void automation_changed ();
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_pan_automation_time_axis_h__ */
|
||||
|
|
@ -314,7 +314,7 @@ PannerUI::setup_pan ()
|
|||
}
|
||||
|
||||
pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
|
||||
bc = new PannerBar (*pan_adjustments[asz], _io->panner()[asz]->control());
|
||||
bc = new PannerBar (*pan_adjustments[asz], _io->panner()[asz]->pan_control());
|
||||
|
||||
/* now set adjustment with current value of panner, then connect the signals */
|
||||
pan_adjustments.back()->set_value(rx);
|
||||
|
|
@ -573,7 +573,7 @@ PannerUI::update_pan_bars (bool only_if_aplay)
|
|||
float xpos, val;
|
||||
|
||||
if (only_if_aplay) {
|
||||
boost::shared_ptr<AutomationList> alist (_io->panner()[n]->automation());
|
||||
boost::shared_ptr<AutomationList> alist (_io->panner()[n]->pan_control()->list());
|
||||
|
||||
if (!alist->automation_playback()) {
|
||||
continue;
|
||||
|
|
@ -707,7 +707,7 @@ PannerUI::pan_automation_state_changed ()
|
|||
return;
|
||||
}
|
||||
|
||||
x = (_io->panner().front()->automation()->automation_state() != Off);
|
||||
x = (_io->panner().front()->pan_control()->list()->automation_state() != Off);
|
||||
|
||||
if (pan_automation_state_button.get_active() != x) {
|
||||
ignore_toggle = true;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include <gtkmm/scrolledwindow.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/adjustment.h>
|
||||
#include <gtkmm/togglebutton.h>
|
||||
#include <gtkmm/socket.h>
|
||||
#include <gtkmm/comboboxtext.h>
|
||||
|
|
@ -44,6 +43,7 @@
|
|||
#include <ardour/types.h>
|
||||
|
||||
#include "latency_gui.h"
|
||||
#include "automation_controller.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class PluginInsert;
|
||||
|
|
@ -139,21 +139,19 @@ class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
|
|||
static const int32_t initial_output_rows = 1;
|
||||
static const int32_t initial_output_cols = 4;
|
||||
|
||||
/* TODO: pull this out of PluginUI and make it generic.
|
||||
* Sticking this in the track controls of an automation track would
|
||||
* make a handy touch controller for anything.
|
||||
*/
|
||||
/* FIXME: Unify with AutomationController */
|
||||
struct ControlUI : public Gtk::HBox {
|
||||
|
||||
uint32_t port_index;
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control;
|
||||
|
||||
ARDOUR::ParamID param_id() { return control->list()->param_id(); }
|
||||
|
||||
/* input */
|
||||
|
||||
Gtk::Adjustment* adjustment;
|
||||
Gtk::ComboBoxText* combo;
|
||||
std::map<string, float>* combo_map;
|
||||
Gtk::ToggleButton* button;
|
||||
Gtkmm2ext::BarController* control;
|
||||
boost::shared_ptr<AutomationController> controller;
|
||||
Gtkmm2ext::ClickBox* clickbox;
|
||||
Gtk::Label label;
|
||||
bool logarithmic;
|
||||
|
|
@ -179,10 +177,9 @@ class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
|
|||
void output_update();
|
||||
|
||||
void build ();
|
||||
ControlUI* build_control_ui (guint32 port_index, PBD::Controllable *);
|
||||
ControlUI* build_control_ui (guint32 port_index, boost::shared_ptr<ARDOUR::AutomationControl>);
|
||||
std::vector<string> setup_scale_values(guint32 port_index, ControlUI* cui);
|
||||
void control_adjustment_changed (ControlUI* cui);
|
||||
void parameter_changed (uint32_t, float, ControlUI* cui);
|
||||
void parameter_changed (ControlUI* cui);
|
||||
void update_control_display (ControlUI* cui);
|
||||
void control_port_toggled (ControlUI* cui);
|
||||
void control_combo_changed (ControlUI* cui);
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2002-2003 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 "public_editor.h"
|
||||
#include "processor_automation_line.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <ardour/ladspa_plugin.h>
|
||||
#include <ardour/plugin_insert.h>
|
||||
#include <ardour/curve.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
ProcessorAutomationLine::ProcessorAutomationLine (const string & name, Processor& proc,
|
||||
TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> l)
|
||||
|
||||
: AutomationLine (name, tv, parent, l),
|
||||
_processor(proc)
|
||||
{
|
||||
set_verbose_cursor_uses_gain_mapping (false);
|
||||
|
||||
PluginInsert *pi;
|
||||
Plugin::ParameterDescriptor desc;
|
||||
|
||||
if ((pi = dynamic_cast<PluginInsert*>(&_processor)) == 0) {
|
||||
fatal << _("insert automation created for non-plugin") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
pi->plugin()->get_parameter_descriptor (l->param_id(), desc);
|
||||
|
||||
_upper = desc.upper;
|
||||
_lower = desc.lower;
|
||||
|
||||
if (desc.toggled) {
|
||||
no_draw = true;
|
||||
return;
|
||||
}
|
||||
|
||||
no_draw = false;
|
||||
_range = _upper - _lower;
|
||||
|
||||
/* XXX set min/max for underlying curve ??? */
|
||||
}
|
||||
|
||||
string
|
||||
ProcessorAutomationLine::get_verbose_cursor_string (float fraction)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf (buf, sizeof (buf), "%.2f", _lower + (fraction * _range));
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationLine::view_to_model_y (double& y)
|
||||
{
|
||||
y = _lower + (y * _range);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationLine::model_to_view_y (double& y)
|
||||
{
|
||||
y = (y - _lower) / _range;
|
||||
y = max (0.0, y);
|
||||
y = min (y, 1.0);
|
||||
}
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000 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_gtk_processor_automation_line_h__
|
||||
#define __ardour_gtk_processor_automation_line_h__
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
|
||||
#include "automation_line.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Processor;
|
||||
}
|
||||
|
||||
class TimeAxisView;
|
||||
|
||||
class ProcessorAutomationLine : public AutomationLine
|
||||
{
|
||||
public:
|
||||
ProcessorAutomationLine (const string & name, ARDOUR::Processor&,
|
||||
TimeAxisView&, ArdourCanvas::Group& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
||||
|
||||
ARDOUR::Processor& processor() const { return _processor; }
|
||||
|
||||
string get_verbose_cursor_string (float);
|
||||
|
||||
private:
|
||||
ARDOUR::Processor& _processor;
|
||||
|
||||
float _upper;
|
||||
float _lower;
|
||||
float _range;
|
||||
|
||||
void view_to_model_y (double&);
|
||||
void model_to_view_y (double&);
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_region_gain_line_h__ */
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 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 <ardour/processor.h>
|
||||
#include <ardour/session.h>
|
||||
#include <cstdlib>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "processor_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
|
||||
ProcessorAutomationTimeAxisView::ProcessorAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
|
||||
PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
|
||||
ParamID param, Processor& proc, string state_name)
|
||||
|
||||
: AxisView (s),
|
||||
AutomationTimeAxisView (s, r, e, parent, canvas, n, state_name, proc.name()),
|
||||
_processor(proc),
|
||||
_param (param)
|
||||
|
||||
{
|
||||
char buf[32];
|
||||
_xml_node = 0;
|
||||
_marked_for_display = false;
|
||||
|
||||
ensure_xml_node ();
|
||||
|
||||
XMLNodeList kids;
|
||||
XMLNodeConstIterator iter;
|
||||
|
||||
kids = _xml_node->children ();
|
||||
|
||||
snprintf (buf, sizeof(buf), "Port_%" PRIu32, param.id());
|
||||
|
||||
for (iter = kids.begin(); iter != kids.end(); ++iter) {
|
||||
if ((*iter)->name() == buf) {
|
||||
|
||||
XMLProperty *shown = (*iter)->property("shown_editor");
|
||||
|
||||
if (shown && shown->value() == "yes") {
|
||||
_marked_for_display = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProcessorAutomationTimeAxisView::~ProcessorAutomationTimeAxisView ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
|
||||
{
|
||||
double x = 0;
|
||||
|
||||
canvas_display->w2i (x, y);
|
||||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
else if (y > height)
|
||||
y = height;
|
||||
|
||||
y = 1.0 - (y / height);
|
||||
|
||||
/* map to model space */
|
||||
|
||||
if (!lines.empty()) {
|
||||
boost::shared_ptr<AutomationList> alist (_processor.control(_param, true)->list());
|
||||
string description = _("add automation event to ");
|
||||
description += _processor.describe_parameter (_param);
|
||||
|
||||
lines.front().first->view_to_model_y (y);
|
||||
|
||||
_session.begin_reversible_command (description);
|
||||
XMLNode &before = alist->get_state();
|
||||
alist->add (when, y);
|
||||
XMLNode &after = alist->get_state();
|
||||
_session.add_command(new MementoCommand<AutomationList>(*alist, &before, &after));
|
||||
_session.commit_reversible_command ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::ensure_xml_node ()
|
||||
{
|
||||
if (_xml_node == 0) {
|
||||
if ((_xml_node = _processor.extra_xml ("GUI")) == 0) {
|
||||
_xml_node = new XMLNode ("GUI");
|
||||
_processor.add_extra_xml (*_xml_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guint32
|
||||
ProcessorAutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
|
||||
{
|
||||
ensure_xml_node ();
|
||||
update_extra_xml_shown (true);
|
||||
|
||||
return TimeAxisView::show_at (y, nth, parent);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::hide ()
|
||||
{
|
||||
ensure_xml_node ();
|
||||
update_extra_xml_shown (false);
|
||||
|
||||
TimeAxisView::hide ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
XMLNodeList nlist = _xml_node->children ();
|
||||
XMLNodeConstIterator i;
|
||||
XMLNode * port_node = 0;
|
||||
|
||||
snprintf (buf, sizeof(buf), "Port_%" PRIu32, _param.id());
|
||||
|
||||
for (i = nlist.begin(); i != nlist.end(); ++i) {
|
||||
if ((*i)->name() == buf) {
|
||||
port_node = (*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!port_node) {
|
||||
port_node = new XMLNode(buf);
|
||||
_xml_node->add_child_nocopy(*port_node);
|
||||
}
|
||||
|
||||
port_node->add_property ("shown_editor", editor_shown ? "yes": "no");
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::set_automation_state (AutoState state)
|
||||
{
|
||||
if (!ignore_state_request) {
|
||||
_processor.control (_param, true)->list()->set_automation_state (state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorAutomationTimeAxisView::add_line (AutomationLine& line)
|
||||
{
|
||||
bool get = false;
|
||||
|
||||
if (lines.empty()) {
|
||||
/* first line is the Model for automation state */
|
||||
automation_connection = line.the_list()->automation_state_changed.connect
|
||||
(mem_fun(*this, &ProcessorAutomationTimeAxisView::automation_state_changed));
|
||||
get = true;
|
||||
}
|
||||
|
||||
lines.push_back (std::make_pair(&line,
|
||||
AutomationController::create(_session, line.the_list(),
|
||||
_processor.control(line.the_list()->param_id()))));
|
||||
|
||||
line.set_y_position_and_height (0, height);
|
||||
|
||||
if (get) {
|
||||
/* pick up the current state */
|
||||
automation_state_changed ();
|
||||
}
|
||||
|
||||
line.show();
|
||||
}
|
||||
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000-2007 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_gtk_processor_automation_time_axis_h__
|
||||
#define __ardour_gtk_processor_automation_time_axis_h__
|
||||
|
||||
#include <pbd/xml++.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include <ardour/param_id.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
class Processor;
|
||||
}
|
||||
|
||||
class ProcessorAutomationTimeAxisView : public AutomationTimeAxisView
|
||||
{
|
||||
public:
|
||||
ProcessorAutomationTimeAxisView (ARDOUR::Session&,
|
||||
boost::shared_ptr<ARDOUR::Route>,
|
||||
PublicEditor&,
|
||||
TimeAxisView& parent,
|
||||
ArdourCanvas::Canvas& canvas,
|
||||
std::string name,
|
||||
ARDOUR::ParamID param,
|
||||
ARDOUR::Processor& i,
|
||||
std::string state_name);
|
||||
|
||||
~ProcessorAutomationTimeAxisView();
|
||||
|
||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, nframes_t, double);
|
||||
void add_line (AutomationLine&);
|
||||
|
||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||
void hide ();
|
||||
|
||||
|
||||
private:
|
||||
ARDOUR::Processor& _processor;
|
||||
ARDOUR::ParamID _param;
|
||||
XMLNode* _xml_node;
|
||||
|
||||
void ensure_xml_node();
|
||||
void update_extra_xml_shown (bool editor_shown);
|
||||
|
||||
void set_automation_state (ARDOUR::AutoState);
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_processor_automation_time_axis_h__ */
|
||||
|
|
@ -56,8 +56,6 @@
|
|||
#include "ardour_ui.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "processor_automation_time_axis.h"
|
||||
#include "processor_automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "enums.h"
|
||||
|
|
@ -207,9 +205,7 @@ RouteTimeAxisView::~RouteTimeAxisView ()
|
|||
{
|
||||
GoingAway (); /* EMIT_SIGNAL */
|
||||
|
||||
vector_delete (&processor_automation_curves);
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
|
|
@ -456,6 +452,7 @@ RouteTimeAxisView::build_automation_action_menu ()
|
|||
}
|
||||
|
||||
i->second->menu_item->set_active(show_automation(i->second->param));
|
||||
//i->second->menu_item->set_active(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1106,7 +1103,7 @@ RouteTimeAxisView::selection_click (GdkEventButton* ev)
|
|||
void
|
||||
RouteTimeAxisView::set_selected_points (PointSelection& points)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->set_selected_points (points);
|
||||
}
|
||||
}
|
||||
|
|
@ -1140,7 +1137,7 @@ RouteTimeAxisView::get_selectables (nframes_t start, nframes_t end, double top,
|
|||
|
||||
/* pick up visible automation tracks */
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
if (!(*i)->hidden()) {
|
||||
(*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results);
|
||||
}
|
||||
|
|
@ -1154,7 +1151,7 @@ RouteTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>&
|
|||
_view->get_inverted_selectables (sel, results);
|
||||
}
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
if (!(*i)->hidden()) {
|
||||
(*i)->get_inverted_selectables (sel, results);
|
||||
}
|
||||
|
|
@ -1348,12 +1345,12 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
|
|||
}
|
||||
|
||||
|
||||
list<TimeAxisView*>
|
||||
TimeAxisView::Children
|
||||
RouteTimeAxisView::get_child_list()
|
||||
{
|
||||
list<TimeAxisView*> redirect_children;
|
||||
TimeAxisView::Children redirect_children;
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
if (!(*i)->hidden()) {
|
||||
redirect_children.push_back(*i);
|
||||
}
|
||||
|
|
@ -1542,8 +1539,8 @@ RouteTimeAxisView::show_all_automation ()
|
|||
|
||||
/* Show processor automation */
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<ProcessorAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
if ((*ii)->view == 0) {
|
||||
add_processor_automation_curve ((*i)->processor, (*ii)->what);
|
||||
}
|
||||
|
|
@ -1569,8 +1566,7 @@ RouteTimeAxisView::show_existing_automation ()
|
|||
|
||||
map<ARDOUR::ParamID, RouteAutomationNode*>::iterator i;
|
||||
for (i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
||||
// FIXME: only shown if /first/ line has points
|
||||
if (!i->second->track->lines.empty() && i->second->track->lines[0].first->npoints() > 0) {
|
||||
if (i->second->track->line() && i->second->track->line()->npoints() > 0) {
|
||||
i->second->track->set_marked_for_display (true);
|
||||
i->second->track->canvas_display->show();
|
||||
i->second->track->get_state_node()->add_property ("shown", X_("yes"));
|
||||
|
|
@ -1581,9 +1577,9 @@ RouteTimeAxisView::show_existing_automation ()
|
|||
|
||||
/* Show processor automation */
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
if ((*ii)->view != 0) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<ProcessorAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
if ((*ii)->view != 0 && (*i)->processor->control((*ii)->what)->list()->size() > 0) {
|
||||
(*ii)->menu_item->set_active (true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1599,12 +1595,14 @@ RouteTimeAxisView::hide_all_automation ()
|
|||
{
|
||||
no_redraw = true;
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (vector<ProcessorAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
(*ii)->menu_item->set_active (false);
|
||||
}
|
||||
}
|
||||
|
||||
_show_automation.clear();
|
||||
|
||||
no_redraw = false;
|
||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
|
|
@ -1613,54 +1611,50 @@ RouteTimeAxisView::hide_all_automation ()
|
|||
void
|
||||
RouteTimeAxisView::region_view_added (RegionView* rv)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
AutomationTimeAxisView* atv;
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
boost::shared_ptr<AutomationTimeAxisView> atv;
|
||||
|
||||
if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
|
||||
rv->add_ghost (*atv);
|
||||
if ((atv = boost::dynamic_pointer_cast<AutomationTimeAxisView> (*i)) != 0) {
|
||||
rv->add_ghost (*atv.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::add_ghost_to_processor (RegionView* rv, AutomationTimeAxisView* atv)
|
||||
RouteTimeAxisView::add_ghost_to_processor (RegionView* rv, boost::shared_ptr<AutomationTimeAxisView> atv)
|
||||
{
|
||||
rv->add_ghost (*atv);
|
||||
rv->add_ghost (*atv.get());
|
||||
}
|
||||
|
||||
RouteTimeAxisView::InsertAutomationInfo::~InsertAutomationInfo ()
|
||||
RouteTimeAxisView::ProcessorAutomationInfo::~ProcessorAutomationInfo ()
|
||||
{
|
||||
for (vector<InsertAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
for (vector<ProcessorAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RouteTimeAxisView::InsertAutomationNode::~InsertAutomationNode ()
|
||||
RouteTimeAxisView::ProcessorAutomationNode::~ProcessorAutomationNode ()
|
||||
{
|
||||
parent.remove_ran (this);
|
||||
|
||||
if (view) {
|
||||
delete view;
|
||||
}
|
||||
parent.remove_processor_automation_node (this);
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::remove_ran (InsertAutomationNode* ran)
|
||||
RouteTimeAxisView::remove_processor_automation_node (ProcessorAutomationNode* pan)
|
||||
{
|
||||
if (ran->view) {
|
||||
remove_child (ran->view);
|
||||
if (pan->view) {
|
||||
remove_child (pan->view);
|
||||
}
|
||||
}
|
||||
|
||||
RouteTimeAxisView::InsertAutomationNode*
|
||||
RouteTimeAxisView::ProcessorAutomationNode*
|
||||
RouteTimeAxisView::find_processor_automation_node (boost::shared_ptr<Processor> processor, ParamID what)
|
||||
{
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
|
||||
if ((*i)->processor == processor) {
|
||||
|
||||
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
for (vector<ProcessorAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
|
||||
if ((*ii)->what == what) {
|
||||
return *ii;
|
||||
}
|
||||
|
|
@ -1693,11 +1687,10 @@ legalize_for_xml_node (string str)
|
|||
void
|
||||
RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor> processor, ParamID what)
|
||||
{
|
||||
ProcessorAutomationLine* ral;
|
||||
string name;
|
||||
InsertAutomationNode* ran;
|
||||
ProcessorAutomationNode* pan;
|
||||
|
||||
if ((ran = find_processor_automation_node (processor, what)) == 0) {
|
||||
if ((pan = find_processor_automation_node (processor, what)) == 0) {
|
||||
fatal << _("programming error: ")
|
||||
<< string_compose (X_("processor automation curve for %1:%2 not registered with track!"),
|
||||
processor->name(), what)
|
||||
|
|
@ -1706,7 +1699,7 @@ RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor>
|
|||
return;
|
||||
}
|
||||
|
||||
if (ran->view) {
|
||||
if (pan->view) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1719,42 +1712,37 @@ RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor>
|
|||
char state_name[256];
|
||||
snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (processor->name()).c_str(), what.id());
|
||||
|
||||
ran->view = new ProcessorAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *processor, state_name);
|
||||
boost::shared_ptr<AutomationControl> control = processor->control(what, true);
|
||||
|
||||
ral = new ProcessorAutomationLine (name,
|
||||
*processor, *ran->view, *ran->view->canvas_display,
|
||||
processor->control (what, true)->list());
|
||||
|
||||
ral->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
|
||||
ral->queue_reset ();
|
||||
pan->view = boost::shared_ptr<AutomationTimeAxisView>(
|
||||
new AutomationTimeAxisView (_session, _route, processor, control,
|
||||
editor, *this, parent_canvas, name, state_name));
|
||||
|
||||
ran->view->add_line (*ral);
|
||||
pan->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::processor_automation_track_hidden), pan, processor));
|
||||
|
||||
ran->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::processor_automation_track_hidden), ran, processor));
|
||||
|
||||
if (!ran->view->marked_for_display()) {
|
||||
ran->view->hide ();
|
||||
if (!pan->view->marked_for_display()) {
|
||||
pan->view->hide ();
|
||||
} else {
|
||||
ran->menu_item->set_active (true);
|
||||
pan->menu_item->set_active (true);
|
||||
}
|
||||
|
||||
add_child (ran->view);
|
||||
add_child (pan->view);
|
||||
|
||||
if (_view) {
|
||||
_view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_processor), ran->view));
|
||||
_view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_processor), pan->view));
|
||||
}
|
||||
|
||||
processor->mark_automation_visible (what, true);
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::processor_automation_track_hidden (RouteTimeAxisView::InsertAutomationNode* ran, boost::shared_ptr<Processor> i)
|
||||
RouteTimeAxisView::processor_automation_track_hidden (RouteTimeAxisView::ProcessorAutomationNode* pan, boost::shared_ptr<Processor> i)
|
||||
{
|
||||
if (!_hidden) {
|
||||
ran->menu_item->set_active (false);
|
||||
pan->menu_item->set_active (false);
|
||||
}
|
||||
|
||||
i->mark_automation_visible (ran->what, false);
|
||||
i->mark_automation_visible (pan->what, false);
|
||||
|
||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
|
|
@ -1763,14 +1751,14 @@ void
|
|||
RouteTimeAxisView::add_existing_processor_automation_curves (boost::shared_ptr<Processor> processor)
|
||||
{
|
||||
set<ParamID> s;
|
||||
ProcessorAutomationLine *ral;
|
||||
boost::shared_ptr<AutomationLine> al;
|
||||
|
||||
processor->what_has_visible_automation (s);
|
||||
|
||||
for (set<ParamID>::iterator i = s.begin(); i != s.end(); ++i) {
|
||||
|
||||
if ((ral = find_processor_automation_curve (processor, *i)) != 0) {
|
||||
ral->queue_reset ();
|
||||
if ((al = find_processor_automation_curve (processor, *i)) != 0) {
|
||||
al->queue_reset ();
|
||||
} else {
|
||||
add_processor_automation_curve (processor, (*i));
|
||||
}
|
||||
|
|
@ -1778,7 +1766,7 @@ RouteTimeAxisView::add_existing_processor_automation_curves (boost::shared_ptr<P
|
|||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::add_automation_child(ParamID param, AutomationTimeAxisView* track)
|
||||
RouteTimeAxisView::add_automation_child(ParamID param, boost::shared_ptr<AutomationTimeAxisView> track)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
|
|
@ -1817,8 +1805,8 @@ void
|
|||
RouteTimeAxisView::add_processor_to_subplugin_menu (boost::shared_ptr<Processor> processor)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
InsertAutomationInfo *rai;
|
||||
list<InsertAutomationInfo*>::iterator x;
|
||||
ProcessorAutomationInfo *rai;
|
||||
list<ProcessorAutomationInfo*>::iterator x;
|
||||
|
||||
const std::set<ParamID>& automatable = processor->what_can_be_automated ();
|
||||
std::set<ParamID> has_visible_automation;
|
||||
|
|
@ -1837,7 +1825,7 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::shared_ptr<Processor>
|
|||
|
||||
if (x == processor_automation.end()) {
|
||||
|
||||
rai = new InsertAutomationInfo (processor);
|
||||
rai = new ProcessorAutomationInfo (processor);
|
||||
processor_automation.push_back (rai);
|
||||
|
||||
} else {
|
||||
|
|
@ -1858,7 +1846,7 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::shared_ptr<Processor>
|
|||
|
||||
for (std::set<ParamID>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
|
||||
|
||||
InsertAutomationNode* ran;
|
||||
ProcessorAutomationNode* pan;
|
||||
CheckMenuItem* mitem;
|
||||
|
||||
string name = processor->describe_parameter (*i);
|
||||
|
|
@ -1870,21 +1858,21 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::shared_ptr<Processor>
|
|||
mitem->set_active(true);
|
||||
}
|
||||
|
||||
if ((ran = find_processor_automation_node (processor, *i)) == 0) {
|
||||
if ((pan = find_processor_automation_node (processor, *i)) == 0) {
|
||||
|
||||
/* new item */
|
||||
|
||||
ran = new InsertAutomationNode (*i, mitem, *this);
|
||||
pan = new ProcessorAutomationNode (*i, mitem, *this);
|
||||
|
||||
rai->lines.push_back (ran);
|
||||
rai->lines.push_back (pan);
|
||||
|
||||
} else {
|
||||
|
||||
ran->menu_item = mitem;
|
||||
pan->menu_item = mitem;
|
||||
|
||||
}
|
||||
|
||||
mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::processor_menu_item_toggled), rai, ran));
|
||||
mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::processor_menu_item_toggled), rai, pan));
|
||||
}
|
||||
|
||||
/* add the menu for this processor, because the subplugin
|
||||
|
|
@ -1898,26 +1886,26 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::shared_ptr<Processor>
|
|||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::InsertAutomationInfo* rai,
|
||||
RouteTimeAxisView::InsertAutomationNode* ran)
|
||||
RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::ProcessorAutomationInfo* rai,
|
||||
RouteTimeAxisView::ProcessorAutomationNode* pan)
|
||||
{
|
||||
bool showit = ran->menu_item->get_active();
|
||||
bool showit = pan->menu_item->get_active();
|
||||
bool redraw = false;
|
||||
|
||||
if (ran->view == 0 && showit) {
|
||||
add_processor_automation_curve (rai->processor, ran->what);
|
||||
if (pan->view == 0 && showit) {
|
||||
add_processor_automation_curve (rai->processor, pan->what);
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
if (showit != ran->view->marked_for_display()) {
|
||||
if (showit != pan->view->marked_for_display()) {
|
||||
|
||||
if (showit) {
|
||||
ran->view->set_marked_for_display (true);
|
||||
ran->view->canvas_display->show();
|
||||
pan->view->set_marked_for_display (true);
|
||||
pan->view->canvas_display->show();
|
||||
} else {
|
||||
rai->processor->mark_automation_visible (ran->what, true);
|
||||
ran->view->set_marked_for_display (false);
|
||||
ran->view->hide ();
|
||||
rai->processor->mark_automation_visible (pan->what, true);
|
||||
pan->view->set_marked_for_display (false);
|
||||
pan->view->hide ();
|
||||
}
|
||||
|
||||
redraw = true;
|
||||
|
|
@ -1938,7 +1926,7 @@ RouteTimeAxisView::processors_changed ()
|
|||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||
(*i)->valid = false;
|
||||
}
|
||||
|
||||
|
|
@ -1947,9 +1935,9 @@ RouteTimeAxisView::processors_changed ()
|
|||
_route->foreach_processor (this, &RouteTimeAxisView::add_processor_to_subplugin_menu);
|
||||
_route->foreach_processor (this, &RouteTimeAxisView::add_existing_processor_automation_curves);
|
||||
|
||||
for (list<InsertAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ) {
|
||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ) {
|
||||
|
||||
list<InsertAutomationInfo*>::iterator tmp;
|
||||
list<ProcessorAutomationInfo*>::iterator tmp;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
|
|
@ -1969,24 +1957,24 @@ RouteTimeAxisView::processors_changed ()
|
|||
_route->gui_changed ("track_height", this);
|
||||
}
|
||||
|
||||
ProcessorAutomationLine *
|
||||
boost::shared_ptr<AutomationLine>
|
||||
RouteTimeAxisView::find_processor_automation_curve (boost::shared_ptr<Processor> processor, ParamID what)
|
||||
{
|
||||
InsertAutomationNode* ran;
|
||||
ProcessorAutomationNode* pan;
|
||||
|
||||
if ((ran = find_processor_automation_node (processor, what)) != 0) {
|
||||
if (ran->view) {
|
||||
return dynamic_cast<ProcessorAutomationLine*> (ran->view->lines.front().first);
|
||||
if ((pan = find_processor_automation_node (processor, what)) != 0) {
|
||||
if (pan->view) {
|
||||
pan->view->line();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return boost::shared_ptr<AutomationLine>();
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::reset_processor_automation_curves ()
|
||||
{
|
||||
for (vector<ProcessorAutomationLine*>::iterator i = processor_automation_curves.begin(); i != processor_automation_curves.end(); ++i) {
|
||||
for (ProcessorAutomationCurves::iterator i = processor_automation_curves.begin(); i != processor_automation_curves.end(); ++i) {
|
||||
(*i)->reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
bool cut_copy_clear (Selection&, Editing::CutCopyOp);
|
||||
bool paste (nframes_t, float times, Selection&, size_t nth);
|
||||
|
||||
list<TimeAxisView*> get_child_list();
|
||||
TimeAxisView::Children get_child_list();
|
||||
|
||||
/* The editor calls these when mapping an operation across multiple tracks */
|
||||
void use_new_playlist (bool prompt);
|
||||
|
|
@ -106,36 +106,36 @@ protected:
|
|||
friend class StreamView;
|
||||
|
||||
struct RouteAutomationNode {
|
||||
ARDOUR::ParamID param;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
AutomationTimeAxisView* track;
|
||||
ARDOUR::ParamID param;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
boost::shared_ptr<AutomationTimeAxisView> track;
|
||||
|
||||
RouteAutomationNode (ARDOUR::ParamID par, Gtk::CheckMenuItem* mi, AutomationTimeAxisView* tr)
|
||||
RouteAutomationNode (ARDOUR::ParamID par, Gtk::CheckMenuItem* mi, boost::shared_ptr<AutomationTimeAxisView> tr)
|
||||
: param (par), menu_item (mi), track (tr) {}
|
||||
};
|
||||
|
||||
struct InsertAutomationNode {
|
||||
ARDOUR::ParamID what;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
AutomationTimeAxisView* view;
|
||||
RouteTimeAxisView& parent;
|
||||
struct ProcessorAutomationNode {
|
||||
ARDOUR::ParamID what;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
boost::shared_ptr<AutomationTimeAxisView> view;
|
||||
RouteTimeAxisView& parent;
|
||||
|
||||
InsertAutomationNode (ARDOUR::ParamID w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
|
||||
: what (w), menu_item (mitem), view (0), parent (p) {}
|
||||
ProcessorAutomationNode (ARDOUR::ParamID w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
|
||||
: what (w), menu_item (mitem), parent (p) {}
|
||||
|
||||
~InsertAutomationNode ();
|
||||
~ProcessorAutomationNode ();
|
||||
};
|
||||
|
||||
struct InsertAutomationInfo {
|
||||
struct ProcessorAutomationInfo {
|
||||
boost::shared_ptr<ARDOUR::Processor> processor;
|
||||
bool valid;
|
||||
Gtk::Menu* menu;
|
||||
vector<InsertAutomationNode*> lines;
|
||||
vector<ProcessorAutomationNode*> lines;
|
||||
|
||||
InsertAutomationInfo (boost::shared_ptr<ARDOUR::Processor> i)
|
||||
ProcessorAutomationInfo (boost::shared_ptr<ARDOUR::Processor> i)
|
||||
: processor (i), valid (true), menu (0) {}
|
||||
|
||||
~InsertAutomationInfo ();
|
||||
~ProcessorAutomationInfo ();
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -147,12 +147,12 @@ protected:
|
|||
void processors_changed ();
|
||||
|
||||
void add_processor_to_subplugin_menu (boost::shared_ptr<ARDOUR::Processor>);
|
||||
void remove_ran (InsertAutomationNode* ran);
|
||||
void remove_processor_automation_node (ProcessorAutomationNode* pan);
|
||||
|
||||
void processor_menu_item_toggled (RouteTimeAxisView::InsertAutomationInfo*,
|
||||
RouteTimeAxisView::InsertAutomationNode*);
|
||||
void processor_menu_item_toggled (RouteTimeAxisView::ProcessorAutomationInfo*,
|
||||
RouteTimeAxisView::ProcessorAutomationNode*);
|
||||
|
||||
void processor_automation_track_hidden (InsertAutomationNode*,
|
||||
void processor_automation_track_hidden (ProcessorAutomationNode*,
|
||||
boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
||||
void automation_track_hidden (ARDOUR::ParamID param);
|
||||
|
|
@ -160,16 +160,16 @@ protected:
|
|||
RouteAutomationNode* automation_track(ARDOUR::ParamID param);
|
||||
RouteAutomationNode* automation_track(ARDOUR::AutomationType type);
|
||||
|
||||
InsertAutomationNode*
|
||||
ProcessorAutomationNode*
|
||||
find_processor_automation_node (boost::shared_ptr<ARDOUR::Processor> i, ARDOUR::ParamID);
|
||||
|
||||
ProcessorAutomationLine*
|
||||
boost::shared_ptr<AutomationLine>
|
||||
find_processor_automation_curve (boost::shared_ptr<ARDOUR::Processor> i, ARDOUR::ParamID);
|
||||
|
||||
void add_processor_automation_curve (boost::shared_ptr<ARDOUR::Processor> r, ARDOUR::ParamID);
|
||||
void add_existing_processor_automation_curves (boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
||||
void add_automation_child(ARDOUR::ParamID param, AutomationTimeAxisView* track);
|
||||
void add_automation_child(ARDOUR::ParamID param, boost::shared_ptr<AutomationTimeAxisView> track);
|
||||
|
||||
void reset_processor_automation_curves ();
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ protected:
|
|||
void color_handler ();
|
||||
|
||||
void region_view_added (RegionView*);
|
||||
void add_ghost_to_processor (RegionView*, AutomationTimeAxisView*);
|
||||
void add_ghost_to_processor (RegionView*, boost::shared_ptr<AutomationTimeAxisView>);
|
||||
|
||||
StreamView* _view;
|
||||
ArdourCanvas::Canvas& parent_canvas;
|
||||
|
|
@ -256,13 +256,16 @@ protected:
|
|||
void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
|
||||
void track_mode_changed ();
|
||||
|
||||
list<InsertAutomationInfo*> processor_automation;
|
||||
vector<ProcessorAutomationLine*> processor_automation_curves;
|
||||
list<ProcessorAutomationInfo*> processor_automation;
|
||||
|
||||
typedef vector<boost::shared_ptr<AutomationLine> > ProcessorAutomationCurves;
|
||||
ProcessorAutomationCurves processor_automation_curves;
|
||||
|
||||
// Set from XML so context menu automation buttons can be correctly initialized
|
||||
set<ARDOUR::ParamID> _show_automation;
|
||||
|
||||
map<ARDOUR::ParamID, RouteAutomationNode*> _automation_tracks;
|
||||
typedef map<ARDOUR::ParamID, RouteAutomationNode*> AutomationTracks;
|
||||
AutomationTracks _automation_tracks;
|
||||
|
||||
sigc::connection modified_connection;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,10 +157,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
|
|||
|
||||
TimeAxisView::~TimeAxisView()
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
|
||||
delete (*i)->rect;
|
||||
delete (*i)->start_trim;
|
||||
|
|
@ -231,7 +227,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
|
|||
|
||||
/* now show children */
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
|
||||
if ((*i)->marked_for_display()) {
|
||||
(*i)->canvas_display->show();
|
||||
|
|
@ -315,7 +311,7 @@ TimeAxisView::hide ()
|
|||
|
||||
/* now hide children */
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->hide ();
|
||||
}
|
||||
|
||||
|
|
@ -572,7 +568,7 @@ TimeAxisView::set_selected (bool yn)
|
|||
have to do this here.
|
||||
*/
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->set_selected (false);
|
||||
}
|
||||
|
||||
|
|
@ -611,7 +607,7 @@ TimeAxisView::build_display_menu ()
|
|||
void
|
||||
TimeAxisView::set_samples_per_unit (double spu)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->set_samples_per_unit (spu);
|
||||
}
|
||||
}
|
||||
|
|
@ -619,7 +615,7 @@ TimeAxisView::set_samples_per_unit (double spu)
|
|||
void
|
||||
TimeAxisView::show_timestretch (nframes_t start, nframes_t end)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->show_timestretch (start, end);
|
||||
}
|
||||
}
|
||||
|
|
@ -627,7 +623,7 @@ TimeAxisView::show_timestretch (nframes_t start, nframes_t end)
|
|||
void
|
||||
TimeAxisView::hide_timestretch ()
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->hide_timestretch ();
|
||||
}
|
||||
}
|
||||
|
|
@ -640,7 +636,7 @@ TimeAxisView::show_selection (TimeSelection& ts)
|
|||
double y2;
|
||||
SelectionRect *rect;
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->show_selection (ts);
|
||||
}
|
||||
|
||||
|
|
@ -706,7 +702,7 @@ TimeAxisView::reshow_selection (TimeSelection& ts)
|
|||
{
|
||||
show_selection (ts);
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->show_selection (ts);
|
||||
}
|
||||
}
|
||||
|
|
@ -725,7 +721,7 @@ TimeAxisView::hide_selection ()
|
|||
selection_group->hide();
|
||||
}
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->hide_selection ();
|
||||
}
|
||||
}
|
||||
|
|
@ -815,22 +811,24 @@ TimeAxisView::get_selection_rect (uint32_t id)
|
|||
return rect;
|
||||
}
|
||||
|
||||
struct null_deleter { void operator()(void const *) const {} };
|
||||
|
||||
bool
|
||||
TimeAxisView::is_child (TimeAxisView* tav)
|
||||
{
|
||||
return find (children.begin(), children.end(), tav) != children.end();
|
||||
return find (children.begin(), children.end(), boost::shared_ptr<TimeAxisView>(tav, null_deleter())) != children.end();
|
||||
}
|
||||
|
||||
void
|
||||
TimeAxisView::add_child (TimeAxisView* child)
|
||||
TimeAxisView::add_child (boost::shared_ptr<TimeAxisView> child)
|
||||
{
|
||||
children.push_back (child);
|
||||
}
|
||||
|
||||
void
|
||||
TimeAxisView::remove_child (TimeAxisView* child)
|
||||
TimeAxisView::remove_child (boost::shared_ptr<TimeAxisView> child)
|
||||
{
|
||||
vector<TimeAxisView*>::iterator i;
|
||||
Children::iterator i;
|
||||
|
||||
if ((i = find (children.begin(), children.end(), child)) != children.end()) {
|
||||
children.erase (i);
|
||||
|
|
@ -923,7 +921,7 @@ TimeAxisView::reset_height()
|
|||
{
|
||||
set_height_pixels (height);
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
(*i)->set_height_pixels ((TrackHeight)(*i)->height);
|
||||
}
|
||||
}
|
||||
|
|
@ -1095,7 +1093,7 @@ TimeAxisView::covers_y_position (double y)
|
|||
return this;
|
||||
}
|
||||
|
||||
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
TimeAxisView* tv;
|
||||
|
||||
if ((tv = (*i)->covers_y_position (y)) != 0) {
|
||||
|
|
|
|||
|
|
@ -209,6 +209,8 @@ class TimeAxisView : public virtual AxisView
|
|||
/* call this on the parent */
|
||||
|
||||
virtual XMLNode* get_child_xml_node (const string & childname) { return 0; }
|
||||
|
||||
typedef std::vector<boost::shared_ptr<TimeAxisView> > Children;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -279,11 +281,11 @@ class TimeAxisView : public virtual AxisView
|
|||
/** Find the parent with state */
|
||||
TimeAxisView* get_parent_with_state();
|
||||
|
||||
std::vector<TimeAxisView*> children;
|
||||
Children children;
|
||||
bool is_child (TimeAxisView*);
|
||||
|
||||
void remove_child (TimeAxisView*);
|
||||
void add_child (TimeAxisView*);
|
||||
void remove_child (boost::shared_ptr<TimeAxisView>);
|
||||
void add_child (boost::shared_ptr<TimeAxisView>);
|
||||
|
||||
/* selection display */
|
||||
|
||||
|
|
|
|||
|
|
@ -48,10 +48,14 @@ public:
|
|||
|
||||
virtual boost::shared_ptr<AutomationControl> control(ParamID id, bool create_if_missing=false);
|
||||
virtual boost::shared_ptr<const AutomationControl> control(ParamID id) const;
|
||||
|
||||
typedef std::map<ParamID,boost::shared_ptr<AutomationControl> > Controls;
|
||||
Controls controls() { return _controls; }
|
||||
|
||||
virtual void add_control(boost::shared_ptr<AutomationControl>);
|
||||
|
||||
virtual void automation_snapshot(nframes_t now);
|
||||
virtual void transport_stopped(nframes_t now);
|
||||
|
||||
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
|
||||
|
||||
|
|
@ -60,7 +64,7 @@ public:
|
|||
|
||||
virtual void clear_automation();
|
||||
|
||||
AutoState get_parameter_automation_state (ParamID param);
|
||||
AutoState get_parameter_automation_state (ParamID param, bool lock = true);
|
||||
virtual void set_parameter_automation_state (ParamID param, AutoState);
|
||||
|
||||
AutoStyle get_parameter_automation_style (ParamID param);
|
||||
|
|
@ -88,8 +92,6 @@ protected:
|
|||
|
||||
mutable Glib::Mutex _automation_lock;
|
||||
|
||||
typedef std::map<ParamID,boost::shared_ptr<AutomationControl> > Controls;
|
||||
|
||||
Controls _controls;
|
||||
std::set<ParamID> _visible_controls;
|
||||
std::set<ParamID> _can_automate_list;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/curve.h>
|
||||
#include <ardour/automation_control.h>
|
||||
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
|
|
@ -69,22 +70,8 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful
|
|||
virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs,
|
||||
nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0;
|
||||
|
||||
/* automation */
|
||||
|
||||
virtual void snapshot (nframes_t now) = 0;
|
||||
virtual void transport_stopped (nframes_t frame) = 0;
|
||||
virtual void set_automation_state (AutoState) = 0;
|
||||
virtual void set_automation_style (AutoStyle) = 0;
|
||||
boost::shared_ptr<AutomationControl> pan_control() { return _control; }
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> control() { return _control; }
|
||||
|
||||
/* XXX this is wrong. for multi-dimensional panners, there
|
||||
must surely be more than 1 automation curve.
|
||||
*/
|
||||
/* TODO: Panner is-a Automation solves this */
|
||||
|
||||
virtual boost::shared_ptr<AutomationList> automation() = 0;
|
||||
|
||||
sigc::signal<void> Changed; /* for position */
|
||||
sigc::signal<void> StateChanged; /* for mute */
|
||||
|
||||
|
|
@ -115,8 +102,11 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful
|
|||
|
||||
bool _muted;
|
||||
|
||||
struct PanControllable : public PBD::Controllable {
|
||||
PanControllable (std::string name, StreamPanner& p) : Controllable (name), panner (p) {}
|
||||
struct PanControllable : public AutomationControl {
|
||||
PanControllable (Session& s, std::string name, StreamPanner& p)
|
||||
: AutomationControl (s, boost::shared_ptr<AutomationList>(new AutomationList(
|
||||
ParamID(PanAutomation), 0.0, 1.0, 0.5)), name)
|
||||
, panner (p) {}
|
||||
|
||||
StreamPanner& panner;
|
||||
|
||||
|
|
@ -145,14 +135,6 @@ class BaseStereoPanner : public StreamPanner
|
|||
|
||||
void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
|
||||
|
||||
void snapshot (nframes_t now);
|
||||
void transport_stopped (nframes_t frame);
|
||||
void set_automation_state (AutoState);
|
||||
void set_automation_style (AutoStyle);
|
||||
|
||||
/* TODO: StreamPanner is-a Automatable? */
|
||||
boost::shared_ptr<AutomationList> automation() { return _automation; }
|
||||
|
||||
/* old school automation loading */
|
||||
|
||||
int load (istream&, string path, uint32_t&);
|
||||
|
|
@ -164,8 +146,6 @@ class BaseStereoPanner : public StreamPanner
|
|||
float desired_right;
|
||||
float left_interp;
|
||||
float right_interp;
|
||||
|
||||
boost::shared_ptr<AutomationList> _automation;
|
||||
};
|
||||
|
||||
class EqualPowerStereoPanner : public BaseStereoPanner
|
||||
|
|
@ -197,19 +177,6 @@ class Multi2dPanner : public StreamPanner
|
|||
Multi2dPanner (Panner& parent);
|
||||
~Multi2dPanner ();
|
||||
|
||||
void snapshot (nframes_t now);
|
||||
void transport_stopped (nframes_t frame);
|
||||
void set_automation_state (AutoState);
|
||||
void set_automation_style (AutoStyle);
|
||||
|
||||
/* XXX this is wrong. for multi-dimensional panners, there
|
||||
must surely be more than 1 automation curve.
|
||||
*/
|
||||
|
||||
/* TODO: StreamPanner is-a Automatable? */
|
||||
|
||||
boost::shared_ptr<AutomationList> automation() { return _automation; }
|
||||
|
||||
void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
|
||||
void distribute_automated (AudioBuffer& src, BufferSet& obufs,
|
||||
nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers);
|
||||
|
|
@ -226,7 +193,6 @@ class Multi2dPanner : public StreamPanner
|
|||
int load (istream&, string path, uint32_t&);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<AutomationList> _automation;
|
||||
void update ();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
|||
virtual const char * maker() const = 0;
|
||||
virtual uint32_t parameter_count () const = 0;
|
||||
virtual float default_value (uint32_t port) = 0;
|
||||
virtual void set_parameter (uint32_t which, float val) = 0;
|
||||
virtual float get_parameter(uint32_t which) const = 0;
|
||||
|
||||
virtual int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const = 0;
|
||||
|
|
@ -140,10 +139,6 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
|||
|
||||
virtual bool has_editor() const = 0;
|
||||
|
||||
sigc::signal<void,ParamID,float> ParameterChanged;
|
||||
|
||||
PBD::Controllable *get_nth_control (uint32_t);
|
||||
|
||||
PluginInfoPtr get_info() { return _info; }
|
||||
void set_info (const PluginInfoPtr inf) { _info = inf; }
|
||||
|
||||
|
|
@ -154,32 +149,15 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
|||
cycles_t cycles() const { return _cycles; }
|
||||
|
||||
protected:
|
||||
friend class PluginInsert;
|
||||
virtual void set_parameter (uint32_t which, float val) = 0;
|
||||
|
||||
ARDOUR::AudioEngine& _engine;
|
||||
ARDOUR::Session& _session;
|
||||
PluginInfoPtr _info;
|
||||
uint32_t _cycles;
|
||||
map<string,string> presets;
|
||||
bool save_preset(string name, string domain /* vst, ladspa etc. */);
|
||||
|
||||
void setup_controls ();
|
||||
|
||||
struct PortControllable : public PBD::Controllable {
|
||||
PortControllable (std::string name, Plugin&, uint32_t abs_port_id,
|
||||
float lower, float upper, bool toggled, bool logarithmic);
|
||||
|
||||
void set_value (float);
|
||||
float get_value () const;
|
||||
|
||||
Plugin& plugin;
|
||||
uint32_t absolute_port;
|
||||
float upper;
|
||||
float lower;
|
||||
float range;
|
||||
bool toggled;
|
||||
bool logarithmic;
|
||||
};
|
||||
|
||||
vector<PortControllable*> controls;
|
||||
};
|
||||
|
||||
PluginPtr find_plugin(ARDOUR::Session&, string name, long unique_id, ARDOUR::PluginType);
|
||||
|
|
|
|||
|
|
@ -77,8 +77,22 @@ class PluginInsert : public Processor
|
|||
bool is_generator() const;
|
||||
|
||||
void set_parameter (ParamID param, float val);
|
||||
float get_parameter (ParamID param);
|
||||
|
||||
float default_parameter_value (ParamID param);
|
||||
|
||||
struct PluginControl : public AutomationControl {
|
||||
PluginControl (PluginInsert& p, boost::shared_ptr<AutomationList> list);
|
||||
|
||||
void set_value (float val);
|
||||
float get_value (void) const;
|
||||
|
||||
private:
|
||||
PluginInsert& _plugin;
|
||||
boost::shared_ptr<AutomationList> _list;
|
||||
bool _logarithmic;
|
||||
bool _toggled;
|
||||
};
|
||||
|
||||
boost::shared_ptr<Plugin> plugin(uint32_t num=0) const {
|
||||
if (num < _plugins.size()) {
|
||||
|
|
@ -94,9 +108,6 @@ class PluginInsert : public Processor
|
|||
|
||||
nframes_t signal_latency() const;
|
||||
|
||||
void transport_stopped (nframes_t now);
|
||||
void automation_snapshot (nframes_t now);
|
||||
|
||||
private:
|
||||
|
||||
void parameter_changed (ParamID, float);
|
||||
|
|
|
|||
|
|
@ -127,8 +127,6 @@ Automatable::add_control(boost::shared_ptr<AutomationControl> ac)
|
|||
|
||||
cerr << _name << ": added parameter " << param.to_string() << endl;
|
||||
|
||||
// FIXME: sane default behaviour?
|
||||
_visible_controls.insert(param);
|
||||
_can_automate_list.insert(param);
|
||||
|
||||
// Sync everything (derived classes) up to initial values
|
||||
|
|
@ -355,17 +353,22 @@ Automatable::set_parameter_automation_state (ParamID param, AutoState s)
|
|||
}
|
||||
|
||||
AutoState
|
||||
Automatable::get_parameter_automation_state (ParamID param)
|
||||
Automatable::get_parameter_automation_state (ParamID param, bool lock)
|
||||
{
|
||||
Glib::Mutex::Lock lm (_automation_lock);
|
||||
AutoState result = Off;
|
||||
|
||||
if (lock)
|
||||
_automation_lock.lock();
|
||||
|
||||
boost::shared_ptr<AutomationControl> c = control(param);
|
||||
|
||||
if (c) {
|
||||
return c->list()->automation_state();
|
||||
} else {
|
||||
return Off;
|
||||
}
|
||||
if (c)
|
||||
result = c->list()->automation_state();
|
||||
|
||||
if (lock)
|
||||
_automation_lock.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -434,3 +437,18 @@ Automatable::automation_snapshot (nframes_t now)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Automatable::transport_stopped (nframes_t now)
|
||||
{
|
||||
for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
||||
|
||||
boost::shared_ptr<AutomationControl> c = li->second;
|
||||
|
||||
c->list()->reposition_for_rt_add (now);
|
||||
|
||||
if (c->list()->automation_state() != Off) {
|
||||
c->set_value(c->list()->eval(now));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
|
|||
{
|
||||
assert(type != DataType::NIL);
|
||||
assert(type < _buffers.size());
|
||||
assert(buffer_capacity > 0);
|
||||
|
||||
if (num_buffers == 0)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2271,7 +2271,7 @@ void
|
|||
IO::start_pan_touch (uint32_t which)
|
||||
{
|
||||
if (which < _panner->size()) {
|
||||
(*_panner)[which]->automation()->start_touch();
|
||||
(*_panner)[which]->pan_control()->list()->start_touch();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2279,7 +2279,7 @@ void
|
|||
IO::end_pan_touch (uint32_t which)
|
||||
{
|
||||
if (which < _panner->size()) {
|
||||
(*_panner)[which]->automation()->stop_touch();
|
||||
(*_panner)[which]->pan_control()->list()->stop_touch();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,8 +136,6 @@ LadspaPlugin::init (void *mod, uint32_t index, nframes_t rate)
|
|||
}
|
||||
}
|
||||
|
||||
Plugin::setup_controls ();
|
||||
|
||||
latency_compute_run ();
|
||||
}
|
||||
|
||||
|
|
@ -318,11 +316,13 @@ LadspaPlugin::set_parameter (uint32_t which, float val)
|
|||
{
|
||||
if (which < descriptor->PortCount) {
|
||||
shadow_data[which] = (LADSPA_Data) val;
|
||||
#if 0
|
||||
ParameterChanged (ParamID(PluginAutomation, which), val); /* EMIT SIGNAL */
|
||||
|
||||
if (which < parameter_count() && controls[which]) {
|
||||
controls[which]->Changed ();
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may"
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static double direct_pan_to_control (pan_t val) {
|
|||
|
||||
StreamPanner::StreamPanner (Panner& p)
|
||||
: parent (p),
|
||||
_control (new PanControllable(X_("panner"), *this))
|
||||
_control (new PanControllable(p.session(), X_("panner"), *this))
|
||||
{
|
||||
_muted = false;
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ StreamPanner::add_state (XMLNode& node)
|
|||
/*---------------------------------------------------------------------- */
|
||||
|
||||
BaseStereoPanner::BaseStereoPanner (Panner& p)
|
||||
: StreamPanner (p), _automation (new AutomationList(ParamID(PanAutomation), 0.0, 1.0, 0.5))
|
||||
: StreamPanner (p)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -198,50 +198,13 @@ BaseStereoPanner::~BaseStereoPanner ()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
BaseStereoPanner::snapshot (nframes_t now)
|
||||
{
|
||||
if (_automation->automation_state() == Write || _automation->automation_state() == Touch) {
|
||||
_automation->rt_add (now, x);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseStereoPanner::transport_stopped (nframes_t frame)
|
||||
{
|
||||
_automation->reposition_for_rt_add (frame);
|
||||
|
||||
if (_automation->automation_state() != Off) {
|
||||
set_position (_automation->eval (frame));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseStereoPanner::set_automation_style (AutoStyle style)
|
||||
{
|
||||
_automation->set_automation_style (style);
|
||||
}
|
||||
|
||||
void
|
||||
BaseStereoPanner::set_automation_state (AutoState state)
|
||||
{
|
||||
if (state != _automation->automation_state()) {
|
||||
|
||||
_automation->set_automation_state (state);
|
||||
|
||||
if (state != Off) {
|
||||
set_position (_automation->eval (parent.session().transport_frame()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
BaseStereoPanner::load (istream& in, string path, uint32_t& linecnt)
|
||||
{
|
||||
char line[128];
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
_automation->clear ();
|
||||
_control->list()->clear ();
|
||||
|
||||
while (in.getline (line, sizeof (line), '\n')) {
|
||||
nframes_t when;
|
||||
|
|
@ -258,12 +221,12 @@ BaseStereoPanner::load (istream& in, string path, uint32_t& linecnt)
|
|||
continue;
|
||||
}
|
||||
|
||||
_automation->fast_simple_add (when, value);
|
||||
_control->list()->fast_simple_add (when, value);
|
||||
}
|
||||
|
||||
/* now that we are done loading */
|
||||
|
||||
_automation->StateChanged ();
|
||||
_control->list()->StateChanged ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -438,7 +401,7 @@ EqualPowerStereoPanner::distribute_automated (AudioBuffer& srcbuf, BufferSet& ob
|
|||
|
||||
/* fetch positional data */
|
||||
|
||||
if (!_automation->curve().rt_safe_get_vector (start, end, buffers[0], nframes)) {
|
||||
if (!_control->list()->curve().rt_safe_get_vector (start, end, buffers[0], nframes)) {
|
||||
/* fallback */
|
||||
if (!_muted) {
|
||||
distribute (srcbuf, obufs, 1.0, nframes);
|
||||
|
|
@ -518,7 +481,7 @@ EqualPowerStereoPanner::state (bool full_state)
|
|||
root->add_property (X_("type"), EqualPowerStereoPanner::name);
|
||||
|
||||
XMLNode* autonode = new XMLNode (X_("Automation"));
|
||||
autonode->add_child_nocopy (_automation->state (full_state));
|
||||
autonode->add_child_nocopy (_control->list()->state (full_state));
|
||||
root->add_child_nocopy (*autonode);
|
||||
|
||||
StreamPanner::add_state (*root);
|
||||
|
|
@ -551,10 +514,10 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
|
|||
|
||||
} else if ((*iter)->name() == X_("Automation")) {
|
||||
|
||||
_automation->set_state (*((*iter)->children().front()));
|
||||
_control->list()->set_state (*((*iter)->children().front()));
|
||||
|
||||
if (_automation->automation_state() != Off) {
|
||||
set_position (_automation->eval (parent.session().transport_frame()));
|
||||
if (_control->list()->automation_state() != Off) {
|
||||
set_position (_control->list()->eval (parent.session().transport_frame()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -565,7 +528,7 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
|
|||
/*----------------------------------------------------------------------*/
|
||||
|
||||
Multi2dPanner::Multi2dPanner (Panner& p)
|
||||
: StreamPanner (p), _automation (new AutomationList(ParamID(PanAutomation), 0.0, 1.0, 0.5)) // XXX useless
|
||||
: StreamPanner (p)
|
||||
{
|
||||
update ();
|
||||
}
|
||||
|
|
@ -574,30 +537,6 @@ Multi2dPanner::~Multi2dPanner ()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
Multi2dPanner::snapshot (nframes_t now)
|
||||
{
|
||||
// how?
|
||||
}
|
||||
|
||||
void
|
||||
Multi2dPanner::transport_stopped (nframes_t frame)
|
||||
{
|
||||
//what?
|
||||
}
|
||||
|
||||
void
|
||||
Multi2dPanner::set_automation_style (AutoStyle style)
|
||||
{
|
||||
//what?
|
||||
}
|
||||
|
||||
void
|
||||
Multi2dPanner::set_automation_state (AutoState state)
|
||||
{
|
||||
// what?
|
||||
}
|
||||
|
||||
void
|
||||
Multi2dPanner::update ()
|
||||
{
|
||||
|
|
@ -930,10 +869,10 @@ Panner::reset (uint32_t nouts, uint32_t npans)
|
|||
if (changed || ((left == 0.5) && (right == 0.5))) {
|
||||
|
||||
front()->set_position (0.0);
|
||||
front()->automation()->reset_default (0.0);
|
||||
front()->pan_control()->list()->reset_default (0.0);
|
||||
|
||||
back()->set_position (1.0);
|
||||
back()->automation()->reset_default (1.0);
|
||||
back()->pan_control()->list()->reset_default (1.0);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
|
@ -972,7 +911,7 @@ void
|
|||
Panner::set_automation_style (AutoStyle style)
|
||||
{
|
||||
for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
|
||||
(*i)->set_automation_style (style);
|
||||
(*i)->pan_control()->list()->set_automation_style (style);
|
||||
}
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
|
@ -981,7 +920,7 @@ void
|
|||
Panner::set_automation_state (AutoState state)
|
||||
{
|
||||
for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
|
||||
(*i)->set_automation_state (state);
|
||||
(*i)->pan_control()->list()->set_automation_state (state);
|
||||
}
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
|
@ -990,7 +929,7 @@ AutoState
|
|||
Panner::automation_state () const
|
||||
{
|
||||
if (!empty()) {
|
||||
return front()->automation()->automation_state ();
|
||||
return front()->pan_control()->list()->automation_state ();
|
||||
} else {
|
||||
return Off;
|
||||
}
|
||||
|
|
@ -1000,7 +939,7 @@ AutoStyle
|
|||
Panner::automation_style () const
|
||||
{
|
||||
if (!empty()) {
|
||||
return front()->automation()->automation_style ();
|
||||
return front()->pan_control()->list()->automation_style ();
|
||||
} else {
|
||||
return Absolute;
|
||||
}
|
||||
|
|
@ -1010,7 +949,7 @@ void
|
|||
Panner::transport_stopped (nframes_t frame)
|
||||
{
|
||||
for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
|
||||
(*i)->transport_stopped (frame);
|
||||
(*i)->pan_control()->list()->reposition_for_rt_add (frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1018,7 +957,9 @@ void
|
|||
Panner::snapshot (nframes_t now)
|
||||
{
|
||||
for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
|
||||
(*i)->snapshot (now);
|
||||
boost::shared_ptr<AutomationList> list = (*i)->pan_control()->list();
|
||||
if (list->automation_write())
|
||||
list->rt_add(now, (*i)->pan_control()->get_value());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1026,7 +967,7 @@ void
|
|||
Panner::clear_automation ()
|
||||
{
|
||||
for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
|
||||
(*i)->automation()->clear ();
|
||||
(*i)->pan_control()->list()->clear ();
|
||||
}
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
|
@ -1181,7 +1122,7 @@ bool
|
|||
Panner::touching () const
|
||||
{
|
||||
for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) {
|
||||
if ((*i)->automation()->touching ()) {
|
||||
if ((*i)->pan_control()->list()->touching ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,105 +58,10 @@ Plugin::Plugin (const Plugin& other)
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
Plugin::setup_controls ()
|
||||
{
|
||||
uint32_t port_cnt = parameter_count();
|
||||
|
||||
/* set up a vector of null pointers for the controls.
|
||||
we'll fill this in on an as-needed basis.
|
||||
*/
|
||||
|
||||
for (uint32_t i = 0; i < port_cnt; ++i) {
|
||||
controls.push_back (0);
|
||||
}
|
||||
}
|
||||
|
||||
Plugin::~Plugin ()
|
||||
{
|
||||
for (vector<PortControllable*>::iterator i = controls.begin(); i != controls.end(); ++i) {
|
||||
if (*i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controllable *
|
||||
Plugin::get_nth_control (uint32_t n)
|
||||
{
|
||||
if (n >= parameter_count()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (controls[n] == 0) {
|
||||
|
||||
Plugin::ParameterDescriptor desc;
|
||||
|
||||
get_parameter_descriptor (n, desc);
|
||||
|
||||
controls[n] = new PortControllable (describe_parameter (ParamID(PluginAutomation, n)), *this, n,
|
||||
desc.lower, desc.upper, desc.toggled, desc.logarithmic);
|
||||
}
|
||||
|
||||
return controls[n];
|
||||
}
|
||||
|
||||
Plugin::PortControllable::PortControllable (string name, Plugin& p, uint32_t port_id,
|
||||
float low, float up, bool t, bool loga)
|
||||
: Controllable (name), plugin (p), absolute_port (port_id)
|
||||
{
|
||||
toggled = t;
|
||||
logarithmic = loga;
|
||||
lower = low;
|
||||
upper = up;
|
||||
range = upper - lower;
|
||||
}
|
||||
|
||||
void
|
||||
Plugin::PortControllable::set_value (float value)
|
||||
{
|
||||
if (toggled) {
|
||||
if (value > 0.5) {
|
||||
value = 1.0;
|
||||
} else {
|
||||
value = 0.0;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!logarithmic) {
|
||||
value = lower + (range * value);
|
||||
} else {
|
||||
float _lower = 0.0f;
|
||||
if (lower > 0.0f) {
|
||||
_lower = log(lower);
|
||||
}
|
||||
|
||||
value = exp(_lower + log(range) * value);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.set_parameter (absolute_port, value);
|
||||
}
|
||||
|
||||
float
|
||||
Plugin::PortControllable::get_value (void) const
|
||||
{
|
||||
float val = plugin.get_parameter (absolute_port);
|
||||
|
||||
if (toggled) {
|
||||
|
||||
return val;
|
||||
|
||||
} else {
|
||||
|
||||
if (logarithmic) {
|
||||
val = log(val);
|
||||
}
|
||||
|
||||
return ((val - lower) / range);
|
||||
}
|
||||
}
|
||||
|
||||
vector<string>
|
||||
Plugin::get_presets()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placemen
|
|||
|
||||
_plugins.push_back (plug);
|
||||
|
||||
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
|
||||
|
||||
init ();
|
||||
|
||||
{
|
||||
|
|
@ -80,8 +78,6 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node)
|
|||
|
||||
set_automatable ();
|
||||
|
||||
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em (_session.engine().process_lock());
|
||||
IO::MoreChannels (max(input_streams(), output_streams()));
|
||||
|
|
@ -98,9 +94,6 @@ PluginInsert::PluginInsert (const PluginInsert& other)
|
|||
_plugins.push_back (plugin_factory (other.plugin (n)));
|
||||
}
|
||||
|
||||
|
||||
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
|
||||
|
||||
init ();
|
||||
|
||||
ProcessorCreated (this); /* EMIT SIGNAL */
|
||||
|
|
@ -215,12 +208,13 @@ PluginInsert::set_automatable ()
|
|||
_plugins.front()->get_parameter_descriptor(i->id(), desc);
|
||||
boost::shared_ptr<AutomationList> list(new AutomationList(
|
||||
*i,
|
||||
(desc.min_unbound ? FLT_MIN : desc.lower),
|
||||
(desc.max_unbound ? FLT_MAX : desc.upper),
|
||||
//(desc.min_unbound ? FLT_MIN : desc.lower),
|
||||
//(desc.max_unbound ? FLT_MAX : desc.upper),
|
||||
desc.lower, desc.upper,
|
||||
_plugins.front()->default_value(i->id())));
|
||||
|
||||
add_control(boost::shared_ptr<AutomationControl>(
|
||||
new AutomationControl(_session, list)));
|
||||
new PluginControl(*this, list)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -288,11 +282,10 @@ PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t off
|
|||
if (c->list()->param_id().type() == PluginAutomation && c->list()->automation_playback()) {
|
||||
bool valid;
|
||||
|
||||
float val = c->list()->rt_safe_eval (now, valid);
|
||||
const float val = c->list()->rt_safe_eval (now, valid);
|
||||
|
||||
if (valid) {
|
||||
/* set the first plugin, the others will be set via signals */
|
||||
_plugins[0]->set_parameter (c->list()->param_id(), val);
|
||||
c->set_value(val);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -306,38 +299,6 @@ PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t off
|
|||
/* leave remaining channel buffers alone */
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::automation_snapshot (nframes_t now)
|
||||
{
|
||||
for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
||||
|
||||
boost::shared_ptr<AutomationControl> c = li->second;
|
||||
|
||||
if (c->list() != 0 && c->list()->param_id().type() == PluginAutomation
|
||||
&& c->list()->automation_write ()) {
|
||||
|
||||
float val = _plugins[0]->get_parameter (c->list()->param_id());
|
||||
c->list()->rt_add (now, val);
|
||||
_last_automation_snapshot = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::transport_stopped (nframes_t now)
|
||||
{
|
||||
for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
||||
|
||||
boost::shared_ptr<AutomationControl> c = li->second;
|
||||
|
||||
c->list()->reposition_for_rt_add (now);
|
||||
|
||||
if (c->list()->param_id().type() == PluginAutomation && c->list()->automation_state() != Off) {
|
||||
_plugins[0]->set_parameter (li->first, c->list()->eval (now));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::silence (nframes_t nframes, nframes_t offset)
|
||||
{
|
||||
|
|
@ -393,13 +354,22 @@ PluginInsert::set_parameter (ParamID param, float val)
|
|||
|
||||
boost::shared_ptr<AutomationControl> c = control (param);
|
||||
|
||||
if (c && c->list()->automation_write()) {
|
||||
c->list()->add (_session.audible_frame(), val);
|
||||
}
|
||||
if (c)
|
||||
c->set_value(val);
|
||||
|
||||
_session.set_dirty();
|
||||
}
|
||||
|
||||
float
|
||||
PluginInsert::get_parameter (ParamID param)
|
||||
{
|
||||
if (param.type() != PluginAutomation)
|
||||
return 0.0;
|
||||
else
|
||||
return
|
||||
_plugins[0]->get_parameter (param.id());
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offset)
|
||||
{
|
||||
|
|
@ -877,3 +847,74 @@ PluginInsert::type ()
|
|||
}
|
||||
}
|
||||
|
||||
PluginInsert::PluginControl::PluginControl (PluginInsert& p, boost::shared_ptr<AutomationList> list)
|
||||
: AutomationControl (p.session(), list, p.describe_parameter(list->param_id()))
|
||||
, _plugin (p)
|
||||
, _list (list)
|
||||
{
|
||||
Plugin::ParameterDescriptor desc;
|
||||
p.plugin(0)->get_parameter_descriptor (list->param_id().id(), desc);
|
||||
_logarithmic = desc.logarithmic;
|
||||
_toggled = desc.toggled;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::PluginControl::set_value (float val)
|
||||
{
|
||||
/* FIXME: probably should be taking out some lock here.. */
|
||||
|
||||
if (_toggled) {
|
||||
if (val > 0.5) {
|
||||
val = 1.0;
|
||||
} else {
|
||||
val = 0.0;
|
||||
}
|
||||
} else {
|
||||
|
||||
/*const float range = _list->get_max_y() - _list->get_min_y();
|
||||
const float lower = _list->get_min_y();
|
||||
|
||||
if (!_logarithmic) {
|
||||
val = lower + (range * val);
|
||||
} else {
|
||||
float log_lower = 0.0f;
|
||||
if (lower > 0.0f) {
|
||||
log_lower = log(lower);
|
||||
}
|
||||
|
||||
val = exp(log_lower + log(range) * val);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugin._plugins.begin();
|
||||
i != _plugin._plugins.end(); ++i) {
|
||||
(*i)->set_parameter (_list->param_id().id(), val);
|
||||
}
|
||||
|
||||
AutomationControl::set_value(val);
|
||||
}
|
||||
|
||||
float
|
||||
PluginInsert::PluginControl::get_value (void) const
|
||||
{
|
||||
/* FIXME: probably should be taking out some lock here.. */
|
||||
|
||||
float val = _plugin.get_parameter (_list->param_id());
|
||||
|
||||
return val;
|
||||
|
||||
/*if (_toggled) {
|
||||
|
||||
return val;
|
||||
|
||||
} else {
|
||||
|
||||
if (_logarithmic) {
|
||||
val = log(val);
|
||||
}
|
||||
|
||||
return ((val - lower) / range);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3678,6 +3678,9 @@ Session::tempo_map_changed (Change ignored)
|
|||
void
|
||||
Session::ensure_buffers (ChanCount howmany)
|
||||
{
|
||||
if (current_block_size == 0)
|
||||
return; // too early? (is this ok?)
|
||||
|
||||
// We need at least 1 MIDI scratch buffer to mix/merge
|
||||
if (howmany.n_midi() < 1)
|
||||
howmany.set_midi(1);
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ void
|
|||
VSTPlugin::set_parameter (uint32_t which, float val)
|
||||
{
|
||||
_plugin->setParameter (_plugin, which, val);
|
||||
ParameterChanged (which, val); /* EMIT SIGNAL */
|
||||
//ParameterChanged (which, val); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
float
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue