Class: Coltrane::Theory::Interval

Inherits:
IntervalClass show all
Defined in:
lib/coltrane/theory/interval.rb

Constant Summary

Constants inherited from IntervalClass

Coltrane::Theory::IntervalClass::ALTERATIONS, Coltrane::Theory::IntervalClass::COMPOUND_DISTANCES_NAMES, Coltrane::Theory::IntervalClass::DISTANCES_NAMES, Coltrane::Theory::IntervalClass::QUALITY_NAMES, Coltrane::Theory::IntervalClass::QUALITY_SEQUENCE, Coltrane::Theory::IntervalClass::SINGLE_DISTANCES_NAMES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IntervalClass

#+, #-, #-@, #==, all_names_including_compound, #alteration, #compound_interval, #compound_name, compound_names, #distance, distance_name, distances_names, expand_name, #full_name, full_names, full_names_including_compound, #interval, #inversion, names, #quality, quality_name, split

Methods inherited from FrequencyInterval

#+, #-, #-@, #<=>, #==, #ascending?, #descending?, #inversion, #semitones

Constructor Details

#initialize(arg_1 = nil, arg_2 = nil, ascending: true, letter_distance: nil, semitones: nil, compound: false) ⇒ Interval

Returns a new instance of Interval.



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
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/coltrane/theory/interval.rb', line 40

def initialize(arg_1 = nil, arg_2 = nil, ascending: true,
               letter_distance: nil,
               semitones: nil,
               compound: false)
  if arg_1 && !arg_2 # assumes arg_1 is a letter
    @compound = compound
    IntervalClass[arg_1].interval.yield_self do |interval|
      @letter_distance = interval.letter_distance
      @cents = interval.cents
    end
  elsif arg_1 && arg_2 # assumes those are notes
    if ascending
      @compound = compound
      @cents =
        (arg_1.frequency / arg_2.frequency)
        .interval_class
        .cents

      @letter_distance = calculate_letter_distance arg_1.letter,
                                                   arg_2.letter,
                                                   ascending
    else
      self.class.new(arg_1, arg_2).descending.yield_self do |base_interval|
        @compound        = base_interval.compound?
        @cents           = base_interval.cents
        @letter_distance = base_interval.letter_distance
      end
    end
  elsif letter_distance && semitones
    @compound        = compound || letter_distance > 8
    @cents           = semitones * 100
    @letter_distance = letter_distance
  else
    raise WrongKeywordsError,
          '[interval_class_name]' \
          'Provide: [first_note, second_note] || ' \
          '[letter_distance:, semitones:]'
  end
end

Instance Attribute Details

#centsObject (readonly)

Returns the value of attribute cents.



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

def cents
  @cents
end

#letter_distanceObject (readonly)

Returns the value of attribute letter_distance.



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

def letter_distance
  @letter_distance
end

Class Method Details

.[](arg) ⇒ Object



80
81
82
# File 'lib/coltrane/theory/interval.rb', line 80

def self.[](arg)
  new(arg)
end

.allObject



10
11
12
# File 'lib/coltrane/theory/interval.rb', line 10

def all
  @all ||= super.map(&:interval)
end

.all_augmentedObject



22
23
24
25
# File 'lib/coltrane/theory/interval.rb', line 22

def all_augmented
  @all_augmented ||= all_including_compound.select(&:has_augmented?)
                                           .map(&:augmented)
end

.all_compoundObject



14
15
16
# File 'lib/coltrane/theory/interval.rb', line 14

def all_compound
  @all_compound ||= all.map(&:compound)
end

.all_diminishedObject



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

def all_diminished
  @all_diminished ||= all_including_compound.select(&:has_diminished?)
                                            .map(&:diminished)
end

.all_including_compoundObject



18
19
20
# File 'lib/coltrane/theory/interval.rb', line 18

def all_including_compound
  @all_including_compound ||= all + all_compound
end

.all_including_compound_and_alteredObject



32
33
34
35
36
37
# File 'lib/coltrane/theory/interval.rb', line 32

def all_including_compound_and_altered
  @all_including_compound_and_altered ||=
    all_including_compound +
    all_diminished +
    all_augmented
end

Instance Method Details

#accidentalsObject



100
101
102
103
104
105
# File 'lib/coltrane/theory/interval.rb', line 100

def accidentals
  if distance_to_starting.positive? then 'A' * distance_to_starting.abs
  elsif distance_to_starting.negative? then 'd' * distance_to_starting.abs
  else ''
  end
end

#as(n) ⇒ Object



117
118
119
120
# File 'lib/coltrane/theory/interval.rb', line 117

def as(n)
  i = clone(letter_distance: n)
  i if i.name.match?(n.to_s)
end

#as!(n) ⇒ Object



122
123
124
125
# File 'lib/coltrane/theory/interval.rb', line 122

def as!(n)
  i = as(n)
  i unless i&.name&.match? /d|A/
end

#as_augmented(n = 1) ⇒ Object



131
132
133
# File 'lib/coltrane/theory/interval.rb', line 131

def as_augmented(n = 1)
  as(letter_distance - n)
end

#as_diminished(n = 1) ⇒ Object



127
128
129
# File 'lib/coltrane/theory/interval.rb', line 127

def as_diminished(n = 1)
  as(letter_distance + n)
end

#ascendingObject



159
160
161
# File 'lib/coltrane/theory/interval.rb', line 159

def ascending
  ascending? ? self : opposite
end

#augment(n = 1) ⇒ Object Also known as: augmented



149
150
151
# File 'lib/coltrane/theory/interval.rb', line 149

def augment(n = 1)
  clone(semitones: semitones + n)
end

#clone(override_args = {}) ⇒ Object



135
136
137
138
139
140
141
# File 'lib/coltrane/theory/interval.rb', line 135

def clone(override_args = {})
  self.class.new({
    semitones: semitones,
    letter_distance: letter_distance,
    compound: compound?
  }.merge(override_args))
end

#descendingObject



163
164
165
# File 'lib/coltrane/theory/interval.rb', line 163

def descending
  descending? ? self : opposite
end

#diminish(n = 1) ⇒ Object Also known as: diminished



143
144
145
# File 'lib/coltrane/theory/interval.rb', line 143

def diminish(n = 1)
  clone(semitones: semitones - n)
end

#has_augmented?Boolean

Returns:

  • (Boolean)


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

def has_augmented?
  name.match? /M|P|A/
end

#has_diminished?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/coltrane/theory/interval.rb', line 96

def has_diminished?
  name.match? /m|P|d/
end

#interval_classObject



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

def interval_class
  FrequencyInterval[cents].interval_class
end

#nameObject



107
108
109
110
111
112
113
114
115
# File 'lib/coltrane/theory/interval.rb', line 107

def name
  @name ||= begin
    if distance_to_starting.zero? || distance_to_starting.abs > 2
      compound? ? interval_class.compound_name : interval_class.name
    else
      "#{accidentals}#{starting_interval.distance + (compound? ? 7 : 0)}"
    end
  end
end

#oppositeObject



155
156
157
# File 'lib/coltrane/theory/interval.rb', line 155

def opposite
  clone(semitones: -semitones, letter_distance: (-letter_distance % 8) + 1)
end