Accessing soundfile resources

I write an UGen that needs to load sound files. I would like the sound files to be located in a “standard” location like Library/Application\ Support/SuperCollider path on macOS. So the UGen would need to know this path.

Some variables like Platform.userExtensionDir are defined in Platform | SuperCollider 3.12.2 Help, but I would need to have them at C++ level.

I see SC_Filesystem::defaultResourceDirectory() in the SC source code, but this is not part of the public headers to be used by an Ugen. So is there a way for an Ugen to access this information ?

In short: no. Of course, you can always hardcode these paths in your Ugen.

BTW, I would highly recommed to use scsynth’s buffer commands for allocating soundfiles. Is there a particular reason why this is not an option?

I should also mention that soundfile loading should always be done as an asynchronous command and this is not trivial to do (safely) within an Ugen! This is another reason why you should prefer the buffer commands.

The use case is adding support for the “soundfile” primitive in the faust2supercollider command. So the Faust DSP code is:

process = 0,_~+(1):soundfile("sound[url:{'tango.wav'}]",2):!,!,_,_;

assuming the ‘tango.wav’ file can be copied in Library/Application\ Support/SuperCollider.

Then the C++ architecture is: https://github.com/grame-cncm/faust/blob/master-dev/architecture/supercollider.cpp where:

and files are loaded once in memory in void Faust_Ctor(Faust* unit)

I see! This doesn’t really sound real-time safe, though.

Keep in mind that the UGen constructor runs on the audio thread, so all code in Faust_Ctor must be real-time safe. This is very different from VST plugins where the constructor typically runs on the main/UI thread and there are pretty much no restrictions on what you can do.

I have the suspicion that unit->mDSP->instanceInit((int)SAMPLERATE); isn’t real-time safe, either.

Sounds good!

I just misread

and files are loaded once in memory in void Faust_Ctor(Faust* unit) in

as meaning that the files are loaded in the constructor. But what you probably meant was

once in memory, the files are loaded in void Faust_Ctor(Faust* unit) in

:slight_smile:

Anyway, this certainly explains why you can’t use the Buffer mechanism, as everything needs to be allocated upfront.

unit->mDSP->buildUserInterface

And this is also realtime safe?

Yes, no memory allocation or non RT stuff.

:+1: (and some more characters)