VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
vae_bank_manager.hpp
Go to the documentation of this file.
1#ifndef _VAE_BANK_MANAGER
2#define _VAE_BANK_MANAGER
3
4#include "./vae_util.hpp"
5#include "./vae_types.hpp"
6#include "./pod/vae_bank.hpp"
8#include "../../external/tklb/src/types/audio/resampler/TResampler.hpp"
10namespace vae { namespace core {
11 /**
12 * @brief Holds all the banks
13 *
14 */
16 HeapBuffer<Bank> mBanks; // All the currently loaded banks
17 VAE_PROFILER_MUTEX(Mutex, mMutex, "Bank Manager mutex")
19
20 void initMixer(Mixer& mixer, Size sampleRate) {
21 VAE_PROFILER_SCOPE_NAMED("Mixer Init")
23 for (auto& i : mixer.effects) {
24 if (i.name.empty()) { continue; }
25 i.effect = effect::EffectsFactory::create(i.name);
26 if (i.effect == nullptr) {
27 VAE_ERROR("Effect %s could not be loaded.", i.name.c_str())
28 continue;
29 }
30 i.effect->init(sampleRate);
31 }
32 }
33 public:
34 /**
35 * @brief Will unload all the banks
36 *
37 * @param rootPath
38 * @param sampleRate
39 */
40 void init(const char* rootPath, int sampleRate) {
41 VAE_PROFILER_SCOPE_NAMED("Bankmanager Init")
42 for (auto& i : mBanks) {
43 if (i.id != InvalidBankHandle) { continue; }
44 unloadFromId(i.id);
45 }
46 }
47
49 void lock() { mMutex.lock(); }
50 void unlock() { mMutex.unlock(); }
51 Bank& get(BankHandle bank) { return mBanks[bank]; }
52 bool has(BankHandle bank) {
53 const auto size = mBanks.size();
54 if (size <= bank) { return false; }
55 return mBanks[bank].id != InvalidBankHandle;
56 }
57
58 /**
59 * @brief Iterate all loaded banks
60 *
61 * @tparam Func Callable type
62 * @param func Callable
63 */
64 template <class Func>
65 void forEach(const Func&& func) {
66 VAE_PROFILER_SCOPE_NAMED("Foreach Bank")
67 Lock l(mMutex);
68 for (auto& i : mBanks) {
69 if (i.id == InvalidBankHandle) { continue; }
70 func(i);
71 }
72 }
73
74 Result load(const char* path, Size size, const char* rootPath, int sampleRate) {
76 VAE_INFO("Loading bank from file %s%s", rootPath, path)
77 Bank bank;
78 auto result = mBankLoader.load(path, size, rootPath, bank);
79 if (result != Result::Success) {
80 VAE_ERROR("Failed to load bank from file %s%s", rootPath, path)
81 return result;
82 }
83 return load(bank, sampleRate);
84 }
85
86 Result load(Bank& bank, int sampleRate) {
88 // TODO init mixer effects
89
90 if (bank.mixers.empty()) {
91 // Ensure there's a master channel per bank
92 bank.mixers.resize(1);
93 bank.mixers[0].id = 0;
94 bank.mixers[0].name = "Bank Master";
95 }
96
97 for (auto& m : bank.mixers) {
98 initMixer(m, sampleRate);
99 }
100
101 {
102 VAE_PROFILER_SCOPE_NAMED("Offline resampling")
103 for (auto& s : bank.sources) {
104 if (s.resample && s.signal.sampleRate && s.signal.sampleRate != sampleRate) {
106 }
107 }
108 }
109
110 {
111 Lock l(mMutex);
112 if (mBanks.size() < bank.id + 1) {
113 mBanks.resize(bank.id + 1);
114 }
115 mBanks[bank.id] = std::move(bank);
116 }
117 VAE_INFO("Bank %s loaded.", mBanks[bank.id].name.c_str())
118 return Result::Success;
119 }
120
121 Result addSource(BankHandle bankHandle, Source& source, int sampleRate) {
123 if (source.resample && source.signal.sampleRate && source.signal.sampleRate != sampleRate) {
125 }
126 auto& bank = mBanks[bankHandle];
127 Lock l(mMutex);
128 if (bank.sources.size() <= source.id) {
129 bank.sources.resize(source.id + 1);
130 }
131 bank.sources[source.id] = std::move(source);
132 return Result::Success;
133 }
134
135 Result addEvent(BankHandle bankHandle, Event& event) {
137 auto& bank = mBanks[bankHandle];
138 Lock l(mMutex);
139 if (bank.events.size() <= event.id) {
140 bank.events.resize(event.id + 1);
141 }
142 bank.events[event.id] = std::move(event);
143 return Result::Success;
144 }
145
146 Result addMixer(BankHandle bankHandle, Mixer& mixer) {
148 // TODO init mixer effects
150 Lock l(mMutex);
151 auto& bank = mBanks[bankHandle];
152 if (bank.mixers.size() <= mixer.id) {
153 bank.mixers.resize(mixer.id + 1);
154 }
155 bank.mixers[mixer.id] = std::move(mixer);
156 return Result::Success;
157 }
158
160 if (mBanks.size() < bank.id) {
161 mBanks.resize(bank.id);
162 }
163 mBanks[bank.id] = std::move(bank);
164 return Result::Success;
165 }
166
169 Lock l(mMutex);
170 if (mBanks.size() <= bankHandle) {
171 VAE_WARN("Could not unload bank with handle %i", bankHandle)
173 }
174 auto& bank = mBanks[bankHandle];
175 VAE_ASSERT(bank.id == bankHandle)
176 VAE_INFO("Unloading bank %s", bank.name.c_str())
177 // TODO use a smart pointer or something
178 for (auto& m : bank.mixers) {
179 for (auto& e : m.effects) {
180 if (e.effect != nullptr) {
181 delete e.effect;
182 }
183 }
184 }
185 bank = { }; // should free all the memory
186 return Result::Success;
187 }
188
189 void unloadAll() {
191 for (auto& i : mBanks) {
192 if (i.id == InvalidBankHandle) { continue; }
193 unloadFromId(i.id);
194 }
195 }
196 };
197
198 constexpr int _VAE_SIZE_BANK_MANAGER = sizeof(BankManager);
199} } // namespace vae::core
200
201#endif // _VAE_BANK_MANAGER
bool resize(const Size length, uchar channels)
! Will not keep the contents! Resizes the buffer to the desired length and channel count.
ushort sampleRate
Only relevant for resampling and oversampling.
Basically a bad std::vector without exceptions which can also work with foreign memory.
Definition: THeapBuffer.hpp:49
static void resample(Buffer &buffer, const uint rateOut, const uchar quality=5)
Resamples the provided buffer from its sampleRate to the target rate.
Result load(const char *path, Size length, const char *rootPath, Bank &bank)
Load a bank.json and all wav files referenced in it.
Holds all the banks.
Result load(const char *path, Size size, const char *rootPath, int sampleRate)
Result unloadFromId(BankHandle bankHandle)
Result addEvent(BankHandle bankHandle, Event &event)
void initMixer(Mixer &mixer, Size sampleRate)
HeapBuffer< Bank > & all()
Result addMixer(BankHandle bankHandle, Mixer &mixer)
HeapBuffer< Bank > mBanks
Bank & get(BankHandle bank)
void forEach(const Func &&func)
Iterate all loaded banks.
Result addSource(BankHandle bankHandle, Source &source, int sampleRate)
Result addBank(Bank &bank)
Result load(Bank &bank, int sampleRate)
void init(const char *rootPath, int sampleRate)
Will unload all the banks.
bool has(BankHandle bank)
static EffectBase * create(IdString &id)
constexpr Size MaxBlock
Maximum block size.
Definition: vae.hpp:276
constexpr unsigned char MaxChannels
Maximum channel count used to pre allocate buffers.
Definition: vae.hpp:268
constexpr int _VAE_SIZE_BANK_MANAGER
std::mutex Mutex
Definition: vae_types.hpp:52
std::unique_lock< Mutex > Lock
Definition: vae_types.hpp:53
Contains Typedefinitions and basic structures use by the public API and internally.
Definition: vae.hpp:31
unsigned int Size
How the elements are addressed in the heapbuffer.
Definition: vae.hpp:33
SmallHandle BankHandle
Definition: vae.hpp:40
Result
Return Types for most engine functions.
Definition: vae.hpp:73
@ ElementNotFound
Referenced data not found.
constexpr BankHandle InvalidBankHandle
Definition: vae.hpp:57
Bank object containing Sources, Mixers and Events Can be loaded and unloaded at runtime.
Definition: vae_bank.hpp:14
HeapBuffer< Mixer > mixers
Audio Mixers which can have effects ! is presorted !
Definition: vae_bank.hpp:16
BankHandle id
Definition: vae_bank.hpp:18
HeapBuffer< Source > sources
Audio sources defined.
Definition: vae_bank.hpp:15
An Event is used to control most of the eingines behavior.
Definition: vae_event.hpp:14
EventHandle id
Own id.
Definition: vae_event.hpp:30
ScratchBuffer buffer
Definition: vae_mixer.hpp:14
MixerHandle id
The handle of the mixer the signal will be routed to.
Definition: vae_mixer.hpp:21
AudioBuffer signal
Audio signal itself loaded by SourceLoader.
Definition: vae_source.hpp:21
bool resample
Whether the sound will be resampled when loading it.
Definition: vae_source.hpp:12
SourceHandle id
Definition: vae_source.hpp:10
#define VAE_ERROR(msg,...)
Definition: vae_logger.hpp:80
#define VAE_WARN(msg,...)
Definition: vae_logger.hpp:85
#define VAE_INFO(msg,...)
Definition: vae_logger.hpp:84
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.
#define VAE_PROFILER_MUTEX(type, name, desc)
#define VAE_PROFILER_SCOPE()
Profiles a scope.
Internal types used across VAE.
#define VAE_ASSERT(condition)
Definition: vae_util.hpp:11