Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoPluginCarla.cpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |
4 * | |
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
6 * or without fee is hereby granted, provided that the above copyright notice and this | |
7 * permission notice appear in all copies. | |
8 * | |
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #include "DistrhoPluginInternal.hpp" | |
18 | |
19 #if DISTRHO_PLUGIN_HAS_UI | |
20 # include "DistrhoUIInternal.hpp" | |
21 #endif | |
22 | |
23 #include "CarlaNative.hpp" | |
24 | |
25 // TODO | |
26 #undef DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST | |
27 #define DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST 0 | |
28 | |
29 // ----------------------------------------------------------------------- | |
30 | |
31 START_NAMESPACE_DISTRHO | |
32 | |
33 #if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |
34 static constexpr const writeMidiFunc writeMidiCallback = nullptr; | |
35 #endif | |
36 #if ! DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST | |
37 static constexpr const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr; | |
38 #endif | |
39 // TODO | |
40 static constexpr const updateStateValueFunc updateStateValueCallback = nullptr; | |
41 | |
42 #if DISTRHO_PLUGIN_HAS_UI | |
43 // ----------------------------------------------------------------------- | |
44 // Carla UI | |
45 | |
46 #if ! DISTRHO_PLUGIN_WANT_STATE | |
47 static const setStateFunc setStateCallback = nullptr; | |
48 #endif | |
49 #if ! DISTRHO_PLUGIN_IS_SYNTH | |
50 static const sendNoteFunc sendNoteCallback = nullptr; | |
51 #endif | |
52 | |
53 class UICarla | |
54 { | |
55 public: | |
56 UICarla(const NativeHostDescriptor* const host, PluginExporter* const plugin) | |
57 : fHost(host), | |
58 fUI(this, 0, plugin->getSampleRate(), | |
59 editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, | |
60 nullptr, // window size | |
61 nullptr, // TODO file request | |
62 nullptr, // bundle path | |
63 plugin->getInstancePointer()) | |
64 { | |
65 fUI.setWindowTitle(host->uiName); | |
66 | |
67 if (host->uiParentId != 0) | |
68 fUI.setWindowTransientWinId(host->uiParentId); | |
69 } | |
70 | |
71 ~UICarla() | |
72 { | |
73 fUI.quit(); | |
74 } | |
75 | |
76 // --------------------------------------------- | |
77 | |
78 void carla_show(const bool yesNo) | |
79 { | |
80 fUI.setWindowVisible(yesNo); | |
81 } | |
82 | |
83 bool carla_idle() | |
84 { | |
85 return fUI.plugin_idle(); | |
86 } | |
87 | |
88 void carla_setParameterValue(const uint32_t index, const float value) | |
89 { | |
90 fUI.parameterChanged(index, value); | |
91 } | |
92 | |
93 #if DISTRHO_PLUGIN_WANT_PROGRAMS | |
94 void carla_setMidiProgram(const uint32_t realProgram) | |
95 { | |
96 fUI.programLoaded(realProgram); | |
97 } | |
98 #endif | |
99 | |
100 #if DISTRHO_PLUGIN_WANT_STATE | |
101 void carla_setCustomData(const char* const key, const char* const value) | |
102 { | |
103 fUI.stateChanged(key, value); | |
104 } | |
105 #endif | |
106 | |
107 void carla_setUiTitle(const char* const uiTitle) | |
108 { | |
109 fUI.setWindowTitle(uiTitle); | |
110 } | |
111 | |
112 // --------------------------------------------- | |
113 | |
114 protected: | |
115 void handleEditParameter(const uint32_t, const bool) | |
116 { | |
117 // TODO | |
118 } | |
119 | |
120 void handleSetParameterValue(const uint32_t rindex, const float value) | |
121 { | |
122 fHost->ui_parameter_changed(fHost->handle, rindex, value); | |
123 } | |
124 | |
125 #if DISTRHO_PLUGIN_WANT_STATE | |
126 void handleSetState(const char* const key, const char* const value) | |
127 { | |
128 fHost->ui_custom_data_changed(fHost->handle, key, value); | |
129 } | |
130 #endif | |
131 | |
132 #if DISTRHO_PLUGIN_IS_SYNTH | |
133 void handleSendNote(const uint8_t, const uint8_t, const uint8_t) | |
134 { | |
135 // TODO | |
136 } | |
137 #endif | |
138 | |
139 // --------------------------------------------- | |
140 | |
141 private: | |
142 // Plugin stuff | |
143 const NativeHostDescriptor* const fHost; | |
144 | |
145 // UI | |
146 UIExporter fUI; | |
147 | |
148 // --------------------------------------------- | |
149 // Callbacks | |
150 | |
151 #define handlePtr ((UICarla*)ptr) | |
152 | |
153 static void editParameterCallback(void* ptr, uint32_t index, bool started) | |
154 { | |
155 handlePtr->handleEditParameter(index, started); | |
156 } | |
157 | |
158 static void setParameterCallback(void* ptr, uint32_t rindex, float value) | |
159 { | |
160 handlePtr->handleSetParameterValue(rindex, value); | |
161 } | |
162 | |
163 #if DISTRHO_PLUGIN_WANT_STATE | |
164 static void setStateCallback(void* ptr, const char* key, const char* value) | |
165 { | |
166 handlePtr->handleSetState(key, value); | |
167 } | |
168 #endif | |
169 | |
170 #if DISTRHO_PLUGIN_IS_SYNTH | |
171 static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity) | |
172 { | |
173 handlePtr->handleSendNote(channel, note, velocity); | |
174 } | |
175 #endif | |
176 | |
177 #undef handlePtr | |
178 | |
179 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UICarla) | |
180 }; | |
181 #endif // DISTRHO_PLUGIN_HAS_UI | |
182 | |
183 // ----------------------------------------------------------------------- | |
184 // Carla Plugin | |
185 | |
186 class PluginCarla : public NativePluginClass | |
187 { | |
188 public: | |
189 PluginCarla(const NativeHostDescriptor* const host) | |
190 : NativePluginClass(host), | |
191 fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback), | |
192 fScalePointsCache(nullptr) | |
193 { | |
194 #if DISTRHO_PLUGIN_HAS_UI | |
195 fUiPtr = nullptr; | |
196 #endif | |
197 } | |
198 | |
199 ~PluginCarla() override | |
200 { | |
201 #if DISTRHO_PLUGIN_HAS_UI | |
202 if (fUiPtr != nullptr) | |
203 { | |
204 delete fUiPtr; | |
205 fUiPtr = nullptr; | |
206 } | |
207 #endif | |
208 | |
209 if (fScalePointsCache != nullptr) | |
210 { | |
211 delete[] fScalePointsCache; | |
212 fScalePointsCache = nullptr; | |
213 } | |
214 } | |
215 | |
216 protected: | |
217 // ------------------------------------------------------------------- | |
218 // Plugin parameter calls | |
219 | |
220 uint32_t getParameterCount() const override | |
221 { | |
222 return fPlugin.getParameterCount(); | |
223 } | |
224 | |
225 const NativeParameter* getParameterInfo(const uint32_t index) const override | |
226 { | |
227 CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(), nullptr); | |
228 | |
229 static NativeParameter param; | |
230 | |
231 param.scalePointCount = 0; | |
232 param.scalePoints = nullptr; | |
233 | |
234 { | |
235 int nativeParamHints = ::NATIVE_PARAMETER_IS_ENABLED; | |
236 const uint32_t paramHints = fPlugin.getParameterHints(index); | |
237 | |
238 if (paramHints & kParameterIsAutomatable) | |
239 nativeParamHints |= ::NATIVE_PARAMETER_IS_AUTOMABLE; | |
240 if (paramHints & kParameterIsBoolean) | |
241 nativeParamHints |= ::NATIVE_PARAMETER_IS_BOOLEAN; | |
242 if (paramHints & kParameterIsInteger) | |
243 nativeParamHints |= ::NATIVE_PARAMETER_IS_INTEGER; | |
244 if (paramHints & kParameterIsLogarithmic) | |
245 nativeParamHints |= ::NATIVE_PARAMETER_IS_LOGARITHMIC; | |
246 if (paramHints & kParameterIsOutput) | |
247 nativeParamHints |= ::NATIVE_PARAMETER_IS_OUTPUT; | |
248 | |
249 param.hints = static_cast<NativeParameterHints>(nativeParamHints); | |
250 } | |
251 | |
252 param.name = fPlugin.getParameterName(index); | |
253 param.unit = fPlugin.getParameterUnit(index); | |
254 | |
255 { | |
256 const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); | |
257 | |
258 param.ranges.def = ranges.def; | |
259 param.ranges.min = ranges.min; | |
260 param.ranges.max = ranges.max; | |
261 } | |
262 | |
263 { | |
264 const ParameterEnumerationValues& enumValues(fPlugin.getParameterEnumValues(index)); | |
265 | |
266 if (const uint32_t scalePointCount = enumValues.count) | |
267 { | |
268 NativeParameterScalePoint* const scalePoints = new NativeParameterScalePoint[scalePointCount]; | |
269 | |
270 for (uint32_t i=0; i<scalePointCount; ++i) | |
271 { | |
272 scalePoints[i].label = enumValues.values[i].label.buffer(); | |
273 scalePoints[i].value = enumValues.values[i].value; | |
274 } | |
275 | |
276 param.scalePoints = scalePoints; | |
277 param.scalePointCount = scalePointCount; | |
278 | |
279 if (enumValues.restrictedMode) | |
280 param.hints = static_cast<NativeParameterHints>(param.hints|::NATIVE_PARAMETER_USES_SCALEPOINTS); | |
281 } | |
282 else if (fScalePointsCache != nullptr) | |
283 { | |
284 delete[] fScalePointsCache; | |
285 fScalePointsCache = nullptr; | |
286 } | |
287 } | |
288 | |
289 return ¶m; | |
290 } | |
291 | |
292 float getParameterValue(const uint32_t index) const override | |
293 { | |
294 CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(), 0.0f); | |
295 | |
296 return fPlugin.getParameterValue(index); | |
297 } | |
298 | |
299 // ------------------------------------------------------------------- | |
300 // Plugin midi-program calls | |
301 | |
302 #if DISTRHO_PLUGIN_WANT_PROGRAMS | |
303 uint32_t getMidiProgramCount() const override | |
304 { | |
305 return fPlugin.getProgramCount(); | |
306 } | |
307 | |
308 const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const override | |
309 { | |
310 CARLA_SAFE_ASSERT_RETURN(index < getMidiProgramCount(), nullptr); | |
311 | |
312 static NativeMidiProgram midiProgram; | |
313 | |
314 midiProgram.bank = index / 128; | |
315 midiProgram.program = index % 128; | |
316 midiProgram.name = fPlugin.getProgramName(index); | |
317 | |
318 return &midiProgram; | |
319 } | |
320 #endif | |
321 | |
322 // ------------------------------------------------------------------- | |
323 // Plugin state calls | |
324 | |
325 void setParameterValue(const uint32_t index, const float value) override | |
326 { | |
327 CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); | |
328 | |
329 fPlugin.setParameterValue(index, value); | |
330 } | |
331 | |
332 #if DISTRHO_PLUGIN_WANT_PROGRAMS | |
333 void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override | |
334 { | |
335 const uint32_t realProgram(bank * 128 + program); | |
336 | |
337 CARLA_SAFE_ASSERT_RETURN(realProgram < getMidiProgramCount(),); | |
338 | |
339 fPlugin.loadProgram(realProgram); | |
340 } | |
341 #endif | |
342 | |
343 #if DISTRHO_PLUGIN_WANT_STATE | |
344 void setCustomData(const char* const key, const char* const value) override | |
345 { | |
346 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | |
347 CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | |
348 | |
349 fPlugin.setState(key, value); | |
350 } | |
351 #endif | |
352 | |
353 // ------------------------------------------------------------------- | |
354 // Plugin process calls | |
355 | |
356 void activate() override | |
357 { | |
358 fPlugin.activate(); | |
359 } | |
360 | |
361 void deactivate() override | |
362 { | |
363 fPlugin.deactivate(); | |
364 } | |
365 | |
366 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |
367 void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, | |
368 const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override | |
369 { | |
370 MidiEvent realMidiEvents[midiEventCount]; | |
371 | |
372 for (uint32_t i=0; i < midiEventCount; ++i) | |
373 { | |
374 const NativeMidiEvent& midiEvent(midiEvents[i]); | |
375 MidiEvent& realMidiEvent(realMidiEvents[i]); | |
376 | |
377 realMidiEvent.frame = midiEvent.time; | |
378 realMidiEvent.size = midiEvent.size; | |
379 | |
380 uint8_t j=0; | |
381 for (; j<midiEvent.size; ++j) | |
382 realMidiEvent.data[j] = midiEvent.data[j]; | |
383 for (; j<midiEvent.size; ++j) | |
384 realMidiEvent.data[j] = midiEvent.data[j]; | |
385 | |
386 realMidiEvent.dataExt = nullptr; | |
387 } | |
388 | |
389 fPlugin.run(const_cast<const float**>(inBuffer), outBuffer, frames, realMidiEvents, midiEventCount); | |
390 } | |
391 #else | |
392 void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, | |
393 const NativeMidiEvent* const, const uint32_t) override | |
394 { | |
395 fPlugin.run(const_cast<const float**>(inBuffer), outBuffer, frames); | |
396 } | |
397 #endif | |
398 | |
399 // ------------------------------------------------------------------- | |
400 // Plugin UI calls | |
401 | |
402 #if DISTRHO_PLUGIN_HAS_UI | |
403 void uiShow(const bool show) override | |
404 { | |
405 if (show) | |
406 { | |
407 createUiIfNeeded(); | |
408 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
409 | |
410 fUiPtr->carla_show(show); | |
411 } | |
412 else if (fUiPtr != nullptr) | |
413 { | |
414 delete fUiPtr; | |
415 fUiPtr = nullptr; | |
416 } | |
417 } | |
418 | |
419 void uiIdle() override | |
420 { | |
421 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
422 | |
423 if (! fUiPtr->carla_idle()) | |
424 { | |
425 uiClosed(); | |
426 | |
427 delete fUiPtr; | |
428 fUiPtr = nullptr; | |
429 } | |
430 } | |
431 | |
432 void uiSetParameterValue(const uint32_t index, const float value) override | |
433 { | |
434 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
435 CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); | |
436 | |
437 fUiPtr->carla_setParameterValue(index, value); | |
438 } | |
439 | |
440 # if DISTRHO_PLUGIN_WANT_PROGRAMS | |
441 void uiSetMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override | |
442 { | |
443 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
444 | |
445 const uint32_t realProgram(bank * 128 + program); | |
446 | |
447 CARLA_SAFE_ASSERT_RETURN(realProgram < getMidiProgramCount(),); | |
448 | |
449 fUiPtr->carla_setMidiProgram(realProgram); | |
450 } | |
451 # endif | |
452 | |
453 # if DISTRHO_PLUGIN_WANT_STATE | |
454 void uiSetCustomData(const char* const key, const char* const value) override | |
455 { | |
456 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
457 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | |
458 CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | |
459 | |
460 fUiPtr->carla_setCustomData(key, value); | |
461 } | |
462 # endif | |
463 #endif | |
464 | |
465 // ------------------------------------------------------------------- | |
466 // Plugin dispatcher calls | |
467 | |
468 void bufferSizeChanged(const uint32_t bufferSize) override | |
469 { | |
470 fPlugin.setBufferSize(bufferSize, true); | |
471 } | |
472 | |
473 void sampleRateChanged(const double sampleRate) override | |
474 { | |
475 fPlugin.setSampleRate(sampleRate, true); | |
476 } | |
477 | |
478 #if DISTRHO_PLUGIN_HAS_UI | |
479 void uiNameChanged(const char* const uiName) override | |
480 { | |
481 CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); | |
482 | |
483 fUiPtr->carla_setUiTitle(uiName); | |
484 } | |
485 #endif | |
486 | |
487 // ------------------------------------------------------------------- | |
488 | |
489 private: | |
490 PluginExporter fPlugin; | |
491 mutable NativeParameterScalePoint* fScalePointsCache; | |
492 | |
493 #if DISTRHO_PLUGIN_HAS_UI | |
494 // UI | |
495 UICarla* fUiPtr; | |
496 | |
497 void createUiIfNeeded() | |
498 { | |
499 if (fUiPtr == nullptr) | |
500 fUiPtr = new UICarla(getHostHandle(), &fPlugin); | |
501 } | |
502 #endif | |
503 | |
504 #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |
505 static bool writeMidiCallback(void* ptr, const MidiEvent& midiEvent) | |
506 { | |
507 if (midiEvent.size > 4) | |
508 return; | |
509 | |
510 const NativeMidiEvent event = { | |
511 midiEvent.frame, 0, midiEvent.size, midiEvent.data | |
512 }; | |
513 | |
514 return ((PluginCarla*)ptr)->fPlugin.writeMidiEvent(midiEvent); | |
515 } | |
516 #endif | |
517 | |
518 #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST | |
519 bool requestParameterValueChange(const uint32_t index, const float value) | |
520 { | |
521 // TODO implementation | |
522 return false; | |
523 } | |
524 | |
525 static bool requestParameterValueChangeCallback(void* ptr, const uint32_t index, const float value) | |
526 { | |
527 return thisPtr->requestParameterValueChange(index, value); | |
528 } | |
529 #endif | |
530 | |
531 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginCarla) | |
532 | |
533 // ------------------------------------------------------------------- | |
534 | |
535 public: | |
536 static NativePluginHandle _instantiate(const NativeHostDescriptor* host) | |
537 { | |
538 d_nextBufferSize = host->get_buffer_size(host->handle); | |
539 d_nextSampleRate = host->get_sample_rate(host->handle); | |
540 return new PluginCarla(host); | |
541 } | |
542 | |
543 static void _cleanup(NativePluginHandle handle) | |
544 { | |
545 delete (PluginCarla*)handle; | |
546 } | |
547 }; | |
548 | |
549 END_NAMESPACE_DISTRHO | |
550 | |
551 // ----------------------------------------------------------------------- |