diff options
26 files changed, 199 insertions, 89 deletions
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 568bfb54ed..e40b7ea30f 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -115,7 +115,7 @@ ARDOUR_UI::display_message (const char *prefix, gint prefix_len, RefPtr<TextBuff } else if (strcmp (prefix, _("[INFO]: ")) == 0) { text = "<span color=\"green\" weight=\"bold\">"; } else { - text = "<span color=\"blue\" weight=\"bold\">???"; + text = "<span color=\"white\" weight=\"bold\">???"; } text += prefix; diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index bc9c75e8f7..5a1b63740b 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -143,8 +143,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin ArdourCanvas::Group& _parent_group; ArdourCanvas::Group* group; - ArdourCanvas::Line* line; /* line */ - ArdourCanvas::Points line_points; /* coordinates for canvas line */ + ArdourCanvas::Line* line; /* line */ + ArdourCanvas::Points line_points; /* coordinates for canvas line */ vector<ControlPoint*> control_points; /* visible control points */ struct ALPoint { diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc index 00cb8be5c4..7b43f2f0af 100644 --- a/gtk2_ardour/automation_region_view.cc +++ b/gtk2_ardour/automation_region_view.cc @@ -26,17 +26,16 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* parent, AutomationTimeAxisView& time_axis, boost::shared_ptr<ARDOUR::Region> region, + const ARDOUR::Parameter& param, boost::shared_ptr<ARDOUR::AutomationList> list, double spu, Gdk::Color& basic_color) : RegionView(parent, time_axis, region, spu, basic_color) + , _parameter(param) { if (list) { - _line = boost::shared_ptr<AutomationLine>(new AutomationLine( - list->parameter().symbol(), time_axis, *group, list)); - _line->set_colors(); - _line->show(); - _line->show_all_control_points(); + assert(list->parameter() == param); + create_line(list); } 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; } +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 AutomationRegionView::canvas_event(GdkEvent* ev) { @@ -79,9 +90,13 @@ void AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, double y) { if (!_line) { - cerr << "ERROR: AutomationRegionView::add_automation_event called without line" << endl; - return; + boost::shared_ptr<Evoral::Control> c = _region->control(_parameter, true); + boost::shared_ptr<ARDOUR::AutomationControl> ac + = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(c); + assert(ac); + create_line(ac->alist()); } + assert(_line); double x = 0; AutomationTimeAxisView* const view = automation_view(); @@ -109,14 +124,24 @@ AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, dou view->session().set_dirty (); } - void 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); 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 diff --git a/gtk2_ardour/automation_region_view.h b/gtk2_ardour/automation_region_view.h index e69845461c..90fa9f3e44 100644 --- a/gtk2_ardour/automation_region_view.h +++ b/gtk2_ardour/automation_region_view.h @@ -31,6 +31,7 @@ namespace ARDOUR { class AutomationList; + class Parameter; }; class TimeAxisView; @@ -41,6 +42,7 @@ public: AutomationRegionView(ArdourCanvas::Group*, AutomationTimeAxisView&, boost::shared_ptr<ARDOUR::Region>, + const ARDOUR::Parameter& parameter, boost::shared_ptr<ARDOUR::AutomationList>, double initial_samples_per_unit, Gdk::Color& basic_color); @@ -57,9 +59,11 @@ public: // We are a ghost. Meta ghosts? Crazy talk. virtual GhostRegion* add_ghost(TimeAxisView&) { return NULL; } + void set_height (double); void reset_width_dependent_items(double pixel_width); protected: + void create_line(boost::shared_ptr<ARDOUR::AutomationList> list); bool set_position(nframes_t pos, void* src, double* ignored); void set_y_position_and_height(double y, double h); void region_resized(ARDOUR::Change what_changed); @@ -69,6 +73,7 @@ protected: void exited(); private: + ARDOUR::Parameter _parameter; boost::shared_ptr<AutomationLine> _line; }; diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index 68da972ba0..206dc3753b 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -88,8 +88,10 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region region->control(_controller->controllable()->parameter())); boost::shared_ptr<AutomationList> list; - if (control) + if (control) { list = boost::dynamic_pointer_cast<AutomationList>(control->list()); + assert(!control->list() || list); + } AutomationRegionView *region_view; 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); region_view->init (region_color, false); diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc index 3e85bd22db..6e4cbb3457 100644 --- a/gtk2_ardour/crossfade_edit.cc +++ b/gtk2_ardour/crossfade_edit.cc @@ -65,7 +65,8 @@ CrossfadeEditor::Presets* CrossfadeEditor::fade_out_presets = 0; CrossfadeEditor::Half::Half () : 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)) { } diff --git a/gtk2_ardour/curvetest.cc b/gtk2_ardour/curvetest.cc index 88c7b8e116..9235fb9ba9 100644 --- a/gtk2_ardour/curvetest.cc +++ b/gtk2_ardour/curvetest.cc @@ -34,7 +34,8 @@ curvetest (string filename) { ifstream in (filename.c_str()); 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); double minx = DBL_MAX; double maxx = DBL_MIN; diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index f2b8456fd9..1dd9a44e80 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -414,7 +414,7 @@ Editor::hide_all_tracks (bool with_select) void Editor::build_route_list_menu () { - using namespace Menu_Helpers; + using namespace Menu_Helpers; using namespace Gtk; route_list_menu = new Menu; @@ -434,7 +434,7 @@ Editor::build_route_list_menu () void 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; no_route_list_redisplay = true; @@ -458,7 +458,7 @@ Editor::set_all_tracks_visibility (bool yn) void 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; no_route_list_redisplay = true; diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 579b6e5594..a001e241f1 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -58,7 +58,6 @@ class RegionView : public TimeAxisViewItem bool is_valid() const { return valid; } - void set_valid (bool yn) { valid = yn; } virtual void set_height (double); diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 66257372a9..e0caddd954 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -80,10 +80,10 @@ class MidiRegion : public Region Controls& controls() { 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) - { return midi_source()->model()->control(id, create_if_missing); } + boost::shared_ptr<Evoral::Control> control(const Evoral::Parameter& id, bool create=false) + { 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); } int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&); diff --git a/libs/ardour/ardour/parameter.h b/libs/ardour/ardour/parameter.h index dbcccd811f..9ffeb98995 100644 --- a/libs/ardour/ardour/parameter.h +++ b/libs/ardour/ardour/parameter.h @@ -47,50 +47,58 @@ public: Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0) : Evoral::Parameter((uint32_t)type, id, channel) { - init(type); + init_metadata(type); } +#if 0 Parameter(AutomationType type, double min, double max, double 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) : Evoral::Parameter(copy) { - init((AutomationType)_type); } - void init(AutomationType type) { - _normal = 0.0f; + static void init_metadata(AutomationType type) { + double min = 0.0f; + double max = 1.0f; + double normal = 0.0f; switch(type) { case NullAutomation: case GainAutomation: - _min = 0.0f; - _max = 2.0f; - _normal = 1.0f; + max = 2.0f; + normal = 1.0f; break; case PanAutomation: - _min = 0.0f; - _max = 1.0f; - _normal = 0.5f; + normal = 0.5f; + break; case PluginAutomation: case SoloAutomation: case MuteAutomation: case FadeInAutomation: case FadeOutAutomation: case EnvelopeAutomation: - _min = 0.0f; - _max = 2.0f; - _normal = 1.0f; + max = 2.0f; + normal = 1.0f; + break; case MidiCCAutomation: - Evoral::MIDI::ContinuousController::set_range(*this); break; case MidiPgmChangeAutomation: - Evoral::MIDI::ProgramChange::set_range(*this); break; - case MidiPitchBenderAutomation: - Evoral::MIDI::PitchBender::set_range(*this); break; 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); diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index f80f26098d..859c707c79 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -77,7 +77,7 @@ class PluginInsert : public Processor void set_parameter (Parameter param, float val); float get_parameter (Parameter param); - float default_parameter_value (Evoral::Parameter param); + float default_parameter_value (const Evoral::Parameter& param); struct PluginControl : public AutomationControl { diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 6a76e98c3c..71481e695f 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -85,6 +85,21 @@ AudioEngine::AudioEngine (string client_name) } 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 () diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index c1203d7ba9..ffe8b20303 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -729,7 +729,23 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf) void 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()); size_t size = 3; diff --git a/libs/ardour/parameter.cc b/libs/ardour/parameter.cc index ea70ea7927..87b5d329a2 100644 --- a/libs/ardour/parameter.cc +++ b/libs/ardour/parameter.cc @@ -79,7 +79,7 @@ Parameter::Parameter(const std::string& str) 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) { return string_compose("midi-channel-aftertouch-%1", int(_channel)); } else { - PBD::warning << "Uninitialized Parameter to_string() called." << endmsg; + PBD::warning << "Uninitialized Parameter symbol() called." << endmsg; return ""; } } diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 4f92295e55..b82ba28290 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -430,7 +430,7 @@ PluginInsert::automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offs } float -PluginInsert::default_parameter_value (Evoral::Parameter param) +PluginInsert::default_parameter_value (const Evoral::Parameter& param) { if (param.type() != PluginAutomation) return 1.0; diff --git a/libs/evoral/evoral/Control.hpp b/libs/evoral/evoral/Control.hpp index ed957522a1..15d50fcdca 100644 --- a/libs/evoral/evoral/Control.hpp +++ b/libs/evoral/evoral/Control.hpp @@ -46,7 +46,7 @@ public: boost::shared_ptr<ControlList> list() { return _list; } boost::shared_ptr<const ControlList> list() const { return _list; } - Parameter parameter() const; + const Parameter& parameter() const; protected: boost::shared_ptr<ControlList> _list; diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index c035b6ddcf..45519955c5 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -83,7 +83,7 @@ public: typedef EventList::reverse_iterator reverse_iterator; typedef EventList::const_iterator const_iterator; - ControlList (Parameter id); + ControlList (const Parameter& id); //ControlList (const XMLNode&, Parameter id); ~ControlList(); @@ -97,8 +97,8 @@ public: void freeze(); void thaw (); - const Parameter& parameter() const { return _parameter; } - void set_parameter(Parameter p) { _parameter = p; } + const Parameter& parameter() const { return _parameter; } + void set_parameter(const Parameter& p) { _parameter = p; } EventList::size_type size() const { return _events.size(); } bool empty() const { return _events.empty(); } diff --git a/libs/evoral/evoral/ControlSet.hpp b/libs/evoral/evoral/ControlSet.hpp index ba6e5e5623..73fa5554e6 100644 --- a/libs/evoral/evoral/ControlSet.hpp +++ b/libs/evoral/evoral/ControlSet.hpp @@ -37,8 +37,8 @@ public: ControlSet(); virtual ~ControlSet() {} - virtual boost::shared_ptr<Control> control(Evoral::Parameter id, bool create_if_missing=false); - virtual boost::shared_ptr<const Control> control(Evoral::Parameter id) const; + virtual boost::shared_ptr<Control> control(const Parameter& id, bool create_if_missing=false); + 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<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 float default_parameter_value(Parameter param) { return 1.0f; } + virtual float default_parameter_value(const Parameter& param) { return 1.0f; } virtual void clear(); diff --git a/libs/evoral/evoral/MIDIParameters.hpp b/libs/evoral/evoral/MIDIParameters.hpp index c21a86264d..e2bfdc3fb0 100644 --- a/libs/evoral/evoral/MIDIParameters.hpp +++ b/libs/evoral/evoral/MIDIParameters.hpp @@ -23,29 +23,34 @@ namespace Evoral { namespace MIDI { struct ContinuousController : public Parameter { - ContinuousController(uint32_t cc_type, uint32_t channel, uint32_t controller) - : Parameter(cc_type, controller, channel) { set_range(*this); } - static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); } + ContinuousController(uint32_t cc_type, uint8_t channel, uint32_t controller) + : Parameter(cc_type, channel, controller) {} }; struct ProgramChange : public Parameter { - ProgramChange(uint32_t pc_type, uint32_t channel) - : Parameter(pc_type, 0, channel) { set_range(*this); } - static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); } + ProgramChange(uint32_t pc_type, uint8_t channel) : Parameter(pc_type, 0, channel) {} }; struct ChannelAftertouch : public Parameter { - ChannelAftertouch(uint32_t ca_type, uint32_t channel) - : Parameter(ca_type, 0, channel) { set_range(*this); } - static void set_range(Parameter& p) { p.set_range(0.0, 127.0, 0.0); } + ChannelAftertouch(uint32_t ca_type, uint32_t channel) : Parameter(ca_type, 0, channel) {} }; struct PitchBender : public Parameter { - PitchBender(uint32_t pb_type, uint32_t channel) - : Parameter(pb_type, 0, channel) { set_range(*this); } - static void set_range(Parameter& p) { p.set_range(0.0, 16383.0, 8192.0); } + PitchBender(uint32_t pb_type, uint32_t channel) : Parameter(pb_type, 0, channel) {} }; +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 Evoral diff --git a/libs/evoral/evoral/Parameter.hpp b/libs/evoral/evoral/Parameter.hpp index ae405ec039..301a432bd0 100644 --- a/libs/evoral/evoral/Parameter.hpp +++ b/libs/evoral/evoral/Parameter.hpp @@ -20,7 +20,10 @@ #define EVORAL_PARAMETER_HPP #include <string> +#include <map> +#include <boost/shared_ptr.hpp> #include <boost/format.hpp> +#include <iostream> namespace Evoral { @@ -37,19 +40,27 @@ namespace Evoral { class Parameter { public: - Parameter(uint32_t type, uint32_t id, int8_t channel=0, - double min=0.0f, double max=0.0f, double def=0.0f) - : _type(type), _id(id), _channel(channel), _min(min), _max(max), _normal(def) + Parameter(uint32_t type, uint8_t channel, uint32_t id=0) + : _type(type), _id(id), _channel(channel) {} - //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 id() const { return _id; } inline uint8_t channel() const { return _channel; } - /** - * Equivalence operator + /** Equivalence operator * It is obvious from the definition that this operator * is transitive, as required by stict weak ordering * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html) @@ -101,18 +112,37 @@ public: inline operator bool() const { return (_type != 0); } 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 void set_range(double min, double max, double normal) { - _min = min; - _max = max; - _normal = normal; + inline static void set_range(uint32_t type, double min, double max, double normal) { + _type_metadata[type] = Metadata(min, max, normal); } - inline const double min() const { return _min; } - inline const double max() const { return _max; } - inline const double normal() const { return _normal; } + inline void set_range(double min, double max, double normal) { + _metadata = boost::shared_ptr<Metadata>(new Metadata(min, max, normal)); + } + + inline Metadata& metadata() const { + if (_metadata) + 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: // Default copy constructor is ok @@ -121,11 +151,11 @@ protected: uint32_t _type; uint32_t _id; uint8_t _channel; + + boost::shared_ptr<Metadata> _metadata; - // Metadata (not used in comparison) - double _min; - double _max; - double _normal; + typedef std::map<uint32_t, Metadata> TypeMetadata; + static TypeMetadata _type_metadata; }; diff --git a/libs/evoral/evoral/Sequence.hpp b/libs/evoral/evoral/Sequence.hpp index 0f1de2a7af..10a61704ed 100644 --- a/libs/evoral/evoral/Sequence.hpp +++ b/libs/evoral/evoral/Sequence.hpp @@ -177,7 +177,7 @@ private: 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_control_unlocked(Parameter param, double time, double value); + void append_control_unlocked(const Parameter& param, double time, double value); mutable Glib::RWLock _lock; diff --git a/libs/evoral/src/Control.cpp b/libs/evoral/src/Control.cpp index 8efc2a6659..d23f6c3c9a 100644 --- a/libs/evoral/src/Control.cpp +++ b/libs/evoral/src/Control.cpp @@ -22,6 +22,8 @@ namespace Evoral { +Parameter::TypeMetadata Parameter::_type_metadata; + Control::Control(boost::shared_ptr<ControlList> list) : _list(list) , _user_value(list->default_value()) @@ -72,7 +74,7 @@ Control::set_list(boost::shared_ptr<ControlList> list) } -Parameter +const Parameter& Control::parameter() const { return _list->parameter(); diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 8f6ea1872f..62c49a97e6 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -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) , _interpolation(Linear) , _curve(new Curve(*this)) diff --git a/libs/evoral/src/ControlSet.cpp b/libs/evoral/src/ControlSet.cpp index 93a0b0ef25..5aacff598d 100644 --- a/libs/evoral/src/ControlSet.cpp +++ b/libs/evoral/src/ControlSet.cpp @@ -53,7 +53,7 @@ ControlSet::what_has_data (set<Parameter>& s) const * for \a parameter does not exist. */ 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); @@ -73,7 +73,7 @@ ControlSet::control (Parameter parameter, bool create_if_missing) } boost::shared_ptr<const Control> -ControlSet::control (Parameter parameter) const +ControlSet::control (const Parameter& parameter) const { Controls::const_iterator i = _controls.find(parameter); diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index 81502fdb5f..4880b5a04d 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -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); } |