Module: NoteTranspose

Defined in:
lib/note-transpose.rb

Defined Under Namespace

Classes: Error

Class Method Summary collapse

Class Method Details

.transpose(half_steps, *notes, pref_flat: false) ⇒ Object

Transposes array of notes by specified number of half_steps

Examples:

transpose(-1, %w(C F Am G))
=> ["Bb", "Eb", "Gm", "F"]

transpose(-10, %w(C F Am G))
=> ["D", "G", "Bm", "A"]

transpose(3, %w(D# F Bm G7))
=> ["F#", "Ab", "Dm", "Bb7"]

transpose(3, %w(D# F Bm G7), pref_flat: true)
=> ["Gb", "Ab", "Dm", "Bb7"]


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/note-transpose.rb', line 28

def self.transpose(half_steps, *notes, pref_flat: false)
    notes.flatten!
    transposed_notes = []

    notes.each do |note|
        note.downcase!
        begin
            m = note.match /^[a-g](#|b)?/
            actual_note = m[0]

            index = NOTES[:flat].find_index(actual_note)

            if index.nil?
                source = NOTES[:sharp]
                index  = NOTES[:sharp].find_index(actual_note)
            else
                source = NOTES[:flat]
            end

            # Still haven't found the note
            raise Error if index.nil?

            index += half_steps
            index %= source.size

            if pref_flat
                transposed_note = NOTES[:flat][index]
            else
                transposed_note = source[index]
            end

            transposed_notes << note.gsub(actual_note, transposed_note).capitalize
        rescue
            raise "'#{note.capitalize}' is not a valid note!"
        end
    end

    transposed_notes
end