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 // -----------------------------------------------------------------------
37 const char* EngineType2Str(const EngineType type
) noexcept
42 return "kEngineTypeNull";
44 return "kEngineTypeJack";
46 return "kEngineTypeJuce";
47 case kEngineTypeRtAudio
:
48 return "kEngineTypeRtAudio";
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
);
64 const char* EnginePortType2Str(const EnginePortType type
) noexcept
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
);
83 const char* EngineEventType2Str(const EngineEventType type
) noexcept
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
);
100 const char* EngineControlEventType2Str(const EngineControlEventType type
) noexcept
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
);
122 // -----------------------------------------------------------------------
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
)
138 engineEventIndex
= i
;
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 // -----------------------------------------------------------------------
158 void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer
& midiBuffer
, const EngineEvent engineEvents
[kMaxEngineEventInternalCount
])
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
)
173 else if (engineEvent
.type
== kEngineEventTypeControl
)
175 const EngineControlEvent
& ctrlEvent(engineEvent
.ctrl
);
177 size
= ctrlEvent
.convertToMidiData(engineEvent
.channel
, 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
;
195 mdataTmp
[0] = static_cast<uint8_t>(midiEvent
.data
[0] | (engineEvent
.channel
& MIDI_CHANNEL_BIT
));
200 carla_copy
<uint8_t>(mdataTmp
+1, midiEvent
.data
+1, size
-1U);
213 midiBuffer
.addEvent(mdataPtr
, static_cast<int>(size
), static_cast<int>(engineEvent
.time
));
217 // -------------------------------------------------------------------
220 class ScopedEngineEnvironmentLocker
223 ScopedEngineEnvironmentLocker(CarlaEngine
* const engine
) noexcept
;
224 ~ScopedEngineEnvironmentLocker() noexcept
;
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