Class: HeadMusic::Voice

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/head_music/content/voice.rb

Overview

A Voice is a stream of music with some indepedence that is conceptually one part or for one performer. The melodic lines in counterpoint are each a voice.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(composition: nil, role: nil) ⇒ Voice

Returns a new instance of Voice.



12
13
14
15
16
# File 'lib/head_music/content/voice.rb', line 12

def initialize(composition: nil, role: nil)
  @composition = composition || HeadMusic::Composition.new
  @role = role
  @placements = []
end

Instance Attribute Details

#compositionObject (readonly)

Returns the value of attribute composition.



8
9
10
# File 'lib/head_music/content/voice.rb', line 8

def composition
  @composition
end

#placementsObject (readonly)

Returns the value of attribute placements.



8
9
10
# File 'lib/head_music/content/voice.rb', line 8

def placements
  @placements
end

#roleObject (readonly)

Returns the value of attribute role.



8
9
10
# File 'lib/head_music/content/voice.rb', line 8

def role
  @role
end

Instance Method Details

#cantus_firmus?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/head_music/content/voice.rb', line 74

def cantus_firmus?
  role.to_s =~ /cantus.?firmus/i
end

#earliest_bar_numberObject



94
95
96
97
98
# File 'lib/head_music/content/voice.rb', line 94

def earliest_bar_number
  return 1 if notes.empty?

  placements.first.position.bar_number
end

#highest_notesObject



49
50
51
# File 'lib/head_music/content/voice.rb', line 49

def highest_notes
  notes.select { |note| note.pitch == highest_pitch }
end

#highest_pitchObject



41
42
43
# File 'lib/head_music/content/voice.rb', line 41

def highest_pitch
  pitches.max
end

#large_leapsObject



70
71
72
# File 'lib/head_music/content/voice.rb', line 70

def large_leaps
  melodic_intervals.select(&:large_leap?)
end

#latest_bar_numberObject



100
101
102
103
104
# File 'lib/head_music/content/voice.rb', line 100

def latest_bar_number
  return 1 if notes.empty?

  placements.last.position.bar_number
end

#leapsObject



66
67
68
# File 'lib/head_music/content/voice.rb', line 66

def leaps
  melodic_intervals.select(&:leap?)
end

#lowest_notesObject



53
54
55
# File 'lib/head_music/content/voice.rb', line 53

def lowest_notes
  notes.select { |note| note.pitch == lowest_pitch }
end

#lowest_pitchObject



45
46
47
# File 'lib/head_music/content/voice.rb', line 45

def lowest_pitch
  pitches.min
end

#melodic_intervalsObject



61
62
63
64
# File 'lib/head_music/content/voice.rb', line 61

def melodic_intervals
  @melodic_intervals ||=
    notes.each_cons(2).map { |note_pair| HeadMusic::MelodicInterval.new(*note_pair) }
end

#note_at(position) ⇒ Object



78
79
80
# File 'lib/head_music/content/voice.rb', line 78

def note_at(position)
  notes.detect { |note| position.within_placement?(note) }
end

#note_following(position) ⇒ Object



90
91
92
# File 'lib/head_music/content/voice.rb', line 90

def note_following(position)
  notes.detect { |note| note.position > position }
end

#note_preceding(position) ⇒ Object



86
87
88
# File 'lib/head_music/content/voice.rb', line 86

def note_preceding(position)
  notes.reverse.find { |note| note.position < position }
end

#notesObject



24
25
26
# File 'lib/head_music/content/voice.rb', line 24

def notes
  @placements.select(&:note?)
end

#notes_during(placement) ⇒ Object



82
83
84
# File 'lib/head_music/content/voice.rb', line 82

def notes_during(placement)
  notes.select { |note| note.during?(placement) }
end

#notes_not_in_keyObject



28
29
30
31
# File 'lib/head_music/content/voice.rb', line 28

def notes_not_in_key
  key_spellings = key_signature.pitches.map(&:spelling).uniq
  notes.reject { |note| key_spellings.include? note.pitch.spelling }
end

#pitchesObject



33
34
35
# File 'lib/head_music/content/voice.rb', line 33

def pitches
  notes.map(&:pitch)
end

#place(position, rhythmic_value, pitch = nil) ⇒ Object



18
19
20
21
22
# File 'lib/head_music/content/voice.rb', line 18

def place(position, rhythmic_value, pitch = nil)
  HeadMusic::Placement.new(self, position, rhythmic_value, pitch).tap do |placement|
    insert_into_placements(placement)
  end
end

#rangeObject



57
58
59
# File 'lib/head_music/content/voice.rb', line 57

def range
  HeadMusic::DiatonicInterval.new(lowest_pitch, highest_pitch)
end

#restsObject



37
38
39
# File 'lib/head_music/content/voice.rb', line 37

def rests
  @placements.select(&:rest?)
end

#to_sObject



106
107
108
# File 'lib/head_music/content/voice.rb', line 106

def to_s
  "#{role}: #{pitches.first(10).map(&:to_s)}"
end