Add initial bits for Qt6 support
[carla.git] / source / includes / CarlaNativePrograms.hpp
blob23c930b42ce2c0365f9a698b5feba979512c4907
1 /*
2 * Carla Native Plugin API (C++)
3 * Copyright (C) 2012-2024 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_NATIVE_PROGRAMS_HPP_INCLUDED
19 #define CARLA_NATIVE_PROGRAMS_HPP_INCLUDED
21 #include "CarlaNative.hpp"
23 #include "CarlaMathUtils.hpp"
24 #include "CarlaMutex.hpp"
26 #include "water/files/File.h"
27 #include "water/memory/SharedResourcePointer.h"
28 #include "water/text/StringArray.h"
30 using water::File;
31 using water::SharedResourcePointer;
32 using water::String;
33 using water::StringArray;
35 /*!
36 * @defgroup CarlaNativeAPI Carla Native API
37 * @{
40 // -----------------------------------------------------------------------
41 // ...
43 enum FileType {
44 FileNone,
45 FileAudio,
46 FileMIDI,
49 template <FileType fileType>
50 struct NativePluginPresetManager {
51 StringArray filenames;
53 NativePluginPresetManager(const char* const paths, const char* const wildcard)
54 : filenames()
56 CARLA_SAFE_ASSERT_RETURN(wildcard != nullptr,);
58 if (paths == nullptr || paths[0] == '\0' || wildcard[0] == '\0')
59 return;
61 const StringArray splitPaths(StringArray::fromTokens(paths, CARLA_OS_SPLIT_STR, ""));
63 for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
65 std::vector<File> results;
67 if (const uint count = File(it->toRawUTF8()).findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard))
69 for (uint i=0; i<count; ++i)
70 filenames.add(results[i].getFullPathName());
74 filenames.sort(true);
78 // -----------------------------------------------------------------------
79 // Native Plugin with MIDI programs class
81 template <FileType fileType>
82 class NativePluginWithMidiPrograms : public NativePluginClass
84 public:
85 typedef NativePluginPresetManager<fileType> NativePluginPresetManagerType;
86 typedef SharedResourcePointer<NativePluginPresetManagerType> NativeMidiPrograms;
88 NativePluginWithMidiPrograms(const NativeHostDescriptor* const host,
89 const NativeMidiPrograms& programs,
90 const uint32_t numOutputs)
91 : NativePluginClass(host),
92 fRetMidiProgram(),
93 fRetMidiProgramName(),
94 fNextFilename(nullptr),
95 fProgramChangeMutex(),
96 kPrograms(programs),
97 kNumOutputs(numOutputs) {}
99 protected:
100 // -------------------------------------------------------------------
101 // New Plugin program calls
103 virtual void setStateFromFile(const char* filename) = 0;
104 virtual void process2(const float* const* inBuffer, float** outBuffer, uint32_t frames,
105 const NativeMidiEvent* midiEvents, uint32_t midiEventCount) = 0;
107 void invalidateNextFilename() noexcept
109 const CarlaMutexLocker cml(fProgramChangeMutex);
110 fNextFilename = nullptr;
113 // -------------------------------------------------------------------
114 // Plugin midi-program calls
116 uint32_t getMidiProgramCount() const override
118 const NativePluginPresetManagerType& pm(kPrograms.get());
119 return static_cast<uint32_t>(pm.filenames.size());
122 const NativeMidiProgram* getMidiProgramInfo(const uint32_t uindex) const override
124 const int index = static_cast<int>(uindex);
126 const NativePluginPresetManagerType& pm(kPrograms.get());
127 CARLA_SAFE_ASSERT_RETURN(index < pm.filenames.size(), nullptr);
129 fRetMidiProgramName = File(pm.filenames.strings.getUnchecked(index).toRawUTF8()).getFileNameWithoutExtension();
131 fRetMidiProgram.bank = 0;
132 fRetMidiProgram.program = uindex;
133 fRetMidiProgram.name = fRetMidiProgramName.toRawUTF8();
135 return &fRetMidiProgram;
138 // -------------------------------------------------------------------
139 // Plugin state calls
141 void setMidiProgram(const uint8_t, const uint32_t, const uint32_t program) override
143 const int iprogram = static_cast<int>(program);
145 const NativePluginPresetManagerType& pm(kPrograms.get());
146 CARLA_SAFE_ASSERT_RETURN(iprogram < pm.filenames.size(),);
148 const char* const filename(pm.filenames.strings.getUnchecked(iprogram).toRawUTF8());
150 const CarlaMutexLocker cml(fProgramChangeMutex);
152 if (isOffline())
154 setStateFromFile(filename);
156 else
158 fNextFilename = filename;
159 hostRequestIdle();
163 // -------------------------------------------------------------------
164 // Plugin process calls
166 void process(const float* const* const inBuffer, float** const outBuffer, uint32_t frames,
167 const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
169 const CarlaMutexTryLocker cmtl(fProgramChangeMutex, isOffline());
171 if (cmtl.wasLocked())
173 process2(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
175 else
177 for (uint32_t i=0; i<kNumOutputs; ++i)
178 carla_zeroFloats(outBuffer[i], frames);
182 // -------------------------------------------------------------------
183 // Plugin dispatcher calls
185 void idle() override
187 if (const char* const filename = fNextFilename)
189 const CarlaMutexLocker cml(fProgramChangeMutex);
191 fNextFilename = nullptr;
192 setStateFromFile(filename);
196 private:
197 mutable NativeMidiProgram fRetMidiProgram;
198 mutable String fRetMidiProgramName;
199 const char* fNextFilename;
200 CarlaMutex fProgramChangeMutex;
201 const NativeMidiPrograms& kPrograms;
202 const uint32_t kNumOutputs;
204 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginWithMidiPrograms)
207 /**@}*/
209 // -----------------------------------------------------------------------
211 #endif // CARLA_NATIVE_PROGRAMS_HPP_INCLUDED