Class: Musicality::Note
- Inherits:
-
Object
show all
- Includes:
- Parseable, Packable, Validatable
- Defined in:
- lib/musicality/notation/model/note.rb,
lib/musicality/printing/lilypond/note_engraving.rb,
lib/musicality/notation/parsing/convenience_methods.rb
Constant Summary
collapse
- SMALLEST_PIECE =
Rational(1,256)
- PARSER =
Parsing::NoteParser.new
- CONVERSION_METHOD =
:to_note
Constants included
from Parseable
Parseable::DEFAULT_SPLIT_PATTERN
Constants included
from Packable
Packable::PACKED_CLASS_KEY
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Parseable
included
#errors, #invalid?, #valid?, #validatables, #validate
Methods included from Packable
#class_str, included, #init_params, #pack, pack_val, recover_class, unpack_val
Constructor Details
#initialize(duration, pitches = [], links: {}, articulation: Articulations::NORMAL, marks: []) ⇒ Note
Returns a new instance of Note.
12
13
14
15
16
17
18
19
20
21
|
# File 'lib/musicality/notation/model/note.rb', line 12
def initialize duration, pitches = [], links: {}, articulation: Articulations::NORMAL, marks: []
self.duration = duration
if !pitches.is_a? Enumerable
pitches = [ pitches ]
end
@pitches = Set.new(pitches).sort
@links = links
@articulation = articulation
@marks = marks
end
|
Instance Attribute Details
#articulation ⇒ Object
Returns the value of attribute articulation.
10
11
12
|
# File 'lib/musicality/notation/model/note.rb', line 10
def articulation
@articulation
end
|
#duration ⇒ Object
Returns the value of attribute duration.
9
10
11
|
# File 'lib/musicality/notation/model/note.rb', line 9
def duration
@duration
end
|
#links ⇒ Object
Returns the value of attribute links.
9
10
11
|
# File 'lib/musicality/notation/model/note.rb', line 9
def links
@links
end
|
#marks ⇒ Object
Returns the value of attribute marks.
9
10
11
|
# File 'lib/musicality/notation/model/note.rb', line 9
def marks
@marks
end
|
#pitches ⇒ Object
Returns the value of attribute pitches.
9
10
11
|
# File 'lib/musicality/notation/model/note.rb', line 9
def pitches
@pitches
end
|
Class Method Details
.add_note_method(name, dur) ⇒ Object
126
127
128
129
130
|
# File 'lib/musicality/notation/model/note.rb', line 126
def self.add_note_method(name, dur)
self.class.send(:define_method,name.to_sym) do |pitches = [], links: {}, articulation: Articulations::NORMAL, marks: []|
Note.new(dur, pitches, articulation: articulation, links: links, marks: marks)
end
end
|
Instance Method Details
#==(other) ⇒ Object
40
41
42
43
44
45
46
|
# File 'lib/musicality/notation/model/note.rb', line 40
def == other
return (@duration == other.duration) &&
(self.pitches == other.pitches) &&
(@links.to_a.sort == other.links.to_a.sort) &&
(@articulation == other.articulation) &&
(@marks == marks)
end
|
#begins_slur? ⇒ Boolean
92
93
94
|
# File 'lib/musicality/notation/model/note.rb', line 92
def begins_slur?
marks.count {|m| m.is_a?(Mark::Slur::Begin) } > 0
end
|
#check_duration ⇒ Object
27
28
29
30
31
|
# File 'lib/musicality/notation/model/note.rb', line 27
def check_duration
if duration <= 0
raise RangeError, "Duration is non-positive: #{duration}"
end
end
|
#check_methods ⇒ Object
23
24
25
|
# File 'lib/musicality/notation/model/note.rb', line 23
def check_methods
[ :check_duration, :check_pitches ]
end
|
#check_pitches ⇒ Object
33
34
35
36
37
38
|
# File 'lib/musicality/notation/model/note.rb', line 33
def check_pitches
non_pitches = @pitches.select {|p| !p.is_a?(Pitch) }
if non_pitches.any?
raise TypeError, "Found non-pitches: #{non_pitches}"
end
end
|
#clone ⇒ Object
48
49
50
|
# File 'lib/musicality/notation/model/note.rb', line 48
def clone
Marshal.load(Marshal.dump(self))
end
|
#ends_slur? ⇒ Boolean
96
97
98
|
# File 'lib/musicality/notation/model/note.rb', line 96
def ends_slur?
marks.count {|m| m.is_a?(Mark::Slur::End) } > 0
end
|
#fractional_subdurs(smallest_piece) ⇒ Object
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/musicality/printing/lilypond/note_engraving.rb', line 77
def fractional_subdurs smallest_piece
remaining = @duration - @duration.to_i
pieces = []
i = 0
while((current_dur = Rational(1,2<<i)) >= smallest_piece)
if remaining >= current_dur
pieces.push current_dur
remaining -= current_dur
end
i += 1
end
unless remaining.zero?
raise RuntimeError, "Non-zero remainder #{remaining}"
end
return pieces
end
|
#mark_accented! ⇒ Object
76
77
78
|
# File 'lib/musicality/notation/model/note.rb', line 76
def mark_accented!
@articulation = Articulations::ACCENT
end
|
#resize(duration) ⇒ Object
58
59
60
61
62
|
# File 'lib/musicality/notation/model/note.rb', line 58
def resize duration
new_note = self.clone
new_note.duration = duration
return new_note
end
|
#tie_to(pitches) ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/musicality/notation/model/note.rb', line 64
def tie_to pitches
new_note = self.clone
if pitches.is_a? Pitch
pitches = [pitches]
end
pitches.each do |pitch|
new_note.links[pitch] = Link::Tie.new
end
return new_note
end
|
#to_lilypond(sharpit = false, begins_triplet: false, ends_triplet: false) ⇒ Object
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
|
# File 'lib/musicality/printing/lilypond/note_engraving.rb', line 6
def to_lilypond sharpit = false, begins_triplet: false, ends_triplet: false
subdurs = [1]*@duration.to_i + fractional_subdurs(SMALLEST_PIECE)
piece_strs = []
pitches_to_strs = Hash[ pitches.map {|p| [p,p.to_lilypond(sharpit)] }]
while subdurs.any?
subdur = subdurs.shift
dur_str = subdur.denominator.to_s
if subdurs.any? && subdur == subdurs.first*2
dur_str += "."
subdurs.shift
end
last = subdurs.empty?
piece_str = if pitches.any?
if last
if pitches_to_strs.size == 1
p, p_str = pitches_to_strs.first
needs_tie = links.include?(p) && links[p].is_a?(Link::Tie)
p_str + dur_str + (needs_tie ? "~" : "")
else
p_strs = pitches_to_strs.map do |p,p_str|
if links.include?(p) && links[p].is_a?(Link::Tie)
p_str + "~"
else
p_str
end
end
"<#{p_strs.join(" ")}>" + dur_str
end
else
str = if pitches.size == 1
pitches_to_strs.values.first
else
"<#{pitches_to_strs.values.join(" ")}>"
end
str + dur_str + "~"
end
else
"r" + dur_str
end
piece_strs.push piece_str
end
if pitches.any?
if articulation != Articulations::NORMAL
piece_strs[0] += "-" + ARTICULATION_SYMBOLS[articulation]
end
if begins_slur?
piece_strs[-1] += MARK_SYMBOLS[Mark::Slur::Begin]
end
if ends_slur?
piece_strs[-1] += MARK_SYMBOLS[Mark::Slur::End]
end
end
if begins_triplet
piece_strs[0].prepend("\\tuplet 3/2 {")
end
if ends_triplet
piece_strs[-1].concat("}")
end
return piece_strs.join(" ")
end
|
#to_s ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/musicality/notation/model/note.rb', line 100
def to_s
d = @duration.to_r
if d.denominator == 1
dur_str = "#{d.numerator}"
elsif d.numerator == 1
dur_str = "/#{d.denominator}"
else
dur_str = d.to_s
end
pitch_links_str = @pitches.map do |p|
if @links.has_key?(p)
p.to_s + @links[p].to_s
else
p.to_s
end
end.join(",")
art_str = ARTICULATION_SYMBOLS[@articulation] || ""
begin_marks_str = marks.select {|m| m.begins? }.map {|m| m.to_s }.join
end_marks_str = marks.select {|m| m.ends? }.map {|m| m.to_s }.join
return begin_marks_str + dur_str + pitch_links_str + art_str + end_marks_str
end
|
#transpose(diff) ⇒ Object
80
81
82
|
# File 'lib/musicality/notation/model/note.rb', line 80
def transpose diff
self.clone.transpose! diff
end
|
#transpose!(diff) ⇒ Object
84
85
86
87
88
89
90
|
# File 'lib/musicality/notation/model/note.rb', line 84
def transpose! diff
@pitches = @pitches.map {|pitch| pitch.transpose(diff) }
@links = Hash[ @links.map do |k,v|
[ k.transpose(diff), v.transpose(diff) ]
end ]
return self
end
|