summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-12-01 14:28:03 -0500
committerDavid Robillard <d@drobilla.net>2014-12-01 23:35:24 -0500
commit767c0238a34ef4acc4d345e88cd5ddb0c8a8e421 (patch)
treefed11fb6f4e4e08a7c35eb45f53aea70dc66e4f8 /libs/ardour
parentcb8abbe8d2f0e4dfe52bd35613ebba7689628eca (diff)
Replace half-baked param metadata with descriptor.
Among other things, this means that automation controls/lists have the actual min/max/normal/toggled of parameters, and not those inferred from the Parameter ID, which is not correct for things like plugin parameters. Pushing things down to the Evoral::ParmeterDescriptor may be useful in the future to have lists do smarter things based on parameter range, but currently I have just pushed down the above-mentioned currently used attributes.
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/MSVClibardour/ardour.vcproj4
-rw-r--r--libs/ardour/amp.cc1
-rw-r--r--libs/ardour/ardour/automation_list.h6
-rw-r--r--libs/ardour/ardour/event_type_map.h19
-rw-r--r--libs/ardour/ardour/parameter_descriptor.h76
-rw-r--r--libs/ardour/audioregion.cc14
-rw-r--r--libs/ardour/automatable.cc22
-rw-r--r--libs/ardour/automation_control.cc2
-rw-r--r--libs/ardour/automation_list.cc27
-rw-r--r--libs/ardour/event_type_map.cc120
-rw-r--r--libs/ardour/midi_automation_list_binder.cc2
-rw-r--r--libs/ardour/midi_source.cc4
-rw-r--r--libs/ardour/midi_track.cc12
-rw-r--r--libs/ardour/parameter_descriptor.cc135
-rw-r--r--libs/ardour/plugin_insert.cc9
-rw-r--r--libs/ardour/value_as_string.cc76
-rw-r--r--libs/ardour/wscript1
17 files changed, 316 insertions, 214 deletions
diff --git a/libs/ardour/MSVClibardour/ardour.vcproj b/libs/ardour/MSVClibardour/ardour.vcproj
index 5965410763..5d4b535343 100644
--- a/libs/ardour/MSVClibardour/ardour.vcproj
+++ b/libs/ardour/MSVClibardour/ardour.vcproj
@@ -764,6 +764,10 @@
>
</File>
<File
+ RelativePath="..\parameter_descriptor.cc"
+ >
+ </File>
+ <File
RelativePath="..\pcm_utils.cc"
>
</File>
diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc
index 2265c6de03..0cf7049c47 100644
--- a/libs/ardour/amp.cc
+++ b/libs/ardour/amp.cc
@@ -46,7 +46,6 @@ Amp::Amp (Session& s)
, _gain_automation_buffer(0)
{
Evoral::Parameter p (GainAutomation);
- p.set_range (0, max_gain_coefficient, 1, false);
boost::shared_ptr<AutomationList> gl (new AutomationList (p));
_gain_control = boost::shared_ptr<GainControl> (new GainControl (X_("gaincontrol"), s, this, p, gl));
_gain_control->set_flags (Controllable::GainLike);
diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h
index 28f9be3fd4..cfeaeafa86 100644
--- a/libs/ardour/ardour/automation_list.h
+++ b/libs/ardour/ardour/automation_list.h
@@ -64,13 +64,15 @@ private:
class LIBARDOUR_API AutomationList : public PBD::StatefulDestructible, public Evoral::ControlList
{
public:
- AutomationList (Evoral::Parameter id);
+ AutomationList (const Evoral::Parameter& id, const Evoral::ParameterDescriptor& desc);
+ AutomationList (const Evoral::Parameter& id);
AutomationList (const XMLNode&, Evoral::Parameter id);
AutomationList (const AutomationList&);
AutomationList (const AutomationList&, double start, double end);
~AutomationList();
- virtual boost::shared_ptr<Evoral::ControlList> create(Evoral::Parameter id);
+ virtual boost::shared_ptr<ControlList> create(const Evoral::Parameter& id,
+ const Evoral::ParameterDescriptor& desc);
AutomationList& operator= (const AutomationList&);
diff --git a/libs/ardour/ardour/event_type_map.h b/libs/ardour/ardour/event_type_map.h
index f69d20b773..0d7e623754 100644
--- a/libs/ardour/ardour/event_type_map.h
+++ b/libs/ardour/ardour/event_type_map.h
@@ -21,9 +21,12 @@
#ifndef __ardour_event_type_map_h__
#define __ardour_event_type_map_h__
+#include <map>
#include <string>
+
#include "evoral/TypeMap.hpp"
#include "evoral/ControlList.hpp"
+#include "evoral/ParameterDescriptor.hpp"
#include "ardour/libardour_visibility.h"
@@ -43,19 +46,23 @@ public:
uint32_t midi_event_type(uint8_t status) const;
Evoral::ControlList::InterpolationStyle interpolation_of(const Evoral::Parameter& param);
- bool is_integer(const Evoral::Parameter& param) const;
- Evoral::Parameter new_parameter(uint32_t type, uint8_t channel=0, uint32_t id=0) const;
- Evoral::Parameter new_parameter(const std::string& str) const;
- std::string to_symbol(const Evoral::Parameter& param) const;
+ Evoral::Parameter from_symbol(const std::string& str) const;
+ std::string to_symbol(const Evoral::Parameter& param) const;
+
+ const Evoral::ParameterDescriptor& descriptor(const Evoral::Parameter& param) const;
- bool is_midi_parameter(const Evoral::Parameter& param);
+ void set_descriptor(const Evoral::Parameter& param,
+ const Evoral::ParameterDescriptor& desc);
URIMap& uri_map() { return _uri_map; }
private:
+ typedef std::map<Evoral::Parameter, Evoral::ParameterDescriptor> Descriptors;
+
EventTypeMap(URIMap& uri_map) : _uri_map(uri_map) {}
- URIMap& _uri_map;
+ URIMap& _uri_map;
+ Descriptors _descriptors;
static EventTypeMap* event_type_map;
};
diff --git a/libs/ardour/ardour/parameter_descriptor.h b/libs/ardour/ardour/parameter_descriptor.h
index 41b1f031d1..d4bef550f5 100644
--- a/libs/ardour/ardour/parameter_descriptor.h
+++ b/libs/ardour/ardour/parameter_descriptor.h
@@ -21,7 +21,9 @@
#define __ardour_parameter_descriptor_h__
#include "ardour/variant.h"
+
#include "evoral/Parameter.hpp"
+#include "evoral/ParameterDescriptor.hpp"
namespace ARDOUR {
@@ -31,7 +33,7 @@ typedef std::map<const std::string, const float> ScalePoints;
*
* Essentially a union of LADSPA, VST and LV2 info.
*/
-struct ParameterDescriptor
+struct ParameterDescriptor : public Evoral::ParameterDescriptor
{
enum Unit {
NONE, ///< No unit
@@ -40,72 +42,12 @@ struct ParameterDescriptor
HZ, ///< Frequency in Hertz
};
- ParameterDescriptor(const Evoral::Parameter& parameter)
- : key((uint32_t)-1)
- , datatype(Variant::NOTHING)
- , unit(NONE)
- , normal(parameter.normal())
- , lower(parameter.min())
- , upper(parameter.max())
- , step(0)
- , smallstep(0)
- , largestep(0)
- , integer_step(parameter.type() >= MidiCCAutomation &&
- parameter.type() <= MidiChannelPressureAutomation)
- , toggled(parameter.toggled())
- , logarithmic(false)
- , sr_dependent(false)
- , min_unbound(0)
- , max_unbound(0)
- , enumeration(false)
- {
- if (parameter.type() == GainAutomation) {
- unit = DB;
- }
- update_steps();
- }
-
- ParameterDescriptor()
- : key((uint32_t)-1)
- , datatype(Variant::NOTHING)
- , unit(NONE)
- , normal(0)
- , lower(0)
- , upper(0)
- , step(0)
- , smallstep(0)
- , largestep(0)
- , integer_step(false)
- , toggled(false)
- , logarithmic(false)
- , sr_dependent(false)
- , min_unbound(0)
- , max_unbound(0)
- , enumeration(false)
- {}
-
- /* Set step, smallstep, and largestep, based on current description */
- void update_steps() {
- if (unit == ParameterDescriptor::MIDI_NOTE) {
- step = smallstep = 1; // semitone
- largestep = 12; // octave
- } else if (integer_step) {
- const float delta = upper - lower;
+ ParameterDescriptor(const Evoral::Parameter& parameter);
- smallstep = delta / 10000.0f;
- step = delta / 1000.0f;
- largestep = delta / 40.0f;
+ ParameterDescriptor();
- smallstep = std::max(1.0, rint(smallstep));
- step = std::max(1.0, rint(step));
- largestep = std::max(1.0, rint(largestep));
- }
- /* else: leave all others as default '0'
- * in that case the UI (eg. AutomationController::create)
- * uses internal_to_interface() to map the value
- * to an appropriate interface range
- */
- }
+ /** Set step, smallstep, and largestep, based on current description. */
+ void update_steps();
std::string label;
std::string print_fmt; ///< format string for pretty printing
@@ -113,14 +55,10 @@ struct ParameterDescriptor
uint32_t key; ///< for properties
Variant::Type datatype; ///< for properties
Unit unit;
- float normal;
- float lower; ///< for frequencies, this is in Hz (not a fraction of the sample rate)
- float upper; ///< for frequencies, this is in Hz (not a fraction of the sample rate)
float step;
float smallstep;
float largestep;
bool integer_step;
- bool toggled;
bool logarithmic;
bool sr_dependent;
bool min_unbound;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 8c4eb6aa2a..506596430f 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -40,11 +40,13 @@
#include "ardour/session.h"
#include "ardour/dB.h"
#include "ardour/debug.h"
+#include "ardour/event_type_map.h"
#include "ardour/playlist.h"
#include "ardour/audiofilesource.h"
#include "ardour/region_factory.h"
#include "ardour/runtime_functions.h"
#include "ardour/transient_detector.h"
+#include "ardour/parameter_descriptor.h"
#include "ardour/progress.h"
#include "i18n.h"
@@ -1011,9 +1013,10 @@ AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
void
AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
{
- boost::shared_ptr<Evoral::ControlList> c1 (new Evoral::ControlList (FadeInAutomation));
- boost::shared_ptr<Evoral::ControlList> c2 (new Evoral::ControlList (FadeInAutomation));
- boost::shared_ptr<Evoral::ControlList> c3 (new Evoral::ControlList (FadeInAutomation));
+ const ARDOUR::ParameterDescriptor desc(FadeInAutomation);
+ boost::shared_ptr<Evoral::ControlList> c1 (new Evoral::ControlList (FadeInAutomation, desc));
+ boost::shared_ptr<Evoral::ControlList> c2 (new Evoral::ControlList (FadeInAutomation, desc));
+ boost::shared_ptr<Evoral::ControlList> c3 (new Evoral::ControlList (FadeInAutomation, desc));
_fade_in->freeze ();
_fade_in->clear ();
@@ -1093,8 +1096,9 @@ AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
void
AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
{
- boost::shared_ptr<Evoral::ControlList> c1 (new Evoral::ControlList (FadeOutAutomation));
- boost::shared_ptr<Evoral::ControlList> c2 (new Evoral::ControlList (FadeOutAutomation));
+ const ARDOUR::ParameterDescriptor desc(FadeOutAutomation);
+ boost::shared_ptr<Evoral::ControlList> c1 (new Evoral::ControlList (FadeOutAutomation, desc));
+ boost::shared_ptr<Evoral::ControlList> c2 (new Evoral::ControlList (FadeOutAutomation, desc));
_fade_out->freeze ();
_fade_out->clear ();
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc
index 906ff4ed3e..0538c84cc5 100644
--- a/libs/ardour/automatable.cc
+++ b/libs/ardour/automatable.cc
@@ -212,7 +212,7 @@ Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter le
const XMLProperty* id_prop = (*niter)->property("automation-id");
Evoral::Parameter param = (id_prop
- ? EventTypeMap::instance().new_parameter(id_prop->value())
+ ? EventTypeMap::instance().from_symbol(id_prop->value())
: legacy_param);
if (param.type() == NullAutomation) {
@@ -399,14 +399,15 @@ Automatable::transport_stopped (framepos_t now)
boost::shared_ptr<Evoral::Control>
Automatable::control_factory(const Evoral::Parameter& param)
{
- boost::shared_ptr<AutomationList> list(new AutomationList(param));
- Evoral::Control* control = NULL;
- ParameterDescriptor desc(param);
+ Evoral::Control* control = NULL;
+ bool make_list = true;
+ ParameterDescriptor desc(param);
+ boost::shared_ptr<AutomationList> list;
if (param.type() >= MidiCCAutomation && param.type() <= MidiChannelPressureAutomation) {
MidiTrack* mt = dynamic_cast<MidiTrack*>(this);
if (mt) {
control = new MidiTrack::MidiControl(mt, param);
- list.reset(); // No list, this is region "automation"
+ make_list = false; // No list, this is region "automation"
} else {
warning << "MidiCCAutomation for non-MidiTrack" << endl;
}
@@ -424,7 +425,9 @@ Automatable::control_factory(const Evoral::Parameter& param)
desc = pi->plugin(0)->get_property_descriptor(param.id());
if (desc.datatype != Variant::NOTHING) {
if (!Variant::type_is_numeric(desc.datatype)) {
- list.reset(); // Can't automate non-numeric data yet
+ make_list = false; // Can't automate non-numeric data yet
+ } else {
+ list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
}
control = new PluginInsert::PluginPropertyControl(pi, param, desc, list);
}
@@ -447,11 +450,14 @@ Automatable::control_factory(const Evoral::Parameter& param)
}
}
+ if (make_list && !list) {
+ list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
+ }
+
if (!control) {
- control = new AutomationControl(_a_session, param, desc);
+ control = new AutomationControl(_a_session, param, desc, list);
}
- control->set_list(list);
return boost::shared_ptr<Evoral::Control>(control);
}
diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc
index e21fda6874..773fd3f40c 100644
--- a/libs/ardour/automation_control.cc
+++ b/libs/ardour/automation_control.cc
@@ -35,7 +35,7 @@ AutomationControl::AutomationControl(ARDOUR::Session& s
boost::shared_ptr<ARDOUR::AutomationList> list,
const string& name)
: Controllable (name.empty() ? EventTypeMap::instance().to_symbol(parameter) : name)
- , Evoral::Control(parameter, list)
+ , Evoral::Control(parameter, desc, list)
, _session(session)
, _desc(desc)
{
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index e5a4493618..cf41c41839 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -25,6 +25,7 @@
#include <algorithm>
#include "ardour/automation_list.h"
#include "ardour/event_type_map.h"
+#include "ardour/parameter_descriptor.h"
#include "evoral/Curve.hpp"
#include "pbd/stacktrace.h"
#include "pbd/enumwriter.h"
@@ -47,8 +48,21 @@ static void dumpit (const AutomationList& al, string prefix = "")
cerr << "\n";
}
#endif
-AutomationList::AutomationList (Evoral::Parameter id)
- : ControlList(id)
+AutomationList::AutomationList (const Evoral::Parameter& id, const Evoral::ParameterDescriptor& desc)
+ : ControlList(id, desc)
+{
+ _state = Off;
+ _style = Absolute;
+ g_atomic_int_set (&_touching, 0);
+
+ create_curve_if_necessary();
+
+ assert(_parameter.type() != NullAutomation);
+ AutomationListCreated(this);
+}
+
+AutomationList::AutomationList (const Evoral::Parameter& id)
+ : ControlList(id, ARDOUR::ParameterDescriptor(id))
{
_state = Off;
_style = Absolute;
@@ -91,7 +105,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
* in or below the AutomationList node. It is used if @param id is non-null.
*/
AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id)
- : ControlList(id)
+ : ControlList(id, ARDOUR::ParameterDescriptor(id))
{
g_atomic_int_set (&_touching, 0);
_state = Off;
@@ -114,9 +128,10 @@ AutomationList::~AutomationList()
}
boost::shared_ptr<Evoral::ControlList>
-AutomationList::create(Evoral::Parameter id)
+AutomationList::create(const Evoral::Parameter& id,
+ const Evoral::ParameterDescriptor& desc)
{
- return boost::shared_ptr<Evoral::ControlList>(new AutomationList(id));
+ return boost::shared_ptr<Evoral::ControlList>(new AutomationList(id, desc));
}
void
@@ -414,7 +429,7 @@ AutomationList::set_state (const XMLNode& node, int version)
}
if ((prop = node.property (X_("automation-id"))) != 0){
- _parameter = EventTypeMap::instance().new_parameter(prop->value());
+ _parameter = EventTypeMap::instance().from_symbol(prop->value());
} else {
warning << "Legacy session: automation list has no automation-id property." << endmsg;
}
diff --git a/libs/ardour/event_type_map.cc b/libs/ardour/event_type_map.cc
index 6c1c8363ee..14f609bd8a 100644
--- a/libs/ardour/event_type_map.cc
+++ b/libs/ardour/event_type_map.cc
@@ -25,6 +25,7 @@
#include "ardour/parameter_types.h"
#include "ardour/uri_map.h"
#include "evoral/Parameter.hpp"
+#include "evoral/ParameterDescriptor.hpp"
#include "evoral/midi_events.h"
#include "pbd/error.h"
#include "pbd/compose.h"
@@ -40,25 +41,6 @@ EventTypeMap::instance()
{
if (!EventTypeMap::event_type_map) {
EventTypeMap::event_type_map = new EventTypeMap(URIMap::instance());
-
- // Initialize parameter metadata
- EventTypeMap::event_type_map->new_parameter(NullAutomation);
- EventTypeMap::event_type_map->new_parameter(GainAutomation);
- EventTypeMap::event_type_map->new_parameter(PanAzimuthAutomation);
- EventTypeMap::event_type_map->new_parameter(PanElevationAutomation);
- EventTypeMap::event_type_map->new_parameter(PanWidthAutomation);
- EventTypeMap::event_type_map->new_parameter(PluginAutomation);
- EventTypeMap::event_type_map->new_parameter(PluginPropertyAutomation);
- EventTypeMap::event_type_map->new_parameter(SoloAutomation);
- EventTypeMap::event_type_map->new_parameter(MuteAutomation);
- EventTypeMap::event_type_map->new_parameter(MidiCCAutomation);
- EventTypeMap::event_type_map->new_parameter(MidiPgmChangeAutomation);
- EventTypeMap::event_type_map->new_parameter(MidiPitchBenderAutomation);
- EventTypeMap::event_type_map->new_parameter(MidiChannelPressureAutomation);
- EventTypeMap::event_type_map->new_parameter(FadeInAutomation);
- EventTypeMap::event_type_map->new_parameter(FadeOutAutomation);
- EventTypeMap::event_type_map->new_parameter(EnvelopeAutomation);
- EventTypeMap::event_type_map->new_parameter(MidiCCAutomation);
}
return *EventTypeMap::event_type_map;
}
@@ -69,12 +51,6 @@ EventTypeMap::type_is_midi(uint32_t type) const
return ARDOUR::parameter_is_midi((AutomationType)type);
}
-bool
-EventTypeMap::is_midi_parameter(const Evoral::Parameter& param)
-{
- return type_is_midi(param.type());
-}
-
uint8_t
EventTypeMap::parameter_midi_type(const Evoral::Parameter& param) const
{
@@ -87,13 +63,6 @@ EventTypeMap::midi_event_type(uint8_t status) const
return (uint32_t)ARDOUR::midi_parameter_type(status);
}
-bool
-EventTypeMap::is_integer(const Evoral::Parameter& param) const
-{
- return ( param.type() >= MidiCCAutomation
- && param.type() <= MidiChannelPressureAutomation);
-}
-
Evoral::ControlList::InterpolationStyle
EventTypeMap::interpolation_of(const Evoral::Parameter& param)
{
@@ -147,75 +116,8 @@ EventTypeMap::interpolation_of(const Evoral::Parameter& param)
return Evoral::ControlList::Linear; // Not reached, suppress warnings
}
-
Evoral::Parameter
-EventTypeMap::new_parameter(uint32_t type, uint8_t channel, uint32_t id) const
-{
- Evoral::Parameter p(type, channel, id);
-
- double min = 0.0f;
- double max = 1.0f;
- double normal = 0.0f;
- bool toggled = false;
-
- switch((AutomationType)type) {
- case NullAutomation:
- case GainAutomation:
- max = 2.0f;
- normal = 1.0f;
- break;
- case PanAzimuthAutomation:
- normal = 0.5f; // there really is no normal but this works for stereo, sort of
- break;
- case PanWidthAutomation:
- min = -1.0;
- max = 1.0;
- normal = 0.0f;
- break;
- case PanElevationAutomation:
- case PanFrontBackAutomation:
- case PanLFEAutomation:
- break;
- case RecEnableAutomation:
- /* default 0.0 - 1.0 is fine */
- toggled = true;
- break;
- case PluginAutomation:
- case FadeInAutomation:
- case FadeOutAutomation:
- case EnvelopeAutomation:
- max = 2.0f;
- normal = 1.0f;
- break;
- case SoloAutomation:
- case MuteAutomation:
- max = 1.0f;
- normal = 0.0f;
- toggled = true;
- break;
- case MidiCCAutomation:
- case MidiPgmChangeAutomation:
- case MidiChannelPressureAutomation:
- min = 0.0;
- normal = 0.0;
- max = 127.0;
- break;
- case MidiPitchBenderAutomation:
- min = 0.0;
- normal = 8192.0;
- max = 16383.0;
- case MidiSystemExclusiveAutomation:
- return p;
- case PluginPropertyAutomation:
- return p;
- }
-
- p.set_range(type, min, max, normal, toggled);
- return p;
-}
-
-Evoral::Parameter
-EventTypeMap::new_parameter(const string& str) const
+EventTypeMap::from_symbol(const string& str) const
{
AutomationType p_type = NullAutomation;
uint8_t p_channel = 0;
@@ -285,7 +187,7 @@ EventTypeMap::new_parameter(const string& str) const
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
}
- return new_parameter(p_type, p_channel, p_id);
+ return Evoral::Parameter(p_type, p_channel, p_id);
}
/** Unique string representation, suitable as an XML property value.
@@ -341,5 +243,21 @@ EventTypeMap::to_symbol(const Evoral::Parameter& param) const
}
}
+const Evoral::ParameterDescriptor&
+EventTypeMap::descriptor(const Evoral::Parameter& param) const
+{
+ static const Evoral::ParameterDescriptor nil;
+
+ Descriptors::const_iterator d = _descriptors.find(param);
+ return (d != _descriptors.end()) ? d->second : nil;
+}
+
+void
+EventTypeMap::set_descriptor(const Evoral::Parameter& param,
+ const Evoral::ParameterDescriptor& desc)
+{
+ _descriptors.insert(std::make_pair(param, desc));
+}
+
} // namespace ARDOUR
diff --git a/libs/ardour/midi_automation_list_binder.cc b/libs/ardour/midi_automation_list_binder.cc
index fbb87c5cfa..f7249d72b1 100644
--- a/libs/ardour/midi_automation_list_binder.cc
+++ b/libs/ardour/midi_automation_list_binder.cc
@@ -45,7 +45,7 @@ MidiAutomationListBinder::MidiAutomationListBinder (XMLNode* node, Session::Sour
assert (i != sources.end());
_source = boost::dynamic_pointer_cast<MidiSource> (i->second);
- _parameter = EventTypeMap::instance().new_parameter (parameter->value());
+ _parameter = EventTypeMap::instance().from_symbol (parameter->value());
}
AutomationList*
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index 0f3df97f9b..5bfa73518c 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -123,7 +123,7 @@ MidiSource::set_state (const XMLNode& node, int /*version*/)
error << _("Missing parameter property on InterpolationStyle") << endmsg;
return -1;
}
- Evoral::Parameter p = EventTypeMap::instance().new_parameter (prop->value());
+ Evoral::Parameter p = EventTypeMap::instance().from_symbol (prop->value());
if ((prop = (*i)->property (X_("style"))) == 0) {
error << _("Missing style property on InterpolationStyle") << endmsg;
@@ -138,7 +138,7 @@ MidiSource::set_state (const XMLNode& node, int /*version*/)
error << _("Missing parameter property on AutomationState") << endmsg;
return -1;
}
- Evoral::Parameter p = EventTypeMap::instance().new_parameter (prop->value());
+ Evoral::Parameter p = EventTypeMap::instance().from_symbol (prop->value());
if ((prop = (*i)->property (X_("state"))) == 0) {
error << _("Missing state property on AutomationState") << endmsg;
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index f7294d8e3b..b8fe7ada4c 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -37,6 +37,7 @@
#include "ardour/buffer_set.h"
#include "ardour/debug.h"
#include "ardour/delivery.h"
+#include "ardour/event_type_map.h"
#include "ardour/meter.h"
#include "ardour/midi_diskstream.h"
#include "ardour/midi_playlist.h"
@@ -657,16 +658,17 @@ void
MidiTrack::MidiControl::set_value(double val)
{
const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
+ const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
bool valid = false;
if (isinf_local(val)) {
cerr << "MIDIControl value is infinity" << endl;
} else if (isnan_local(val)) {
cerr << "MIDIControl value is NaN" << endl;
- } else if (val < parameter.min()) {
- cerr << "MIDIControl value is < " << parameter.min() << endl;
- } else if (val > parameter.max()) {
- cerr << "MIDIControl value is > " << parameter.max() << endl;
+ } else if (val < desc.lower) {
+ cerr << "MIDIControl value is < " << desc.lower << endl;
+ } else if (val > desc.upper) {
+ cerr << "MIDIControl value is > " << desc.upper << endl;
} else {
valid = true;
}
@@ -675,7 +677,7 @@ MidiTrack::MidiControl::set_value(double val)
return;
}
- assert(val <= parameter.max());
+ assert(val <= desc.upper);
if ( ! _list || ! automation_playback()) {
size_t size = 3;
uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
diff --git a/libs/ardour/parameter_descriptor.cc b/libs/ardour/parameter_descriptor.cc
new file mode 100644
index 0000000000..88debb0200
--- /dev/null
+++ b/libs/ardour/parameter_descriptor.cc
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2014 Paul Davis
+ Author: David Robillard
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "ardour/amp.h"
+#include "ardour/parameter_descriptor.h"
+#include "ardour/types.h"
+
+namespace ARDOUR {
+
+ParameterDescriptor::ParameterDescriptor(const Evoral::Parameter& parameter)
+ : Evoral::ParameterDescriptor()
+ , key((uint32_t)-1)
+ , datatype(Variant::NOTHING)
+ , unit(NONE)
+ , step(0)
+ , smallstep(0)
+ , largestep(0)
+ , integer_step(parameter.type() >= MidiCCAutomation &&
+ parameter.type() <= MidiChannelPressureAutomation)
+ , logarithmic(false)
+ , sr_dependent(false)
+ , min_unbound(0)
+ , max_unbound(0)
+ , enumeration(false)
+{
+ if (parameter.type() == GainAutomation) {
+ unit = DB;
+ }
+
+ switch((AutomationType)parameter.type()) {
+ case GainAutomation:
+ upper = Amp::max_gain_coefficient;
+ normal = 1.0f;
+ break;
+ case PanAzimuthAutomation:
+ normal = 0.5f; // there really is no _normal but this works for stereo, sort of
+ break;
+ case PanWidthAutomation:
+ lower = -1.0;
+ upper = 1.0;
+ normal = 0.0f;
+ break;
+ case RecEnableAutomation:
+ /* default 0.0 - 1.0 is fine */
+ toggled = true;
+ break;
+ case PluginAutomation:
+ case FadeInAutomation:
+ case FadeOutAutomation:
+ case EnvelopeAutomation:
+ upper = 2.0f;
+ normal = 1.0f;
+ break;
+ case SoloAutomation:
+ case MuteAutomation:
+ upper = 1.0f;
+ normal = 0.0f;
+ toggled = true;
+ break;
+ case MidiCCAutomation:
+ case MidiPgmChangeAutomation:
+ case MidiChannelPressureAutomation:
+ lower = 0.0;
+ normal = 0.0;
+ upper = 127.0;
+ break;
+ case MidiPitchBenderAutomation:
+ lower = 0.0;
+ normal = 8192.0;
+ upper = 16383.0;
+ break;
+ default:
+ break;
+ }
+
+ update_steps();
+}
+
+ParameterDescriptor::ParameterDescriptor()
+ : Evoral::ParameterDescriptor()
+ , key((uint32_t)-1)
+ , datatype(Variant::NOTHING)
+ , unit(NONE)
+ , step(0)
+ , smallstep(0)
+ , largestep(0)
+ , integer_step(false)
+ , logarithmic(false)
+ , sr_dependent(false)
+ , min_unbound(0)
+ , max_unbound(0)
+ , enumeration(false)
+{}
+
+void
+ParameterDescriptor::update_steps()
+{
+ if (unit == ParameterDescriptor::MIDI_NOTE) {
+ step = smallstep = 1; // semitone
+ largestep = 12; // octave
+ } else if (integer_step) {
+ const float delta = upper - lower;
+
+ smallstep = delta / 10000.0f;
+ step = delta / 1000.0f;
+ largestep = delta / 40.0f;
+
+ smallstep = std::max(1.0, rint(smallstep));
+ step = std::max(1.0, rint(step));
+ largestep = std::max(1.0, rint(largestep));
+ }
+ /* else: leave all others as default '0'
+ * in that case the UI (eg. AutomationController::create)
+ * uses internal_to_interface() to map the value
+ * to an appropriate interface range
+ */
+}
+
+} // namespace ARDOUR
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 5dd35c881c..156f7b02a0 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -248,13 +248,8 @@ PluginInsert::create_automatable_parameters ()
ParameterDescriptor desc;
_plugins.front()->get_parameter_descriptor(i->id(), desc);
- /* the Parameter belonging to the actual plugin doesn't have its range set
- but we want the Controllable related to this Parameter to have those limits.
- */
-
- param.set_range (desc.lower, desc.upper, _plugins.front()->default_value(i->id()), desc.toggled);
can_automate (param);
- boost::shared_ptr<AutomationList> list(new AutomationList(param));
+ boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
} else if (i->type() == PluginPropertyAutomation) {
Evoral::Parameter param(*i);
@@ -262,7 +257,7 @@ PluginInsert::create_automatable_parameters ()
if (desc.datatype != Variant::NOTHING) {
boost::shared_ptr<AutomationList> list;
if (Variant::type_is_numeric(desc.datatype)) {
- list = boost::shared_ptr<AutomationList>(new AutomationList(param));
+ list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
}
add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
}
diff --git a/libs/ardour/value_as_string.cc b/libs/ardour/value_as_string.cc
new file mode 100644
index 0000000000..3d79d24b9c
--- /dev/null
+++ b/libs/ardour/value_as_string.cc
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2014 Paul Davis
+ Author: David Robillard
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "ardour/value_as_string.h"
+
+namespace ARDOUR {
+
+std::string
+value_as_string(const Evoral::ParameterDescriptor& desc,
+ double v)
+{
+ char buf[32];
+
+ if (desc.scale_points) {
+ // Check if value is on a scale point
+ for (Evoral::ScalePoints::const_iterator i = desc.scale_points->begin();
+ i != desc.scale_points->end();
+ ++i) {
+ if (i->second == v) {
+ return i->first; // Found it, return scale point label
+ }
+ }
+ }
+
+ // Value is not a scale point, print it normally
+ if (desc.unit == Evoral::ParameterDescriptor::MIDI_NOTE) {
+ if (v >= 0 && v <= 127) {
+ const int num = rint(v);
+ static const char names[12][3] = {
+ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
+ };
+ snprintf(buf, sizeof(buf), "%s %d", names[num % 12], (num / 12) - 2);
+ } else {
+ // Odd, invalid range, just print the number
+ snprintf(buf, sizeof(buf), "%.0f", v);
+ }
+ } else if (!desc.print_fmt.empty()) {
+ snprintf(buf, sizeof(buf), desc.print_fmt.c_str(), v);
+ } else if (desc.integer_step) {
+ snprintf(buf, sizeof(buf), "%d", (int)v);
+ } else {
+ snprintf(buf, sizeof(buf), "%.3f", v);
+ }
+ if (desc.print_fmt.empty() && desc.unit == Evoral::ParameterDescriptor::DB) {
+ // TODO: Move proper dB printing from AutomationLine here
+ return std::string(buf) + " dB";
+ }
+ return buf;
+}
+
+std::string
+value_as_string(const Evoral::ParameterDescriptor& desc,
+ const Evoral::Variant& val)
+{
+ // Only numeric support, for now
+ return value_as_string(desc, val.to_double());
+}
+
+} // namespace ARDOUR
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 0abeb865a4..beca18f0e5 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -141,6 +141,7 @@ libardour_sources = [
'panner.cc',
'panner_manager.cc',
'panner_shell.cc',
+ 'parameter_descriptor.cc',
'pcm_utils.cc',
'playlist.cc',
'playlist_factory.cc',