- Edited
I have ported CNMAT's [resonators~] object to Bela C++: https://github.com/jarmitage/resonators
It enables resonant filter bank synthesis and loading of resonance models.
Basic example:
#include <Bela.h>
#include "Resonators.h"
#include "Model.h"
ResonatorBank resBank;
ResonatorBankOptions resBankOptions = {};
ModelLoader model;
bool setup(BelaContext *context, void *userData) {
model.load("models/marimba.json");
resBankOptions.total = model.getSize();
resBank.setup(resBankOptions, context->audioSampleRate, context->audioFrames);
resBank.setBank(model.get());
resBank.update();
return true;
}
void render(BelaContext *context, void *userData) {
for (unsigned int n = 0; n < context->audioFrames; ++n) {
float in = audioRead(context, n, 0); // an excitation signal
float out = resBank.render(in);
audioWrite(context, n, 0, out);
audioWrite(context, n, 1, out);
}
}
The corresponding marimba.json
:
{
"metadata": {
"name": "marimba",
"fundamental": 800,
"resonators": 8
},
"resonators": [
{ "freq": 800, "gain": 0.500000, "decay": 0.2 },
{ "freq": 1600, "gain": 0.033333, "decay": 0.4 },
{ "freq": 2400, "gain": 0.016666, "decay": 0.6 },
{ "freq": 3200, "gain": 0.006666, "decay": 0.7 },
{ "freq": 4000, "gain": 0.003333, "decay": 0.8 },
{ "freq": 4800, "gain": 0.001666, "decay": 0.9 },
{ "freq": 5400, "gain": 0.000666, "decay": 1.0 },
{ "freq": 6200, "gain": 0.000333, "decay": 1.0 }
]
}
The repo features:
- 5 Bela examples.
- ~100 resonance models (based on Ali Momeni's) in a JSON format.
- Python bindings for offline rendering / data science, and utility functions for working with models (still a bit messy).
- A work in progress p5.js interface for real-time GUI manipulation that works over Web Sockets.
It is designed for real-time manipulation of the model parameters, and has been trialled in a concert involving adding resonance to a pitch-tracked violin.
I am considering methods for generating models based on audio recordings, and methods for non-linear pitch envelope generation to "animate" the models. If anyone has any suggestions regarding those ideas I'd be grateful to hear them.
If you use this and find any problems or have feedback/suggestions, please let me know!
EDIT: Performance wise, I have been able to run ~120 resonators if I'm not updating in real-time, less if there's a lot of real-time updates happening. There hasn't been much thought put into optimisation yet, so suggestions welcome there too.