3 * Copyright (C) 2013-2023 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_BRIDGE_UTILS_HPP_INCLUDED
19 #define CARLA_BRIDGE_UTILS_HPP_INCLUDED
21 #include "CarlaBridgeDefines.hpp"
22 #include "CarlaMutex.hpp"
23 #include "CarlaRingBuffer.hpp"
24 #include "CarlaString.hpp"
26 // -------------------------------------------------------------------------------------------------------------------
29 const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode
) noexcept
33 case kPluginBridgeRtClientNull
:
34 return "kPluginBridgeRtClientNull";
35 case kPluginBridgeRtClientSetAudioPool
:
36 return "kPluginBridgeRtClientSetAudioPool";
37 case kPluginBridgeRtClientSetBufferSize
:
38 return "kPluginBridgeRtClientSetBufferSize";
39 case kPluginBridgeRtClientSetSampleRate
:
40 return "kPluginBridgeRtClientSetSampleRate";
41 case kPluginBridgeRtClientSetOnline
:
42 return "kPluginBridgeRtClientSetOnline";
43 case kPluginBridgeRtClientControlEventParameter
:
44 return "kPluginBridgeRtClientControlEventParameter";
45 case kPluginBridgeRtClientControlEventMidiBank
:
46 return "kPluginBridgeRtClientControlEventMidiBank";
47 case kPluginBridgeRtClientControlEventMidiProgram
:
48 return "kPluginBridgeRtClientControlEventMidiProgram";
49 case kPluginBridgeRtClientControlEventAllSoundOff
:
50 return "kPluginBridgeRtClientControlEventAllSoundOff";
51 case kPluginBridgeRtClientControlEventAllNotesOff
:
52 return "kPluginBridgeRtClientControlEventAllNotesOff";
53 case kPluginBridgeRtClientMidiEvent
:
54 return "kPluginBridgeRtClientMidiEvent";
55 case kPluginBridgeRtClientProcess
:
56 return "kPluginBridgeRtClientProcess";
57 case kPluginBridgeRtClientQuit
:
58 return "kPluginBridgeRtClientQuit";
61 carla_stderr("CarlaBackend::PluginBridgeRtClientOpcode2str(%i) - invalid opcode", opcode
);
66 const char* PluginBridgeNonRtClientOpcode2str(const PluginBridgeNonRtClientOpcode opcode
) noexcept
70 case kPluginBridgeNonRtClientNull
:
71 return "kPluginBridgeNonRtClientNull";
72 case kPluginBridgeNonRtClientVersion
:
73 return "kPluginBridgeNonRtClientVersion";
74 case kPluginBridgeNonRtClientPing
:
75 return "kPluginBridgeNonRtClientPing";
76 case kPluginBridgeNonRtClientPingOnOff
:
77 return "kPluginBridgeNonRtClientPingOnOff";
78 case kPluginBridgeNonRtClientActivate
:
79 return "kPluginBridgeNonRtClientActivate";
80 case kPluginBridgeNonRtClientDeactivate
:
81 return "kPluginBridgeNonRtClientDeactivate";
82 case kPluginBridgeNonRtClientInitialSetup
:
83 return "kPluginBridgeNonRtClientInitialSetup";
84 case kPluginBridgeNonRtClientSetParameterValue
:
85 return "kPluginBridgeNonRtClientSetParameterValue";
86 case kPluginBridgeNonRtClientSetParameterMidiChannel
:
87 return "kPluginBridgeNonRtClientSetParameterMidiChannel";
88 case kPluginBridgeNonRtClientSetParameterMappedControlIndex
:
89 return "kPluginBridgeNonRtClientSetParameterMappedControlIndex";
90 case kPluginBridgeNonRtClientSetProgram
:
91 return "kPluginBridgeNonRtClientSetProgram";
92 case kPluginBridgeNonRtClientSetMidiProgram
:
93 return "kPluginBridgeNonRtClientSetMidiProgram";
94 case kPluginBridgeNonRtClientSetCustomData
:
95 return "kPluginBridgeNonRtClientSetCustomData";
96 case kPluginBridgeNonRtClientSetChunkDataFile
:
97 return "kPluginBridgeNonRtClientSetChunkDataFile";
98 case kPluginBridgeNonRtClientSetCtrlChannel
:
99 return "kPluginBridgeNonRtClientSetCtrlChannel";
100 case kPluginBridgeNonRtClientSetOption
:
101 return "kPluginBridgeNonRtClientSetOption";
102 case kPluginBridgeNonRtClientGetParameterText
:
103 return "kPluginBridgeNonRtClientGetParameterText";
104 case kPluginBridgeNonRtClientPrepareForSave
:
105 return "kPluginBridgeNonRtClientPrepareForSave";
106 case kPluginBridgeNonRtClientRestoreLV2State
:
107 return "kPluginBridgeNonRtClientRestoreLV2State";
108 case kPluginBridgeNonRtClientShowUI
:
109 return "kPluginBridgeNonRtClientShowUI";
110 case kPluginBridgeNonRtClientHideUI
:
111 return "kPluginBridgeNonRtClientHideUI";
112 case kPluginBridgeNonRtClientUiParameterChange
:
113 return "kPluginBridgeNonRtClientUiParameterChange";
114 case kPluginBridgeNonRtClientUiProgramChange
:
115 return "kPluginBridgeNonRtClientUiProgramChange";
116 case kPluginBridgeNonRtClientUiMidiProgramChange
:
117 return "kPluginBridgeNonRtClientUiMidiProgramChange";
118 case kPluginBridgeNonRtClientUiNoteOn
:
119 return "kPluginBridgeNonRtClientUiNoteOn";
120 case kPluginBridgeNonRtClientUiNoteOff
:
121 return "kPluginBridgeNonRtClientUiNoteOff";
122 case kPluginBridgeNonRtClientQuit
:
123 return "kPluginBridgeNonRtClientQuit";
124 case kPluginBridgeNonRtClientSetParameterMappedRange
:
125 return "kPluginBridgeNonRtClientSetParameterMappedRange";
126 case kPluginBridgeNonRtClientSetOptions
:
127 return "kPluginBridgeNonRtClientSetOptions";
128 case kPluginBridgeNonRtClientSetWindowTitle
:
129 return "kPluginBridgeNonRtClientSetWindowTitle";
130 case kPluginBridgeNonRtClientEmbedUI
:
131 return "kPluginBridgeNonRtClientEmbedUI";
132 case kPluginBridgeNonRtClientReload
:
133 return "kPluginBridgeNonRtClientReload";
136 carla_stderr("CarlaBackend::PluginBridgeNonRtClientOpcode2str(%i) - invalid opcode", opcode
);
141 const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcode opcode
) noexcept
145 case kPluginBridgeNonRtServerNull
:
146 return "kPluginBridgeNonRtServerNull";
147 case kPluginBridgeNonRtServerPong
:
148 return "kPluginBridgeNonRtServerPong";
149 case kPluginBridgeNonRtServerPluginInfo1
:
150 return "kPluginBridgeNonRtServerPluginInfo1";
151 case kPluginBridgeNonRtServerPluginInfo2
:
152 return "kPluginBridgeNonRtServerPluginInfo2";
153 case kPluginBridgeNonRtServerAudioCount
:
154 return "kPluginBridgeNonRtServerAudioCount";
155 case kPluginBridgeNonRtServerMidiCount
:
156 return "kPluginBridgeNonRtServerMidiCount";
157 case kPluginBridgeNonRtServerCvCount
:
158 return "kPluginBridgeNonRtServerCvCount";
159 case kPluginBridgeNonRtServerParameterCount
:
160 return "kPluginBridgeNonRtServerParameterCount";
161 case kPluginBridgeNonRtServerProgramCount
:
162 return "kPluginBridgeNonRtServerProgramCount";
163 case kPluginBridgeNonRtServerMidiProgramCount
:
164 return "kPluginBridgeNonRtServerMidiProgramCount";
165 case kPluginBridgeNonRtServerPortName
:
166 return "kPluginBridgeNonRtServerPortName";
167 case kPluginBridgeNonRtServerParameterData1
:
168 return "kPluginBridgeNonRtServerParameterData1";
169 case kPluginBridgeNonRtServerParameterData2
:
170 return "kPluginBridgeNonRtServerParameterData2";
171 case kPluginBridgeNonRtServerParameterRanges
:
172 return "kPluginBridgeNonRtServerParameterRanges";
173 case kPluginBridgeNonRtServerParameterValue
:
174 return "kPluginBridgeNonRtServerParameterValue";
175 case kPluginBridgeNonRtServerParameterValue2
:
176 return "kPluginBridgeNonRtServerParameterValue2";
177 case kPluginBridgeNonRtServerParameterTouch
:
178 return "kPluginBridgeNonRtServerParameterTouch";
179 case kPluginBridgeNonRtServerDefaultValue
:
180 return "kPluginBridgeNonRtServerDefaultValue";
181 case kPluginBridgeNonRtServerCurrentProgram
:
182 return "kPluginBridgeNonRtServerCurrentProgram";
183 case kPluginBridgeNonRtServerCurrentMidiProgram
:
184 return "kPluginBridgeNonRtServerCurrentMidiProgram";
185 case kPluginBridgeNonRtServerProgramName
:
186 return "kPluginBridgeNonRtServerProgramName";
187 case kPluginBridgeNonRtServerMidiProgramData
:
188 return "kPluginBridgeNonRtServerMidiProgramData";
189 case kPluginBridgeNonRtServerSetCustomData
:
190 return "kPluginBridgeNonRtServerSetCustomData";
191 case kPluginBridgeNonRtServerSetChunkDataFile
:
192 return "kPluginBridgeNonRtServerSetChunkDataFile";
193 case kPluginBridgeNonRtServerSetLatency
:
194 return "kPluginBridgeNonRtServerSetLatency";
195 case kPluginBridgeNonRtServerSetParameterText
:
196 return "kPluginBridgeNonRtServerSetParameterText";
197 case kPluginBridgeNonRtServerReady
:
198 return "kPluginBridgeNonRtServerReady";
199 case kPluginBridgeNonRtServerSaved
:
200 return "kPluginBridgeNonRtServerSaved";
201 case kPluginBridgeNonRtServerUiClosed
:
202 return "kPluginBridgeNonRtServerUiClosed";
203 case kPluginBridgeNonRtServerError
:
204 return "kPluginBridgeNonRtServerError";
205 case kPluginBridgeNonRtServerVersion
:
206 return "kPluginBridgeNonRtServerVersion";
207 case kPluginBridgeNonRtServerRespEmbedUI
:
208 return "kPluginBridgeNonRtServerRespEmbedUI";
209 case kPluginBridgeNonRtServerResizeEmbedUI
:
210 return "kPluginBridgeNonRtServerResizeEmbedUI";
213 carla_stderr("CarlaBackend::PluginBridgeNonRtServerOpcode2str%i) - invalid opcode", opcode
);
217 // -------------------------------------------------------------------------------------------------------------------
219 static constexpr const std::size_t kBridgeRtClientDataMidiOutSize
= 511*4;
220 static constexpr const std::size_t kBridgeBaseMidiOutHeaderSize
= 6U /* time, port and size */;
222 // Server => Client RT
223 struct BridgeRtClientData
{
225 BridgeTimeInfo timeInfo
;
226 SmallStackBuffer ringBuffer
;
227 uint8_t midiOut
[kBridgeRtClientDataMidiOutSize
];
231 // Server => Client Non-RT
232 struct BridgeNonRtClientData
{
233 BigStackBuffer ringBuffer
;
236 // Client => Server Non-RT
237 struct BridgeNonRtServerData
{
238 HugeStackBuffer ringBuffer
;
241 // -------------------------------------------------------------------------------------------------------------------
243 struct CARLA_API BridgeAudioPool
{
245 std::size_t dataSize
;
246 CarlaString filename
;
250 BridgeAudioPool() noexcept
;
251 ~BridgeAudioPool() noexcept
;
253 bool initializeServer() noexcept
;
254 bool attachClient(const char* const fname
) noexcept
;
255 void clear() noexcept
;
257 void resize(const uint32_t bufferSize
, const uint32_t audioPortCount
, const uint32_t cvPortCount
) noexcept
;
259 const char* getFilenameSuffix() const noexcept
;
261 CARLA_DECLARE_NON_COPYABLE(BridgeAudioPool
)
264 // -------------------------------------------------------------------------------------------------------------------
266 struct CARLA_API BridgeRtClientControl
: public CarlaRingBufferControl
<SmallStackBuffer
> {
267 BridgeRtClientData
* data
;
268 CarlaString filename
;
269 bool needsSemDestroy
; // client only
273 BridgeRtClientControl() noexcept
;
274 ~BridgeRtClientControl() noexcept override
;
276 bool initializeServer() noexcept
;
277 bool attachClient(const char* const basename
) noexcept
;
278 void clear() noexcept
;
280 bool mapData() noexcept
;
281 void unmapData() noexcept
;
283 // non-bridge, server
284 bool waitForClient(const uint msecs
) noexcept
;
285 bool writeOpcode(const PluginBridgeRtClientOpcode opcode
) noexcept
;
288 PluginBridgeRtClientOpcode
readOpcode() noexcept
;
290 // helper class that automatically posts semaphore on destructor
292 BridgeRtClientData
* const data
;
295 WaitHelper(BridgeRtClientControl
& c
) noexcept
;
296 ~WaitHelper() noexcept
;
298 CARLA_DECLARE_NON_COPYABLE(WaitHelper
)
301 CARLA_DECLARE_NON_COPYABLE(BridgeRtClientControl
)
304 // -------------------------------------------------------------------------------------------------------------------
306 struct CARLA_API BridgeNonRtClientControl
: public CarlaRingBufferControl
<BigStackBuffer
> {
307 BridgeNonRtClientData
* data
;
308 CarlaString filename
;
313 BridgeNonRtClientControl() noexcept
;
314 ~BridgeNonRtClientControl() noexcept override
;
316 bool initializeServer() noexcept
;
317 bool attachClient(const char* const basename
) noexcept
;
318 void clear() noexcept
;
320 bool mapData() noexcept
;
321 void unmapData() noexcept
;
323 // non-bridge, server
324 void waitIfDataIsReachingLimit() noexcept
;
325 bool writeOpcode(const PluginBridgeNonRtClientOpcode opcode
) noexcept
;
328 PluginBridgeNonRtClientOpcode
readOpcode() noexcept
;
330 CARLA_DECLARE_NON_COPYABLE(BridgeNonRtClientControl
)
333 // -------------------------------------------------------------------------------------------------------------------
335 struct CARLA_API BridgeNonRtServerControl
: public CarlaRingBufferControl
<HugeStackBuffer
> {
336 BridgeNonRtServerData
* data
;
337 CarlaString filename
;
342 BridgeNonRtServerControl() noexcept
;
343 ~BridgeNonRtServerControl() noexcept override
;
345 bool initializeServer() noexcept
;
346 bool attachClient(const char* const basename
) noexcept
;
347 void clear() noexcept
;
349 bool mapData() noexcept
;
350 void unmapData() noexcept
;
352 // non-bridge, server
353 PluginBridgeNonRtServerOpcode
readOpcode() noexcept
;
356 void waitIfDataIsReachingLimit() noexcept
;
357 bool writeOpcode(const PluginBridgeNonRtServerOpcode opcode
) noexcept
;
359 CARLA_DECLARE_NON_COPYABLE(BridgeNonRtServerControl
)
362 // -------------------------------------------------------------------------------------------------------------------
364 #endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED