mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
Fix parameter range stuff and automation time axis height (somewhat...).
Create a new AutomationLine when an AutomationRegionView without a line is clicked. git-svn-id: svn://localhost/ardour2/branches/3.0@3757 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
2539b8fc18
commit
60f588f21d
26 changed files with 199 additions and 89 deletions
|
|
@ -115,7 +115,7 @@ ARDOUR_UI::display_message (const char *prefix, gint prefix_len, RefPtr<TextBuff
|
||||||
} else if (strcmp (prefix, _("[INFO]: ")) == 0) {
|
} else if (strcmp (prefix, _("[INFO]: ")) == 0) {
|
||||||
text = "<span color=\"green\" weight=\"bold\">";
|
text = "<span color=\"green\" weight=\"bold\">";
|
||||||
} else {
|
} else {
|
||||||
text = "<span color=\"blue\" weight=\"bold\">???";
|
text = "<span color=\"white\" weight=\"bold\">???";
|
||||||
}
|
}
|
||||||
|
|
||||||
text += prefix;
|
text += prefix;
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
|
||||||
|
|
||||||
ArdourCanvas::Group& _parent_group;
|
ArdourCanvas::Group& _parent_group;
|
||||||
ArdourCanvas::Group* group;
|
ArdourCanvas::Group* group;
|
||||||
ArdourCanvas::Line* line; /* line */
|
ArdourCanvas::Line* line; /* line */
|
||||||
ArdourCanvas::Points line_points; /* coordinates for canvas line */
|
ArdourCanvas::Points line_points; /* coordinates for canvas line */
|
||||||
vector<ControlPoint*> control_points; /* visible control points */
|
vector<ControlPoint*> control_points; /* visible control points */
|
||||||
|
|
||||||
struct ALPoint {
|
struct ALPoint {
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,16 @@
|
||||||
AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* parent,
|
AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* parent,
|
||||||
AutomationTimeAxisView& time_axis,
|
AutomationTimeAxisView& time_axis,
|
||||||
boost::shared_ptr<ARDOUR::Region> region,
|
boost::shared_ptr<ARDOUR::Region> region,
|
||||||
|
const ARDOUR::Parameter& param,
|
||||||
boost::shared_ptr<ARDOUR::AutomationList> list,
|
boost::shared_ptr<ARDOUR::AutomationList> list,
|
||||||
double spu,
|
double spu,
|
||||||
Gdk::Color& basic_color)
|
Gdk::Color& basic_color)
|
||||||
: RegionView(parent, time_axis, region, spu, basic_color)
|
: RegionView(parent, time_axis, region, spu, basic_color)
|
||||||
|
, _parameter(param)
|
||||||
{
|
{
|
||||||
if (list) {
|
if (list) {
|
||||||
_line = boost::shared_ptr<AutomationLine>(new AutomationLine(
|
assert(list->parameter() == param);
|
||||||
list->parameter().symbol(), time_axis, *group, list));
|
create_line(list);
|
||||||
_line->set_colors();
|
|
||||||
_line->show();
|
|
||||||
_line->show_all_control_points();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
group->signal_event().connect (mem_fun (this, &AutomationRegionView::canvas_event), false);
|
group->signal_event().connect (mem_fun (this, &AutomationRegionView::canvas_event), false);
|
||||||
|
|
@ -62,6 +61,18 @@ AutomationRegionView::init (Gdk::Color& basic_color, bool wfd)
|
||||||
_enable_display = true;
|
_enable_display = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationRegionView::create_line (boost::shared_ptr<ARDOUR::AutomationList> list)
|
||||||
|
{
|
||||||
|
_line = boost::shared_ptr<AutomationLine>(new AutomationLine(
|
||||||
|
list->parameter().symbol(), trackview, *get_canvas_group(), list));
|
||||||
|
_line->set_colors();
|
||||||
|
_line->show();
|
||||||
|
_line->show_all_control_points();
|
||||||
|
_line->set_y_position_and_height (trackview.y_position,
|
||||||
|
(uint32_t)rint(trackview.current_height() - NAME_HIGHLIGHT_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AutomationRegionView::canvas_event(GdkEvent* ev)
|
AutomationRegionView::canvas_event(GdkEvent* ev)
|
||||||
{
|
{
|
||||||
|
|
@ -79,9 +90,13 @@ void
|
||||||
AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, double y)
|
AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, double y)
|
||||||
{
|
{
|
||||||
if (!_line) {
|
if (!_line) {
|
||||||
cerr << "ERROR: AutomationRegionView::add_automation_event called without line" << endl;
|
boost::shared_ptr<Evoral::Control> c = _region->control(_parameter, true);
|
||||||
return;
|
boost::shared_ptr<ARDOUR::AutomationControl> ac
|
||||||
|
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(c);
|
||||||
|
assert(ac);
|
||||||
|
create_line(ac->alist());
|
||||||
}
|
}
|
||||||
|
assert(_line);
|
||||||
|
|
||||||
double x = 0;
|
double x = 0;
|
||||||
AutomationTimeAxisView* const view = automation_view();
|
AutomationTimeAxisView* const view = automation_view();
|
||||||
|
|
@ -109,14 +124,24 @@ AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, dou
|
||||||
view->session().set_dirty ();
|
view->session().set_dirty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationRegionView::set_y_position_and_height (double y, double h)
|
AutomationRegionView::set_y_position_and_height (double y, double h)
|
||||||
{
|
{
|
||||||
|
cout << "ARV SET Y POSITION AND HEIGHT: " << y << ", " << h << endl;
|
||||||
RegionView::set_y_position_and_height(y, h - 1);
|
RegionView::set_y_position_and_height(y, h - 1);
|
||||||
|
|
||||||
if (_line)
|
if (_line)
|
||||||
_line->set_y_position_and_height ((uint32_t)y, (uint32_t) rint (h - NAME_HIGHLIGHT_SIZE));
|
_line->set_y_position_and_height (y, h - NAME_HIGHLIGHT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationRegionView::set_height (double h)
|
||||||
|
{
|
||||||
|
cout << "ARV SET HEIGHT: " << h << endl;
|
||||||
|
RegionView::set_height(h);
|
||||||
|
if (_line)
|
||||||
|
_line->set_y_position_and_height (trackview.y_position - h,
|
||||||
|
(uint32_t)rint(h - NAME_HIGHLIGHT_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class AutomationList;
|
class AutomationList;
|
||||||
|
class Parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimeAxisView;
|
class TimeAxisView;
|
||||||
|
|
@ -41,6 +42,7 @@ public:
|
||||||
AutomationRegionView(ArdourCanvas::Group*,
|
AutomationRegionView(ArdourCanvas::Group*,
|
||||||
AutomationTimeAxisView&,
|
AutomationTimeAxisView&,
|
||||||
boost::shared_ptr<ARDOUR::Region>,
|
boost::shared_ptr<ARDOUR::Region>,
|
||||||
|
const ARDOUR::Parameter& parameter,
|
||||||
boost::shared_ptr<ARDOUR::AutomationList>,
|
boost::shared_ptr<ARDOUR::AutomationList>,
|
||||||
double initial_samples_per_unit,
|
double initial_samples_per_unit,
|
||||||
Gdk::Color& basic_color);
|
Gdk::Color& basic_color);
|
||||||
|
|
@ -57,9 +59,11 @@ public:
|
||||||
// We are a ghost. Meta ghosts? Crazy talk.
|
// We are a ghost. Meta ghosts? Crazy talk.
|
||||||
virtual GhostRegion* add_ghost(TimeAxisView&) { return NULL; }
|
virtual GhostRegion* add_ghost(TimeAxisView&) { return NULL; }
|
||||||
|
|
||||||
|
void set_height (double);
|
||||||
void reset_width_dependent_items(double pixel_width);
|
void reset_width_dependent_items(double pixel_width);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void create_line(boost::shared_ptr<ARDOUR::AutomationList> list);
|
||||||
bool set_position(nframes_t pos, void* src, double* ignored);
|
bool set_position(nframes_t pos, void* src, double* ignored);
|
||||||
void set_y_position_and_height(double y, double h);
|
void set_y_position_and_height(double y, double h);
|
||||||
void region_resized(ARDOUR::Change what_changed);
|
void region_resized(ARDOUR::Change what_changed);
|
||||||
|
|
@ -69,6 +73,7 @@ protected:
|
||||||
void exited();
|
void exited();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ARDOUR::Parameter _parameter;
|
||||||
boost::shared_ptr<AutomationLine> _line;
|
boost::shared_ptr<AutomationLine> _line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,10 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region
|
||||||
region->control(_controller->controllable()->parameter()));
|
region->control(_controller->controllable()->parameter()));
|
||||||
|
|
||||||
boost::shared_ptr<AutomationList> list;
|
boost::shared_ptr<AutomationList> list;
|
||||||
if (control)
|
if (control) {
|
||||||
list = boost::dynamic_pointer_cast<AutomationList>(control->list());
|
list = boost::dynamic_pointer_cast<AutomationList>(control->list());
|
||||||
|
assert(!control->list() || list);
|
||||||
|
}
|
||||||
|
|
||||||
AutomationRegionView *region_view;
|
AutomationRegionView *region_view;
|
||||||
std::list<RegionView *>::iterator i;
|
std::list<RegionView *>::iterator i;
|
||||||
|
|
@ -107,7 +109,8 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
region_view = new AutomationRegionView (canvas_group, _automation_view, region, list,
|
region_view = new AutomationRegionView (canvas_group, _automation_view, region,
|
||||||
|
_controller->controllable()->parameter(), list,
|
||||||
_samples_per_unit, region_color);
|
_samples_per_unit, region_color);
|
||||||
|
|
||||||
region_view->init (region_color, false);
|
region_view->init (region_color, false);
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ CrossfadeEditor::Presets* CrossfadeEditor::fade_out_presets = 0;
|
||||||
|
|
||||||
CrossfadeEditor::Half::Half ()
|
CrossfadeEditor::Half::Half ()
|
||||||
: line (0),
|
: line (0),
|
||||||
normative_curve (Parameter(GainAutomation, 0.0, 1.0, 1.0)), // FIXME: GainAutomation?
|
//normative_curve (Parameter(GainAutomation, 0.0, 1.0, 1.0)), // FIXME: GainAutomation?
|
||||||
|
normative_curve (Parameter(GainAutomation)),
|
||||||
gain_curve (Parameter(GainAutomation))
|
gain_curve (Parameter(GainAutomation))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ curvetest (string filename)
|
||||||
{
|
{
|
||||||
ifstream in (filename.c_str());
|
ifstream in (filename.c_str());
|
||||||
stringstream line;
|
stringstream line;
|
||||||
Parameter param(GainAutomation, -1.0, +1.0, 0.0);
|
//Parameter param(GainAutomation, -1.0, +1.0, 0.0);
|
||||||
|
Parameter param(GainAutomation);
|
||||||
AutomationList al (param);
|
AutomationList al (param);
|
||||||
double minx = DBL_MAX;
|
double minx = DBL_MAX;
|
||||||
double maxx = DBL_MIN;
|
double maxx = DBL_MIN;
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ Editor::hide_all_tracks (bool with_select)
|
||||||
void
|
void
|
||||||
Editor::build_route_list_menu ()
|
Editor::build_route_list_menu ()
|
||||||
{
|
{
|
||||||
using namespace Menu_Helpers;
|
using namespace Menu_Helpers;
|
||||||
using namespace Gtk;
|
using namespace Gtk;
|
||||||
|
|
||||||
route_list_menu = new Menu;
|
route_list_menu = new Menu;
|
||||||
|
|
@ -434,7 +434,7 @@ Editor::build_route_list_menu ()
|
||||||
void
|
void
|
||||||
Editor::set_all_tracks_visibility (bool yn)
|
Editor::set_all_tracks_visibility (bool yn)
|
||||||
{
|
{
|
||||||
TreeModel::Children rows = route_display_model->children();
|
TreeModel::Children rows = route_display_model->children();
|
||||||
TreeModel::Children::iterator i;
|
TreeModel::Children::iterator i;
|
||||||
|
|
||||||
no_route_list_redisplay = true;
|
no_route_list_redisplay = true;
|
||||||
|
|
@ -458,7 +458,7 @@ Editor::set_all_tracks_visibility (bool yn)
|
||||||
void
|
void
|
||||||
Editor::set_all_audio_visibility (int tracks, bool yn)
|
Editor::set_all_audio_visibility (int tracks, bool yn)
|
||||||
{
|
{
|
||||||
TreeModel::Children rows = route_display_model->children();
|
TreeModel::Children rows = route_display_model->children();
|
||||||
TreeModel::Children::iterator i;
|
TreeModel::Children::iterator i;
|
||||||
|
|
||||||
no_route_list_redisplay = true;
|
no_route_list_redisplay = true;
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ class RegionView : public TimeAxisViewItem
|
||||||
|
|
||||||
bool is_valid() const { return valid; }
|
bool is_valid() const { return valid; }
|
||||||
|
|
||||||
|
|
||||||
void set_valid (bool yn) { valid = yn; }
|
void set_valid (bool yn) { valid = yn; }
|
||||||
|
|
||||||
virtual void set_height (double);
|
virtual void set_height (double);
|
||||||
|
|
|
||||||
|
|
@ -80,10 +80,10 @@ class MidiRegion : public Region
|
||||||
Controls& controls() { return midi_source()->model()->controls(); }
|
Controls& controls() { return midi_source()->model()->controls(); }
|
||||||
const Controls& controls() const { return midi_source()->model()->controls(); }
|
const Controls& controls() const { return midi_source()->model()->controls(); }
|
||||||
|
|
||||||
boost::shared_ptr<Evoral::Control> control(Evoral::Parameter id, bool create_if_missing=false)
|
boost::shared_ptr<Evoral::Control> control(const Evoral::Parameter& id, bool create=false)
|
||||||
{ return midi_source()->model()->control(id, create_if_missing); }
|
{ return midi_source()->model()->control(id, create); }
|
||||||
|
|
||||||
boost::shared_ptr<const Evoral::Control> control(Evoral::Parameter id) const
|
boost::shared_ptr<const Evoral::Control> control(const Evoral::Parameter& id) const
|
||||||
{ return midi_source()->model()->control(id); }
|
{ return midi_source()->model()->control(id); }
|
||||||
|
|
||||||
int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&);
|
int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&);
|
||||||
|
|
|
||||||
|
|
@ -47,50 +47,58 @@ public:
|
||||||
Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0)
|
Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0)
|
||||||
: Evoral::Parameter((uint32_t)type, id, channel)
|
: Evoral::Parameter((uint32_t)type, id, channel)
|
||||||
{
|
{
|
||||||
init(type);
|
init_metadata(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Parameter(AutomationType type, double min, double max, double normal)
|
Parameter(AutomationType type, double min, double max, double normal)
|
||||||
: Evoral::Parameter((uint32_t)type, 0, 0, min, max, normal)
|
: Evoral::Parameter((uint32_t)type, 0, 0, min, max, normal)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
Parameter(const Parameter& copy)
|
||||||
|
: Evoral::Parameter(copy)
|
||||||
|
{
|
||||||
|
_min = copy._min;
|
||||||
|
_max = copy._max;
|
||||||
|
_normal = copy._max;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Parameter(const Evoral::Parameter& copy)
|
Parameter(const Evoral::Parameter& copy)
|
||||||
: Evoral::Parameter(copy)
|
: Evoral::Parameter(copy)
|
||||||
{
|
{
|
||||||
init((AutomationType)_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(AutomationType type) {
|
static void init_metadata(AutomationType type) {
|
||||||
_normal = 0.0f;
|
double min = 0.0f;
|
||||||
|
double max = 1.0f;
|
||||||
|
double normal = 0.0f;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case NullAutomation:
|
case NullAutomation:
|
||||||
case GainAutomation:
|
case GainAutomation:
|
||||||
_min = 0.0f;
|
max = 2.0f;
|
||||||
_max = 2.0f;
|
normal = 1.0f;
|
||||||
_normal = 1.0f;
|
|
||||||
break;
|
break;
|
||||||
case PanAutomation:
|
case PanAutomation:
|
||||||
_min = 0.0f;
|
normal = 0.5f;
|
||||||
_max = 1.0f;
|
break;
|
||||||
_normal = 0.5f;
|
|
||||||
case PluginAutomation:
|
case PluginAutomation:
|
||||||
case SoloAutomation:
|
case SoloAutomation:
|
||||||
case MuteAutomation:
|
case MuteAutomation:
|
||||||
case FadeInAutomation:
|
case FadeInAutomation:
|
||||||
case FadeOutAutomation:
|
case FadeOutAutomation:
|
||||||
case EnvelopeAutomation:
|
case EnvelopeAutomation:
|
||||||
_min = 0.0f;
|
max = 2.0f;
|
||||||
_max = 2.0f;
|
normal = 1.0f;
|
||||||
_normal = 1.0f;
|
break;
|
||||||
case MidiCCAutomation:
|
case MidiCCAutomation:
|
||||||
Evoral::MIDI::ContinuousController::set_range(*this); break;
|
|
||||||
case MidiPgmChangeAutomation:
|
case MidiPgmChangeAutomation:
|
||||||
Evoral::MIDI::ProgramChange::set_range(*this); break;
|
|
||||||
case MidiPitchBenderAutomation:
|
|
||||||
Evoral::MIDI::PitchBender::set_range(*this); break;
|
|
||||||
case MidiChannelAftertouchAutomation:
|
case MidiChannelAftertouchAutomation:
|
||||||
Evoral::MIDI::ChannelAftertouch::set_range(*this); break;
|
Evoral::MIDI::controller_range(min, max, normal); break;
|
||||||
|
case MidiPitchBenderAutomation:
|
||||||
|
Evoral::MIDI::bender_range(min, max, normal); break;
|
||||||
}
|
}
|
||||||
|
set_range(type, min, max, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter(const std::string& str);
|
Parameter(const std::string& str);
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ class PluginInsert : public Processor
|
||||||
void set_parameter (Parameter param, float val);
|
void set_parameter (Parameter param, float val);
|
||||||
float get_parameter (Parameter param);
|
float get_parameter (Parameter param);
|
||||||
|
|
||||||
float default_parameter_value (Evoral::Parameter param);
|
float default_parameter_value (const Evoral::Parameter& param);
|
||||||
|
|
||||||
struct PluginControl : public AutomationControl
|
struct PluginControl : public AutomationControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,21 @@ AudioEngine::AudioEngine (string client_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
Port::set_engine (this);
|
Port::set_engine (this);
|
||||||
|
|
||||||
|
Parameter::init_metadata(NullAutomation);
|
||||||
|
Parameter::init_metadata(GainAutomation);
|
||||||
|
Parameter::init_metadata(PanAutomation);
|
||||||
|
Parameter::init_metadata(PluginAutomation);
|
||||||
|
Parameter::init_metadata(SoloAutomation);
|
||||||
|
Parameter::init_metadata(MuteAutomation);
|
||||||
|
Parameter::init_metadata(MidiCCAutomation);
|
||||||
|
Parameter::init_metadata(MidiPgmChangeAutomation);
|
||||||
|
Parameter::init_metadata(MidiPitchBenderAutomation);
|
||||||
|
Parameter::init_metadata(MidiChannelAftertouchAutomation);
|
||||||
|
Parameter::init_metadata(FadeInAutomation);
|
||||||
|
Parameter::init_metadata(FadeOutAutomation);
|
||||||
|
Parameter::init_metadata(EnvelopeAutomation);
|
||||||
|
Parameter::init_metadata(MidiCCAutomation);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEngine::~AudioEngine ()
|
AudioEngine::~AudioEngine ()
|
||||||
|
|
|
||||||
|
|
@ -729,7 +729,23 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
|
||||||
void
|
void
|
||||||
MidiTrack::MidiControl::set_value(float val)
|
MidiTrack::MidiControl::set_value(float val)
|
||||||
{
|
{
|
||||||
assert(val >= _list->parameter().min());
|
bool valid = false;
|
||||||
|
if (isinf(val)) {
|
||||||
|
cerr << "MIDIControl value is infinity" << endl;
|
||||||
|
} else if (isnan(val)) {
|
||||||
|
cerr << "MIDIControl value is NaN" << endl;
|
||||||
|
} else if (val < _list->parameter().min()) {
|
||||||
|
cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
|
||||||
|
} else if (val > _list->parameter().max()) {
|
||||||
|
cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
|
||||||
|
} else {
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert(val <= _list->parameter().max());
|
assert(val <= _list->parameter().max());
|
||||||
size_t size = 3;
|
size_t size = 3;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ Parameter::Parameter(const std::string& str)
|
||||||
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
|
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
init((AutomationType)_type); // set min/max/normal
|
init_metadata((AutomationType)_type); // set min/max/normal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ Parameter::symbol() const
|
||||||
} else if (_type == MidiChannelAftertouchAutomation) {
|
} else if (_type == MidiChannelAftertouchAutomation) {
|
||||||
return string_compose("midi-channel-aftertouch-%1", int(_channel));
|
return string_compose("midi-channel-aftertouch-%1", int(_channel));
|
||||||
} else {
|
} else {
|
||||||
PBD::warning << "Uninitialized Parameter to_string() called." << endmsg;
|
PBD::warning << "Uninitialized Parameter symbol() called." << endmsg;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -430,7 +430,7 @@ PluginInsert::automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offs
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
PluginInsert::default_parameter_value (Evoral::Parameter param)
|
PluginInsert::default_parameter_value (const Evoral::Parameter& param)
|
||||||
{
|
{
|
||||||
if (param.type() != PluginAutomation)
|
if (param.type() != PluginAutomation)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public:
|
||||||
boost::shared_ptr<ControlList> list() { return _list; }
|
boost::shared_ptr<ControlList> list() { return _list; }
|
||||||
boost::shared_ptr<const ControlList> list() const { return _list; }
|
boost::shared_ptr<const ControlList> list() const { return _list; }
|
||||||
|
|
||||||
Parameter parameter() const;
|
const Parameter& parameter() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boost::shared_ptr<ControlList> _list;
|
boost::shared_ptr<ControlList> _list;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public:
|
||||||
typedef EventList::reverse_iterator reverse_iterator;
|
typedef EventList::reverse_iterator reverse_iterator;
|
||||||
typedef EventList::const_iterator const_iterator;
|
typedef EventList::const_iterator const_iterator;
|
||||||
|
|
||||||
ControlList (Parameter id);
|
ControlList (const Parameter& id);
|
||||||
//ControlList (const XMLNode&, Parameter id);
|
//ControlList (const XMLNode&, Parameter id);
|
||||||
~ControlList();
|
~ControlList();
|
||||||
|
|
||||||
|
|
@ -97,8 +97,8 @@ public:
|
||||||
void freeze();
|
void freeze();
|
||||||
void thaw ();
|
void thaw ();
|
||||||
|
|
||||||
const Parameter& parameter() const { return _parameter; }
|
const Parameter& parameter() const { return _parameter; }
|
||||||
void set_parameter(Parameter p) { _parameter = p; }
|
void set_parameter(const Parameter& p) { _parameter = p; }
|
||||||
|
|
||||||
EventList::size_type size() const { return _events.size(); }
|
EventList::size_type size() const { return _events.size(); }
|
||||||
bool empty() const { return _events.empty(); }
|
bool empty() const { return _events.empty(); }
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ public:
|
||||||
ControlSet();
|
ControlSet();
|
||||||
virtual ~ControlSet() {}
|
virtual ~ControlSet() {}
|
||||||
|
|
||||||
virtual boost::shared_ptr<Control> control(Evoral::Parameter id, bool create_if_missing=false);
|
virtual boost::shared_ptr<Control> control(const Parameter& id, bool create_if_missing=false);
|
||||||
virtual boost::shared_ptr<const Control> control(Evoral::Parameter id) const;
|
virtual boost::shared_ptr<const Control> control(const Parameter& id) const;
|
||||||
|
|
||||||
virtual boost::shared_ptr<Control> control_factory(boost::shared_ptr<ControlList> list) const;
|
virtual boost::shared_ptr<Control> control_factory(boost::shared_ptr<ControlList> list) const;
|
||||||
virtual boost::shared_ptr<ControlList> control_list_factory(const Parameter& param) const;
|
virtual boost::shared_ptr<ControlList> control_list_factory(const Parameter& param) const;
|
||||||
|
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
|
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
|
||||||
|
|
||||||
virtual float default_parameter_value(Parameter param) { return 1.0f; }
|
virtual float default_parameter_value(const Parameter& param) { return 1.0f; }
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,29 +23,34 @@ namespace Evoral {
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
struct ContinuousController : public Parameter {
|
struct ContinuousController : public Parameter {
|
||||||
ContinuousController(uint32_t cc_type, uint32_t channel, uint32_t controller)
|
ContinuousController(uint32_t cc_type, uint8_t channel, uint32_t controller)
|
||||||
: Parameter(cc_type, controller, channel) { set_range(*this); }
|
: Parameter(cc_type, channel, controller) {}
|
||||||
static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProgramChange : public Parameter {
|
struct ProgramChange : public Parameter {
|
||||||
ProgramChange(uint32_t pc_type, uint32_t channel)
|
ProgramChange(uint32_t pc_type, uint8_t channel) : Parameter(pc_type, 0, channel) {}
|
||||||
: Parameter(pc_type, 0, channel) { set_range(*this); }
|
|
||||||
static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChannelAftertouch : public Parameter {
|
struct ChannelAftertouch : public Parameter {
|
||||||
ChannelAftertouch(uint32_t ca_type, uint32_t channel)
|
ChannelAftertouch(uint32_t ca_type, uint32_t channel) : Parameter(ca_type, 0, channel) {}
|
||||||
: Parameter(ca_type, 0, channel) { set_range(*this); }
|
|
||||||
static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PitchBender : public Parameter {
|
struct PitchBender : public Parameter {
|
||||||
PitchBender(uint32_t pb_type, uint32_t channel)
|
PitchBender(uint32_t pb_type, uint32_t channel) : Parameter(pb_type, 0, channel) {}
|
||||||
: Parameter(pb_type, 0, channel) { set_range(*this); }
|
|
||||||
static void set_range(Parameter& p) { p.set_range(0.0, 16383.0, 8192.0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline static void controller_range(double& min, double& max, double& normal) {
|
||||||
|
min = 0.0;
|
||||||
|
normal = 0.0;
|
||||||
|
max = 127.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void bender_range(double& min, double& max, double& normal) {
|
||||||
|
min = 0.0;
|
||||||
|
normal = 8192.0;
|
||||||
|
max = 16383.0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
} // namespace Evoral
|
} // namespace Evoral
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@
|
||||||
#define EVORAL_PARAMETER_HPP
|
#define EVORAL_PARAMETER_HPP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
|
|
@ -37,19 +40,27 @@ namespace Evoral {
|
||||||
class Parameter
|
class Parameter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Parameter(uint32_t type, uint32_t id, int8_t channel=0,
|
Parameter(uint32_t type, uint8_t channel, uint32_t id=0)
|
||||||
double min=0.0f, double max=0.0f, double def=0.0f)
|
: _type(type), _id(id), _channel(channel)
|
||||||
: _type(type), _id(id), _channel(channel), _min(min), _max(max), _normal(def)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Parameter(const std::string& str);
|
Parameter(const std::string& str) {
|
||||||
|
int channel;
|
||||||
|
if (sscanf(str.c_str(), "%d_c%d_n%d", &_type, &channel, &_id) == 3) {
|
||||||
|
if (channel >= 0 && channel <= 127) {
|
||||||
|
_channel = channel;
|
||||||
|
} else {
|
||||||
|
std::cerr << "WARNING: Channel out of range: " << channel << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << "WARNING: Unable to create parameter from string: " << str << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t type() const { return _type; }
|
inline uint32_t type() const { return _type; }
|
||||||
inline uint32_t id() const { return _id; }
|
inline uint32_t id() const { return _id; }
|
||||||
inline uint8_t channel() const { return _channel; }
|
inline uint8_t channel() const { return _channel; }
|
||||||
|
|
||||||
/**
|
/** Equivalence operator
|
||||||
* Equivalence operator
|
|
||||||
* It is obvious from the definition that this operator
|
* It is obvious from the definition that this operator
|
||||||
* is transitive, as required by stict weak ordering
|
* is transitive, as required by stict weak ordering
|
||||||
* (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
|
* (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
|
||||||
|
|
@ -101,18 +112,37 @@ public:
|
||||||
inline operator bool() const { return (_type != 0); }
|
inline operator bool() const { return (_type != 0); }
|
||||||
|
|
||||||
virtual std::string symbol() const {
|
virtual std::string symbol() const {
|
||||||
return (boost::format("%1%_c%2%_n%3%\n") % _type % _channel % _id).str();
|
return (boost::format("%1%_c%2%_n%3%") % _type % (int)_channel % _id).str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Not used in indentity/comparison */
|
||||||
|
struct Metadata {
|
||||||
|
Metadata(double low=0.0, double high=1.0, double mid=0.0)
|
||||||
|
: min(low), max(high), normal(mid)
|
||||||
|
{}
|
||||||
|
double min;
|
||||||
|
double max;
|
||||||
|
double normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static void set_range(uint32_t type, double min, double max, double normal) {
|
||||||
|
_type_metadata[type] = Metadata(min, max, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_range(double min, double max, double normal) {
|
inline void set_range(double min, double max, double normal) {
|
||||||
_min = min;
|
_metadata = boost::shared_ptr<Metadata>(new Metadata(min, max, normal));
|
||||||
_max = max;
|
|
||||||
_normal = normal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const double min() const { return _min; }
|
inline Metadata& metadata() const {
|
||||||
inline const double max() const { return _max; }
|
if (_metadata)
|
||||||
inline const double normal() const { return _normal; }
|
return *_metadata.get();
|
||||||
|
else
|
||||||
|
return _type_metadata[_type];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const double min() const { return metadata().min; }
|
||||||
|
inline const double max() const { return metadata().max; }
|
||||||
|
inline const double normal() const { return metadata().normal; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Default copy constructor is ok
|
// Default copy constructor is ok
|
||||||
|
|
@ -121,11 +151,11 @@ protected:
|
||||||
uint32_t _type;
|
uint32_t _type;
|
||||||
uint32_t _id;
|
uint32_t _id;
|
||||||
uint8_t _channel;
|
uint8_t _channel;
|
||||||
|
|
||||||
|
boost::shared_ptr<Metadata> _metadata;
|
||||||
|
|
||||||
// Metadata (not used in comparison)
|
typedef std::map<uint32_t, Metadata> TypeMetadata;
|
||||||
double _min;
|
static TypeMetadata _type_metadata;
|
||||||
double _max;
|
|
||||||
double _normal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ private:
|
||||||
|
|
||||||
void append_note_on_unlocked(uint8_t chan, double time, uint8_t note, uint8_t velocity);
|
void append_note_on_unlocked(uint8_t chan, double time, uint8_t note, uint8_t velocity);
|
||||||
void append_note_off_unlocked(uint8_t chan, double time, uint8_t note);
|
void append_note_off_unlocked(uint8_t chan, double time, uint8_t note);
|
||||||
void append_control_unlocked(Parameter param, double time, double value);
|
void append_control_unlocked(const Parameter& param, double time, double value);
|
||||||
|
|
||||||
mutable Glib::RWLock _lock;
|
mutable Glib::RWLock _lock;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
|
Parameter::TypeMetadata Parameter::_type_metadata;
|
||||||
|
|
||||||
Control::Control(boost::shared_ptr<ControlList> list)
|
Control::Control(boost::shared_ptr<ControlList> list)
|
||||||
: _list(list)
|
: _list(list)
|
||||||
, _user_value(list->default_value())
|
, _user_value(list->default_value())
|
||||||
|
|
@ -72,7 +74,7 @@ Control::set_list(boost::shared_ptr<ControlList> list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Parameter
|
const Parameter&
|
||||||
Control::parameter() const
|
Control::parameter() const
|
||||||
{
|
{
|
||||||
return _list->parameter();
|
return _list->parameter();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ inline bool event_time_less_than (ControlEvent* a, ControlEvent* b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ControlList::ControlList (Parameter id)
|
ControlList::ControlList (const Parameter& id)
|
||||||
: _parameter(id)
|
: _parameter(id)
|
||||||
, _interpolation(Linear)
|
, _interpolation(Linear)
|
||||||
, _curve(new Curve(*this))
|
, _curve(new Curve(*this))
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ ControlSet::what_has_data (set<Parameter>& s) const
|
||||||
* for \a parameter does not exist.
|
* for \a parameter does not exist.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Control>
|
boost::shared_ptr<Control>
|
||||||
ControlSet::control (Parameter parameter, bool create_if_missing)
|
ControlSet::control (const Parameter& parameter, bool create_if_missing)
|
||||||
{
|
{
|
||||||
Controls::iterator i = _controls.find(parameter);
|
Controls::iterator i = _controls.find(parameter);
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ ControlSet::control (Parameter parameter, bool create_if_missing)
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<const Control>
|
boost::shared_ptr<const Control>
|
||||||
ControlSet::control (Parameter parameter) const
|
ControlSet::control (const Parameter& parameter) const
|
||||||
{
|
{
|
||||||
Controls::const_iterator i = _controls.find(parameter);
|
Controls::const_iterator i = _controls.find(parameter);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -587,7 +587,7 @@ void Sequence::append_note_off_unlocked(uint8_t chan, double time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::append_control_unlocked(Parameter param, double time, double value)
|
void Sequence::append_control_unlocked(const Parameter& param, double time, double value)
|
||||||
{
|
{
|
||||||
control(param, true)->list()->rt_add(time, value);
|
control(param, true)->list()->rt_add(time, value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue