Doing some mucking around with optimization in Unity. Trying to figure out where the output from csound is actually passed to Unity’s audio engine. Was trying to figure out if there’s a way to apply Unity’s “Preserve Sample Rate” setting that they have for audio sample files to csound, so it doesn’t automatically upsample in the case of mismatch. Still delving into Unity and how it works, so this may not be possible, but looking into it
Yes everything works thanks to the OnAudioFilterRead callback, that is used to read the AudioSource samples and pass them to Csound (if an AudioClip is provided, and processAudioClip is true) and then fill the AudioSource samples with the output from Csound.
Ahh okay, that makes sense. I wonder if there is a way to prevent Unity’s default upsampling. OnAudioFilterRead is called based on Unity’s AudioSettings sample rate correct? I wonder if there’s a way to force synchronization with csounds sample rate on a single object or if that is currently impossible. My initial thought is to have some sort of check on each OnAudioFilterRead where frames not within the csounds instance sample rate are essentially ignored. I don’t know if OnAudioFilterRead would be stable enough for an operation like this though, if it’s linked to some constant in a manner similar to FixedUpdate or if there’s fluctuations that might make such an approach unreliable. The documentation on how it actually functions seems sparse
Having a generic low, medium and high setting for csounds with predetermined ksmps and sr values to save DSP CPU for sounds that might be more in the background, where it wouldn’t matter as much if they have a very sample rate would be extremely handy.
Realized kind of a janky solution that seems to do the trick
If your csound instance is set to run at a sample rate lower than that of your Unity project, you can just have a quick check of the csound instance’s sample rate and the projects and then set the pitch of the AudioSource object. So 10K sample rate csound instance, 44.1K sample rate Unity project, AudioSource pitch set to 0.2268
The instance I was running, differences in performance:
10K sr Unity Project, 10K sr csound, Audio Source Pitch 1.0: peak~2.4% consumption
44.1K sr Unity Project, 10K sr csound, Audio Source Pitch 1.0: peak~9.1% consumption
44.1K sr Unity Project, 10K sr csound, AudioSource Pitch 0.2: Peak~2.4% consumption
So this seems to solve the issue without any complicated solutions. Obviously if there was a way to forcibly set OnAudioFilterRead’s sample rate per AudioSource instance, that would be ideal for long term stability purposes, but this seems to do the trick well enough with current versions of Unity
This is very interesting, thanks for reporting.
I never tried messing with the pitch of the CsoundUnity’s AudioSource, this is really smart!
Yes the ideal solution would be having more control on how the OnAudioFilterRead callback works (and a more detailed documentation).
I will add this trick to the CsoundUnity docs (and add you to the contributors if you want), many thanks!!
Oh awesome, yeah absolutely, glad to be of service
I modified the code so I can easily set the sample rate in inspector right on the Csound Unity script. I could push up a PR if you wanted to scope if it’s something you may want to include in the package.
Yes please!
I tried messing with the AudioSource’s pitch and I didn’t hear / see any change, so yes a pull req would be great
Be aware that I pushed a new version yesterday!
You need only fork the current project. Clone the fork to your PC, and checkout the branch you wish to make the pull request to. Make your changes. Push your changes to your fork. Then from your fork’s github page, you can make a pull request. You don’t need any permissions to do this.
So got another question. Where is the AudioSource actually linked to csound’s out opcode?
Does this happen somewhere in CsoundUnityBridge? Or is this somewhere in the precompiled DLL?
There is no link, the destination of the out opcode depends on the Csound options.
In this case we grab that output with the API (GetOutputSample).
Sorry yesterday I didn’t have time to look at the pull request!
Ah okay, thanks for clarifying, finally clicked. One final question, is there a maximum number of output channels that csounds supports in a single instance? I see up to 8 in the documentation, but I’m assuming there’s a way it could write to more than that
I’m not sure, maybe @rory has more info on this.
For sure you can use chnset to output as many aux channels you need.
In CsoundUnity we’re limited by Unity of course, in the ProjectSettings/Audio you can go up to Surround 7.1. But the availability of this channel setup depends on the target platform.