1#ifndef _VAE_BANK_LOADER
2#define _VAE_BANK_LOADER
4#include "../vae_types.hpp"
5#include "../vae_config.hpp"
6#include "../vae_util.hpp"
7#include "../pod/vae_source.hpp"
8#include "../pod/vae_event.hpp"
9#include "../pod/vae_bank.hpp"
12#include "../../wrapped/vae_fs.hpp"
15 #include "../../../external/headeronly/json.h"
16 #include "../../../external/headeronly/json.c"
20namespace vae {
namespace core {
22 static void*
allocate(
size_t size,
int zero,
void* context) {
24 void* ptr =
reinterpret_cast<void*
>(allocator.
allocate(size));
33 allocator.
deallocate(
reinterpret_cast<char*
>(ptr), 0);
51 const char* encoded = path;
56 VAE_DEBUG(
"Started loading bank %s", path)
69 length = jsonText.
size();
70 encoded = jsonText.
c_str();
75 json_settings settings = { };
82 json = json_parse_ex(&settings, encoded, length, 0);
85 json_value& data = (*json);
87 bank.
name = (
const char*) data[
"name"];
88 bank.
id = (json_int_t) data[
"id"];
94 auto sources = data[
"sources"];
95 if (sources.type == json_array) {
97 bank.
sources.resize(sources.u.array.length);
98 for (
auto& iraw : sources.u.array) {
104 String asd = (
const char*) i[
"name"];
108 VAE_ERROR(
"Duplicate Source id %i in bank %i", s.
id, bank.
id)
112 s.
name = (
const char*) i[
"name"];
113 s.
path = (
const char*) i[
"path"];
115 if (i[
"gain"].type == json_double) s.
gain = (double) i[
"gain"];
116 if (i[
"resample"].type == json_boolean) s.
resample = i[
"resample"];
117 if (i[
"stream"].type == json_boolean) s.
stream = i[
"stream"];
134 auto mixers = data[
"mixers"];
135 if (mixers.type == json_array) {
137 bank.
mixers.resize(mixers.u.array.length);
138 for (
auto& iraw : mixers.u.array) {
143 if (mixers.u.array.length <=
id) {
144 VAE_ERROR(
"Mixer %i:%i id out of bounds.",
id, bank.
id);
148 auto& m = bank.
mixers[id];
151 VAE_ERROR(
"Duplicate Mixer id %i in bank %i", m.id, bank.
id)
155 m.name = (
const char*) i[
"name"];
158 if (i[
"parent"].type == json_integer) m.parent = (json_int_t) i[
"parent"];
159 if (i[
"gain"].type == json_double) m.gain = (double) i[
"gain"];
164 VAE_ERROR(
"Mixer %i:%i tried to mix to %i. ",
id, bank.
id, m.parent);
168 auto effects = i[
"effects"];
169 if (effects.type != json_array || effects.u.array.length == 0) {
continue; }
172 for (
auto& iraw : effects.u.array) {
175 json_int_t index = i[
"index"];
176 auto& e = m.effects[index];
177 e.bypassed = i[
"bypassed"];
181 for (
auto& j : i[
"parameters"].u.array) {
183 e.parameters[paramIndex].name = (
const char*) (*j)[0];
184 e.parameters[paramIndex].value = (double) (*j)[1];
191 auto events = data[
"events"];
194 bank.
events.resize(events.u.array.length);
195 for (
auto& iraw : events.u.array) {
199 if (events.u.array.length <=
id) {
200 VAE_ERROR(
"Event %i:%i id out of bounds.",
id, bank.
id)
212 e.
name = (
const char*) i[
"name"];
220 if (i[
"force_mixer"].type == json_boolean) e.
force_mixer = i[
"force_mixer"];
221 if (i[
"spatial"].type == json_boolean) e.
spatial = i[
"spatial"];
222 if (i[
"critical"].type == json_boolean) e.
critical = i[
"critical"];
223 if (i[
"loop"].type == json_boolean) e.
loop = i[
"loop"];
224 if (i[
"hrtf"].type == json_boolean) e.
HRTF = i[
"hrtf"];
225 if (i[
"attenuate"].type == json_boolean) e.
attenuate = i[
"attenuate"];
226 if (i[
"mixer"].type == json_integer) e.
mixer = (json_int_t) i[
"mixer"];
227 if (i[
"gain"].type == json_double) e.
gain = (double) i[
"gain"];
228 if (i[
"source"].type == json_integer) e.
source = (json_int_t) i[
"source"];
229 if (i[
"on_end"].type == json_integer) e.
on_end = (json_int_t) i[
"on_end"];
231 if (i[
"chained_events"].type == json_array) {
232 auto onStart = i[
"chained_events"].u.array;
234 VAE_ERROR(
"Event %i:%i has too many chained chained_events events.",
id, bank.
id)
237 for (
size_t j = 0; j < onStart.length; j++) {
245 json_value_free_ex(&settings, json);
const char * c_str() const
void append(const String &str)
SourceLoader mSourceLoader
Result load(const char *path, Size length, const char *rootPath, Bank &bank)
Load a bank.json and all wav files referenced in it.
static void * allocate(size_t size, int zero, void *context)
static void deallocate(void *ptr, void *context)
constexpr Size MaxChainedEvents
How many chained events can fit in chain_events on the core::Event structure.
Contains Typedefinitions and basic structures use by the public API and internally.
unsigned int Size
How the elements are addressed in the heapbuffer.
constexpr SourceHandle InvalidSourceHandle
constexpr EventHandle InvalidEventHandle
GenericHandle EventHandle
The handle used to address events within a bank.
Result
Return Types for most engine functions.
@ FileOpenError
File system could not load file.
@ BankFormatError
Generic bank loading error.
@ TooManyRecords
Can't fit all data in fixed size array.
@ BankFormatDuplicateIndex
A index is used muktiple times.
@ BankFormatBadMixHirarchy
A mixer can only write to mixers with lower ids than themselves (no recursion)
@ BankFormatIndexError
A index is out of bounds.
GenericHandle SourceHandle
constexpr MixerHandle InvalidMixerHandle
Bank object containing Sources, Mixers and Events Can be loaded and unloaded at runtime.
NameString name
Name of the bank used for debugging, needs to be last so it can be zero sized.
HeapBuffer< Mixer > mixers
Audio Mixers which can have effects ! is presorted !
PathString path
Path to the bank definition file.
HeapBuffer< Event > events
Events defined.
HeapBuffer< Source > sources
Audio sources defined.
An Event is used to control most of the eingines behavior.
EventHandle on_end
Event fired once the source is finished, not called when there's no source.
SourceHandle source
Handle to a source.
Sample gain
Volume applied to triggered voice.
@ random
triggers one random chained_events event
@ emit
Emits an event to the EventCallback defined in the engine config.
@ start
Starts a source if defined and every Event in chained_events.
@ stop
Stops a source if defined and stops every voice started from a event in chained_events.
bool attenuate
whether distance is taken into consideration
NameString name
Name for debugging.
MixerHandle mixer
Mixer the source gets written to.
bool force_mixer
Prevents overriding the mixer from chained events or fireEvent.
enum vae::core::Event::Action action
bool HRTF
Listener and event has to have hrtf set.
EventHandle chained_events[StaticConfig::MaxChainedEvents]
Events called when the source starts playing.
bool critical
wheather the voice can be killer
bool spatial
no spatial rendering at all
static constexpr MixerHandle MasterMixerHandle
This is the master mixer for a bank.
bool stream
If false entire sample will be loaded in ram, there's no streaming for now.
@ ogg
Uses stb_vorbis to decode oggs.
@ wav
Uses dr_wav to decode wavs.
@ generator
Not implemented.
PathString path
Filesystem path.
bool resample
Whether the sound will be resampled when loading it.
enum vae::core::Source::Format format
NameString name
Name for debugging.
Sample gain
Gain applied to every voice creatd frin this source.
Result load(Source &s, const char *path)
Loads a wav file for the resource.
Allocator used for all heapbuffers in VAE.
T * allocate(size_t n) noexcept
void deallocate(T *ptr, std::size_t n) noexcept
#define VAE_ERROR(msg,...)
#define VAE_DEBUG(msg,...)
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.
#define VAE_PROFILER_SCOPE()
Profiles a scope.