2 * Copyright (C) 2009-2016 David Robillard <d@drobilla.net>
3 * Copyright (C) 2010-2017 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2016-2019 Robin Gareus <robin@gareus.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "pbd/error.h"
30 #include "ardour/uri_map.h"
31 #include "ardour/lv2_extensions.h"
35 URIMap* URIMap::uri_map;
38 URIMap::URIDs::init(URIMap& uri_map)
40 // Use string literals here instead of LV2 defines to avoid LV2 dependency
41 atom_Chunk = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Chunk");
42 atom_Path = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Path");
43 atom_Sequence = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Sequence");
44 atom_eventTransfer = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#eventTransfer");
45 atom_URID = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#URID");
46 atom_Blank = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Blank");
47 atom_Object = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Object");
48 atom_Float = uri_map.uri_to_id("http://lv2plug.in/ns/ext/atom#Float");
49 log_Error = uri_map.uri_to_id("http://lv2plug.in/ns/ext/log#Error");
50 log_Note = uri_map.uri_to_id("http://lv2plug.in/ns/ext/log#Note");
51 log_Trace = uri_map.uri_to_id("http://lv2plug.in/ns/ext/log#Trace");
52 log_Warning = uri_map.uri_to_id("http://lv2plug.in/ns/ext/log#Warning");
53 midi_MidiEvent = uri_map.uri_to_id("http://lv2plug.in/ns/ext/midi#MidiEvent");
54 time_Position = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#Position");
55 time_bar = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#bar");
56 time_barBeat = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#barBeat");
57 time_beatUnit = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#beatUnit");
58 time_beatsPerBar = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#beatsPerBar");
59 time_beatsPerMinute = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#beatsPerMinute");
60 time_frame = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#frame");
61 time_speed = uri_map.uri_to_id("http://lv2plug.in/ns/ext/time#speed");
62 patch_Get = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#Get");
63 patch_Set = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#Set");
64 patch_property = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#property");
65 patch_value = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#value");
66 state_StateChanged = uri_map.uri_to_id("http://lv2plug.in/ns/ext/state#StateChanged"); // since LV2 1.15.1
68 auto_event = uri_map.uri_to_id(LV2_AUTOMATE_URI__event);
69 auto_setup = uri_map.uri_to_id(LV2_AUTOMATE_URI__setup);
70 auto_finalize = uri_map.uri_to_id(LV2_AUTOMATE_URI__finalize);
71 auto_start = uri_map.uri_to_id(LV2_AUTOMATE_URI__start);
72 auto_end = uri_map.uri_to_id(LV2_AUTOMATE_URI__end);
73 auto_parameter = uri_map.uri_to_id(LV2_AUTOMATE_URI__parameter);
74 auto_value = uri_map.uri_to_id(LV2_AUTOMATE_URI__value);
81 if (!URIMap::uri_map) {
82 URIMap::uri_map = new URIMap();
84 return *URIMap::uri_map;
88 c_uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data,
92 URIMap* const me = (URIMap*)callback_data;
93 const uint32_t id = me->uri_to_id(uri);
95 /* The event context with the uri-map extension guarantees a value in the
96 range of uint16_t. Ardour used to map to a separate range to achieve
97 this, but unfortunately some plugins are broken and use the incorrect
98 context. To compensate, we simply use the same context for everything
99 and hope that anything in the event context gets mapped before
100 UINT16_MAX is reached (which will be fine unless something seriously
101 weird is going on). If this fails there is nothing we can do, die.
103 assert(!map || strcmp(map, "http://lv2plug.in/ns/ext/event")
110 c_urid_map(LV2_URID_Map_Handle handle,
113 URIMap* const me = (URIMap*)handle;
114 return me->uri_to_id(uri);
118 c_urid_unmap(LV2_URID_Unmap_Handle handle,
121 URIMap* const me = (URIMap*)handle;
122 return me->id_to_uri(urid);
127 _uri_map_feature_data.uri_to_id = c_uri_map_uri_to_id;
128 _uri_map_feature_data.callback_data = this;
129 _uri_map_feature.URI = LV2_URI_MAP_URI;
130 _uri_map_feature.data = &_uri_map_feature_data;
132 _urid_map_feature_data.map = c_urid_map;
133 _urid_map_feature_data.handle = this;
134 _urid_map_feature.URI = LV2_URID_MAP_URI;
135 _urid_map_feature.data = &_urid_map_feature_data;
137 _urid_unmap_feature_data.unmap = c_urid_unmap;
138 _urid_unmap_feature_data.handle = this;
139 _urid_unmap_feature.URI = LV2_URID_UNMAP_URI;
140 _urid_unmap_feature.data = &_urid_unmap_feature_data;
146 URIMap::uri_to_id(const char* uri)
148 Glib::Threads::Mutex::Lock lm (_lock);
150 const std::string urimm(uri);
151 const Map::const_iterator i = _map.find(urimm);
152 if (i != _map.end()) {
155 const uint32_t id = _map.size() + 1;
156 _map.insert(std::make_pair(urimm, id));
157 _unmap.insert(std::make_pair(id, urimm));
162 URIMap::id_to_uri(const uint32_t id) const
164 Glib::Threads::Mutex::Lock lm (_lock);
166 const Unmap::const_iterator i = _unmap.find(id);
167 return (i != _unmap.end()) ? i->second.c_str() : NULL;
170 } // namespace ARDOUR