Cleanup
[carla.git] / source / backend / engine / CarlaEngineData.cpp
bloba2fb54608470ec03d9f1fd07e43e888533881d3e
1 /*
2 * Carla Plugin Host
3 * Copyright (C) 2011-2021 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "CarlaEngine.hpp"
19 #include "CarlaMathUtils.hpp"
20 #include "CarlaMIDI.h"
22 CARLA_BACKEND_START_NAMESPACE
24 // -----------------------------------------------------------------------
25 // EngineControlEvent
27 uint8_t EngineControlEvent::convertToMidiData(const uint8_t channel, uint8_t data[3]) const noexcept
29 switch (type)
31 case kEngineControlEventTypeNull:
32 break;
34 case kEngineControlEventTypeParameter:
35 CARLA_SAFE_ASSERT_RETURN(param < MAX_MIDI_VALUE, 0);
37 data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
39 if (MIDI_IS_CONTROL_BANK_SELECT(param))
41 data[1] = MIDI_CONTROL_BANK_SELECT;
42 if (midiValue >= 0)
43 data[2] = uint8_t(midiValue);
44 else
45 data[2] = uint8_t(carla_fixedValue<float>(0.0f, static_cast<float>(MAX_MIDI_VALUE-1), normalizedValue));
47 else
49 data[1] = static_cast<uint8_t>(param);
50 if (midiValue >= 0)
51 data[2] = uint8_t(midiValue);
52 else
53 data[2] = uint8_t(carla_fixedValue<float>(0.0f, 1.0f, normalizedValue) * static_cast<float>(MAX_MIDI_VALUE-1) + 0.5f);
55 return 3;
57 case kEngineControlEventTypeMidiBank:
58 data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
59 data[1] = MIDI_CONTROL_BANK_SELECT;
60 data[2] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
61 return 3;
63 case kEngineControlEventTypeMidiProgram:
64 data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT));
65 data[1] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
66 return 2;
68 case kEngineControlEventTypeAllSoundOff:
69 data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
70 data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
71 return 2;
73 case kEngineControlEventTypeAllNotesOff:
74 data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
75 data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
76 return 2;
79 return 0;
82 // -----------------------------------------------------------------------
83 // EngineEvent
85 void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data, const uint8_t midiPortOffset) noexcept
87 if (size == 0 || data == nullptr || data[0] < MIDI_STATUS_NOTE_OFF)
89 type = kEngineEventTypeNull;
90 channel = 0;
91 return;
94 // get channel
95 channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data));
97 // get status
98 const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data)));
100 if (midiStatus == MIDI_STATUS_CONTROL_CHANGE)
102 CARLA_SAFE_ASSERT_RETURN(size >= 2,);
104 type = kEngineEventTypeControl;
106 const uint8_t midiControl(data[1]);
108 if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
110 CARLA_SAFE_ASSERT_RETURN(size >= 3,);
112 const uint8_t midiBank(data[2]);
114 ctrl.type = kEngineControlEventTypeMidiBank;
115 ctrl.param = midiBank;
116 ctrl.midiValue = -1;
117 ctrl.normalizedValue = 0.0f;
118 ctrl.handled = true;
120 else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
122 ctrl.type = kEngineControlEventTypeAllSoundOff;
123 ctrl.param = 0;
124 ctrl.midiValue = -1;
125 ctrl.normalizedValue = 0.0f;
126 ctrl.handled = true;
128 else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
130 ctrl.type = kEngineControlEventTypeAllNotesOff;
131 ctrl.param = 0;
132 ctrl.midiValue = -1;
133 ctrl.normalizedValue = 0.0f;
134 ctrl.handled = true;
136 else
138 CARLA_SAFE_ASSERT_RETURN(size >= 3,);
140 // ensures 0.0<->1.0 value range
141 const int8_t midiValue = static_cast<int8_t>(carla_fixedValue<uint8_t>(0, 127, data[2]));
143 ctrl.type = kEngineControlEventTypeParameter;
144 ctrl.param = midiControl;
145 ctrl.midiValue = midiValue;
146 ctrl.normalizedValue = float(midiValue)/127.0f;
147 ctrl.handled = false;
150 else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE)
152 CARLA_SAFE_ASSERT_RETURN(size >= 2,);
154 type = kEngineEventTypeControl;
156 const uint8_t midiProgram(data[1]);
158 ctrl.type = kEngineControlEventTypeMidiProgram;
159 ctrl.param = midiProgram;
160 ctrl.midiValue = -1;
161 ctrl.normalizedValue = 0.0f;
162 ctrl.handled = true;
164 else
166 type = kEngineEventTypeMidi;
168 midi.port = midiPortOffset;
169 midi.size = size;
171 if (size > EngineMidiEvent::kDataSize)
173 midi.dataExt = data;
174 std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize);
176 else
178 midi.data[0] = midiStatus;
180 uint8_t i=1;
181 for (; i < size; ++i)
182 midi.data[i] = data[i];
183 for (; i < EngineMidiEvent::kDataSize; ++i)
184 midi.data[i] = 0;
186 midi.dataExt = nullptr;
191 // -----------------------------------------------------------------------
192 // EngineOptions
194 EngineOptions::EngineOptions() noexcept
195 #ifdef CARLA_OS_LINUX
196 : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS),
197 transportMode(ENGINE_TRANSPORT_MODE_JACK),
198 #else
199 : processMode(ENGINE_PROCESS_MODE_PATCHBAY),
200 transportMode(ENGINE_TRANSPORT_MODE_INTERNAL),
201 #endif
202 transportExtra(nullptr),
203 forceStereo(false),
204 resetXruns(false),
205 preferPluginBridges(false),
206 #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
207 preferUiBridges(false),
208 #else
209 preferUiBridges(true),
210 #endif
211 uisAlwaysOnTop(true),
212 pluginsAreStandalone(false),
213 bgColor(0x000000ff),
214 fgColor(0xffffffff),
215 uiScale(1.0f),
216 maxParameters(MAX_DEFAULT_PARAMETERS),
217 uiBridgesTimeout(4000),
218 audioBufferSize(512),
219 audioSampleRate(44100),
220 audioTripleBuffer(false),
221 audioDriver(nullptr),
222 audioDevice(nullptr),
223 #ifndef BUILD_BRIDGE
224 # ifdef CARLA_OS_WIN
225 oscEnabled(false),
226 # else
227 oscEnabled(true),
228 # endif
229 oscPortTCP(22752),
230 oscPortUDP(22752),
231 #endif
232 pathAudio(nullptr),
233 pathMIDI(nullptr),
234 pathLADSPA(nullptr),
235 pathDSSI(nullptr),
236 pathLV2(nullptr),
237 pathVST2(nullptr),
238 pathVST3(nullptr),
239 pathSF2(nullptr),
240 pathSFZ(nullptr),
241 pathJSFX(nullptr),
242 pathCLAP(nullptr),
243 binaryDir(nullptr),
244 resourceDir(nullptr),
245 clientNamePrefix(nullptr),
246 preventBadBehaviour(false),
247 frontendWinId(0)
248 #ifndef CARLA_OS_WIN
249 , wine()
250 #endif
254 EngineOptions::~EngineOptions() noexcept
256 if (audioDriver != nullptr)
258 delete[] audioDriver;
259 audioDriver = nullptr;
261 if (audioDevice != nullptr)
263 delete[] audioDevice;
264 audioDevice = nullptr;
266 if (pathAudio != nullptr)
268 delete[] pathAudio;
269 pathAudio = nullptr;
271 if (pathMIDI != nullptr)
273 delete[] pathMIDI;
274 pathMIDI = nullptr;
276 if (pathLADSPA != nullptr)
278 delete[] pathLADSPA;
279 pathLADSPA = nullptr;
281 if (pathDSSI != nullptr)
283 delete[] pathDSSI;
284 pathDSSI = nullptr;
286 if (pathLV2 != nullptr)
288 delete[] pathLV2;
289 pathLV2 = nullptr;
291 if (pathVST2 != nullptr)
293 delete[] pathVST2;
294 pathVST2 = nullptr;
296 if (pathVST3 != nullptr)
298 delete[] pathVST3;
299 pathVST3 = nullptr;
301 if (pathSF2 != nullptr)
303 delete[] pathSF2;
304 pathSF2 = nullptr;
306 if (pathSFZ != nullptr)
308 delete[] pathSFZ;
309 pathSFZ = nullptr;
311 if (pathJSFX != nullptr)
313 delete[] pathJSFX;
314 pathJSFX = nullptr;
316 if (pathCLAP != nullptr)
318 delete[] pathCLAP;
319 pathCLAP = nullptr;
321 if (binaryDir != nullptr)
323 delete[] binaryDir;
324 binaryDir = nullptr;
326 if (resourceDir != nullptr)
328 delete[] resourceDir;
329 resourceDir = nullptr;
331 if (clientNamePrefix != nullptr)
333 delete[] clientNamePrefix;
334 clientNamePrefix = nullptr;
338 #ifndef CARLA_OS_WIN
339 EngineOptions::Wine::Wine() noexcept
340 : executable(nullptr),
341 autoPrefix(true),
342 fallbackPrefix(nullptr),
343 rtPrio(true),
344 baseRtPrio(15),
345 serverRtPrio(10) {}
347 EngineOptions::Wine::~Wine() noexcept
349 if (executable != nullptr)
351 delete[] executable;
352 executable = nullptr;
355 if (fallbackPrefix != nullptr)
357 delete[] fallbackPrefix;
358 fallbackPrefix = nullptr;
361 #endif
363 // -----------------------------------------------------------------------
364 // EngineTimeInfoBBT
366 EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
367 : valid(false),
368 bar(0),
369 beat(0),
370 tick(0.0),
371 barStartTick(0.0),
372 beatsPerBar(0.0f),
373 beatType(0.0f),
374 ticksPerBeat(0.0),
375 beatsPerMinute(0.0) {}
377 EngineTimeInfoBBT::EngineTimeInfoBBT(const EngineTimeInfoBBT& bbt) noexcept
378 : valid(bbt.valid),
379 bar(bbt.bar),
380 beat(bbt.beat),
381 tick(bbt.tick),
382 barStartTick(bbt.barStartTick),
383 beatsPerBar(bbt.beatsPerBar),
384 beatType(bbt.beatType),
385 ticksPerBeat(bbt.ticksPerBeat),
386 beatsPerMinute(bbt.beatsPerMinute) {}
388 void EngineTimeInfoBBT::clear() noexcept
390 valid = false;
391 bar = 0;
392 beat = 0;
393 tick = 0.0;
394 barStartTick = 0.0;
395 beatsPerBar = 0.0f;
396 beatType = 0.0f;
397 ticksPerBeat = 0.0;
398 beatsPerMinute = 0.0;
401 // -----------------------------------------------------------------------
402 // EngineTimeInfo
404 EngineTimeInfo::EngineTimeInfo() noexcept
405 : playing(false),
406 frame(0),
407 usecs(0),
408 bbt() {}
410 void EngineTimeInfo::clear() noexcept
412 playing = false;
413 frame = 0;
414 usecs = 0;
415 bbt.clear();
418 EngineTimeInfo::EngineTimeInfo(const EngineTimeInfo& info) noexcept
419 : playing(info.playing),
420 frame(info.frame),
421 usecs(info.usecs),
422 bbt(info.bbt) {}
424 EngineTimeInfo& EngineTimeInfo::operator=(const EngineTimeInfo& info) noexcept
426 playing = info.playing;
427 frame = info.frame;
428 usecs = info.usecs;
429 bbt.valid = info.bbt.valid;
430 bbt.bar = info.bbt.bar;
431 bbt.beat = info.bbt.beat;
432 bbt.tick = info.bbt.tick;
433 bbt.barStartTick = info.bbt.barStartTick;
434 bbt.beatsPerBar = info.bbt.beatsPerBar;
435 bbt.beatType = info.bbt.beatType;
436 bbt.ticksPerBeat = info.bbt.ticksPerBeat;
437 bbt.beatsPerMinute = info.bbt.beatsPerMinute;
439 return *this;
442 bool EngineTimeInfo::compareIgnoringRollingFrames(const EngineTimeInfo& timeInfo, const uint32_t maxFrames) const noexcept
444 if (timeInfo.playing != playing || timeInfo.bbt.valid != bbt.valid)
445 return false;
447 if (bbt.valid)
449 if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
450 return false;
451 if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
452 return false;
455 // frame matches, nothing else to compare
456 if (timeInfo.frame == frame)
457 return true;
459 // if we went back in time, so a case of reposition
460 if (frame > timeInfo.frame)
461 return false;
463 // not playing, so don't bother checking transport
464 // assume frame changed, likely playback has stopped
465 if (! playing)
466 return false;
468 // if we are within expected bounds, assume we are rolling normally
469 if (frame + maxFrames <= timeInfo.frame)
470 return true;
472 // out of bounds, another reposition
473 return false;
476 bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept
478 if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.bbt.valid != bbt.valid)
479 return false;
480 if (! bbt.valid)
481 return true;
482 if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
483 return false;
484 if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
485 return false;
486 return true;
489 bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept
491 return !operator==(timeInfo);
494 // -----------------------------------------------------------------------
496 CARLA_BACKEND_END_NAMESPACE