1 /*
2  * Carla Plugin Host
3  * Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
4  *
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.
9  *
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.
14  *
15  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
16  */
17 
18 #ifndef CARLA_ENGINE_INTERNAL_HPP_INCLUDED
19 #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
20 
21 #include "CarlaEngineThread.hpp"
22 #include "CarlaEngineUtils.hpp"
23 #include "CarlaPlugin.hpp"
24 #include "LinkedList.hpp"
25 
26 #ifndef BUILD_BRIDGE
27 # include "CarlaEngineOsc.hpp"
28 # include "hylia/hylia.h"
29 #endif
30 
31 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
32 # include "water/processors/AudioProcessorGraph.h"
33 # include "water/containers/Array.h"
34 # include "water/memory/Atomic.h"
35 #endif
36 
37 #include <vector>
38 
39 // FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs
40 // maybe separate macro
41 
42 typedef struct _jack_position jack_position_t;
43 struct carla_sem_t;
44 
45 CARLA_BACKEND_START_NAMESPACE
46 
47 // -----------------------------------------------------------------------
48 // Engine helper macro, sets lastError and returns false/NULL
49 
50 #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err)  if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false;   }
51 #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }
52 
53 #define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg)  catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return false;   }
54 #define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return nullptr; }
55 
56 // -----------------------------------------------------------------------
57 // InternalEvents
58 
59 struct EngineInternalEvents {
60     EngineEvent* in;
61     EngineEvent* out;
62 
63     EngineInternalEvents() noexcept;
64     ~EngineInternalEvents() noexcept;
65     void clear() noexcept;
66 
67     CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalEvents)
68 };
69 
70 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
71 // -----------------------------------------------------------------------
72 // InternalGraph
73 
74 struct RackGraph;
75 class PatchbayGraph;
76 
77 class EngineInternalGraph
78 {
79 public:
80     EngineInternalGraph(CarlaEngine* engine) noexcept;
81     ~EngineInternalGraph() noexcept;
82 
83     void create(uint32_t audioIns, uint32_t audioOuts, uint32_t cvIns, uint32_t cvOuts);
84     void destroy() noexcept;
85 
86     void setBufferSize(uint32_t bufferSize);
87     void setSampleRate(double sampleRate);
88     void setOffline(bool offline);
89 
isRack() const90     bool isRack() const noexcept
91     {
92         return fIsRack;
93     }
94 
isReady() const95     bool isReady() const noexcept
96     {
97         return fIsReady;
98     }
99 
getNumAudioOuts() const100     uint32_t getNumAudioOuts() const noexcept
101     {
102         return fNumAudioOuts;
103     }
104 
105     RackGraph*     getRackGraph() const noexcept;
106     PatchbayGraph* getPatchbayGraph() const noexcept;
107     PatchbayGraph* getPatchbayGraphOrNull() const noexcept;
108 
109     void process(CarlaEngine::ProtectedData* data, const float* const* inBuf, float* const* outBuf, uint32_t frames);
110 
111     // special direct process with connections already handled, used in JACK and Plugin
112     void processRack(CarlaEngine::ProtectedData* data, const float* inBuf[2], float* outBuf[2], uint32_t frames);
113 
114     // used for internal patchbay mode
115     void addPlugin(CarlaPluginPtr plugin);
116     void replacePlugin(CarlaPluginPtr oldPlugin, CarlaPluginPtr newPlugin);
117     void renamePlugin(CarlaPluginPtr plugin, const char* newName);
118     void switchPlugins(CarlaPluginPtr pluginA, CarlaPluginPtr pluginB);
119     void removePlugin(CarlaPluginPtr plugin);
120     void removeAllPlugins();
121 
122     bool isUsingExternalHost() const noexcept;
123     bool isUsingExternalOSC() const noexcept;
124     void setUsingExternalHost(bool usingExternal) noexcept;
125     void setUsingExternalOSC(bool usingExternal) noexcept;
126 
127 private:
128     bool fIsRack;
129     uint32_t fNumAudioOuts;
130     volatile bool fIsReady;
131 
132     union {
133         RackGraph*     fRack;
134         PatchbayGraph* fPatchbay;
135     };
136 
137     CarlaEngine* const kEngine;
138 
139     CARLA_PREVENT_HEAP_ALLOCATION
140     CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph)
141 };
142 #endif // BUILD_BRIDGE_ALTERNATIVE_ARCH
143 
144 // -----------------------------------------------------------------------
145 // InternalTime
146 
147 class EngineInternalTime {
148 public:
149     EngineInternalTime(EngineTimeInfo& timeInfo, const EngineTransportMode& transportMode) noexcept;
150 
151     void init(uint32_t bufferSize, double sampleRate);
152     void updateAudioValues(uint32_t bufferSize, double sampleRate);
153 
154     void enableLink(bool enable);
155     void setBPM(double bpm);
156     void setNeedsReset() noexcept;
157     void pause() noexcept;
158     void relocate(uint64_t frame) noexcept;
159 
160 private:
161     double beatsPerBar;
162     double beatsPerMinute;
163     double bufferSize;
164     double sampleRate;
165     bool needsReset;
166 
167     uint64_t nextFrame;
168 
169 #ifndef BUILD_BRIDGE
170     struct Hylia {
171         bool enabled;
172         hylia_t* instance;
173         hylia_time_info_t timeInfo;
174 
175         Hylia();
176         ~Hylia();
177         CARLA_DECLARE_NON_COPY_STRUCT(Hylia)
178     } hylia;
179 #endif
180 
181     EngineTimeInfo& timeInfo;
182     const EngineTransportMode& transportMode;
183 
184     friend class PendingRtEventsRunner;
185     void preProcess(uint32_t numFrames);
186     void fillEngineTimeInfo(uint32_t newFrames) noexcept;
187 
188     friend class CarlaEngineJack;
189     void fillJackTimeInfo(jack_position_t* pos, uint32_t newFrames) noexcept;
190 
191     CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalTime)
192 };
193 
194 // -----------------------------------------------------------------------
195 // EngineNextAction
196 
197 enum EnginePostAction {
198     kEnginePostActionNull = 0,
199     kEnginePostActionZeroCount,    // set curPluginCount to 0
200 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
201     kEnginePostActionRemovePlugin, // remove a plugin
202     kEnginePostActionSwitchPlugins // switch between 2 plugins
203 #endif
204 };
205 
206 struct EngineNextAction {
207     EnginePostAction opcode;
208     uint pluginId;
209     uint value;
210 
211     CarlaMutex mutex;
212 
213     bool needsPost;
214     volatile bool postDone;
215     carla_sem_t* sem;
216 
217     EngineNextAction() noexcept;
218     ~EngineNextAction() noexcept;
219     void clearAndReset() noexcept;
220 
221     CARLA_DECLARE_NON_COPY_STRUCT(EngineNextAction)
222 };
223 
224 // -----------------------------------------------------------------------
225 // EnginePluginData
226 
227 struct EnginePluginData {
228     CarlaPluginPtr plugin;
229     float peaks[4];
230 
EnginePluginDataEnginePluginData231     EnginePluginData()
232         : plugin(nullptr),
233 #ifdef CARLA_PROPER_CPP11_SUPPORT
234           peaks{0.0f, 0.0f, 0.0f, 0.0f} {}
235 #else
236           peaks()
237     {
238         carla_zeroStruct(peaks);
239     }
240 #endif
241 };
242 
243 // -----------------------------------------------------------------------
244 // CarlaEngineProtectedData
245 
246 struct CarlaEngine::ProtectedData {
247     CarlaEngineThread thread;
248 
249 #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
250     CarlaEngineOsc osc;
251 #endif
252 
253     EngineCallbackFunc callback;
254     void*              callbackPtr;
255 
256     FileCallbackFunc fileCallback;
257     void*            fileCallbackPtr;
258 
259     bool actionCanceled;
260 
261 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
262     bool loadingProject;
263     bool ignoreClientPrefix; // backwards compat only
264     CarlaString currentProjectFilename;
265     CarlaString currentProjectFolder;
266 #endif
267 
268     uint32_t bufferSize;
269     double   sampleRate;
270 
271     bool aboutToClose;    // don't re-activate thread if true
272     int  isIdling;        // don't allow any operations while idling
273     uint curPluginCount;  // number of plugins loaded (0...max)
274     uint maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
275     uint nextPluginId;    // invalid if == maxPluginNumber
276 
277     CarlaMutex     envMutex;
278     CarlaString    lastError;
279     CarlaString    name;
280     EngineOptions  options;
281     EngineTimeInfo timeInfo;
282 
283 #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
284     EnginePluginData plugins[1];
285 #else
286     EnginePluginData* plugins;
287     uint32_t xruns;
288     float dspLoad;
289 #endif
290     float peaks[4];
291     std::vector<CarlaPluginPtr> pluginsToDelete;
292 
293     EngineInternalEvents events;
294 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
295     EngineInternalGraph  graph;
296 #endif
297     EngineInternalTime   time;
298     EngineNextAction     nextAction;
299 
300     // -------------------------------------------------------------------
301 
302     ProtectedData(CarlaEngine* engine);
303     ~ProtectedData();
304 
305     // -------------------------------------------------------------------
306 
307     bool init(const char* clientName);
308     void close();
309 
310     void initTime(const char* features);
311 
312     // -------------------------------------------------------------------
313 
314     void deletePluginsAsNeeded();
315 
316     // -------------------------------------------------------------------
317 
318     void doPluginRemove(uint pluginId) noexcept;
319     void doPluginsSwitch(uint idA, uint idB) noexcept;
320     void doNextPluginAction() noexcept;
321 
322     // -------------------------------------------------------------------
323 
324 #ifdef CARLA_PROPER_CPP11_SUPPORT
325     ProtectedData() = delete;
326     CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData)
327 #endif
328 };
329 
330 // -----------------------------------------------------------------------
331 
332 class PendingRtEventsRunner
333 {
334 public:
335     PendingRtEventsRunner(CarlaEngine* engine,
336                           uint32_t numFrames,
337                           bool calcDSPLoad = false) noexcept;
338     ~PendingRtEventsRunner() noexcept;
339 
340 private:
341     CarlaEngine::ProtectedData* const pData;
342     int64_t prevTime;
343 
344     CARLA_PREVENT_HEAP_ALLOCATION
345     CARLA_DECLARE_NON_COPY_CLASS(PendingRtEventsRunner)
346 };
347 
348 // -----------------------------------------------------------------------
349 
350 class ScopedActionLock
351 {
352 public:
353     ScopedActionLock(CarlaEngine* engine, EnginePostAction action, uint pluginId, uint value) noexcept;
354     ~ScopedActionLock() noexcept;
355 
356 private:
357     CarlaEngine::ProtectedData* const pData;
358 
359     CARLA_PREVENT_HEAP_ALLOCATION
360     CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
361 };
362 
363 // -----------------------------------------------------------------------
364 
365 class ScopedThreadStopper
366 {
367 public:
368     ScopedThreadStopper(CarlaEngine* engine) noexcept;
369     ~ScopedThreadStopper() noexcept;
370 
371 private:
372     CarlaEngine* const engine;
373     CarlaEngine::ProtectedData* const pData;
374 
375     CARLA_PREVENT_HEAP_ALLOCATION
376     CARLA_DECLARE_NON_COPY_CLASS(ScopedThreadStopper)
377 };
378 
379 // -----------------------------------------------------------------------
380 
381 CARLA_BACKEND_END_NAMESPACE
382 
383 #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED
384