class MusicUtils::Interval
This class represents a music interval
Public Class Methods
high_note(from, short)
click to toggle source
Returns the higher note of an interval calculates from its first note and number and quality in short notation
# File lib/music-utils/interval/interval.rb, line 73 def self.high_note(from, short) quality, number = parse_short(short) while number > 7 number = number - 7 end from_note, from_alter = Note.parse(from) to_note = Scales.diatonic_scale_from(from_note)[number - 1] intervals = Scales::QUALITIES[number].key(quality) intervals += alter_impact_in_semitones(from_alter, false) from_note_index = Scales.cromatic_index(from_note.to_sym) to_note_index = from_note_index + intervals while to_note_index > 11 to_note_index = to_note_index - 12 end Scales::CROMATIC_SCALE[to_note_index].select do |note| raw_note, alter = Note.parse(note) raw_note == to_note end.first end
new(note1, note2, step)
click to toggle source
# File lib/music-utils/interval/interval.rb, line 10 def initialize(note1, note2, step) @note1, @note1_alt = MusicUtils::Note.parse(note1) @note2, @note2_alt = MusicUtils::Note.parse(note2) @step = step end
parse_short(sn)
click to toggle source
Short notation parser method
# File lib/music-utils/interval/interval.rb, line 100 def self.parse_short(sn) short = sn.to_s quality = short[0..1] number = short[2..3].to_i if quality == Scales::DIMP or quality == Scales::AUGP # nothing to do else quality = short[0] number = short[1..2].to_i end [quality, number] end
Private Class Methods
alter_impact_in_semitones(alter, from_note)
click to toggle source
# File lib/music-utils/interval/interval.rb, line 148 def self.alter_impact_in_semitones(alter, from_note) impact = 0 case alter when Scales::FLAT ; impact = from_note ? 1 : -1 when Scales::SHARP ; impact = from_note ? -1 : 1 when Scales::DFLAT ; impact = from_note ? 2 : -2 when Scales::DSHARP ; impact = from_note ? -2 : 2 end impact end
Public Instance Methods
number()
click to toggle source
It classifies the diatonic interval
# File lib/music-utils/interval/interval.rb, line 17 def number # initialize counter and index of scale i = note1_index count = 1 count, i = no_unison(count, i) # Counting notes until_find_note2(i) { count += 1 } count = count + (8 * @step) - 1 if @step > 0 count end
quality()
click to toggle source
Returns the quality of the interval
# File lib/music-utils/interval/interval.rb, line 59 def quality s = ( @step > 0 and semitones - (12 * @step) ) || semitones n = ( @step > 0 and number - (7 * @step) ) || number QUALITIES[n][s] end
semitones()
click to toggle source
Returns the number of semitones
# File lib/music-utils/interval/interval.rb, line 32 def semitones return CROMATIC_SCALE.length if @note1 == @note2 # initialize counter and index of scale i = note1_index count = 0 # counting semi-tones until_find_note2(i) do |ii| # from 'mi' to 'fa' and 'si' to 'do' there 1 semi-tone if DIATONIC_SCALE[ii] == Scales::FA or DIATONIC_SCALE[ii] == Scales::DO count += 1 else count += 2 end end count = count + (12 * @step) if @step > 0 # counting notes alterations count += Interval.alter_impact_in_semitones(@note1_alt, true) count += Interval.alter_impact_in_semitones(@note2_alt, false) count end
short()
click to toggle source
Returns the class interval in the short notation
# File lib/music-utils/interval/interval.rb, line 66 def short quality + number.to_s end
Private Instance Methods
no_unison(count, i)
click to toggle source
Jumps to the next note if note 1 and note 2 are the same
# File lib/music-utils/interval/interval.rb, line 131 def no_unison(count, i) if @note1 == @note2 if DIATONIC_SCALE[i] == Scales::FA or DIATONIC_SCALE[i] == Scales::DO count += 1 else count += 2 end i += 1 end [count, i] end
note1_index()
click to toggle source
Returns index of note 1
# File lib/music-utils/interval/interval.rb, line 144 def note1_index DIATONIC_SCALE.index(@note1) end
until_find_note2(i) { |i| ... }
click to toggle source
Common loop to search note 2
# File lib/music-utils/interval/interval.rb, line 118 def until_find_note2(i) length = DIATONIC_SCALE.length - 1 # search note2 while DIATONIC_SCALE[i] != @note2 i += 1 if i > length i = 0; end yield i end end