I want to add a global path which I can use in the code to provide something like a relative rather than absolute sample path. So I can prepare on one computer and copy to another without having to re-write all the sample paths in each buffer.
Currently I’ve put this into .sonic-pi/init.rb (on Windows)
# Sonic Pi init file
# Code in here will be evaluated on launch.
$mymusicpath = "C:/Users/guy/Music/Sonic Pi/"
Then I can put in the code e.g.
d = $mymusicpath + "foo/samples/"
sample d, "bar.ogg"
Works, but is there a standard sonic-pi-y way to do it?
Thanks but I’ve got multiple buffers, multiple songs and I don’t want to have to edit them all copying from one computer to another, where the paths will be different
Not quite! @soxsa - the idiomatic way to do this in Sonic Pi is to use set & get. It’s sort of like using global variables, though it’s a way to store and retrieve data in a global state store called Time State. It does this in such a way that it’s safe to share data between loops/threads without risk of things like race conditions etc.
It’s all described in section 10 of the tutorial. Have a read of that (and you can find set and get in the Lang help reference too).
Thanks Ethan - I’m good with get and set, using them happily all over now. But this is different as I want a global i.e. system-wide setting that is different on each computer (e.g. a Windows PC and an Raspberry Pi) but shared across all scripts/buffers.
For instance, I want to prepare on a Windows PC on a USB drive (scripts and samples, all local) then pop that directly in the RaspPi without any changes.
It’s never going to change for each system, so I don’t need set/get.
What I’ve done is probably fine, I just want to tune into the mainstream - Sam might have put in some mechanism just for this kind of thing, robust against upgrades. That kind of thing.
Oh, sure. Well, for the moment, there is no specific Sonic Pi mechanism for such a thing, but you can dip into plain Ruby if you want a cross platform way of referring to an absolute path.
If you’re not wanting to use get/set to refer to the path without using a global variable, one option is to make a function in your init.rb. I do something similar to this myself. Something like:
define :samps do |path|
"#{Dir.home}/Music/Samples/#{path}"
end
It doesn’t, IIRC.
Btw, keep in mind that custom pieces of Ruby like this are not officially supported and (though it’s unlikely) may stop working at some point in the future if Sonic Pi’s underlying code changes in some manner
I was looking at the amount of CPU taken by the Ruby interpreter and thinking it’s a bit on the high side vs the sound generation bit. But now I pleased that it is scripted as we can do things like this.
If you end up looking for more ways to reduce the CPU load, you may have seen sections in the tutorial that describe a few things to keep in mind - but if not, worth reading things such as FX in Practice. There’s bound to be other posts here on in_thread about it too - but if you still need to ask, go ahead - plenty of wisdom floating around
Thanks for that tip. I’d got the idea already of not putting fx nested too far down, but I hadn’t thought of putting fx outside the loop altogether. Just tried that on a song I’m working on right now, and it reduced the CPU a lot.
Outside the loop it doesn’t seem to update options on alt-R. Because, because…the fx is created in the ‘unseen’ main thread which never gets redefined? Anyway good for ‘set and forget’ things like overall reverb maybe.