Rename a pipe method, add docs
[carla.git] / source / utils / CarlaEngineUtils.hpp
blob8a59eafd89464215d0a707088682cf424cacd5ec
1 /*
2 * Carla Engine utils
3 * Copyright (C) 2011-2022 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 #ifndef CARLA_ENGINE_UTILS_HPP_INCLUDED
19 #define CARLA_ENGINE_UTILS_HPP_INCLUDED
21 #include "CarlaEngine.hpp"
22 #include "CarlaUtils.hpp"
23 #include "CarlaMIDI.h"
25 #include "water/midi/MidiBuffer.h"
27 CARLA_BACKEND_START_NAMESPACE
29 // -----------------------------------------------------------------------
30 // Maximum internal pre-allocated events
32 const ushort kMaxEngineEventInternalCount = 2048;
34 // -----------------------------------------------------------------------
36 static inline
37 const char* EngineType2Str(const EngineType type) noexcept
39 switch (type)
41 case kEngineTypeNull:
42 return "kEngineTypeNull";
43 case kEngineTypeJack:
44 return "kEngineTypeJack";
45 case kEngineTypeJuce:
46 return "kEngineTypeJuce";
47 case kEngineTypeRtAudio:
48 return "kEngineTypeRtAudio";
49 case kEngineTypeSDL:
50 return "kEngineTypeSDL";
51 case kEngineTypePlugin:
52 return "kEngineTypePlugin";
53 case kEngineTypeBridge:
54 return "kEngineTypeBridge";
55 case kEngineTypeDummy:
56 return "kEngineTypeDummy";
59 carla_stderr("CarlaBackend::EngineType2Str(%i) - invalid type", type);
60 return nullptr;
63 static inline
64 const char* EnginePortType2Str(const EnginePortType type) noexcept
66 switch (type)
68 case kEnginePortTypeNull:
69 return "kEnginePortTypeNull";
70 case kEnginePortTypeAudio:
71 return "kEnginePortTypeAudio";
72 case kEnginePortTypeCV:
73 return "kEnginePortTypeCV";
74 case kEnginePortTypeEvent:
75 return "kEnginePortTypeEvent";
78 carla_stderr("CarlaBackend::EnginePortType2Str(%i) - invalid type", type);
79 return nullptr;
82 static inline
83 const char* EngineEventType2Str(const EngineEventType type) noexcept
85 switch (type)
87 case kEngineEventTypeNull:
88 return "kEngineEventTypeNull";
89 case kEngineEventTypeControl:
90 return "kEngineEventTypeControl";
91 case kEngineEventTypeMidi:
92 return "kEngineEventTypeMidi";
95 carla_stderr("CarlaBackend::EngineEventType2Str(%i) - invalid type", type);
96 return nullptr;
99 static inline
100 const char* EngineControlEventType2Str(const EngineControlEventType type) noexcept
102 switch (type)
104 case kEngineControlEventTypeNull:
105 return "kEngineNullEvent";
106 case kEngineControlEventTypeParameter:
107 return "kEngineControlEventTypeParameter";
108 case kEngineControlEventTypeMidiBank:
109 return "kEngineControlEventTypeMidiBank";
110 case kEngineControlEventTypeMidiProgram:
111 return "kEngineControlEventTypeMidiProgram";
112 case kEngineControlEventTypeAllSoundOff:
113 return "kEngineControlEventTypeAllSoundOff";
114 case kEngineControlEventTypeAllNotesOff:
115 return "kEngineControlEventTypeAllNotesOff";
118 carla_stderr("CarlaBackend::EngineControlEventType2Str(%i) - invalid type", type);
119 return nullptr;
122 // -----------------------------------------------------------------------
124 static inline
125 void fillEngineEventsFromWaterMidiBuffer(EngineEvent engineEvents[kMaxEngineEventInternalCount], const water::MidiBuffer& midiBuffer)
127 const uint8_t* midiData;
128 int numBytes, sampleNumber;
129 ushort engineEventIndex = 0;
131 for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
133 const EngineEvent& engineEvent(engineEvents[i]);
135 if (engineEvent.type != kEngineEventTypeNull)
136 continue;
138 engineEventIndex = i;
139 break;
142 for (water::MidiBuffer::Iterator midiBufferIterator(midiBuffer); midiBufferIterator.getNextEvent(midiData, numBytes, sampleNumber) && engineEventIndex < kMaxEngineEventInternalCount;)
144 CARLA_SAFE_ASSERT_CONTINUE(numBytes > 0);
145 CARLA_SAFE_ASSERT_CONTINUE(sampleNumber >= 0);
146 CARLA_SAFE_ASSERT_CONTINUE(numBytes < 0xFF /* uint8_t max */);
148 EngineEvent& engineEvent(engineEvents[engineEventIndex++]);
150 engineEvent.time = static_cast<uint32_t>(sampleNumber);
151 engineEvent.fillFromMidiData(static_cast<uint8_t>(numBytes), midiData, 0);
155 // -----------------------------------------------------------------------
157 static inline
158 void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const EngineEvent engineEvents[kMaxEngineEventInternalCount])
160 uint8_t size = 0;
161 uint8_t mdata[3] = { 0, 0, 0 };
162 uint8_t mdataTmp[EngineMidiEvent::kDataSize];
163 const uint8_t* mdataPtr;
165 for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
167 const EngineEvent& engineEvent(engineEvents[i]);
169 /**/ if (engineEvent.type == kEngineEventTypeNull)
171 break;
173 else if (engineEvent.type == kEngineEventTypeControl)
175 const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
177 size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
178 mdataPtr = mdata;
180 else if (engineEvent.type == kEngineEventTypeMidi)
182 const EngineMidiEvent& midiEvent(engineEvent.midi);
184 size = midiEvent.size;
185 CARLA_SAFE_ASSERT_CONTINUE(size > 0);
187 if (size > EngineMidiEvent::kDataSize)
189 CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
190 mdataPtr = midiEvent.dataExt;
192 else
194 // set first byte
195 mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
197 if (size > 1)
199 // copy rest
200 carla_copy<uint8_t>(mdataTmp+1, midiEvent.data+1, size-1U);
203 // done
204 mdataPtr = mdataTmp;
207 else
209 continue;
212 if (size > 0)
213 midiBuffer.addEvent(mdataPtr, static_cast<int>(size), static_cast<int>(engineEvent.time));
217 // -------------------------------------------------------------------
218 // Helper classes
220 class ScopedEngineEnvironmentLocker
222 public:
223 ScopedEngineEnvironmentLocker(CarlaEngine* const engine) noexcept;
224 ~ScopedEngineEnvironmentLocker() noexcept;
226 private:
227 CarlaEngine::ProtectedData* const pData;
229 CARLA_PREVENT_HEAP_ALLOCATION
230 CARLA_DECLARE_NON_COPYABLE(ScopedEngineEnvironmentLocker)
233 // -----------------------------------------------------------------------
235 CARLA_BACKEND_END_NAMESPACE
237 #endif // CARLA_ENGINE_UTILS_HPP_INCLUDED