I wanted to give out the semitone steps in a scale: The result for (scale :C1, :blues_minor, num_octaves: 1) should be [3, 2, 1, 1, 3, 2]. With the help of Perplexity I stumbled over the very handy Ruby function each_cons, with which you can take a part of an array. If you combine this function with the map function the solution is a one-liner:
print "blues minor halftone steps: "
+ (scale :C1, :blues_minor, num_octaves: 1).to_a.each_cons(2).map { |a, b| b - a }.to_s
1 Like
Also, if you’re comfortable enough with using the inner Sonic Pi source code in your composition,(with the understanding that there’s no guarantees internal functions remain the same into the future), you can access the scale intervals directly:
puts SonicPi::Scale::SCALE[:blues_minor]
=> [3, 2, 1, 1, 3, 2]
Scale names can be found in the ‘Lang’ section of the help window of course, or in the source code on GitHub at sonic-pi/app/server/ruby/lib/sonicpi/scale.rb at c14f85823db44040b78456ab5f8f5084953ef9e1 · sonic-pi-net/sonic-pi · GitHub.
1 Like
Thanks, that is really cute! But is there any documentation for this syntax with double colons? In the official help file I could not find anything.
This also works with chords, just tried it out
puts SonicPi::Chord::CHORD[:minor]
No documentation in Sonic Pi itself - the difference is that those functions in “SonicPi:: …” come from deep within Sonic Pi’s own source code, rather than the functions provided to users directly.
The ‘::’ is Ruby’s way of writing ‘namespaces’ - which are a way to organise modules of code into groups. You’d want to search for information about Ruby namespaces if you want to find out more.
Thanks, I found docs about ruby namespaces, for example here:
https://www.geeksforgeeks.org/ruby/namespaces-in-ruby/
I just realized that I can use .notes instead of .to_a in my first code example:
puts (scale :B4, :blues_minor).notes.each_cons(2).map { |a, b| b - a }
Thanks for that tip! I was unaware of each_cons, but it’s super handy. Nicely applied to scales, too!