I'm interested
To make this possible you have to create a complete list of all functions for every AudioStream object in the whole "Audio Library" saved as a string array,
so that every function can be called by name.
but fear not, as I have made functionality that extracts that information from the "Design Tool" embedded documentation
it's used by the "auto complete" functionality for the code editor.
And now I made a simple function that takes every object name
and go through every help to extract all the functions mentioned there.
you can check it out here
https://manicken.github.io/
When opened go for the settings tab (right side)
then "Development Tests"-"Export complete function list"
note. it will not show functions that are not mentioned in the help.
Hope it will be a start
The output format can easily be changed,
example the whole lockup table can be autogenerated.
Also my new design tool can use designs by classes as well,
then a object address will be "className"/mixer1/amplitude
but that will be taken care of by the "Design Tool"
what is needed then is some code generated by the "Design Tool" that maps all generated objects to the OSC table.
simple example:
Code:
// note the type numbers are taken from the "generated" list above
#define OSC_TYPE_AudioSynthWaveform 47
#define OSC_TYPE_AudioMixer4 34
#define OSC_TYPE_AudioOutputI2S 14
void decode_osc_funcs_AudioSynthWaveform(AudioStream *osc_obj, const char *func_name, const char *func_value) {
// pseudo code (don't know if it works) specially the string compare don't work like this
float val = std:stod(func_value);
AudioSynthWaveform* aswf = dynamic_cast<AudioSynthWaveform*>(osc_obj);
if (func_name == "amplitude")
aswf->amplitude(val);
else if (func_name == "frequency")
aswf->frequency(val);
else if (func_name == "offset")
aswf->offset(val);
else if (func_name == "phase")
aswf->phase(val);
// ... and so on
}
// same as above but for AudioMixer4 instead
AudioStream *asObjs[4];
int osc_types[4]; // used together with osc_names to determite which decode func to call
const char *osc_names[4] = { "wf0", "wf1", "mixer4", "i2s" };
AudioSynthWaveform wf0;
AudioSynthWaveform wf1;
AudioMixer4 mixer4;
AudioOutputI2S i2s;
void mapToOSC() {
int asObj_index = 0;
asObjs[asObj_index] = wf0;
osc_types[asObj_index++] = OSC_TYPE_AudioSynthWaveform;
asObjs[asObj_index] = wf1;
osc_types[asObj_index++] = OSC_TYPE_AudioSynthWaveform;
asObjs[asObj_index] = mixer4;
osc_types[asObj_index++] = OSC_TYPE_AudioMixer4;
asObjs[asObj_index] = i2s;
osc_types[asObj_index++] = OSC_TYPE_AudioOutputI2S;
}
void decode_osc(const char *type_name, const char *func_name, const char *func_value) {
// pseudo code
for (int i = 0; i < 4; i++) {
if (type_name == osc_names[i]) {
if (osc_types[i] == OSC_TYPE_AudioSynthWaveform)
decode_osc_funcs_AudioSynthWaveform(asObjs[i], func_name, func_value);
else if (osc_types[i] == OSC_TYPE_AudioMixer4)
//decode_osc_funcs_AudioMixer4 (asObjs[i], func_name, func_value);
// ... and so on
}
}
}
void setup() {
mapToOSC();
}
it's a mess but it should work in theory
I think it's best to autogenerate all decoding functions,
if we can just get one type working then it can be applied on all the others (by auto generation in the "Design Tool")
The CNMAT/OSC example don't care about function names at all, it's just the bare message handler.