Class: HeadMusic::Analysis::MelodicInterval

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/analysis/melodic_interval.rb

Overview

A melodic interval is the distance between two sequential pitches.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(first, second) ⇒ MelodicInterval

Returns a new instance of MelodicInterval.



8
9
10
# File 'lib/head_music/analysis/melodic_interval.rb', line 8

def initialize(first, second)
  @first_pitch, @second_pitch = extract_pitches(first, second)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



68
69
70
# File 'lib/head_music/analysis/melodic_interval.rb', line 68

def method_missing(method_name, *args, &block)
  diatonic_interval.respond_to?(method_name) ? diatonic_interval.send(method_name, *args, &block) : super
end

Instance Attribute Details

#first_pitchObject (readonly)

Returns the value of attribute first_pitch.



6
7
8
# File 'lib/head_music/analysis/melodic_interval.rb', line 6

def first_pitch
  @first_pitch
end

#second_pitchObject (readonly)

Returns the value of attribute second_pitch.



6
7
8
# File 'lib/head_music/analysis/melodic_interval.rb', line 6

def second_pitch
  @second_pitch
end

Instance Method Details

#ascending?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/head_music/analysis/melodic_interval.rb', line 24

def ascending?
  direction == :ascending
end

#descending?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/head_music/analysis/melodic_interval.rb', line 28

def descending?
  direction == :descending
end

#diatonic_intervalObject



12
13
14
# File 'lib/head_music/analysis/melodic_interval.rb', line 12

def diatonic_interval
  @diatonic_interval ||= HeadMusic::Analysis::DiatonicInterval.new(first_pitch, second_pitch)
end

#directionObject



48
49
50
51
52
53
54
55
56
57
# File 'lib/head_music/analysis/melodic_interval.rb', line 48

def direction
  @direction ||=
    if first_pitch < second_pitch
      :ascending
    elsif first_pitch > second_pitch
      :descending
    else
      :none
    end
end

#extract_pitches(first, second) ⇒ Object (private)



78
79
80
81
82
# File 'lib/head_music/analysis/melodic_interval.rb', line 78

def extract_pitches(first, second)
  first_pitch = first.respond_to?(:pitch) ? first.pitch : first
  second_pitch = second.respond_to?(:pitch) ? second.pitch : second
  [first_pitch, second_pitch]
end

#high_pitchObject



40
41
42
# File 'lib/head_music/analysis/melodic_interval.rb', line 40

def high_pitch
  pitches.max
end

#low_pitchObject



44
45
46
# File 'lib/head_music/analysis/melodic_interval.rb', line 44

def low_pitch
  pitches.min
end

#moving?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/head_music/analysis/melodic_interval.rb', line 32

def moving?
  ascending? || descending?
end

#pitchesObject



16
17
18
# File 'lib/head_music/analysis/melodic_interval.rb', line 16

def pitches
  [first_pitch, second_pitch]
end

#repetition?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/head_music/analysis/melodic_interval.rb', line 36

def repetition?
  !moving?
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/head_music/analysis/melodic_interval.rb', line 72

def respond_to_missing?(method_name, include_private = false)
  diatonic_interval.respond_to?(method_name, include_private) || super
end

#spells_consonant_triad_with?(other_interval) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
# File 'lib/head_music/analysis/melodic_interval.rb', line 59

def spells_consonant_triad_with?(other_interval)
  return false if step? || other_interval.step?

  combined_pitches = (pitches + other_interval.pitches).uniq
  return false if combined_pitches.length < 3

  HeadMusic::Analysis::PitchSet.new(combined_pitches).consonant_triad?
end

#to_sObject



20
21
22
# File 'lib/head_music/analysis/melodic_interval.rb', line 20

def to_s
  [direction, diatonic_interval].join(" ")
end