Add support for Region Fx Automation
This commit is contained in:
parent
43c15a09f2
commit
c120829796
|
@ -33,6 +33,7 @@
|
|||
#include "ardour/audioregion.h"
|
||||
#include "ardour/session_event.h"
|
||||
#include "ardour/dB.h"
|
||||
#include "ardour/region_fx_plugin.h"
|
||||
|
||||
#include "audio_region_editor.h"
|
||||
#include "audio_region_view.h"
|
||||
|
@ -52,9 +53,10 @@ _peak_amplitude_thread (void* arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r)
|
||||
: RegionEditor (s, r)
|
||||
, _audio_region (r)
|
||||
AudioRegionEditor::AudioRegionEditor (Session* s, AudioRegionView* arv)
|
||||
: RegionEditor (s, arv)
|
||||
, _arv (arv)
|
||||
, _audio_region (arv->audio_region ())
|
||||
, gain_adjustment(accurate_coefficient_to_dB(fabsf (_audio_region->scale_amplitude())), -40.0, +40.0, 0.1, 1.0, 0)
|
||||
, _polarity_toggle (_("Invert"))
|
||||
, _peak_channel (false)
|
||||
|
@ -91,11 +93,20 @@ AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r
|
|||
_table.attach (_polarity_toggle, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
|
||||
++_table_row;
|
||||
|
||||
_region_line_label.set_name ("AudioRegionEditorLabel");
|
||||
_region_line_label.set_text (_("Region Line:"));
|
||||
_table.attach (_region_line_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
|
||||
_table.attach (_region_line, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
|
||||
++_table_row;
|
||||
|
||||
gain_changed ();
|
||||
refill_region_line ();
|
||||
|
||||
gain_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
|
||||
_polarity_toggle.signal_toggled().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
|
||||
|
||||
arv->region_line_changed.connect ((sigc::mem_fun (*this, &AudioRegionEditor::refill_region_line)));
|
||||
|
||||
_peak_amplitude.property_editable() = false;
|
||||
_peak_amplitude.set_text (_("Calculating..."));
|
||||
|
||||
|
@ -189,3 +200,74 @@ AudioRegionEditor::peak_amplitude_found (double p)
|
|||
_peak_amplitude.set_text (s.str ());
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionEditor::refill_region_line ()
|
||||
{
|
||||
using namespace Gtk::Menu_Helpers;
|
||||
|
||||
_region_line.clear_items ();
|
||||
|
||||
MenuList& rm_items (_region_line.items ());
|
||||
|
||||
int nth = 0;
|
||||
PBD::ID rfx_id (0);
|
||||
uint32_t param_id = 0;
|
||||
string active_text = _("Gain Envelope");
|
||||
|
||||
_arv->get_region_fx_line (rfx_id, param_id);
|
||||
_arv->set_ignore_line_change (true);
|
||||
|
||||
Gtk::RadioMenuItem::Group grp; // TODO Fix radio signal duplicate emission, skip inactive one
|
||||
AudioRegionView* arv = _arv;
|
||||
|
||||
rm_items.push_back (RadioMenuElem (grp, _("Gain Envelope")));
|
||||
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&rm_items.back ());
|
||||
cmi->set_active (rfx_id == 0 || param_id == UINT32_MAX);
|
||||
cmi->signal_activate ().connect ([arv] () { arv->set_region_gain_line (); });
|
||||
|
||||
_audio_region->foreach_plugin ([&rm_items, arv, &nth, &grp, &active_text, rfx_id, param_id](std::weak_ptr<RegionFxPlugin> wfx)
|
||||
{
|
||||
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
|
||||
if (!fx) {
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<Plugin> plugin = fx->plugin ();
|
||||
|
||||
Gtk::Menu* acm = manage (new Gtk::Menu);
|
||||
MenuList& acm_items (acm->items ());
|
||||
|
||||
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
|
||||
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
|
||||
continue;
|
||||
}
|
||||
const Evoral::Parameter param (PluginAutomation, 0, i);
|
||||
std::string label = plugin->describe_parameter (param);
|
||||
if (label == X_("latency") || label == X_("hidden")) {
|
||||
continue;
|
||||
}
|
||||
std::shared_ptr<ARDOUR::AutomationControl> c (std::dynamic_pointer_cast<ARDOUR::AutomationControl> (fx->control (param)));
|
||||
if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) {
|
||||
continue;
|
||||
}
|
||||
bool active = fx->id () == rfx_id && param_id == i;
|
||||
|
||||
acm_items.push_back (RadioMenuElem (grp, label));
|
||||
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&acm_items.back ());
|
||||
cmi->set_active (active);
|
||||
cmi->signal_activate ().connect ([arv, nth, i] () { arv->set_region_fx_line (nth, i); });
|
||||
if (active) {
|
||||
active_text = fx->name () + ": " + label;
|
||||
}
|
||||
}
|
||||
|
||||
if (!acm_items.empty ()) {
|
||||
rm_items.push_back (MenuElem (fx->name (), *acm));
|
||||
} else {
|
||||
delete acm;
|
||||
}
|
||||
++nth;
|
||||
});
|
||||
|
||||
_region_line.set_text (active_text);
|
||||
_arv->set_ignore_line_change (false);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <gtkmm/separator.h>
|
||||
#include <gtkmm/spinbutton.h>
|
||||
|
||||
#include "widgets/ardour_dropdown.h"
|
||||
|
||||
#include "pbd/signals.h"
|
||||
#include "pbd/crossthread.h"
|
||||
|
@ -55,7 +56,7 @@ class AudioRegionView;
|
|||
class AudioRegionEditor : public RegionEditor
|
||||
{
|
||||
public:
|
||||
AudioRegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::AudioRegion>);
|
||||
AudioRegionEditor (ARDOUR::Session*, AudioRegionView*);
|
||||
~AudioRegionEditor ();
|
||||
|
||||
void peak_amplitude_thread ();
|
||||
|
@ -67,6 +68,9 @@ private:
|
|||
void gain_changed ();
|
||||
void gain_adjustment_changed ();
|
||||
|
||||
void refill_region_line ();
|
||||
|
||||
AudioRegionView* _arv;
|
||||
std::shared_ptr<ARDOUR::AudioRegion> _audio_region;
|
||||
|
||||
Gtk::Label gain_label;
|
||||
|
@ -79,6 +83,9 @@ private:
|
|||
Gtk::Label _peak_amplitude_label;
|
||||
Gtk::Entry _peak_amplitude;
|
||||
|
||||
Gtk::Label _region_line_label;
|
||||
ArdourWidgets::ArdourDropdown _region_line;
|
||||
|
||||
void signal_peak_thread ();
|
||||
pthread_t _peak_amplitude_thread_handle;
|
||||
void peak_amplitude_found (double);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "ardour/audioregion.h"
|
||||
#include "ardour/audiosource.h"
|
||||
#include "ardour/profile.h"
|
||||
#include "ardour/region_fx_plugin.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "pbd/memento_command.h"
|
||||
|
@ -112,8 +113,7 @@ static Cairo::RefPtr<Cairo::Pattern> create_pending_peak_pattern() {
|
|||
return p;
|
||||
}
|
||||
|
||||
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu,
|
||||
uint32_t basic_color)
|
||||
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu, uint32_t basic_color)
|
||||
: RegionView (parent, tv, r, spu, basic_color)
|
||||
, fade_in_handle(0)
|
||||
, fade_out_handle(0)
|
||||
|
@ -129,6 +129,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
|
|||
, _amplitude_above_axis(1.0)
|
||||
, trim_fade_in_drag_active(false)
|
||||
, trim_fade_out_drag_active(false)
|
||||
, _rfx_id (0)
|
||||
, _rdx_param (UINT32_MAX)
|
||||
, _ignore_line_change (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -149,6 +152,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
|
|||
, _amplitude_above_axis(1.0)
|
||||
, trim_fade_in_drag_active(false)
|
||||
, trim_fade_out_drag_active(false)
|
||||
, _rfx_id (0)
|
||||
, _rdx_param (UINT32_MAX)
|
||||
, _ignore_line_change (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -168,6 +174,9 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, std::shared_ptr<
|
|||
, _amplitude_above_axis (other._amplitude_above_axis)
|
||||
, trim_fade_in_drag_active(false)
|
||||
, trim_fade_out_drag_active(false)
|
||||
, _rfx_id (0)
|
||||
, _rdx_param (UINT32_MAX)
|
||||
, _ignore_line_change (false)
|
||||
{
|
||||
init (true);
|
||||
}
|
||||
|
@ -232,12 +241,7 @@ AudioRegionView::init (bool wfd)
|
|||
set_fade_visibility (false);
|
||||
}
|
||||
|
||||
const string line_name = _region->name() + ":gain";
|
||||
|
||||
gain_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
|
||||
|
||||
update_envelope_visibility ();
|
||||
gain_line->reset ();
|
||||
set_region_gain_line ();
|
||||
|
||||
/* streamview will call set_height() */
|
||||
//set_height (trackview.current_height()); // XXX not correct for Layered mode, but set_height() will fix later.
|
||||
|
@ -278,7 +282,7 @@ AudioRegionView::init (bool wfd)
|
|||
setup_waveform_visibility ();
|
||||
|
||||
get_canvas_frame()->set_data ("linemerger", (LineMerger*) this);
|
||||
gain_line->canvas_group().raise_to_top ();
|
||||
_fx_line->canvas_group().raise_to_top ();
|
||||
|
||||
/* XXX sync mark drag? */
|
||||
}
|
||||
|
@ -606,15 +610,15 @@ AudioRegionView::set_height (gdouble height)
|
|||
}
|
||||
}
|
||||
|
||||
if (gain_line) {
|
||||
if (_fx_line) {
|
||||
|
||||
if ((height / nchans) < NAME_HIGHLIGHT_THRESH) {
|
||||
gain_line->hide ();
|
||||
_fx_line->hide ();
|
||||
} else {
|
||||
update_envelope_visibility ();
|
||||
}
|
||||
|
||||
gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
|
||||
_fx_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
|
||||
}
|
||||
|
||||
reset_fade_shapes ();
|
||||
|
@ -1081,8 +1085,8 @@ AudioRegionView::set_samples_per_pixel (gdouble fpp)
|
|||
}
|
||||
}
|
||||
|
||||
if (gain_line) {
|
||||
gain_line->reset ();
|
||||
if (_fx_line) {
|
||||
_fx_line->reset ();
|
||||
}
|
||||
|
||||
reset_fade_shapes ();
|
||||
|
@ -1101,8 +1105,8 @@ AudioRegionView::set_colors ()
|
|||
{
|
||||
RegionView::set_colors();
|
||||
|
||||
if (gain_line) {
|
||||
gain_line->set_line_color (audio_region()->envelope_active() ?
|
||||
if (_fx_line) {
|
||||
_fx_line->set_line_color (audio_region()->envelope_active() ?
|
||||
UIConfiguration::instance().color ("gain line") :
|
||||
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
|
||||
}
|
||||
|
@ -1148,8 +1152,8 @@ AudioRegionView::setup_waveform_visibility ()
|
|||
void
|
||||
AudioRegionView::temporarily_hide_envelope ()
|
||||
{
|
||||
if (gain_line) {
|
||||
gain_line->hide ();
|
||||
if (_fx_line) {
|
||||
_fx_line->hide ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1160,20 +1164,81 @@ AudioRegionView::unhide_envelope ()
|
|||
}
|
||||
|
||||
void
|
||||
AudioRegionView::update_envelope_visibility ()
|
||||
AudioRegionView::set_region_gain_line ()
|
||||
{
|
||||
if (!gain_line) {
|
||||
if (_ignore_line_change) {
|
||||
return;
|
||||
}
|
||||
const string line_name = _region->name() + ":gain";
|
||||
_fx_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
|
||||
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
|
||||
envelope_active_changed ();
|
||||
update_envelope_visibility ();
|
||||
_fx_line->reset ();
|
||||
_region_fx_connection.disconnect ();
|
||||
bool changed = _rfx_id != PBD::ID (0) || _rdx_param != UINT32_MAX;
|
||||
_rfx_id = PBD::ID (0);
|
||||
_rdx_param = UINT32_MAX;
|
||||
|
||||
if (changed) {
|
||||
region_line_changed (); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionView::set_region_fx_line (uint32_t plugin_id, uint32_t param_id)
|
||||
{
|
||||
if (_ignore_line_change) {
|
||||
return false;
|
||||
}
|
||||
std::shared_ptr<RegionFxPlugin> rfx = _region->nth_plugin (plugin_id);
|
||||
if (rfx) {
|
||||
std::shared_ptr<Evoral::Control> c = rfx->control (Evoral::Parameter (PluginAutomation, 0, param_id));
|
||||
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (c);
|
||||
if (ac) {
|
||||
ac->set_automation_state (Play);
|
||||
const string line_name = _region->name () + ":" + rfx->describe_parameter (Evoral::Parameter (PluginAutomation, 0, param_id));
|
||||
_fx_line.reset (new RegionFxLine (line_name, *this, *group, ac->alist (), ac->desc ()));
|
||||
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
|
||||
envelope_active_changed ();
|
||||
update_envelope_visibility ();
|
||||
_fx_line->reset ();
|
||||
|
||||
rfx->DropReferences.connect (_region_fx_connection, invalidator (*this), boost::bind (&AudioRegionView::set_region_gain_line, this), gui_context ());
|
||||
|
||||
bool changed = _rfx_id != rfx->id () || _rdx_param != param_id;
|
||||
_rfx_id = rfx->id ();
|
||||
_rdx_param = param_id;
|
||||
if (changed) {
|
||||
region_line_changed (); /* EMIT SIGNAL */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionView::get_region_fx_line (PBD::ID& id, uint32_t& param_id)
|
||||
{
|
||||
id = _rfx_id;
|
||||
param_id = _rdx_param;
|
||||
return _rdx_param != UINT32_MAX && _rfx_id != 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionView::update_envelope_visibility ()
|
||||
{
|
||||
assert (_fx_line);
|
||||
|
||||
if (trackview.editor().current_mouse_mode() == Editing::MouseDraw || trackview.editor().current_mouse_mode() == Editing::MouseContent ) {
|
||||
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
|
||||
gain_line->canvas_group().raise_to_top ();
|
||||
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
|
||||
_fx_line->canvas_group().raise_to_top ();
|
||||
} else if (UIConfiguration::instance().get_show_region_gain() || trackview.editor().current_mouse_mode() == Editing::MouseRange ) {
|
||||
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
|
||||
gain_line->canvas_group().raise_to_top ();
|
||||
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
|
||||
_fx_line->canvas_group().raise_to_top ();
|
||||
} else {
|
||||
gain_line->set_visibility (AutomationLine::VisibleAspects(0));
|
||||
_fx_line->set_visibility (AutomationLine::VisibleAspects(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1374,7 +1439,7 @@ AudioRegionView::peaks_ready_handler (uint32_t which)
|
|||
void
|
||||
AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, bool with_guard_points)
|
||||
{
|
||||
if (!gain_line) {
|
||||
if (!_fx_line) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1386,18 +1451,17 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
|
|||
|
||||
samplecnt_t const sample_within_region = (samplecnt_t) floor (mx * samples_per_pixel);
|
||||
|
||||
if (!gain_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
|
||||
/* no adjacent points */
|
||||
return;
|
||||
double y = my;
|
||||
|
||||
if (_fx_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
|
||||
/* y is in item frame */
|
||||
double const bx = _fx_line->nth (before_p)->get_x();
|
||||
double const ax = _fx_line->nth (after_p)->get_x();
|
||||
double const click_ratio = (ax - mx) / (ax - bx);
|
||||
|
||||
y = ((_fx_line->nth (before_p)->get_y() * click_ratio) + (_fx_line->nth (after_p)->get_y() * (1 - click_ratio)));
|
||||
}
|
||||
|
||||
/* y is in item frame */
|
||||
double const bx = gain_line->nth (before_p)->get_x();
|
||||
double const ax = gain_line->nth (after_p)->get_x();
|
||||
double const click_ratio = (ax - mx) / (ax - bx);
|
||||
|
||||
double y = ((gain_line->nth (before_p)->get_y() * click_ratio) + (gain_line->nth (after_p)->get_y() * (1 - click_ratio)));
|
||||
|
||||
/* don't create points that can't be seen */
|
||||
|
||||
update_envelope_visibility ();
|
||||
|
@ -1412,28 +1476,28 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
|
|||
|
||||
/* compute vertical fractional position */
|
||||
|
||||
y = 1.0 - (y / (gain_line->height()));
|
||||
y = 1.0 - (y / (_fx_line->height()));
|
||||
|
||||
/* map using gain line */
|
||||
|
||||
gain_line->view_to_model_coord_y (y);
|
||||
_fx_line->view_to_model_coord_y (y);
|
||||
|
||||
/* XXX STATEFUL: can't convert to stateful diff until we
|
||||
can represent automation data with it.
|
||||
*/
|
||||
|
||||
XMLNode &before = audio_region()->envelope()->get_state();
|
||||
XMLNode &before = _fx_line->the_list()->get_state();
|
||||
MementoCommand<AudioRegion>* region_memento = 0;
|
||||
|
||||
if (!audio_region()->envelope_active()) {
|
||||
if (!audio_region()->envelope_active() && _fx_line->the_list() == audio_region()->envelope()) {
|
||||
XMLNode ®ion_before = audio_region()->get_state();
|
||||
audio_region()->set_envelope_active(true);
|
||||
XMLNode ®ion_after = audio_region()->get_state();
|
||||
region_memento = new MementoCommand<AudioRegion>(*(audio_region().get()), ®ion_before, ®ion_after);
|
||||
}
|
||||
|
||||
if (audio_region()->envelope()->editor_add (timepos_t (fx), y, with_guard_points)) {
|
||||
XMLNode &after = audio_region()->envelope()->get_state();
|
||||
if (_fx_line->the_list()->editor_add (timepos_t (fx), y, with_guard_points)) {
|
||||
XMLNode &after = _fx_line->the_list()->get_state();
|
||||
std::list<Selectable*> results;
|
||||
|
||||
trackview.editor().begin_reversible_command (_("add gain control point"));
|
||||
|
@ -1442,9 +1506,9 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
|
|||
trackview.session()->add_command (region_memento);
|
||||
}
|
||||
|
||||
trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
|
||||
trackview.session()->add_command (new MementoCommand<AutomationList>(*_fx_line->the_list(), &before, &after));
|
||||
|
||||
gain_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
|
||||
_fx_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
|
||||
trackview.editor ().get_selection ().set (results);
|
||||
|
||||
trackview.editor ().commit_reversible_command ();
|
||||
|
@ -1454,12 +1518,14 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // unused
|
||||
void
|
||||
AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent* /*ev*/)
|
||||
{
|
||||
ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
|
||||
audio_region()->envelope()->erase (cp->model());
|
||||
_fx_line->the_list()->erase (cp->model());
|
||||
}
|
||||
#endif
|
||||
|
||||
GhostRegion*
|
||||
AudioRegionView::add_ghost (TimeAxisView& tv)
|
||||
|
@ -1557,10 +1623,6 @@ AudioRegionView::exited ()
|
|||
trackview.editor().set_current_trimmable (std::shared_ptr<Trimmable>());
|
||||
trackview.editor().set_current_movable (std::shared_ptr<Movable>());
|
||||
|
||||
// if (gain_line) {
|
||||
// gain_line->remove_visibility (AutomationLine::ControlPoints);
|
||||
// }
|
||||
|
||||
if (fade_in_handle) { fade_in_handle->hide(); }
|
||||
if (fade_out_handle) { fade_out_handle->hide(); }
|
||||
if (fade_in_trim_handle) { fade_in_trim_handle->hide(); }
|
||||
|
@ -1572,12 +1634,15 @@ AudioRegionView::exited ()
|
|||
void
|
||||
AudioRegionView::envelope_active_changed ()
|
||||
{
|
||||
if (gain_line) {
|
||||
gain_line->set_line_color (audio_region()->envelope_active() ?
|
||||
UIConfiguration::instance().color ("gain line") :
|
||||
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
|
||||
update_envelope_visibility ();
|
||||
assert (_fx_line);
|
||||
if (_rdx_param != UINT32_MAX && _rfx_id != 0) {
|
||||
_fx_line->set_line_color (UIConfiguration::instance().color ("processor automation line")); // XXX
|
||||
} else {
|
||||
_fx_line->set_line_color (audio_region()->envelope_active()
|
||||
? UIConfiguration::instance().color ("gain line")
|
||||
: UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
|
||||
}
|
||||
update_envelope_visibility ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1696,7 +1761,7 @@ void
|
|||
AudioRegionView::show_region_editor ()
|
||||
{
|
||||
if (editor == 0) {
|
||||
editor = new AudioRegionEditor (trackview.session(), audio_region());
|
||||
editor = new AudioRegionEditor (trackview.session(), this);
|
||||
}
|
||||
|
||||
editor->present ();
|
||||
|
@ -1858,7 +1923,7 @@ AudioRegionView::parameter_changed (string const & p)
|
|||
MergeableLine*
|
||||
AudioRegionView::make_merger ()
|
||||
{
|
||||
return new MergeableLine (gain_line, std::shared_ptr<AutomationControl>(),
|
||||
return new MergeableLine (_fx_line, std::shared_ptr<AutomationControl>(),
|
||||
[this](timepos_t const& t) { return timepos_t (_region->position().distance (t)); },
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ namespace ARDOUR {
|
|||
};
|
||||
|
||||
class AudioTimeAxisView;
|
||||
class AudioRegionGainLine;
|
||||
class GhostRegion;
|
||||
class AutomationTimeAxisView;
|
||||
class RegionFxLine;
|
||||
class RouteTimeAxisView;
|
||||
|
||||
class AudioRegionView : public RegionView, public LineMerger
|
||||
|
@ -91,12 +91,18 @@ public:
|
|||
void temporarily_hide_envelope (); ///< Dangerous!
|
||||
void unhide_envelope (); ///< Dangerous!
|
||||
|
||||
void set_region_gain_line ();
|
||||
void set_ignore_line_change (bool v) { _ignore_line_change = v; };
|
||||
bool set_region_fx_line (uint32_t, uint32_t);
|
||||
bool get_region_fx_line (PBD::ID&, uint32_t&);
|
||||
void update_envelope_visibility ();
|
||||
|
||||
sigc::signal<void> region_line_changed;
|
||||
|
||||
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
|
||||
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
|
||||
|
||||
std::shared_ptr<AudioRegionGainLine> get_gain_line() const { return gain_line; }
|
||||
std::shared_ptr<RegionFxLine> fx_line() const { return _fx_line; }
|
||||
|
||||
void region_changed (const PBD::PropertyChange&);
|
||||
void envelope_active_changed ();
|
||||
|
@ -184,7 +190,7 @@ protected:
|
|||
ArdourCanvas::Rectangle* end_xfade_rect;
|
||||
bool _end_xfade_visible;
|
||||
|
||||
std::shared_ptr<AudioRegionGainLine> gain_line;
|
||||
std::shared_ptr<RegionFxLine> _fx_line;
|
||||
|
||||
double _amplitude_above_axis;
|
||||
|
||||
|
@ -234,6 +240,12 @@ private:
|
|||
|
||||
bool trim_fade_in_drag_active;
|
||||
bool trim_fade_out_drag_active;
|
||||
|
||||
PBD::ID _rfx_id;
|
||||
uint32_t _rdx_param;
|
||||
bool _ignore_line_change;
|
||||
|
||||
PBD::ScopedConnection _region_fx_connection;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_audio_region_view_h__ */
|
||||
|
|
|
@ -470,8 +470,8 @@ AudioStreamView::set_selected_points (PointSelection& points)
|
|||
{
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv && arv->get_gain_line ()) {
|
||||
arv->get_gain_line ()->set_selected_points (points);
|
||||
if (arv && arv->fx_line ()) {
|
||||
arv->fx_line ()->set_selected_points (points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -707,11 +707,11 @@ bool
|
|||
Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
|
||||
{
|
||||
ItemType type;
|
||||
AudioRegionGainLine* gl;
|
||||
if ((gl = dynamic_cast<AudioRegionGainLine*> (al)) != 0) {
|
||||
RegionFxLine* rfl;
|
||||
if ((rfl = dynamic_cast<RegionFxLine*> (al)) != 0) {
|
||||
type = GainLineItem;
|
||||
if (event->type == GDK_BUTTON_PRESS) {
|
||||
clicked_regionview = &gl->region_view ();
|
||||
clicked_regionview = &rfl->region_view ();
|
||||
}
|
||||
} else {
|
||||
type = AutomationLineItem;
|
||||
|
|
|
@ -5039,7 +5039,7 @@ LineDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||
AudioRegionView* arv;
|
||||
|
||||
if ((arv = dynamic_cast<AudioRegionView*> (_editor->clicked_regionview)) != 0) {
|
||||
arv->add_gain_point_event (&arv->get_gain_line ()->grab_item (), event, false);
|
||||
arv->add_gain_point_event (&arv->fx_line ()->grab_item (), event, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6367,7 +6367,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> cons
|
|||
|
||||
for (list<RegionView*>::const_iterator i = v.begin (); i != v.end (); ++i) {
|
||||
if (AudioRegionView* audio_view = dynamic_cast<AudioRegionView*> (*i)) {
|
||||
lines.push_back (audio_view->get_gain_line ());
|
||||
lines.push_back (audio_view->fx_line ());
|
||||
} else if (AutomationRegionView* automation_view = dynamic_cast<AutomationRegionView*> (*i)) {
|
||||
lines.push_back (automation_view->line ());
|
||||
_integral = true;
|
||||
|
@ -6394,8 +6394,8 @@ AutomationRangeDrag::setup (list<std::shared_ptr<AutomationLine>> const& lines)
|
|||
|
||||
/* need a special detection for automation lanes (not region gain line) */
|
||||
// TODO: if we implement automation regions, this check can probably be removed
|
||||
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> ((*i).get ());
|
||||
if (!argl) {
|
||||
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> ((*i).get ());
|
||||
if (!fxl) {
|
||||
/* in automation lanes, the EFFECTIVE range should be considered 0->max_position (even if there is no line) */
|
||||
r.first = Temporal::timepos_t ((*i)->the_list ()->time_domain ());
|
||||
r.second = Temporal::timepos_t::max ((*i)->the_list ()->time_domain ());
|
||||
|
|
|
@ -2340,7 +2340,7 @@ Editor::can_remove_control_point (ArdourCanvas::Item* item)
|
|||
}
|
||||
|
||||
AutomationLine& line = control_point->line ();
|
||||
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
|
||||
if (dynamic_cast<RegionFxLine*> (&line)) {
|
||||
/* we shouldn't remove the first or last gain point in region gain lines */
|
||||
if (line.is_last_point(*control_point) || line.is_first_point(*control_point)) {
|
||||
return false;
|
||||
|
|
|
@ -4833,7 +4833,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
|
|||
|
||||
bool erase = true;
|
||||
|
||||
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
|
||||
if (dynamic_cast<RegionFxLine*> (&line)) {
|
||||
/* removing of first and last gain point in region gain lines is prohibited*/
|
||||
if (line.is_last_point (*(*sel_point)) || line.is_first_point (*(*sel_point))) {
|
||||
erase = false;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "ardour_http.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "public_editor.h"
|
||||
#include "region_selection.h"
|
||||
#include "luadialog.h"
|
||||
|
@ -826,10 +827,16 @@ LuaInstance::register_classes (lua_State* L, bool sandbox)
|
|||
.endClass ()
|
||||
|
||||
.deriveClass <RegionView, TimeAxisViewItem> ("RegionView")
|
||||
.addCast<AudioRegionView> ("to_audioregionview")
|
||||
.addFunction ("show_region_editor", &RegionView::show_region_editor)
|
||||
.addFunction ("hide_region_editor", &RegionView::hide_region_editor)
|
||||
.endClass ()
|
||||
|
||||
.deriveClass <AudioRegionView, RegionView> ("RegionView")
|
||||
.addFunction ("set_region_gain_line", &AudioRegionView::set_region_gain_line)
|
||||
.addFunction ("set_region_fx_line", &AudioRegionView::set_region_fx_line)
|
||||
.endClass ()
|
||||
|
||||
.deriveClass <RouteUI, Selectable> ("RouteUI")
|
||||
.endClass ()
|
||||
|
||||
|
|
|
@ -62,11 +62,11 @@ using namespace PBD;
|
|||
using namespace std;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
|
||||
RegionEditor::RegionEditor (Session* s, RegionView* rv)
|
||||
: ArdourDialog (_("Region"))
|
||||
, _table (9, 3)
|
||||
, _table_row (0)
|
||||
, _region (r)
|
||||
, _region (rv->region ())
|
||||
, name_label (_("Name:"))
|
||||
, audition_button (_("Audition"))
|
||||
, _clock_group (new ClockGroup)
|
||||
|
@ -77,12 +77,12 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
|
|||
, sync_offset_absolute_clock (X_("regionsyncoffsetabsolute"), true, "", true, false)
|
||||
/* XXX cannot file start yet */
|
||||
, start_clock (X_("regionstart"), true, "", false, false)
|
||||
, _region_fx_box (r)
|
||||
, _region_fx_box (_region)
|
||||
, _sources (1)
|
||||
{
|
||||
set_session (s);
|
||||
|
||||
switch (r->time_domain()) {
|
||||
switch (_region->time_domain()) {
|
||||
case Temporal::AudioTime:
|
||||
/* XXX check length of region and choose samples or minsec */
|
||||
_clock_group->set_clock_mode (AudioClock::MinSec);
|
||||
|
@ -548,7 +548,7 @@ RegionEditor::RegionFxBox::RegionFxBox (std::shared_ptr<ARDOUR::Region> r)
|
|||
_scroller.show ();
|
||||
_display.show ();
|
||||
|
||||
_region->RegionFxChanged.connect (_region_connection, invalidator (*this), boost::bind (&RegionFxBox::redisplay_plugins, this), gui_context ());
|
||||
_region->RegionFxChanged.connect (_region_connection, invalidator (*this), boost::bind (&RegionFxBox::redisplay_plugins, this), gui_context ()); // -> top
|
||||
|
||||
redisplay_plugins ();
|
||||
}
|
||||
|
|
|
@ -55,12 +55,13 @@ namespace ARDOUR {
|
|||
class RegionFxPlugin;
|
||||
}
|
||||
|
||||
class RegionView;
|
||||
class ClockGroup;
|
||||
|
||||
class RegionEditor : public ArdourDialog
|
||||
{
|
||||
public:
|
||||
RegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::Region>);
|
||||
RegionEditor (ARDOUR::Session*, RegionView*);
|
||||
virtual ~RegionEditor ();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "audio_region_view.h"
|
||||
#include "region_fx_line.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
RegionFxLine::RegionFxLine (std::string const& name, RegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationList> l, ARDOUR::ParameterDescriptor const& d)
|
||||
: AutomationLine (name, r.get_time_axis_view(), parent, l, d)
|
||||
, rv (r)
|
||||
{
|
||||
group->raise_to_top ();
|
||||
group->set_y_position (2);
|
||||
}
|
||||
|
||||
Temporal::timepos_t
|
||||
RegionFxLine::get_origin() const
|
||||
{
|
||||
return rv.region()->position();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_gtk_region_fx_line_h__
|
||||
#define __ardour_gtk_region_fx_line_h__
|
||||
|
||||
#include "automation_line.h"
|
||||
|
||||
class RegionView;
|
||||
|
||||
class RegionFxLine : public AutomationLine
|
||||
{
|
||||
public:
|
||||
RegionFxLine (std::string const&, RegionView&, ArdourCanvas::Container&, std::shared_ptr<ARDOUR::AutomationList>, ARDOUR::ParameterDescriptor const&);
|
||||
|
||||
Temporal::timepos_t get_origin() const;
|
||||
|
||||
RegionView& region_view () { return rv; }
|
||||
|
||||
protected:
|
||||
RegionView& rv;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -44,26 +44,14 @@ using namespace ARDOUR;
|
|||
using namespace PBD;
|
||||
|
||||
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<AutomationList> l)
|
||||
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter())
|
||||
, rv (r)
|
||||
: RegionFxLine (name, r, parent, l, l->parameter ())
|
||||
, arv (r)
|
||||
{
|
||||
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
|
||||
assert(l->parameter().type() == EnvelopeAutomation);
|
||||
|
||||
r.region()->PropertyChanged.connect (_region_changed_connection, invalidator (*this), boost::bind (&AudioRegionGainLine::region_changed, this, _1), gui_context());
|
||||
|
||||
group->raise_to_top ();
|
||||
group->set_y_position (2);
|
||||
terminal_points_can_slide = false;
|
||||
}
|
||||
|
||||
timepos_t
|
||||
AudioRegionGainLine::get_origin() const
|
||||
{
|
||||
return rv.region()->position();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
|
||||
{
|
||||
|
@ -71,9 +59,9 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
|
|||
|
||||
// XXX Stateful need to capture automation curve data
|
||||
|
||||
if (!rv.audio_region()->envelope_active()) {
|
||||
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
|
||||
rv.audio_region()->set_envelope_active(false);
|
||||
if (!arv.audio_region()->envelope_active()) {
|
||||
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
|
||||
arv.audio_region()->set_envelope_active(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,10 +72,10 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
|||
trackview.editor().begin_reversible_command (_("remove control point"));
|
||||
XMLNode &before = alist->get_state();
|
||||
|
||||
if (!rv.audio_region()->envelope_active()) {
|
||||
rv.audio_region()->clear_changes ();
|
||||
rv.audio_region()->set_envelope_active(true);
|
||||
trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
|
||||
if (!arv.audio_region()->envelope_active()) {
|
||||
arv.audio_region()->clear_changes ();
|
||||
arv.audio_region()->set_envelope_active(true);
|
||||
trackview.session()->add_command(new StatefulDiffCommand (arv.audio_region()));
|
||||
}
|
||||
|
||||
trackview.editor ().get_selection ().clear_points ();
|
||||
|
@ -101,9 +89,9 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
|||
void
|
||||
AudioRegionGainLine::end_drag (bool with_push, uint32_t final_index)
|
||||
{
|
||||
if (!rv.audio_region()->envelope_active()) {
|
||||
rv.audio_region()->set_envelope_active(true);
|
||||
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), 0, &rv.audio_region()->get_state()));
|
||||
if (!arv.audio_region()->envelope_active()) {
|
||||
arv.audio_region()->set_envelope_active(true);
|
||||
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), 0, &arv.audio_region()->get_state()));
|
||||
}
|
||||
|
||||
AutomationLine::end_drag (with_push, final_index);
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
|
||||
#include "ardour/ardour.h"
|
||||
|
||||
|
||||
#include "automation_line.h"
|
||||
#include "region_fx_line.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
|
@ -37,23 +36,21 @@ namespace ARDOUR {
|
|||
class TimeAxisView;
|
||||
class AudioRegionView;
|
||||
|
||||
class AudioRegionGainLine : public AutomationLine
|
||||
class AudioRegionGainLine : public RegionFxLine
|
||||
{
|
||||
public:
|
||||
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationList>);
|
||||
|
||||
Temporal::timepos_t get_origin() const;
|
||||
|
||||
void start_drag_single (ControlPoint*, double, float);
|
||||
void end_drag (bool with_push, uint32_t final_index);
|
||||
|
||||
void remove_point (ControlPoint&);
|
||||
AudioRegionView& region_view () { return rv; }
|
||||
|
||||
private:
|
||||
PBD::ScopedConnection _region_changed_connection;
|
||||
void region_changed (const PBD::PropertyChange& what_changed);
|
||||
AudioRegionView& rv;
|
||||
|
||||
AudioRegionView& arv;
|
||||
PBD::ScopedConnection _region_changed_connection;
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_region_gain_line_h__ */
|
||||
|
|
|
@ -750,7 +750,7 @@ void
|
|||
RegionView::show_region_editor ()
|
||||
{
|
||||
if (!editor) {
|
||||
editor = new RegionEditor (trackview.session(), region());
|
||||
editor = new RegionEditor (trackview.session(), this);
|
||||
}
|
||||
|
||||
editor->present ();
|
||||
|
|
|
@ -1176,11 +1176,11 @@ Selection::get_state () const
|
|||
continue;
|
||||
}
|
||||
|
||||
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> (&(*i)->line());
|
||||
if (argl) {
|
||||
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> (&(*i)->line());
|
||||
if (fxl) {
|
||||
XMLNode* r = node->add_child (X_("ControlPoint"));
|
||||
r->set_property (X_("type"), "region");
|
||||
r->set_property (X_("region-id"), argl->region_view ().region ()->id ());
|
||||
r->set_property (X_("region-id"), fxl->region_view ().region ()->id ());
|
||||
r->set_property (X_("view-index"), (*i)->view_index());
|
||||
}
|
||||
|
||||
|
@ -1324,35 +1324,6 @@ Selection::set_state (XMLNode const & node, int)
|
|||
if (!cps.empty()) {
|
||||
add (cps);
|
||||
}
|
||||
} else if (prop_type->value () == "region") {
|
||||
|
||||
PBD::ID region_id;
|
||||
uint32_t view_index;
|
||||
if (!(*i)->get_property (X_("region-id"), region_id) ||
|
||||
!(*i)->get_property (X_("view-index"), view_index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RegionSelection rs;
|
||||
editor->get_regionviews_by_id (region_id, rs);
|
||||
|
||||
if (!rs.empty ()) {
|
||||
vector <ControlPoint *> cps;
|
||||
for (RegionSelection::iterator rsi = rs.begin(); rsi != rs.end(); ++rsi) {
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*rsi);
|
||||
if (arv) {
|
||||
std::shared_ptr<AudioRegionGainLine> gl = arv->get_gain_line ();
|
||||
ControlPoint* cp = gl->nth(view_index);
|
||||
if (cp) {
|
||||
cps.push_back (cp);
|
||||
cp->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cps.empty()) {
|
||||
add (cps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((*i)->name() == X_("TimelineRange")) {
|
||||
|
|
|
@ -622,7 +622,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
|
|||
|| (!within && (*i)->region()->coverage (start, end) != Temporal::OverlapNone)) {
|
||||
if (_trackview.editor().internal_editing()) {
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
|
||||
if (arv && arv->get_gain_line ()) {
|
||||
if (arv && arv->fx_line ()) {
|
||||
/* Note: AutomationLine::get_selectables() uses trackview.current_height (),
|
||||
* disregarding Stacked layer display height
|
||||
*/
|
||||
|
@ -630,7 +630,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
|
|||
double const y = (*i)->get_canvas_group ()->position().y;
|
||||
double t = 1.0 - std::min (1.0, std::max (0., (top - _trackview.y_position () - y) / c));
|
||||
double b = 1.0 - std::min (1.0, std::max (0., (bottom - _trackview.y_position () - y) / c));
|
||||
arv->get_gain_line()->get_selectables (start, end, b, t, results);
|
||||
arv->fx_line()->get_selectables (start, end, b, t, results);
|
||||
}
|
||||
} else {
|
||||
results.push_back (*i);
|
||||
|
|
|
@ -241,6 +241,7 @@ gtk2_ardour_sources = [
|
|||
'recorder_group_tabs.cc',
|
||||
'recorder_ui.cc',
|
||||
'region_editor.cc',
|
||||
'region_fx_line.cc',
|
||||
'region_gain_line.cc',
|
||||
'region_layering_order_editor.cc',
|
||||
'region_list_base.cc',
|
||||
|
|
|
@ -321,7 +321,7 @@ RegionFxPlugin::create_parameters ()
|
|||
Evoral::Parameter param (PluginAutomation, 0, i);
|
||||
const bool automatable = a.find(param) != a.end();
|
||||
|
||||
std::shared_ptr<AutomationList> list(new AutomationList(param, desc, _session));
|
||||
std::shared_ptr<AutomationList> list (new AutomationList (param, desc, _session));
|
||||
std::shared_ptr<AutomationControl> c (new PluginControl (_session, this, param, desc, list));
|
||||
if (!automatable) {
|
||||
c->set_flag (Controllable::NotAutomatable);
|
||||
|
|
Loading…
Reference in New Issue