Module: Fet::MusicTheory
- Defined in:
- lib/fet/music_theory.rb
Overview
Module in charge of handling music theory concepts
Constant Summary collapse
- DEGREES =
All 12 degrees
["1", "b2", "2", "b3", "3", "4", "b5", "5", "b6", "6", "b7", "7"].deep_freeze
- MAJOR_KEYS =
All 15 keys - 7 sharps…0 accidentals…7 flats.
["C#", "F#", "B", "E", "A", "D", "G", "C", "F", "Bb", "Eb", "Ab", "Db", "Gb", "Cb"].deep_freeze
- MINOR_KEYS =
["A#", "D#", "G#", "C#", "F#", "B", "E", "A", "D", "G", "C", "F", "Bb", "Eb", "Ab"].deep_freeze
- MODES_IN_ORDER_OF_DARKNESS =
[ ["lydian"], ["major", "ionian"], ["mixolydian"], ["dorian"], ["minor", "aeolian"], ["phrygian"], ["locrian"], ].deep_freeze
- DEGREES_OF_MODE =
{ ["lydian"] => ["1", "2", "3", "#4", "5", "6", "7"], ["major", "ionian"] => ["1", "2", "3", "4", "5", "6", "7"], ["mixolydian"] => ["1", "2", "3", "4", "5", "6", "b7"], ["dorian"] => ["1", "2", "b3", "4", "5", "6", "b7"], ["minor", "aeolian"] => ["1", "2", "b3", "4", "5", "b6", "b7"], ["phrygian"] => ["1", "b2", "b3", "4", "5", "b6", "b7"], ["locrian"] => ["1", "b2", "b3", "4", "b5", "b6", "b7"], }.deep_freeze
- SEMITONES_FROM_C =
{ "C" => 0, "D" => 2, "E" => 4, "F" => 5, "G" => 7, "A" => 9, "B" => 11, }.deep_freeze
- CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS =
["F", "C", "G", "D", "A", "E", "B"].deep_freeze
- CIRCLE_OF_FIFTHS =
[ *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).flattened_note.flattened_note.flattened_note.full_note }, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).flattened_note.flattened_note.full_note }, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).flattened_note.full_note }, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).sharpened_note.full_note }, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).sharpened_note.sharpened_note.full_note }, *CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.map { |note| Note.new(note).sharpened_note.sharpened_note.sharpened_note.full_note }, ].deep_freeze
- ORDERED_NATURAL_NOTES =
CIRCLE_OF_FIFTHS_WITHOUT_ACCIDENTALS.sort.deep_freeze
- SEMITONES_TO_NEXT_NATURAL_NOTE =
{ "A" => 2, "B" => 1, "C" => 2, "D" => 2, "E" => 1, "F" => 2, "G" => 2, }.deep_freeze
Class Method Summary collapse
- .degrees_of_mode(mode_name) ⇒ Object
-
.notes_of_mode(note_name, mode_name) ⇒ Object
A aeolian -> [“A”, “B”, “C”, “D”, “E”, “F”, “G”].
-
.relative_major(note_name, mode_name) ⇒ Object
A aeolian -> C.
-
.semitones_from_c(note_name) ⇒ Object
NOTE: returns value from 0 to 11.
Class Method Details
.degrees_of_mode(mode_name) ⇒ Object
51 52 53 54 55 56 |
# File 'lib/fet/music_theory.rb', line 51 def self.degrees_of_mode(mode_name) mode_info = DEGREES_OF_MODE.detect { |mode_names, _| mode_names.include?(mode_name) } raise InvalidModeName.new(mode_name) if mode_info.nil? return mode_info[1] end |
.notes_of_mode(note_name, mode_name) ⇒ Object
A aeolian -> [“A”, “B”, “C”, “D”, “E”, “F”, “G”]
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/fet/music_theory.rb', line 81 def self.notes_of_mode(note_name, mode_name) relative_major_note_name = relative_major(note_name, mode_name) index = CIRCLE_OF_FIFTHS.index(relative_major_note_name) result = CIRCLE_OF_FIFTHS[(index - 1)..(index + 5)] raise UnsupportedRootName.new(note_name) unless result.size == 7 result = result.sort return result.rotate(result.index(note_name)) end |
.relative_major(note_name, mode_name) ⇒ Object
A aeolian -> C
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/fet/music_theory.rb', line 93 def self.relative_major(note_name, mode_name) note = Note.new(note_name) index = CIRCLE_OF_FIFTHS.index(note.full_note) raise UnsupportedRootName.new(note_name) if index.nil? result_index = index - mode_offset_from_major(mode_name) raise UnsupportedRootName.new(note_name) if result_index.negative? result = CIRCLE_OF_FIFTHS[index - mode_offset_from_major(mode_name)] return result end |
.semitones_from_c(note_name) ⇒ Object
NOTE: returns value from 0 to 11
46 47 48 49 |
# File 'lib/fet/music_theory.rb', line 46 def self.semitones_from_c(note_name) note = Note.new(note_name) return (SEMITONES_FROM_C[note.natural_note] + note.accidental_to_semitone_offset) % 12 end |