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"
11 #include "water/midi/MidiBuffer.h"
13 CARLA_BACKEND_START_NAMESPACE
15 // -----------------------------------------------------------------------
16 // Maximum internal pre-allocated events
18 const ushort kMaxEngineEventInternalCount
= 2048;
20 // -----------------------------------------------------------------------
23 const char* EngineType2Str(const EngineType type
) noexcept
28 return "kEngineTypeNull";
30 return "kEngineTypeJack";
31 case kEngineTypeRtAudio
:
32 return "kEngineTypeRtAudio";
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
);
48 const char* EnginePortType2Str(const EnginePortType type
) noexcept
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
);
67 const char* EngineEventType2Str(const EngineEventType type
) noexcept
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
);
84 const char* EngineControlEventType2Str(const EngineControlEventType type
) noexcept
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
);
106 // -----------------------------------------------------------------------
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
)
122 engineEventIndex
= i
;
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 // -----------------------------------------------------------------------
142 void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer
& midiBuffer
, const EngineEvent engineEvents
[kMaxEngineEventInternalCount
])
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
)
157 else if (engineEvent
.type
== kEngineEventTypeControl
)
159 const EngineControlEvent
& ctrlEvent(engineEvent
.ctrl
);
161 size
= ctrlEvent
.convertToMidiData(engineEvent
.channel
, 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
;
179 mdataTmp
[0] = static_cast<uint8_t>(midiEvent
.data
[0] | (engineEvent
.channel
& MIDI_CHANNEL_BIT
));
184 carla_copy
<uint8_t>(mdataTmp
+1, midiEvent
.data
+1, size
-1U);
197 midiBuffer
.addEvent(mdataPtr
, static_cast<int>(size
), static_cast<int>(engineEvent
.time
));
201 // -------------------------------------------------------------------
204 class ScopedEngineEnvironmentLocker
207 ScopedEngineEnvironmentLocker(CarlaEngine
* const engine
) noexcept
;
208 ~ScopedEngineEnvironmentLocker() noexcept
;
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