Path to sounds folder

stuff like this doesn’t work

a = Buffer.read(s, “sounds/a11wlk01.wav”);

the sounds folder is in the sc app icon.
It doesn’t work by default.

I don’t know how to set up my startup file to have that line load a file
thanks

Platform.resourceDir +/+ "sounds/a11wlk01.wav"

The +/+ is a shortcut to join two strings and add a / between.

can I mod my startup file so I don’t have to change all the examples ?

You can use/adapt/etc something like this, maybe?

"sounds/a11wlk01.wav".sndDir

// Sound file sounds/a11wlk01.wav found in standard location
// -> /usr/local/share/SuperCollider/sounds/a11wlk01.wav
+ String {
	sndDir {
		var path = Platform.resourceDir +/+ this;
		if(path.pathName.isFile) {
			"Sound file % found in standard location".format(this).inform;
		} {
			"Sound file % NOT found in standard location".format(this).warn;
		};
		^path;
	}
	pathName { ^PathName( this ) }
}

Should relative paths such as this resolve relative to the current document, or to the app bundle? I’m posing this question because this is one of those things where you think “of course it should be relative to the bundle,” until someday you need it to be relative to the current document. It’s not possible to have the same syntax mean one or the other thing at different times. (FWIW my vote would be relative to the current document, because in a project, you’re more likely to store audio files in a “media/” or “resources/” folder alongside the code files – common use case – whereas accessing a11wlk01.wav is something you’re very unlikely to do in production code.)

Also note that only in macOS is there a concept of an app bundle that includes resources within it. What does “relative to the app” mean in Windows or Linux? (I have /usr/local/bin/sclang for the app, and /usr/local/share/SuperCollider/sounds/a11wlk01.wav – not so obvious.)

There was a proposal a while ago for a class to simplify references to helpfile resources. But now I think something a little bit different might be better – perhaps a “search paths” class where you give it a relative path and it finds the first matching folder. (Max and Pd both have preferences panels for this.)

SearchPaths {
	classvar <paths;

	*initClass {
		paths = [
			{
				var p = thisProcess.nowExecutingPath;
				if(p.notNil) { p.dirname } { "/dummy" };
			},
			Platform.resourceDir,
			Platform.resourceDir +/+ "sounds"];
	}

	*addPath { |path|
		if(paths.includesEqual(path).not) {
			paths = paths.add(path);
		}
	}

	*removePath { |path|
		var size = paths.size;
		paths.reverseDo { |p, i|
			if(p == path) {
				paths.removeAt(paths.size - i - 1);
			}
		}
	}

	// simpler usage: SearchPaths("myfile.wav")
	*new { |relPath|
		var dir = paths.detect { |d|
			File.exists(d.value +/+ relPath)
		};
		^dir +/+ relPath
	}
}

Then b = Buffer.read(s, SearchPaths("a11w1k01.wav")).

(Haven’t tested removePath – just a sketch before running to work. Also this sketch doesn’t recursively search subdirectories but that’s not hard.)

EDIT: Added support for relative-to-current-path.

hjh

2 Likes

just needed to set my runtime directory. its was that simple

1 Like