Cycling74 / rnbo.unity.audioplugin

RNBO Adapter for Unity's Native Audio Plugin
MIT License
40 stars 8 forks source link

shared usage of buffers by multiple instances of rnbo? #32

Closed chausch closed 9 months ago

chausch commented 10 months ago

hi there, is it possible to access the same buffers by multiple instances by a rnbo plugin, without the need to load the same data into multiple buffers? i have many instances running at the same time (though not all activated at the same time) and the current implementation, by which one has to load the sample directly into the plugin quickly amounts to gigabytes of gigabytes of memory usage! thanks for any advice!

x37v commented 10 months ago

Unfortunately RNBO's buffers are always read/write as far as the plugin knows so to be safe we have to make copies of the data. I figure we could make an "unsafe" interface that would let you set a buffer without doing a copy if you know for sure that your rnbo patch doesn't do any writing/resizing, and this way you might be able to point directly to audio assets and simply have them loaded once?

chausch commented 10 months ago

that would be awesome!!! i'm working with spatial grains and there will be no recording in the rnbo plugin whatsoever!

x37v commented 10 months ago

@chausch I just created a new develop branch and pushed a change that adds this capability. I simply added Unsafe in the name of the method instead of marking it unsafe as I couldn't figure out how to get unity to allow me to use that code even though I set up my player to allow unsafe code or whatever it is.

The loading approach is the same as before, but you'll just have to manage having some global float [] that you pass into your LoadUnsafeReadOnlyDataRef methods.

Let me know if/how this works for you?

chausch commented 10 months ago

thank you so much! do i understand that correctly that i have to load the audio data into this float array at another location, and pass it to the rnbo plugin?

chausch commented 10 months ago

HA! it seems to work!! 🥳 i will test more and report back! thank you!!!

x37v commented 10 months ago

do i understand that correctly that i have to load the audio data into this float array at another location, and pass it to the rnbo plugin?

Yeah, if you look at the buffer documentation that I linked above you'll see the approach, loading the data into a float array. If you're only using one MonoBehaviour derived class for your setup, you might be able to use a static variable to hold it?

Something like:

using UnityEngine;
using Cycling74.RNBOTypes;

public class PlayerMovement : MonoBehaviour
{
    const int instanceIndex = 1;
    BufferPlayerHelper helper;
    BufferPlayerHandle plugin;

    public float speed = 6f;
    private static float[] samples;

    [SerializeField] AudioClip buffer;

    void Start() {
        helper = BufferPlayerHelper.FindById(instanceIndex);
        plugin = helper.Plugin;

        if (buffer != null && plugin != null)
        {
            if (samples == null) {
                samples = new float[buffer.samples * buffer.channels];
            }
            buffer.GetData(samples, 0);
            plugin.LoadUnsafeReadOnlyDataRef("playback", samples, buffer.channels, buffer.frequency);
        }
    }
}

seems like you figured it out though!

x37v commented 10 months ago

i will test more and report back! thank you!!!

we still have to make a single copy of the data as it could be MP3, int16 wav, etc etc and we need 32-bit float, but I'm curious to hear about the memory usage you're seeing after this change.

x37v commented 9 months ago

merged to main