lib/coltrane/interval_sequence.rb in coltrane-1.0.26 vs lib/coltrane/interval_sequence.rb in coltrane-1.1.0
- old
+ new
@@ -4,18 +4,54 @@
# It describes a sequence of intervals
class IntervalSequence
extend Forwardable
attr_reader :intervals
- def_delegators :@intervals, :map, :each, :[], :size, :reduce
+ def_delegators :@intervals, :map, :each, :[], :size,
+ :reduce, :delete
+ Interval::ALL_FULL_NAMES.each do |full_name|
+ define_method "has_#{full_name.underscore}?" do
+ !!(intervals.detect {|i| i.public_send("#{full_name.underscore}?")})
+ end
+ end
+
+ (1..15).each do |i|
+ # defines methods like :fifth, :third, eleventh:
+ define_method i.interval_name.underscore do
+ priority = send("#{i.interval_name.underscore}!")
+ return priority unless priority.nil?
+ @intervals.each do |ix|
+ ix.full_names.detect do |ixx|
+ return ixx if ixx.match(/#{i.interval_name}/)
+ end
+ end
+ nil
+ end
+
+ define_method "#{i.interval_name.underscore}!" do
+ @intervals.each do |ix|
+ ix.full_names.detect do |ixx|
+ next if ixx.match(/Diminished|Augmented/)
+ return ixx if ixx.match? /#{i.interval_name}/
+ end
+ end
+ nil
+ end
+
+ # defines methods like :has_fifth?, :has_third?, has_eleventh?:
+ define_method "has_#{i.interval_name.underscore}?" do
+ !!@intervals.detect {|ix| ix.full_name.match(/#{i.interval_name}/) }
+ end
+ end
+
def initialize(notes: nil, intervals: nil, distances: nil)
if !notes.nil?
notes = NoteSet[*notes] if notes.is_a?(Array)
@intervals = intervals_from_notes(notes)
elsif !intervals.nil?
- @intervals = intervals.map { |i| Interval.new(i) }
+ @intervals = intervals.map { |i| Interval[i] }
elsif !distances.nil?
@distances = distances
@intervals = intervals_from_distances(distances)
else
raise 'Provide: [notes:] || [intervals:] || [distances:]'
@@ -30,10 +66,20 @@
n - intervals_semitones[i]
end
end + [12 - intervals_semitones.last]
end
+ def names
+ intervals.map(&:name)
+ end
+
+ def has?(interval_name)
+ @intervals.include?(Interval[interval_name])
+ end
+
+ alias interval_names names
+
def all
intervals
end
def [](x)
@@ -66,31 +112,40 @@
Array.new(intervals.length) do |index|
inversion(index)
end
end
- def quality; end
-
def intervals_semitones
map(&:semitones)
end
def names
map(&:name)
end
+ def full_names
+ map(&:full_name)
+ end
+
def notes_for(root_note)
NoteSet[
*intervals.reduce([]) do |memo, interval|
memo + [root_note + interval]
end
]
end
+ def &(other)
+ case other
+ when Array then intervals & other
+ when IntervalSequence then intervals & other.semitones
+ end
+ end
+
private
def intervals_from_distances(distances)
- distances[0..-2].reduce([Interval.new(0)]) do |memo, d|
+ distances[0..-2].reduce([Interval[0]]) do |memo, d|
memo + [memo.last + d]
end
end
def intervals_from_notes(notes)