Cleanup
[carla.git] / source / utils / CarlaEngineUtils.hpp
blobe56812a462f486fc6fc9f43f076e5361e4450aa6
1 // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
2 // SPDX-License-Identifier: GPL-2.0-or-later
4 #ifndef CARLA_ENGINE_UTILS_HPP_INCLUDED
5 #define CARLA_ENGINE_UTILS_HPP_INCLUDED
7 #include "CarlaEngine.hpp"
8 #include "CarlaUtils.hpp"
9 #include "CarlaMIDI.h"
11 #include "water/midi/MidiBuffer.h"
13 CARLA_BACKEND_START_NAMESPACE
15 // -----------------------------------------------------------------------
16 // Maximum internal pre-allocated events
18 const ushort kMaxEngineEventInternalCount = 2048;
20 // -----------------------------------------------------------------------
22 static inline
23 const char* EngineType2Str(const EngineType type) noexcept
25 switch (type)
27 case kEngineTypeNull:
28 return "kEngineTypeNull";
29 case kEngineTypeJack:
30 return "kEngineTypeJack";
31 case kEngineTypeRtAudio:
32 return "kEngineTypeRtAudio";
33 case kEngineTypeSDL:
34 return "kEngineTypeSDL";
35 case kEngineTypePlugin:
36 return "kEngineTypePlugin";
37 case kEngineTypeBridge:
38 return "kEngineTypeBridge";
39 case kEngineTypeDummy:
40 return "kEngineTypeDummy";
43 carla_stderr("CarlaBackend::EngineType2Str(%i) - invalid type", type);
44 return nullptr;
47 static inline
48 const char* EnginePortType2Str(const EnginePortType type) noexcept
50 switch (type)
52 case kEnginePortTypeNull:
53 return "kEnginePortTypeNull";
54 case kEnginePortTypeAudio:
55 return "kEnginePortTypeAudio";
56 case kEnginePortTypeCV:
57 return "kEnginePortTypeCV";
58 case kEnginePortTypeEvent:
59 return "kEnginePortTypeEvent";
62 carla_stderr("CarlaBackend::EnginePortType2Str(%i) - invalid type", type);
63 return nullptr;
66 static inline
67 const char* EngineEventType2Str(const EngineEventType type) noexcept
69 switch (type)
71 case kEngineEventTypeNull:
72 return "kEngineEventTypeNull";
73 case kEngineEventTypeControl:
74 return "kEngineEventTypeControl";
75 case kEngineEventTypeMidi:
76 return "kEngineEventTypeMidi";
79 carla_stderr("CarlaBackend::EngineEventType2Str(%i) - invalid type", type);
80 return nullptr;
83 static inline
84 const char* EngineControlEventType2Str(const EngineControlEventType type) noexcept
86 switch (type)
88 case kEngineControlEventTypeNull:
89 return "kEngineNullEvent";
90 case kEngineControlEventTypeParameter:
91 return "kEngineControlEventTypeParameter";
92 case kEngineControlEventTypeMidiBank:
93 return "kEngineControlEventTypeMidiBank";
94 case kEngineControlEventTypeMidiProgram:
95 return "kEngineControlEventTypeMidiProgram";
96 case kEngineControlEventTypeAllSoundOff:
97 return "kEngineControlEventTypeAllSoundOff";
98 case kEngineControlEventTypeAllNotesOff:
99 return "kEngineControlEventTypeAllNotesOff";
102 carla_stderr("CarlaBackend::EngineControlEventType2Str(%i) - invalid type", type);
103 return nullptr;
106 // -----------------------------------------------------------------------
108 static inline
109 void fillEngineEventsFromWaterMidiBuffer(EngineEvent engineEvents[kMaxEngineEventInternalCount], const water::MidiBuffer& midiBuffer)
111 const uint8_t* midiData;
112 int numBytes, sampleNumber;
113 ushort engineEventIndex = 0;
115 for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
117 const EngineEvent& engineEvent(engineEvents[i]);
119 if (engineEvent.type != kEngineEventTypeNull)
120 continue;
122 engineEventIndex = i;
123 break;
126 for (water::MidiBuffer::Iterator midiBufferIterator(midiBuffer); midiBufferIterator.getNextEvent(midiData, numBytes, sampleNumber) && engineEventIndex < kMaxEngineEventInternalCount;)
128 CARLA_SAFE_ASSERT_CONTINUE(numBytes > 0);
129 CARLA_SAFE_ASSERT_CONTINUE(sampleNumber >= 0);
130 CARLA_SAFE_ASSERT_CONTINUE(numBytes < 0xFF /* uint8_t max */);
132 EngineEvent& engineEvent(engineEvents[engineEventIndex++]);
134 engineEvent.time = static_cast<uint32_t>(sampleNumber);
135 engineEvent.fillFromMidiData(static_cast<uint8_t>(numBytes), midiData, 0);
139 // -----------------------------------------------------------------------
141 static inline
142 void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const EngineEvent engineEvents[kMaxEngineEventInternalCount])
144 uint8_t size = 0;
145 uint8_t mdata[3] = { 0, 0, 0 };
146 uint8_t mdataTmp[EngineMidiEvent::kDataSize];
147 const uint8_t* mdataPtr;
149 for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
151 const EngineEvent& engineEvent(engineEvents[i]);
153 /**/ if (engineEvent.type == kEngineEventTypeNull)
155 break;
157 else if (engineEvent.type == kEngineEventTypeControl)
159 const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
161 size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
162 mdataPtr = mdata;
164 else if (engineEvent.type == kEngineEventTypeMidi)
166 const EngineMidiEvent& midiEvent(engineEvent.midi);
168 size = midiEvent.size;
169 CARLA_SAFE_ASSERT_CONTINUE(size > 0);
171 if (size > EngineMidiEvent::kDataSize)
173 CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
174 mdataPtr = midiEvent.dataExt;
176 else
178 // set first byte
179 mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
181 if (size > 1)
183 // copy rest
184 carla_copy<uint8_t>(mdataTmp+1, midiEvent.data+1, size-1U);
187 // done
188 mdataPtr = mdataTmp;
191 else
193 continue;
196 if (size > 0)
197 midiBuffer.addEvent(mdataPtr, static_cast<int>(size), static_cast<int>(engineEvent.time));
201 // -------------------------------------------------------------------
202 // Helper classes
204 class ScopedEngineEnvironmentLocker
206 public:
207 ScopedEngineEnvironmentLocker(CarlaEngine* const engine) noexcept;
208 ~ScopedEngineEnvironmentLocker() noexcept;
210 private:
211 CarlaEngine::ProtectedData* const pData;
213 CARLA_PREVENT_HEAP_ALLOCATION
214 CARLA_DECLARE_NON_COPYABLE(ScopedEngineEnvironmentLocker)
217 // -----------------------------------------------------------------------
219 CARLA_BACKEND_END_NAMESPACE
221 #endif // CARLA_ENGINE_UTILS_HPP_INCLUDED