I’ve been working for quite a while on a collection of useful methods to help with Sonic Pi, and it’s finally ready to share with y’all!
It’s called YummyFillings.rb, and it’s on github here:
I found myself having to reinvent the wheel, so I decided to build some reusable methods for really common tasks. Examples are lfos and envelopes for any slidable param, trancegates, strumming and arpeggiating chords, making a straight rhythm swing (even to odd beats), arranging multiple voices for more compositional approaches (as opposed to live-coding in the moment), converting drum notation and a simplified musical notation into playable arrays of values to drive performance, etc.
Two things might be of particular interest. The method arrange supports very sophisticated arrangements of multiple voices together. And convertdrumnotation supports simple notation like “x—x—x—x—”, but also controlling dynamics with numerals like “2—4—6—8” (with 9 the loudest and 1 the quietest), easy polyrhythms by subdividing the bar into however many beats you specify (e.g. “x–x–x–x–” will play a 3/4 beat on one line, while “xxxx” is a four-on the floor kick). It also supports nesting subdivisions, a la Tidal Cycles, so “x[x[xx]]” gives the equivalent of “hqee”.
Lots to explore here.
To quote from the readme.md:
Yummyfillings.rb is a collection of ruby methods to make life easier when making music with Sonic Pi.
Load it using eval_file (e.g,: eval_file “E:/Yummy/YummyFillings.rb” )
at the top of the buffer.
There are methods providing envelopes, lfos, trancegates, stutter effects, arpeggiation, transposition of samples,
orchestration of multiple voices, swinging rhythms, euclidean rhythms, etc.
There are also utilities and testing methods to make programming simpler and more readable.
Methods grouped by purpose
Music performance
Method Name
Description
arpeggiate
plays a given chord/scale/array/ring in sequence, with the timing you specify
arrange
play multiple musical voices, each with their own rhythm, melody, etc.
funkify
plays a given synth/sample in a randomly generated funky rhythm
playdegreematrix
play melodies in a scale by specifying scale degrees
playline
simplified wrapper for arrange, plays one instrument line. Threaded by default.
strum
strums the chord passed in. Convenience wrapper for arpeggiate.
stuttersample
plays a sample, chopping it up and stuttering/reversing sections.
transposesample
transposes a sample, hiding the nasty math involved in pitch_stretch and rpitch.
Sound manipulation
Method Name
Description
env
apply an envelope to any sliding param for any synth or sample.
lfo
apply an lfo/mseg to any sliding param for any synth or sample.
trancegate
apply a polyrhythmic trancegate to any synth or sample.
Melody/rhythm manipulation
Method Name
Description
convertdrumnotation
converts drum notation (“x—x—x—x—”) to note-type notation (“q,q,q,q”).
cooktime
converts notation (“q”) to time duration (1.0).
cooktimes
converts a sequence of notation (“q, dq, dq”) to an array of time durations [1, 1.5, 1.5].
degreestoabsolutenotes
converts scale degrees to absolute notes.
euclidiate
applies euclidean rhythms to generate metrical sequence, in notation ([1.5, 1.5, 1]). Convenience wrapper for spreadtobeats.
funkyrandom
generates a random funky rhythm, returned as an array of times.
humanize
applies a random amount of humanization to a given time array.
spreadtobeats
turns a spread into notation for rhythm. Euclidiate wraps this in a friendlier interface.
generates tuples of any time amount. Returns notation if possible.
Array/hash/ring manipulation
Method Name
Description
argstohash
converts an argument string (“amp: 2, cutoff: 60”) to a hash.
argstostring
converts an argument hash ({amp: 2, cutoff: 60}) to a string.
arrayhashtohasharray
converts a hash of arrays to an array of hashes.
cleanchordorscale
turns a chord or scale into a flat array.
paddedrowstocolumns
transforms an array of arrays, pivoting rows to columns and padding short arrays by repeating values.
rowstocolumns
transforms an array of arrays, pivoting rows to columns, but padding short arrays with nils.
setarg
set arguments in an argument hash.
tickargs
if argument values are specified as arrays, will tick through individual values on consecutive calls.
striptrailingnils
strips trailing nils from an array. Useful with rowstocolumns.
Tests and comparisons
Method Name
Description
boolish
test for values that are kinda false, e.g., “”, empty array, 0, etc.
divisibleby
tests whether one number is evenly divisible by another.
equalish
tests for approximate equality. Useful for comparing floats, e.g. triplets.
listorring
tests whether a value is an array, hash or ring.
ringorlist
same as listorring
samplebpm
returns the bpm of a given sample.
tickable
same as listorring
Utilities
Method Name
Description
debugprint
prints anything to stdout, optionally logging to a file, optionally expanding arrays and hashes.
overridekwargs
used to support passing named parameters to methods.
stripparams
used to strip parameters from kwargs that match method params. Useful for collecting params to pass to methods like play or sample.
yummyhelp
print help info to stdout for methods herein.
yh
wrapper for yummyhelp
I’d love to hear feedback. I hope y’all find these things useful. If you run into any bugs, please hit me up and I’ll fix it asap. I’ve done a bunch of testing – I’ve worked on this for months – but no doubt I have blind spots.
Enjoy!
Wow, this must have been an enormous amount of work, thank you! I’ve been wondering about some of the Ruby methods people are using, x-x-x- etc and v interested in arpeggiation and transposing samples.
I’ve downloaded, using eval + amended path, is playing notes, have tried with egs (these are very useful) from the read.me but getting a runtime error referencing a directory which looks to be on your system? I’m new to Ruby so may be doing something basic wrong, sorry! Is it OK to post q’s here, or do you prefer we send somewhere else? Thank you.
Yikes! Sorry about that!
It’s probably the logfile path in debugprint. Just open YummyFillings.rb in a text editor (too big for sonic pi’s editor), search for “define :debugprint”, and you’ll see an argument that is logfile. Change it to a path that points to something on your system. Or, just set logtofile to false.
If that doesn’t fix it, please post the code & the error message.
Hurray! Thank you - removing that line has worked and I’ve had a quick play. It will need a lot more playing, there’s so much in there - have had fun with arpeggiate, and transposesample is something else! Being able to pitchshift and put relative pitches into an array is fantastic (plus duration), means you can easily make melodic sequences from samples. I’ve tried this a bit in other ways, but have v limited skills and this makes it easier.
Aside: have been playing with moog Werkstatt and through that, getting into :mod_pulse and :mod_range (relative intervals) as a way to do polyphony with monophonic sound source (oscillator or recorder sample). Arpeggiate and transposesample are great for this.
Will no doubt be back with more q’s! Thank you for super festive pressie for the Sonic Pi community.
PS your examples in the READ.ME are very useful as a starting-point for Ruby-new people. Here’s my wee transposesample. The SonicPi guitar works really well.
PS the 2nd array, for anyone trying this, is 0= tonic, 5 = +5 semitones, +7 semitones etc
live_loop :pitchshift do
mysample = :guit_em9
[60, 120, 60].each do | thisbpm |
[0, 5, 7,5].each do | thispitch |
use_bpm thisbpm
transposesample mysample, 8, thispitch
sleep 4
end
sleep 1
end
end
I’m glad it’s working for you. I love your example.
I’ve tweaked it a bit, by adding some variables to allow more musical language, and to use samplebpm to synchronize to the sample: