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.
This commit is contained in:
parent
cb8abbe8d2
commit
767c0238a3
|
@ -3941,7 +3941,7 @@ Editor::cut_copy_points (CutCopyOp op)
|
|||
*/
|
||||
framepos_t start = std::numeric_limits<framepos_t>::max();
|
||||
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
|
||||
i->second.copy = i->first->create (i->first->parameter ());
|
||||
i->second.copy = i->first->create (i->first->parameter (), i->first->descriptor());
|
||||
|
||||
/* Calculate earliest start position of any point in selection. */
|
||||
start = std::min(start, i->second.line->session_position(i->first->begin()));
|
||||
|
|
|
@ -1265,7 +1265,7 @@ Selection::set_state (XMLNode const & node, int)
|
|||
RouteTimeAxisView* rtv = editor->get_route_view_by_route_id (id);
|
||||
|
||||
if (rtv) {
|
||||
boost::shared_ptr<AutomationTimeAxisView> atv = rtv->automation_child (EventTypeMap::instance().new_parameter (prop_parameter->value ()));
|
||||
boost::shared_ptr<AutomationTimeAxisView> atv = rtv->automation_child (EventTypeMap::instance().from_symbol (prop_parameter->value ()));
|
||||
|
||||
/* the automation could be for an entity that was never saved
|
||||
in the session file. Don't freak out if we can't find
|
||||
|
|
|
@ -763,6 +763,10 @@
|
|||
RelativePath="..\panner_shell.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\parameter_descriptor.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pcm_utils.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);
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
bool is_midi_parameter(const Evoral::Parameter& param);
|
||||
const Evoral::ParameterDescriptor& descriptor(const Evoral::Parameter& param) const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -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(const Evoral::Parameter& parameter);
|
||||
|
||||
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)
|
||||
{}
|
||||
ParameterDescriptor();
|
||||
|
||||
/* 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;
|
||||
|
||||
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
|
||||
*/
|
||||
}
|
||||
/** 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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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 (!control) {
|
||||
control = new AutomationControl(_a_session, param, desc);
|
||||
if (make_list && !list) {
|
||||
list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
|
||||
}
|
||||
|
||||
if (!control) {
|
||||
control = new AutomationControl(_a_session, param, desc, list);
|
||||
}
|
||||
|
||||
control->set_list(list);
|
||||
return boost::shared_ptr<Evoral::Control>(control);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ¶meter = _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 };
|
||||
|
|
|
@ -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
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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',
|
||||
|
|
|
@ -511,6 +511,10 @@
|
|||
RelativePath="..\evoral\Parameter.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\ParameterDescriptor.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\PatchChange.hpp"
|
||||
>
|
||||
|
|
|
@ -26,11 +26,14 @@
|
|||
|
||||
#include "evoral/visibility.h"
|
||||
#include "evoral/Parameter.hpp"
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
class ControlList;
|
||||
class ParameterDescriptor;
|
||||
class Transport;
|
||||
class TypeMap;
|
||||
|
||||
/** Base class representing some kind of (automatable) control; a fader's gain,
|
||||
* for example, or a compressor plugin's threshold.
|
||||
|
@ -38,11 +41,13 @@ class Transport;
|
|||
* The class knows the Evoral::Parameter that it is controlling, and has
|
||||
* a list of values for automation.
|
||||
*/
|
||||
|
||||
class LIBEVORAL_API Control
|
||||
{
|
||||
public:
|
||||
Control(const Parameter& parameter, boost::shared_ptr<ControlList>);
|
||||
Control(const Parameter& parameter,
|
||||
const ParameterDescriptor& desc,
|
||||
boost::shared_ptr<ControlList> list);
|
||||
|
||||
virtual ~Control() {}
|
||||
|
||||
virtual void set_double (double val, double frame=0, bool to_list=false);
|
||||
|
|
|
@ -34,10 +34,12 @@
|
|||
#include "evoral/types.hpp"
|
||||
#include "evoral/Range.hpp"
|
||||
#include "evoral/Parameter.hpp"
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
class Curve;
|
||||
class TypeMap;
|
||||
|
||||
/** A single event (time-stamped value) for a control
|
||||
*/
|
||||
|
@ -82,12 +84,12 @@ public:
|
|||
typedef EventList::const_iterator const_iterator;
|
||||
typedef EventList::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
ControlList (const Parameter& id);
|
||||
ControlList (const Parameter& id, const ParameterDescriptor& desc);
|
||||
ControlList (const ControlList&);
|
||||
ControlList (const ControlList&, double start, double end);
|
||||
virtual ~ControlList();
|
||||
|
||||
virtual boost::shared_ptr<ControlList> create(Parameter id);
|
||||
virtual boost::shared_ptr<ControlList> create(const Parameter& id, const ParameterDescriptor& desc);
|
||||
|
||||
void dump (std::ostream&);
|
||||
|
||||
|
@ -102,6 +104,9 @@ public:
|
|||
const Parameter& parameter() const { return _parameter; }
|
||||
void set_parameter(const Parameter& p) { _parameter = p; }
|
||||
|
||||
const ParameterDescriptor& descriptor() const { return _desc; }
|
||||
void set_descriptor(const ParameterDescriptor& d) { _desc = d; }
|
||||
|
||||
EventList::size_type size() const { return _events.size(); }
|
||||
double length() const {
|
||||
Glib::Threads::Mutex::Lock lm (_lock);
|
||||
|
@ -218,7 +223,7 @@ public:
|
|||
};
|
||||
|
||||
const EventList& events() const { return _events; }
|
||||
double default_value() const { return _parameter.normal(); }
|
||||
double default_value() const { return _default_value; }
|
||||
|
||||
// FIXME: const violations for Curve
|
||||
Glib::Threads::Mutex& lock() const { return _lock; }
|
||||
|
@ -288,10 +293,12 @@ protected:
|
|||
mutable LookupCache _lookup_cache;
|
||||
mutable SearchCache _search_cache;
|
||||
|
||||
mutable Glib::Threads::Mutex _lock;
|
||||
|
||||
Parameter _parameter;
|
||||
ParameterDescriptor _desc;
|
||||
InterpolationStyle _interpolation;
|
||||
EventList _events;
|
||||
mutable Glib::Threads::Mutex _lock;
|
||||
int8_t _frozen;
|
||||
bool _changed_when_thawed;
|
||||
double _min_yval;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
namespace Evoral {
|
||||
|
||||
|
||||
/** ID of a [play|record|automate]able parameter.
|
||||
*
|
||||
* A parameter is defined by (type, id, channel). Type is an integer which
|
||||
|
@ -41,12 +40,10 @@ namespace Evoral {
|
|||
class LIBEVORAL_API Parameter
|
||||
{
|
||||
public:
|
||||
Parameter(uint32_t type, uint8_t channel=0, uint32_t id=0)
|
||||
inline Parameter(uint32_t type, uint8_t channel=0, uint32_t id=0)
|
||||
: _type(type), _id(id), _channel(channel)
|
||||
{}
|
||||
|
||||
virtual ~Parameter() {}
|
||||
|
||||
inline uint32_t type() const { return _type; }
|
||||
inline uint8_t channel() const { return _channel; }
|
||||
inline uint32_t id() const { return _id; }
|
||||
|
@ -78,52 +75,12 @@ public:
|
|||
|
||||
inline operator bool() const { return (_type != 0); }
|
||||
|
||||
/** Not used in indentity/comparison */
|
||||
struct Metadata {
|
||||
Metadata(double low=0.0, double high=1.0, double mid=0.0, bool tog=false)
|
||||
: min(low), max(high), normal(mid), toggled(tog)
|
||||
{}
|
||||
double min;
|
||||
double max;
|
||||
double normal;
|
||||
bool toggled;
|
||||
};
|
||||
|
||||
inline static void set_range(uint32_t type, double min, double max, double normal, bool toggled) {
|
||||
_type_metadata[type] = Metadata(min, max, normal, toggled);
|
||||
}
|
||||
|
||||
inline void set_range(double min, double max, double normal, bool toggled) {
|
||||
_metadata = boost::shared_ptr<Metadata>(new Metadata(min, max, normal, toggled));
|
||||
}
|
||||
|
||||
inline Metadata& metadata() const {
|
||||
if (_metadata)
|
||||
return *_metadata.get();
|
||||
else
|
||||
return _type_metadata[_type];
|
||||
}
|
||||
|
||||
inline double min() const { return metadata().min; }
|
||||
inline double max() const { return metadata().max; }
|
||||
inline double normal() const { return metadata().normal; }
|
||||
inline double toggled() const { return metadata().toggled; }
|
||||
|
||||
protected:
|
||||
// Default copy constructor is ok
|
||||
|
||||
// ID (used in comparison)
|
||||
private:
|
||||
uint32_t _type;
|
||||
uint32_t _id;
|
||||
uint8_t _channel;
|
||||
|
||||
boost::shared_ptr<Metadata> _metadata;
|
||||
|
||||
typedef std::map<uint32_t, Metadata> TypeMetadata;
|
||||
static TypeMetadata _type_metadata;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Evoral
|
||||
|
||||
#endif // EVORAL_PARAMETER_HPP
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* This file is part of Evoral.
|
||||
* Copyright (C) 2000-2014 Paul Davis
|
||||
* Author: David Robillard
|
||||
*
|
||||
* Evoral 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.
|
||||
*
|
||||
* Evoral 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef EVORAL_PARAMETER_DESCRIPTOR_HPP
|
||||
#define EVORAL_PARAMETER_DESCRIPTOR_HPP
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
/** Description of the value range of a parameter or control. */
|
||||
struct ParameterDescriptor
|
||||
{
|
||||
ParameterDescriptor()
|
||||
: normal(0.0)
|
||||
, lower(0.0)
|
||||
, upper(0.0)
|
||||
, toggled(false)
|
||||
{}
|
||||
|
||||
float normal; ///< Default value
|
||||
float lower; ///< Minimum value (in Hz, for frequencies)
|
||||
float upper; ///< Maximum value (in Hz, for frequencies)
|
||||
bool toggled; ///< True iff parameter is boolean
|
||||
};
|
||||
|
||||
} // namespace Evoral
|
||||
|
||||
#endif // EVORAL_PARAMETER_DESCRIPTOR_HPP
|
|
@ -30,13 +30,13 @@
|
|||
#include "evoral/visibility.h"
|
||||
#include "evoral/types.hpp"
|
||||
#include "evoral/Note.hpp"
|
||||
#include "evoral/Parameter.hpp"
|
||||
#include "evoral/ControlSet.hpp"
|
||||
#include "evoral/ControlList.hpp"
|
||||
#include "evoral/PatchChange.hpp"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
class Parameter;
|
||||
class TypeMap;
|
||||
template<typename Time> class EventSink;
|
||||
template<typename Time> class Note;
|
||||
|
@ -109,6 +109,8 @@ public:
|
|||
|
||||
void append(const Event<Time>& ev, Evoral::event_id_t evid);
|
||||
|
||||
const TypeMap& type_map() const { return _type_map; }
|
||||
|
||||
inline size_t n_notes() const { return _notes.size(); }
|
||||
inline bool empty() const { return _notes.empty() && _sysexes.empty() && _patch_changes.empty() && ControlSet::controls_empty(); }
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
namespace Evoral {
|
||||
|
||||
class Parameter;
|
||||
class ParameterDescriptor;
|
||||
|
||||
/** The applications passes one of these which provide the implementation
|
||||
* with required information about event types in an opaque, type neutral way
|
||||
|
@ -50,11 +51,8 @@ public:
|
|||
*/
|
||||
virtual uint32_t midi_event_type(uint8_t status) const = 0;
|
||||
|
||||
/** Return true iff parameter should be locked to integer boundaries */
|
||||
virtual bool is_integer(const Evoral::Parameter& param) const = 0;
|
||||
|
||||
/** Create a parameter with the given type ID */
|
||||
virtual Parameter new_parameter(uint32_t type, uint8_t channel, uint32_t id) const = 0;
|
||||
/** Return the description of a parameter. */
|
||||
virtual const ParameterDescriptor& descriptor(const Parameter& param) const = 0;
|
||||
|
||||
virtual std::string to_symbol(const Parameter& param) const = 0;
|
||||
};
|
||||
|
|
|
@ -22,14 +22,16 @@
|
|||
|
||||
#include "evoral/Control.hpp"
|
||||
#include "evoral/ControlList.hpp"
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
#include "evoral/TypeMap.hpp"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
Parameter::TypeMetadata Parameter::_type_metadata;
|
||||
|
||||
Control::Control(const Parameter& parameter, boost::shared_ptr<ControlList> list)
|
||||
Control::Control(const Parameter& parameter,
|
||||
const ParameterDescriptor& desc,
|
||||
boost::shared_ptr<ControlList> list)
|
||||
: _parameter(parameter)
|
||||
, _user_value(list ? list->default_value() : parameter.normal())
|
||||
, _user_value(list ? list->default_value() : desc.normal)
|
||||
{
|
||||
set_list (list);
|
||||
}
|
||||
|
|
|
@ -28,10 +28,14 @@
|
|||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "evoral/ControlList.hpp"
|
||||
#include "evoral/Curve.hpp"
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
#include "evoral/TypeMap.hpp"
|
||||
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/debug.h"
|
||||
|
@ -46,16 +50,17 @@ inline bool event_time_less_than (ControlEvent* a, ControlEvent* b)
|
|||
return a->when < b->when;
|
||||
}
|
||||
|
||||
ControlList::ControlList (const Parameter& id)
|
||||
ControlList::ControlList (const Parameter& id, const ParameterDescriptor& desc)
|
||||
: _parameter(id)
|
||||
, _interpolation(id.toggled() ? Discrete : Linear)
|
||||
, _desc(desc)
|
||||
, _curve(0)
|
||||
{
|
||||
_interpolation = desc.toggled ? Discrete : Linear;
|
||||
_frozen = 0;
|
||||
_changed_when_thawed = false;
|
||||
_min_yval = id.min();
|
||||
_max_yval = id.max();
|
||||
_default_value = id.normal();
|
||||
_min_yval = desc.lower;
|
||||
_max_yval = desc.upper;
|
||||
_default_value = desc.normal;
|
||||
_lookup_cache.left = -1;
|
||||
_lookup_cache.range.first = _events.end();
|
||||
_lookup_cache.range.second = _events.end();
|
||||
|
@ -71,6 +76,7 @@ ControlList::ControlList (const Parameter& id)
|
|||
|
||||
ControlList::ControlList (const ControlList& other)
|
||||
: _parameter(other._parameter)
|
||||
, _desc(other._desc)
|
||||
, _interpolation(other._interpolation)
|
||||
, _curve(0)
|
||||
{
|
||||
|
@ -96,6 +102,7 @@ ControlList::ControlList (const ControlList& other)
|
|||
|
||||
ControlList::ControlList (const ControlList& other, double start, double end)
|
||||
: _parameter(other._parameter)
|
||||
, _desc(other._desc)
|
||||
, _interpolation(other._interpolation)
|
||||
, _curve(0)
|
||||
{
|
||||
|
@ -136,9 +143,9 @@ ControlList::~ControlList()
|
|||
}
|
||||
|
||||
boost::shared_ptr<ControlList>
|
||||
ControlList::create(Parameter id)
|
||||
ControlList::create(const Parameter& id, const ParameterDescriptor& desc)
|
||||
{
|
||||
return boost::shared_ptr<ControlList>(new ControlList(id));
|
||||
return boost::shared_ptr<ControlList>(new ControlList(id, desc));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1503,7 +1510,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, do
|
|||
boost::shared_ptr<ControlList>
|
||||
ControlList::cut_copy_clear (double start, double end, int op)
|
||||
{
|
||||
boost::shared_ptr<ControlList> nal = create (_parameter);
|
||||
boost::shared_ptr<ControlList> nal = create (_parameter, _desc);
|
||||
iterator s, e;
|
||||
ControlEvent cp (start, 0.0);
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* This file is part of Evoral.
|
||||
* Copyright (C) 2000-2014 Paul Davis
|
||||
* Author: David Robillard
|
||||
*
|
||||
* Evoral 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.
|
||||
*
|
||||
* Evoral 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
ParameterDescriptor::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
|
||||
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 Evoral
|
|
@ -35,6 +35,7 @@
|
|||
#include "evoral/ControlList.hpp"
|
||||
#include "evoral/ControlSet.hpp"
|
||||
#include "evoral/EventSink.hpp"
|
||||
#include "evoral/ParameterDescriptor.hpp"
|
||||
#include "evoral/Sequence.hpp"
|
||||
#include "evoral/TypeMap.hpp"
|
||||
#include "evoral/midi_util.h"
|
||||
|
@ -140,9 +141,10 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
|
|||
|
||||
assert(x >= 0);
|
||||
|
||||
if (y < i->first.min() || y > i->first.max()) {
|
||||
const ParameterDescriptor& desc = seq.type_map().descriptor(i->first);
|
||||
if (y < desc.lower || y > desc.upper) {
|
||||
cerr << "ERROR: Controller value " << y
|
||||
<< " out of range [" << i->first.min() << "," << i->first.max()
|
||||
<< " out of range [" << desc.lower << "," << desc.upper
|
||||
<< "], event ignored" << endl;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -39,14 +39,6 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
bool is_integer (const Parameter& /*param*/) const { return true; }
|
||||
|
||||
Parameter new_parameter(uint32_t type, uint8_t channel, uint32_t id) const {
|
||||
Parameter p(type, channel, id);
|
||||
p.set_range(type, 0.0f, 1.0f, 0.0f);
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string to_symbol(const Parameter& /*param*/) const { return "control"; }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue