Class: Coltrane::Interval

Inherits:
Object
  • Object
show all
Includes:
Multiton
Defined in:
lib/coltrane/interval.rb

Overview

It describes a interval between 2 pitches

Constant Summary collapse

INTERVALS =
%w[
  P1
  m2
  M2
  m3
  M3
  P4
  A4
  P5
  m6
  M6
  m7
  M7
].freeze
NAMES =

Create full names and methods such as major_third? minor_seventh? TODO: It’s a mess and it really needs a refactor one day

INTERVALS.each_with_index.reduce({}) do |memo, (interval, index)|
  memo[interval] ||= []
  2.times do |o|
    q,i = split(interval)
    num = o * 7 + i.to_i
    prev_q = split(INTERVALS[(index - 1) % 12])[0]
    next_q = split(INTERVALS[(index + 1) % 12])[0]
    memo[interval] << full_name("#{q}#{num}")
    memo[interval] << full_name("d#{(num - 1 + 1) % 14 + 1}") if next_q.match? /m|P/
    next if q == 'A'
    memo[interval] << full_name("A#{(num - 1 - 1) % 14 + 1}") if prev_q.match? /M|P/
  end
  memo
end
ALL_FULL_NAMES =
NAMES.values.flatten

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(semitones) ⇒ Interval

Returns a new instance of Interval.



71
72
73
# File 'lib/coltrane/interval.rb', line 71

def initialize(semitones)
  @semitones = semitones
end

Instance Attribute Details

#semitonesObject (readonly)

Returns the value of attribute semitones.



7
8
9
# File 'lib/coltrane/interval.rb', line 7

def semitones
  @semitones
end

Class Method Details

.[](arg) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/coltrane/interval.rb', line 50

def self.[](arg)
  new(case arg
      when Interval then arg.semitones
      when String   then INTERVALS.index(arg) || interval_by_full_name(arg)
      when Numeric  then arg
      end % 12)
end

.full_name(interval) ⇒ Object



28
29
30
31
# File 'lib/coltrane/interval.rb', line 28

def self.full_name(interval)
  q,n = split(interval)
  "#{q.interval_quality} #{n.to_i.interval_name}"
end

.split(interval) ⇒ Object



24
25
26
# File 'lib/coltrane/interval.rb', line 24

def self.split(interval)
  interval.scan(/(\w)(\d\d?)/)[0]
end

Instance Method Details

#+(other) ⇒ Object



95
96
97
98
99
100
# File 'lib/coltrane/interval.rb', line 95

def +(other)
  case other
  when Numeric then Interval[semitones + other]
  when Interval then Interval[semitones + other.semitones]
  end
end

#all_full_namesObject



77
78
79
# File 'lib/coltrane/interval.rb', line 77

def all_full_names
  ALL_FULL_NAMES
end

#full_nameObject



87
88
89
# File 'lib/coltrane/interval.rb', line 87

def full_name
  self.class.full_name(name)
end

#full_namesObject



91
92
93
# File 'lib/coltrane/interval.rb', line 91

def full_names
  NAMES[name]
end

#nameObject



83
84
85
# File 'lib/coltrane/interval.rb', line 83

def name
  INTERVALS[semitones]
end