{"id":16266748,"url":"https://github.com/jarmitage/resonators","last_synced_at":"2025-08-20T00:16:56.978Z","repository":{"id":34444848,"uuid":"178435264","full_name":"jarmitage/resonators","owner":"jarmitage","description":"Resonant filter bank synthesis on Bela based on [resonators~] Max/Pd object","archived":false,"fork":false,"pushed_at":"2022-03-31T15:47:31.000Z","size":484,"stargazers_count":18,"open_issues_count":3,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T07:39:03.945Z","etag":null,"topics":["audio","bela","belaplatform","cpp","filters","maxmsp","puredata","resonators","synthesis"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jarmitage.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-29T15:54:32.000Z","updated_at":"2025-03-06T20:36:37.000Z","dependencies_parsed_at":"2022-08-08T01:00:48.610Z","dependency_job_id":null,"html_url":"https://github.com/jarmitage/resonators","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jarmitage/resonators","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarmitage%2Fresonators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarmitage%2Fresonators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarmitage%2Fresonators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarmitage%2Fresonators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jarmitage","download_url":"https://codeload.github.com/jarmitage/resonators/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jarmitage%2Fresonators/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268171959,"owners_count":24207437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","bela","belaplatform","cpp","filters","maxmsp","puredata","resonators","synthesis"],"created_at":"2024-10-10T17:42:58.911Z","updated_at":"2025-08-01T05:04:41.713Z","avatar_url":"https://github.com/jarmitage.png","language":"C++","readme":"# Resonators\n\nResonant filter bank synthesis on Bela based on the [[resonators~] Max/Pd object](https://github.com/CNMAT/CNMAT-Externs/blob/6f0208d3a1/src/resonators~/resonators~.c):\n\n```cpp\n#include \u003cBela.h\u003e\n#include \"Resonators.h\"\n#include \"Model.h\"\n\nResonatorBank resBank;\nResonatorBankOptions resBankOptions = {};\nModelLoader model;\n\nbool setup(BelaContext *context, void *userData) {\n  model.load(\"models/marimba.json\");\n  resBankOptions.total = model.getSize();\n  resBank.setup(resBankOptions, context-\u003eaudioSampleRate, context-\u003eaudioFrames);\n  resBank.setBank(model.get());\n  resBank.update();\n  return true;\n}\n\nvoid render(BelaContext *context, void *userData) { \n  for (unsigned int n = 0; n \u003c context-\u003eaudioFrames; ++n) {\n    float in = audioRead(context, n, 0); // an excitation signal\n    float out = resBank.render(in);\n\n    audioWrite(context, n, 0, out);\n    audioWrite(context, n, 1, out);\n  }\n}\n```\n\nThe corresponding `marimba.json`:\n\n```javascript\n{\n  \"metadata\": { \n    \"name\":        \"marimba\",\n    \"fundamental\": 800,\n    \"resonators\":  8\n  },\n  \"resonators\": [\n    { \"freq\": 800,  \"gain\": 0.500000, \"decay\": 0.2 },\n    { \"freq\": 1600, \"gain\": 0.033333, \"decay\": 0.4 },\n    { \"freq\": 2400, \"gain\": 0.016666, \"decay\": 0.6 },\n    { \"freq\": 3200, \"gain\": 0.006666, \"decay\": 0.7 },\n    { \"freq\": 4000, \"gain\": 0.003333, \"decay\": 0.8 },\n    { \"freq\": 4800, \"gain\": 0.001666, \"decay\": 0.9 },\n    { \"freq\": 5400, \"gain\": 0.000666, \"decay\": 1.0 },\n    { \"freq\": 6200, \"gain\": 0.000333, \"decay\": 1.0 }\n  ]\n}\n```\n\n---\n\n### Bela examples\n\n1. An individual resonator.\n2. A bank of resonators based on a model file.\n3. Loading updated models periodically into a bank of resonators via `scp`.\n4. Multiple banks of resonators based on a model file, tranposed up a scale.\n5. Combination of examples 3 \u0026 4, plus Bela scope for inputs.\n\n---\n\n### Resonance models\n\nCollection of ~100 resonance models of mostly percussion instruments, based on [aLib resonance models](http://alimomeni.net/project/alib-resonance-models/)\n\n- Indian percussion instruments (Chakoa, Dhalki, Hand-Dhal, khol, Madal, Manjeera, Mirdangam, Stick-Dhal)\n- A set of 12 Ghanaian double-bells, recorded with hard and soft beater\n- Guitar strings plucked behind the bridge\n- SampleCell Dumbeck, Gong\n\n---\n\n### `p5.js` GUI\n\nWIP! Relies on Bela WebSocket server wrapper and integration with `Resonator.h`.\n\n- `BelaWS.js`: connects to Bela over a Web Socket\n- `Resonators.js`: real-time bidirectional updating of resonator model, using `p5.js`\n\n![p5_gui](https://raw.githubusercontent.com/jarmitage/resonators/master/img/p5_gui.png)\n\n---\n\n### Jupyter \u0026 Python\n\nSome convenience functions, not pretty yet...\n\n- Importing Max/Pd formatted models (see references below)\n- Working with models as Pandas dataframes\n- Loading/saving/converting to/from `.csv`  `.coll` \u0026 `.json`\n- `scp`-ing models to Bela for real-time updates\n\n![jupyter_plot](https://raw.githubusercontent.com/jarmitage/resonators/master/img/jupyter_plot.png)\n\n---\n\n### Max/Pd References\n\n- Max version: https://github.com/CNMAT/CNMAT-Externs/releases/tag/v1.0.4 (resonators~.mxo)\n- Pd example patches: https://github.com/batchku/aLib/tree/master/for%20resonators\n- Example resonance models: http://alimomeni.net/project/alib-resonance-models\n\n---\n\n### Python Bindings\n\nBindings for Python are available via [Swig](http://www.swig.org/), meaning Resonators can be used from a Python script or a Jupyter notebook:\n\n```python\nmodel = resonators.ModelLoader()\nmodel.load(args.model_path)\nrb_ops = resonators.ResonatorBankOptions()\nrb_ops.total = model.getSize()\nrb = resonators.ResonatorBank()\nrb.setup(rb_ops, 44100.0, 128)\nrb.setBank(model.getShiftedToNote(\"c4\"))\nrb.update()\nout = rb.render(0.5)\n```\n\n- At the top level directory, run `cmake .`, and then `make`.\n- If this succeeds, run `py/test_bindings.py` to confirm.\n- For now, you can crudely `sys.path.append` the directory to import the module.\n\n_Note_: this has been tested with Python 3.6.5 (and should support Python 2.7+), SWIG 4.0.0 and CMake 3.14.3 on OSX 10.14.\n\n---\n\n### License\n\nUnless otherwise stated, [CC0](https://creativecommons.org/share-your-work/public-domain/cc0/).\n\n---\n\n### TODO\n\n##### Resonators\n- More comprehensive comments/documentation\n- Add examples for real-time manipulation of model parameters\n- Add functions for useful/interesting real-time variation of model parameters\n\n##### Models\n- Real-time functions for simple scaling of `gain` and `decay` parameters\n- Generate models (offline) based on samples (using [HPSS](http://librosa.github.io/librosa/generated/librosa.decompose.hpss.html)?)\n\n##### Data analysis/offline exploration\n[x] Python bindings for `Resonators.cpp` for offline synthesis (merged [05c089c](https://github.com/jarmitage/resonators/commit/291681df3f56fd44a8118ba048b1ceeae8ed7749))\n- Clean up Python utils\n- Add Jupyter notebook examples\n\n##### p5.js\n- Refactor the `p5.js` sketch to work with [topic/p5-gui](https://github.com/adanlbenito/Bela/tree/topic/p5-gui)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarmitage%2Fresonators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjarmitage%2Fresonators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjarmitage%2Fresonators/lists"}