Rename a pipe method, add docs
[carla.git] / source / utils / CarlaBridgeUtils.hpp
blobad9aafe967444387575b0ecb12e788b067d5af24
1 /*
2 * Carla Bridge utils
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 // -------------------------------------------------------------------------------------------------------------------
28 static inline
29 const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode) noexcept
31 switch (opcode)
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);
62 return "";
65 static inline
66 const char* PluginBridgeNonRtClientOpcode2str(const PluginBridgeNonRtClientOpcode opcode) noexcept
68 switch (opcode)
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);
137 return "";
140 static inline
141 const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcode opcode) noexcept
143 switch (opcode)
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);
214 return "";
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 {
224 BridgeSemaphore sem;
225 BridgeTimeInfo timeInfo;
226 SmallStackBuffer ringBuffer;
227 uint8_t midiOut[kBridgeRtClientDataMidiOutSize];
228 uint32_t procFlags;
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 {
244 float* data;
245 std::size_t dataSize;
246 CarlaString filename;
247 char shm[64];
248 bool isServer;
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
270 char shm[64];
271 bool isServer;
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;
287 // bridge, client
288 PluginBridgeRtClientOpcode readOpcode() noexcept;
290 // helper class that automatically posts semaphore on destructor
291 struct WaitHelper {
292 BridgeRtClientData* const data;
293 const bool ok;
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;
309 CarlaMutex mutex;
310 char shm[64];
311 bool isServer;
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;
327 // bridge, client
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;
338 CarlaMutex mutex;
339 char shm[64];
340 bool isServer;
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;
355 // bridge, client
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