Class: HeadMusic::Content::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.



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

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

Instance Attribute Details

#compositionObject (readonly)

Returns the value of attribute composition.



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

def composition
  @composition
end

#placementsObject (readonly)

Returns the value of attribute placements.



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

def placements
  @placements
end

#roleObject (readonly)

Returns the value of attribute role.



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

def role
  @role
end

Instance Method Details

#cantus_firmus?Boolean

Returns:

  • (Boolean)


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

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

#earliest_bar_numberObject



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

def earliest_bar_number
  return 1 if notes.empty?

  placements.first.position.bar_number
end

#highest_notesObject



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

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

#highest_pitchObject



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

def highest_pitch
  pitches.max
end

#large_leapsObject



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

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

#latest_bar_numberObject



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

def latest_bar_number
  return 1 if notes.empty?

  placements.last.position.bar_number
end

#leapsObject



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

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

#lowest_notesObject



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

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

#lowest_pitchObject



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

def lowest_pitch
  pitches.min
end

#melodic_intervalsObject



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

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

#note_at(position) ⇒ Object



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

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

#note_following(position) ⇒ Object



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

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

#note_preceding(position) ⇒ Object



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

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

#notesObject



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

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

#notes_during(placement) ⇒ Object



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

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

#notes_not_in_keyObject



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

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

#pitchesObject



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

def pitches
  notes.map(&:pitch)
end

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



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

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

#rangeObject



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

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

#restsObject



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

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

#to_sObject



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

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