2 * Copyright (C) 2008-2016 David Robillard <d@drobilla.net>
3 * Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2009 Hans Baier <hansfbaier@googlemail.com>
5 * Copyright (C) 2010-2017 Paul Davis <paul@linuxaudiosystems.com>
6 * Copyright (C) 2015-2016 Robin Gareus <robin@gareus.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "ardour/types.h"
26 #include "ardour/event_type_map.h"
27 #include "ardour/parameter_descriptor.h"
28 #include "ardour/parameter_types.h"
30 #include "ardour/uri_map.h"
32 #include "evoral/Parameter.hpp"
33 #include "evoral/ParameterDescriptor.hpp"
34 #include "evoral/midi_events.h"
35 #include "pbd/error.h"
36 #include "pbd/compose.h"
42 EventTypeMap* EventTypeMap::event_type_map;
45 EventTypeMap::instance()
47 if (!EventTypeMap::event_type_map) {
49 EventTypeMap::event_type_map = new EventTypeMap(&URIMap::instance());
51 EventTypeMap::event_type_map = new EventTypeMap(NULL);
54 return *EventTypeMap::event_type_map;
58 EventTypeMap::type_is_midi(uint32_t type) const
60 return ARDOUR::parameter_is_midi((AutomationType)type);
64 EventTypeMap::parameter_midi_type(const Evoral::Parameter& param) const
66 return ARDOUR::parameter_midi_type((AutomationType)param.type());
70 EventTypeMap::midi_parameter_type(const uint8_t* buf, uint32_t len) const
72 return (uint32_t)ARDOUR::midi_parameter_type(buf[0]);
75 Evoral::ControlList::InterpolationStyle
76 EventTypeMap::interpolation_of(const Evoral::Parameter& param)
78 switch (param.type()) {
79 case MidiCCAutomation:
81 case MIDI_CTL_LSB_BANK:
82 case MIDI_CTL_MSB_BANK:
83 case MIDI_CTL_LSB_EFFECT1:
84 case MIDI_CTL_LSB_EFFECT2:
85 case MIDI_CTL_MSB_EFFECT1:
86 case MIDI_CTL_MSB_EFFECT2:
87 case MIDI_CTL_MSB_GENERAL_PURPOSE1:
88 case MIDI_CTL_MSB_GENERAL_PURPOSE2:
89 case MIDI_CTL_MSB_GENERAL_PURPOSE3:
90 case MIDI_CTL_MSB_GENERAL_PURPOSE4:
91 case MIDI_CTL_SUSTAIN:
92 case MIDI_CTL_PORTAMENTO:
93 case MIDI_CTL_SOSTENUTO:
94 case MIDI_CTL_SOFT_PEDAL:
95 case MIDI_CTL_LEGATO_FOOTSWITCH:
97 case MIDI_CTL_GENERAL_PURPOSE5:
98 case MIDI_CTL_GENERAL_PURPOSE6:
99 case MIDI_CTL_GENERAL_PURPOSE7:
100 case MIDI_CTL_GENERAL_PURPOSE8:
101 case MIDI_CTL_DATA_INCREMENT:
102 case MIDI_CTL_DATA_DECREMENT:
103 case MIDI_CTL_NONREG_PARM_NUM_LSB:
104 case MIDI_CTL_NONREG_PARM_NUM_MSB:
105 case MIDI_CTL_REGIST_PARM_NUM_LSB:
106 case MIDI_CTL_REGIST_PARM_NUM_MSB:
107 case MIDI_CTL_ALL_SOUNDS_OFF:
108 case MIDI_CTL_RESET_CONTROLLERS:
109 case MIDI_CTL_LOCAL_CONTROL_SWITCH:
110 case MIDI_CTL_ALL_NOTES_OFF:
111 case MIDI_CTL_OMNI_OFF:
112 case MIDI_CTL_OMNI_ON:
115 return Evoral::ControlList::Discrete; break;
117 return Evoral::ControlList::Linear; break;
120 case MidiPgmChangeAutomation: return Evoral::ControlList::Discrete; break;
121 case MidiChannelPressureAutomation: return Evoral::ControlList::Linear; break;
122 case MidiNotePressureAutomation: return Evoral::ControlList::Linear; break;
123 case MidiPitchBenderAutomation: return Evoral::ControlList::Linear; break;
124 default: assert(false);
126 return Evoral::ControlList::Linear; // Not reached, suppress warnings
130 EventTypeMap::from_symbol(const string& str) const
132 AutomationType p_type = NullAutomation;
133 uint8_t p_channel = 0;
137 p_type = GainAutomation;
138 } else if (str == "trim") {
139 p_type = TrimAutomation;
140 } else if (str == "solo") {
141 p_type = SoloAutomation;
142 } else if (str == "solo-iso") {
143 p_type = SoloIsolateAutomation;
144 } else if (str == "solo-safe") {
145 p_type = SoloSafeAutomation;
146 } else if (str == "mute") {
147 p_type = MuteAutomation;
148 } else if (str == "fadein") {
149 p_type = FadeInAutomation;
150 } else if (str == "fadeout") {
151 p_type = FadeOutAutomation;
152 } else if (str == "envelope") {
153 p_type = EnvelopeAutomation;
154 } else if (str == "pan-azimuth") {
155 p_type = PanAzimuthAutomation;
156 } else if (str == "pan-width") {
157 p_type = PanWidthAutomation;
158 } else if (str == "pan-elevation") {
159 p_type = PanElevationAutomation;
160 } else if (str == "pan-frontback") {
161 p_type = PanFrontBackAutomation;
162 } else if (str == "pan-lfe") {
163 p_type = PanLFEAutomation;
164 } else if (str == "rec-enable") {
165 p_type = RecEnableAutomation;
166 } else if (str == "rec-safe") {
167 p_type = RecSafeAutomation;
168 } else if (str == "phase") {
169 p_type = PhaseAutomation;
170 } else if (str == "monitor") {
171 p_type = MonitoringAutomation;
172 } else if (str == "pan-lfe") {
173 p_type = PanLFEAutomation;
174 } else if (str.length() > 10 && str.substr(0, 10) == "parameter-") {
175 p_type = PluginAutomation;
176 p_id = atoi(str.c_str()+10);
178 } else if (str.length() > 9 && str.substr(0, 9) == "property-") {
179 p_type = PluginPropertyAutomation;
180 const char* name = str.c_str() + 9;
181 if (isdigit(str.c_str()[0])) {
184 p_id = _uri_map->uri_to_id(name);
187 } else if (str.length() > 7 && str.substr(0, 7) == "midicc-") {
188 p_type = MidiCCAutomation;
189 uint32_t channel = 0;
190 sscanf(str.c_str(), "midicc-%d-%d", &channel, &p_id);
191 assert(channel < 16);
193 } else if (str.length() > 16 && str.substr(0, 16) == "midi-pgm-change-") {
194 p_type = MidiPgmChangeAutomation;
195 uint32_t channel = 0;
196 sscanf(str.c_str(), "midi-pgm-change-%d", &channel);
197 assert(channel < 16);
200 } else if (str.length() > 18 && str.substr(0, 18) == "midi-pitch-bender-") {
201 p_type = MidiPitchBenderAutomation;
202 uint32_t channel = 0;
203 sscanf(str.c_str(), "midi-pitch-bender-%d", &channel);
204 assert(channel < 16);
207 } else if (str.length() > 22 && str.substr(0, 22) == "midi-channel-pressure-") {
208 p_type = MidiChannelPressureAutomation;
209 uint32_t channel = 0;
210 sscanf(str.c_str(), "midi-channel-pressure-%d", &channel);
211 assert(channel < 16);
214 } else if (str.length() > 19 && str.substr(0, 19) == "midi-note-pressure-") {
215 p_type = MidiNotePressureAutomation;
216 uint32_t channel = 0;
217 sscanf(str.c_str(), "midi-note-pressure-%d-%d", &channel, &p_id);
218 assert(channel < 16);
222 PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
225 return Evoral::Parameter(p_type, p_channel, p_id);
228 /** Unique string representation, suitable as an XML property value.
229 * e.g. <AutomationList automation-id="whatthisreturns">
232 EventTypeMap::to_symbol(const Evoral::Parameter& param) const
234 AutomationType t = (AutomationType)param.type();
236 if (t == GainAutomation) {
238 } else if (t == TrimAutomation) {
240 } else if (t == PanAzimuthAutomation) {
241 return "pan-azimuth";
242 } else if (t == PanElevationAutomation) {
243 return "pan-elevation";
244 } else if (t == PanWidthAutomation) {
246 } else if (t == PanFrontBackAutomation) {
247 return "pan-frontback";
248 } else if (t == PanLFEAutomation) {
250 } else if (t == SoloAutomation) {
252 } else if (t == MuteAutomation) {
254 } else if (t == FadeInAutomation) {
256 } else if (t == FadeOutAutomation) {
258 } else if (t == EnvelopeAutomation) {
260 } else if (t == PhaseAutomation) {
262 } else if (t == SoloIsolateAutomation) {
264 } else if (t == SoloSafeAutomation) {
266 } else if (t == MonitoringAutomation) {
268 } else if (t == RecEnableAutomation) {
270 } else if (t == RecSafeAutomation) {
272 } else if (t == PluginAutomation) {
273 return std::string("parameter-") + PBD::to_string(param.id());
275 } else if (t == PluginPropertyAutomation) {
276 const char* uri = _uri_map->id_to_uri(param.id());
278 return std::string("property-") + uri;
280 return std::string("property-") + PBD::to_string(param.id());
283 } else if (t == MidiCCAutomation) {
284 return std::string("midicc-") + PBD::to_string (param.channel()) + "-" + PBD::to_string (param.id());
285 } else if (t == MidiPgmChangeAutomation) {
286 return std::string("midi-pgm-change-") + PBD::to_string(param.channel());
287 } else if (t == MidiPitchBenderAutomation) {
288 return std::string("midi-pitch-bender-") + PBD::to_string(param.channel());
289 } else if (t == MidiChannelPressureAutomation) {
290 return std::string("midi-channel-pressure-") + PBD::to_string(param.channel());
291 } else if (t == MidiNotePressureAutomation) {
292 return std::string ("midi-note-pressure-") + PBD::to_string (param.channel()) + "-" + PBD::to_string (param.id());
294 PBD::warning << "Uninitialized Parameter symbol() called." << endmsg;
299 Evoral::ParameterDescriptor
300 EventTypeMap::descriptor(const Evoral::Parameter& param) const
302 // Found an existing (perhaps custom) descriptor
303 Descriptors::const_iterator d = _descriptors.find(param);
304 if (d != _descriptors.end()) {
308 // Add default descriptor and return that
309 return ARDOUR::ParameterDescriptor(param);
313 EventTypeMap::set_descriptor(const Evoral::Parameter& param,
314 const Evoral::ParameterDescriptor& desc)
316 _descriptors.insert(std::make_pair(param, desc));
319 } // namespace ARDOUR