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.



15
16
17
18
19
# File 'lib/head_music/content/voice.rb', line 15

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.



11
12
13
# File 'lib/head_music/content/voice.rb', line 11

def composition
  @composition
end

#placementsObject (readonly)

Returns the value of attribute placements.



11
12
13
# File 'lib/head_music/content/voice.rb', line 11

def placements
  @placements
end

#roleObject (readonly)

Returns the value of attribute role.



11
12
13
# File 'lib/head_music/content/voice.rb', line 11

def role
  @role
end

Instance Method Details

#cantus_firmus?Boolean

Returns:

  • (Boolean)


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

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

#earliest_bar_numberObject



97
98
99
100
101
# File 'lib/head_music/content/voice.rb', line 97

def earliest_bar_number
  return 1 if notes.empty?

  placements.first.position.bar_number
end

#highest_notesObject



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

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

#highest_pitchObject



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

def highest_pitch
  pitches.max
end

#large_leapsObject



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

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

#latest_bar_numberObject



103
104
105
106
107
# File 'lib/head_music/content/voice.rb', line 103

def latest_bar_number
  return 1 if notes.empty?

  placements.last.position.bar_number
end

#leapsObject



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

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

#lowest_notesObject



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

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

#lowest_pitchObject



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

def lowest_pitch
  pitches.min
end

#melodic_intervalsObject



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

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

#note_at(position) ⇒ Object



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

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

#note_following(position) ⇒ Object



93
94
95
# File 'lib/head_music/content/voice.rb', line 93

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

#note_preceding(position) ⇒ Object



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

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

#notesObject



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

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

#notes_during(placement) ⇒ Object



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

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

#notes_not_in_keyObject



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

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

#pitchesObject



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

def pitches
  notes.map(&:pitch)
end

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



21
22
23
24
25
# File 'lib/head_music/content/voice.rb', line 21

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



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

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

#restsObject



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

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

#to_sObject



109
110
111
# File 'lib/head_music/content/voice.rb', line 109

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