Support for custom scales?

Huh, it been a while … but was thinking about this again and made a monkeypatch for it:

#scale_patch.rb
class SonicPi::Scale

  def initialize(tonic, name, num_octaves=1)
    if name.is_a?(Array)
      intervals = name
      name = :custom
    else
      name = name.to_sym
      intervals = SCALE[name]
    end
    raise InvalidScaleError, "Unknown scale name: #{name.inspect}" unless intervals
    intervals = intervals * num_octaves
    current = SonicPi::Note.resolve_midi_note(tonic)
    res = [current]
    intervals.each do |i|
      current += i
      res << current
    end

    @name = name
    @tonic = tonic
    @num_octaves = num_octaves
    @notes = res
    super(res)
  end

end

Example usage:

load scale_patch.rb
my_scale = scale :C, [1,2,1,2,2,2,1,2,1,2,3,2,2,1]
play_pattern_timed my_scale, 0.125

or something more fun like

24.times do
  my_scale = scale :E3, [1,2,3,4].pick(12)
  play_pattern_timed my_scale, 0.125
end
2 Likes