RNBO Unity Audio Plugin
Alex Van Gils
Apr 19 2023 | 3:12 pm
Hello everyone, this post is to announce an experimental integration that we are excited to share — an adapter for Unity’s Native Audio Plugin. Using RNBO’s C++ source export, this repository will help you build a plugin which provides an API that facilitates integration of your RNBO device with the Unity game engine.
As described, this is experimental software. Please use at your own risk and know that anything in this repository could change in the future. However, we very much want to hear your thoughts and see what you make.
If you find problems or have feature requests, please track them using the GitHub repository’s issues page.
https://github.com/Cycling74/rnbo.unity.audioplugin
Have fun!
- Jan KlugApr 24 2023 | 6:31 amExperimental.. risk.. fun.. what a nice combination! :D Thank you so much for this additional extension or extension of the addition; have been checking the forum once a week in the home that this announcement would pop up (as I hadn‘t yet managed to combine RNBO, Unity and Android).. Will dive in right away!
- Jan KlugMay 26 2023 | 7:25 amHey Alex, I'm building RNBO-generated audio plugins into a multiplayer theatre-VR-installation-performance hybrid, and it's working great so far using Unity and Quest 2. Thanks for this nice starting point!I do have some questions though that don't fall into the category problem or feature request. Do you prefer that I post them here, or also via GitHub issues?
- Alex Van GilsMay 26 2023 | 12:32 pmHi Jan, it’s so cool that you are using this for your project — it sounds awesome.Please feel free to share your thoughts here, and if it makes sense to move some of them over to the repo as an issue, we can do that later!
- Jan KlugMay 26 2023 | 6:03 pmYes, since the announcement of RNBO I had been waiting to be able use it in our Unity VR project.. Good timing! It's an audiovisual experience for (for now) 4 persons in a shared physical / virtual space, where they can engage and interact sonically. And play with a room-sized sequencer... I'm mainly using about 6 RNBO-synths per person, which I control individually via OSC. As all players are networked and hear/see the others, the result is that on each Oculus 2 there are at least 24 synths playing simultaneously, on spatialized objects. And that works fine!Right now they play continuous sounds, but I'd like to make them a spatially distributed synthesizer, so would like to send midi notes to them from Max, Ableton or both - or use the spatial sequencer for that. One question that I'm having is this: The setup I use now is a hacky modification of the CUSTOM_FILTER example code, via local (and spatialized) Audio listeners. But I'm unsure of how to include the Synth Helper as in this example... Doesn't that reside in the audio Mixer? How does that combine with the spatialized setup?
- Alex Van GilsMay 26 2023 | 6:54 pmHi Jan, thank you for this! If it becomes reasonable to do so, it would be super cool if you shared your project. I understand your question. Basically, if you are making a custom filter, like the CUSTOM_FILTER example, you don't need to use the Helper in order to get access to those methods like SendMIDINoteOn() -- you can get the methods from the Handle directly. The Helper is really there to help you access an instance of your plugin which has been loaded onto the audio mixer. Here's an example where we send a MIDI CC message to our custom filter called "synth." You can use the same principle to send MIDI notes with SendMIDINoteOn(), etc, as in the MIDI example.Certainly let me know if I can help further or if this doesn't answer your question.
using UnityEngine; [RequireComponent(typeof(AudioSource))] public class OrbPlayer : MonoBehaviour { TestOrbsHandle synth; public OrbPlayer() : base() {} void Start() { synth = new TestOrbsHandle(); // MIDI channel 1, controller number 1, value 110 synth.SendMIDICC(1, 1, 110); } void Update() { synth.Update(); } void OnAudioFilterRead(float[] data, int channels) { if (synth != null) { synth.Process(data, channels); } } }
- Jan KlugMay 26 2023 | 10:38 pmAh thanks, that de-confuses me in that matter, and it works! Another confusion I have is about the updating of Parameters. Does that have to happen in each Update() cycle for *all* the parameters, likevoid Update() { synth.SetParamValue(param_ratio, ratio); // and then quite some more like this synth.Update(); }- even when the parameter doesn't change in-between?
- Alex Van GilsMay 30 2023 | 8:59 pmHi Jan,Thank you for the question -- You don't need to update the parameter value every frame, when Update() is called. You can call SetParamValue() outside of the Update() method.For example,
using UnityEngine; [RequireComponent(typeof(AudioSource))] public class DrumFilter : MonoBehaviour { RNBODrumHandle drums; readonly System.Int32 numerator = (int)RNBODrumHandle.GetParamIndexById("numerator"); readonly System.Int32 denominator = (int)RNBODrumHandle.GetParamIndexById("denominator"); public DrumFilter() : base() {} void Start() { drums = new RNBODrumHandle(); } void Update() { drums.Update(); if (Input.GetKeyDown(KeyCode.T)) { ChangeSubdivision(Random.Range(1f, 4f), Random.Range(1f, 8f)); } } void OnAudioFilterRead(float[] data, int channels) { if (drums != null) { drums.Process(data, channels); } } void ChangeSubdivision(float numeratorValue, float denominatorValue) { drums.SetParamValue(numerator, numeratorValue); drums.SetParamValue(denominator, denominatorValue); } }