Support pretty display of arbitrary plugin parameter units.
authorDavid Robillard <d@drobilla.net>
Sun, 2 Nov 2014 06:59:18 +0000 (01:59 -0500)
committerDavid Robillard <d@drobilla.net>
Sun, 2 Nov 2014 07:10:24 +0000 (02:10 -0500)
Try e.g. fomp:cs_chorus1 which has Hz and ms controls.

libs/ardour/ardour/parameter_descriptor.h
libs/ardour/ardour/value_as_string.h
libs/ardour/lv2_plugin.cc

index 1576230b8fb3427f81ef25aa02d5a70f1656efce..379d97ef3e190a4f36c6e25b365fe9b319bc1dbd 100644 (file)
@@ -101,6 +101,7 @@ struct ParameterDescriptor
        }
 
        std::string                    label;
+       std::string                    print_fmt;  ///< format string for pretty printing
        boost::shared_ptr<ScalePoints> scale_points;
        uint32_t                       key;  ///< for properties
        Variant::Type                  datatype;  ///< for properties
index 6c17ace5d3baba3f0140ae99e684701ab193a47c..e8361bf117e2c9f8396a1662043ba52c3e0eb657 100644 (file)
@@ -56,6 +56,8 @@ value_as_string(const ARDOUR::ParameterDescriptor& desc,
                        // 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 {
index dca91fd646b857cf8ff10cc63d887aa1bd061fb8..7fe97ddb30bb3cbed0bfe90d5e8efc67d4a28056 100644 (file)
@@ -141,6 +141,7 @@ public:
        LilvNode* ui_externalkx;
        LilvNode* units_db;
        LilvNode* units_unit;
+       LilvNode* units_render;
        LilvNode* units_midiNote;
        LilvNode* patch_writable;
        LilvNode* patch_Message;
@@ -1313,6 +1314,23 @@ LV2Plugin::get_property_descriptor(uint32_t id) const
        return Plugin::get_property_descriptor(id);
 }
 
+static void
+load_parameter_descriptor_units(LilvWorld* lworld, ParameterDescriptor& desc, const LilvNodes* units)
+{
+       if (lilv_nodes_contains(units, _world.units_midiNote)) {
+               desc.unit = ParameterDescriptor::MIDI_NOTE;
+       } else if (lilv_nodes_contains(units, _world.units_db)) {
+               desc.unit = ParameterDescriptor::DB;
+       } else if (lilv_nodes_size(units) > 0) {
+               const LilvNode* unit = lilv_nodes_get_first(units);
+               LilvNode* render = lilv_world_get(lworld, unit, _world.units_render, NULL);
+               if (render) {
+                       desc.print_fmt = lilv_node_as_string(render);
+                       lilv_node_free(render);
+               }
+       }
+}
+
 static void
 load_parameter_descriptor(LV2World&            world,
                           ParameterDescriptor& desc,
@@ -1324,6 +1342,7 @@ load_parameter_descriptor(LV2World&            world,
        LilvNode*  def     = lilv_world_get(lworld, subject, _world.lv2_default, NULL);
        LilvNode*  minimum = lilv_world_get(lworld, subject, _world.lv2_minimum, NULL);
        LilvNode*  maximum = lilv_world_get(lworld, subject, _world.lv2_maximum, NULL);
+       LilvNodes* units   = lilv_world_find_nodes(lworld, subject, _world.units_unit, NULL);
        if (label) {
                desc.label = lilv_node_as_string(label);
        }
@@ -1336,15 +1355,17 @@ load_parameter_descriptor(LV2World&            world,
        if (maximum && lilv_node_is_float(maximum)) {
                desc.upper = lilv_node_as_float(maximum);
        }
+       load_parameter_descriptor_units(lworld, desc, units);
        desc.datatype      = datatype;
        desc.toggled      |= datatype == Variant::BOOL;
        desc.integer_step |= datatype == Variant::INT || datatype == Variant::LONG;
-       if (lilv_world_ask(lworld, subject, _world.units_unit, _world.units_midiNote)) {
-               desc.unit = ParameterDescriptor::MIDI_NOTE;
-       } else if (lilv_world_ask(lworld, subject, _world.units_unit, _world.units_db)) {
-               desc.unit = ParameterDescriptor::DB;
-       }
        desc.update_steps();
+
+       lilv_nodes_free(units);
+       lilv_node_free(label);
+       lilv_node_free(def);
+       lilv_node_free(minimum);
+       lilv_node_free(maximum);
 }
 
 void
@@ -1577,11 +1598,7 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c
        desc.label        = lilv_node_as_string(lilv_port_get_name(_impl->plugin, port));
        desc.lower        = min ? lilv_node_as_float(min) : 0.0f;
        desc.upper        = max ? lilv_node_as_float(max) : 1.0f;
-       if (lilv_nodes_contains(portunits, _world.units_midiNote)) {
-               desc.unit = ParameterDescriptor::MIDI_NOTE;
-       } else if (lilv_nodes_contains(portunits, _world.units_db)) {
-               desc.unit = ParameterDescriptor::DB;
-       }
+       load_parameter_descriptor_units(_world.world, desc, portunits);
 
        if (desc.sr_dependent) {
                desc.lower *= _session.frame_rate ();
@@ -2280,6 +2297,7 @@ LV2World::LV2World()
        ui_external        = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
        ui_externalkx      = lilv_new_uri(world, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget");
        units_unit         = lilv_new_uri(world, LV2_UNITS__unit);
+       units_render       = lilv_new_uri(world, LV2_UNITS__render);
        units_midiNote     = lilv_new_uri(world, LV2_UNITS__midiNote);
        units_db           = lilv_new_uri(world, LV2_UNITS__db);
        patch_writable     = lilv_new_uri(world, LV2_PATCH__writable);
@@ -2293,6 +2311,7 @@ LV2World::~LV2World()
        lilv_node_free(units_midiNote);
        lilv_node_free(units_db);
        lilv_node_free(units_unit);
+       lilv_node_free(units_render);
        lilv_node_free(ui_externalkx);
        lilv_node_free(ui_external);
        lilv_node_free(ui_GtkUI);