musicality 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.coveralls.yml +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -0
- data/ChangeLog.md +11 -0
- data/README.md +3 -0
- data/Rakefile +11 -3
- data/lib/musicality/composition/model/rhythm.rb +33 -0
- data/lib/musicality/composition/model/rhythm_class.rb +30 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_kit.rb +18 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_machine.rb +59 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_parts.rb +21 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_pattern.rb +66 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_patterns/pop_drum_patterns.rb +146 -0
- data/lib/musicality/composition/sequencing/note_array.rb +33 -0
- data/lib/musicality/composition/sequencing/note_fifo.rb +73 -0
- data/lib/musicality/composition/sequencing/sequenceable.rb +9 -0
- data/lib/musicality/composition/sequencing/sequencer.rb +35 -0
- data/lib/musicality/errors.rb +2 -2
- data/lib/musicality/notation/model/dynamics.rb +2 -2
- data/lib/musicality/notation/model/key.rb +42 -91
- data/lib/musicality/notation/model/keys.rb +35 -34
- data/lib/musicality/notation/model/note.rb +31 -9
- data/lib/musicality/notation/model/pitch.rb +2 -2
- data/lib/musicality/notation/parsing/convenience_methods.rb +23 -12
- data/lib/musicality/notation/parsing/duration_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/key_parsing.rb +150 -0
- data/lib/musicality/notation/parsing/key_parsing.treetop +37 -0
- data/lib/musicality/notation/parsing/meter_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +3 -1
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +1 -0
- data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +4 -1
- data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/parseable.rb +13 -17
- data/lib/musicality/notation/parsing/pitch_parsing.rb +7 -0
- data/lib/musicality/notation/parsing/segment_parsing.rb +3 -0
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +82 -134
- data/lib/musicality/performance/model/note_sequence.rb +22 -3
- data/lib/musicality/performance/supercollider/performer.rb +2 -2
- data/lib/musicality/performance/supercollider/sc_drum_kits.rb +29 -0
- data/lib/musicality/performance/supercollider/synthdefs/bass.rb +211 -0
- data/lib/musicality/performance/supercollider/synthdefs/claps.rb +80 -0
- data/lib/musicality/performance/supercollider/synthdefs/cymbals.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdefs/hihats.rb +67 -0
- data/lib/musicality/performance/supercollider/synthdefs/kicks.rb +158 -0
- data/lib/musicality/performance/supercollider/synthdefs/mario.rb +49 -0
- data/lib/musicality/performance/supercollider/{synthdefs.rb → synthdefs/other.rb} +0 -767
- data/lib/musicality/performance/supercollider/synthdefs/pianos.rb +46 -0
- data/lib/musicality/performance/supercollider/synthdefs/snares.rb +169 -0
- data/lib/musicality/performance/supercollider/synthdefs/toms.rb +25 -0
- data/lib/musicality/performance/supercollider/synthdefs/volume.rb +20 -0
- data/lib/musicality/pitch_class.rb +1 -1
- data/lib/musicality/pitch_classes.rb +3 -5
- data/lib/musicality/version.rb +1 -1
- data/lib/musicality.rb +25 -1
- data/musicality.gemspec +3 -2
- data/spec/composition/convenience_methods_spec.rb +8 -8
- data/spec/composition/generation/random_rhythm_generator_spec.rb +5 -5
- data/spec/composition/model/pitch_class_spec.rb +22 -16
- data/spec/composition/model/pitch_classes_spec.rb +5 -5
- data/spec/composition/model/rhythm_class_spec.rb +42 -0
- data/spec/composition/model/rhythm_spec.rb +43 -0
- data/spec/composition/model/scale_class_spec.rb +26 -26
- data/spec/composition/model/scale_spec.rb +38 -38
- data/spec/composition/sequencing/drum_machine/drum_machine_spec.rb +67 -0
- data/spec/composition/sequencing/drum_machine/drum_pattern_spec.rb +58 -0
- data/spec/composition/sequencing/note_array_spec.rb +94 -0
- data/spec/composition/sequencing/note_fifo_spec.rb +183 -0
- data/spec/composition/sequencing/sequencer_spec.rb +76 -0
- data/spec/composition/util/adding_sequence_spec.rb +33 -33
- data/spec/composition/util/compound_sequence_spec.rb +6 -6
- data/spec/composition/util/note_generation_spec.rb +34 -34
- data/spec/composition/util/probabilities_spec.rb +7 -7
- data/spec/composition/util/random_sampler_spec.rb +3 -3
- data/spec/composition/util/repeating_sequence_spec.rb +28 -28
- data/spec/musicality_spec.rb +1 -1
- data/spec/notation/conversion/change_conversion_spec.rb +87 -87
- data/spec/notation/conversion/note_time_converter_spec.rb +22 -22
- data/spec/notation/conversion/score_conversion_spec.rb +1 -1
- data/spec/notation/conversion/score_converter_spec.rb +31 -31
- data/spec/notation/conversion/tempo_conversion_spec.rb +11 -11
- data/spec/notation/model/change_spec.rb +80 -80
- data/spec/notation/model/key_spec.rb +135 -69
- data/spec/notation/model/link_spec.rb +27 -27
- data/spec/notation/model/meter_spec.rb +28 -28
- data/spec/notation/model/note_spec.rb +68 -47
- data/spec/notation/model/part_spec.rb +19 -19
- data/spec/notation/model/pitch_spec.rb +69 -68
- data/spec/notation/model/score_spec.rb +50 -47
- data/spec/notation/parsing/articulation_parsing_spec.rb +4 -4
- data/spec/notation/parsing/convenience_methods_spec.rb +49 -10
- data/spec/notation/parsing/duration_nodes_spec.rb +13 -13
- data/spec/notation/parsing/duration_parsing_spec.rb +10 -10
- data/spec/notation/parsing/key_parsing_spec.rb +19 -0
- data/spec/notation/parsing/link_nodes_spec.rb +7 -7
- data/spec/notation/parsing/link_parsing_spec.rb +4 -4
- data/spec/notation/parsing/meter_parsing_spec.rb +5 -5
- data/spec/notation/parsing/note_node_spec.rb +19 -19
- data/spec/notation/parsing/note_parsing_spec.rb +4 -4
- data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +2 -2
- data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +1 -1
- data/spec/notation/parsing/numbers/positive_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/positive_integer_spec.rb +6 -6
- data/spec/notation/parsing/numbers/positive_rational_spec.rb +6 -6
- data/spec/notation/parsing/pitch_node_spec.rb +7 -7
- data/spec/notation/parsing/pitch_parsing_spec.rb +2 -2
- data/spec/notation/parsing/segment_parsing_spec.rb +3 -3
- data/spec/notation/util/function_spec.rb +15 -15
- data/spec/notation/util/transition_spec.rb +12 -12
- data/spec/notation/util/value_computer_spec.rb +35 -36
- data/spec/performance/conversion/glissando_converter_spec.rb +24 -24
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +39 -39
- data/spec/performance/conversion/portamento_converter_spec.rb +23 -23
- data/spec/performance/midi/midi_util_spec.rb +41 -41
- data/spec/performance/midi/part_sequencer_spec.rb +10 -10
- data/spec/performance/midi/score_sequencer_spec.rb +15 -15
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/util/optimization_spec.rb +9 -9
- data/spec/printing/note_engraving_spec.rb +16 -16
- data/spec/printing/score_engraver_spec.rb +5 -5
- data/spec/spec_helper.rb +5 -0
- metadata +85 -30
@@ -36,18 +36,21 @@ module PositiveFloat
|
|
36
36
|
r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
|
37
37
|
r0 = r1
|
38
38
|
r0.extend(PositiveFloat0)
|
39
|
+
r0.extend(PositiveFloat0)
|
39
40
|
else
|
40
41
|
r2 = _nt_float2
|
41
42
|
if r2
|
42
43
|
r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
|
43
44
|
r0 = r2
|
44
45
|
r0.extend(PositiveFloat0)
|
46
|
+
r0.extend(PositiveFloat0)
|
45
47
|
else
|
46
48
|
r3 = _nt_float3
|
47
49
|
if r3
|
48
50
|
r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
|
49
51
|
r0 = r3
|
50
52
|
r0.extend(PositiveFloat0)
|
53
|
+
r0.extend(PositiveFloat0)
|
51
54
|
else
|
52
55
|
@index = i0
|
53
56
|
r0 = nil
|
@@ -436,7 +439,7 @@ module PositiveFloat
|
|
436
439
|
r1 = true
|
437
440
|
@index += match_len
|
438
441
|
else
|
439
|
-
terminal_parse_failure("e")
|
442
|
+
terminal_parse_failure('"e"')
|
440
443
|
r1 = nil
|
441
444
|
end
|
442
445
|
s0 << r1
|
@@ -3,28 +3,24 @@ module Musicality
|
|
3
3
|
# to use, include Parseable and define PARSER constant that has #parse method.
|
4
4
|
module Parseable
|
5
5
|
DEFAULT_SPLIT_PATTERN = " "
|
6
|
-
|
6
|
+
|
7
7
|
def self.included(base)
|
8
8
|
base.extend(ClassMethods)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
module ClassMethods
|
12
|
-
def parser
|
13
|
-
self.const_get(:PARSER)
|
14
|
-
end
|
15
|
-
|
16
|
-
def convert node
|
17
|
-
node.send(self.const_get(:CONVERSION_METHOD))
|
18
|
-
end
|
19
|
-
|
20
12
|
def parse str
|
21
|
-
|
13
|
+
parser = self.const_get(:PARSER)
|
14
|
+
node = parser.parse(str)
|
15
|
+
raise ParseError, "Failed to parse #{str}" if node.nil?
|
16
|
+
|
17
|
+
node.send(self.const_get(:CONVERSION_METHOD))
|
22
18
|
end
|
23
|
-
|
19
|
+
|
24
20
|
def split_parse str, pattern=" "
|
25
|
-
str.split(pattern).map {|x|
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
21
|
+
str.split(pattern).map {|x| parse(x) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
29
25
|
|
30
|
-
end
|
26
|
+
end
|
@@ -252,6 +252,7 @@ module Pitch
|
|
252
252
|
if has_terminal?(@regexps[gr = '\A[Aa]'] ||= Regexp.new(gr), :regexp, index)
|
253
253
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
254
254
|
r0.extend(LetterA0)
|
255
|
+
r0.extend(LetterA0)
|
255
256
|
@index += 1
|
256
257
|
else
|
257
258
|
terminal_parse_failure('[Aa]')
|
@@ -281,6 +282,7 @@ module Pitch
|
|
281
282
|
if has_terminal?(@regexps[gr = '\A[Bb]'] ||= Regexp.new(gr), :regexp, index)
|
282
283
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
283
284
|
r0.extend(LetterB0)
|
285
|
+
r0.extend(LetterB0)
|
284
286
|
@index += 1
|
285
287
|
else
|
286
288
|
terminal_parse_failure('[Bb]')
|
@@ -310,6 +312,7 @@ module Pitch
|
|
310
312
|
if has_terminal?(@regexps[gr = '\A[Cc]'] ||= Regexp.new(gr), :regexp, index)
|
311
313
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
312
314
|
r0.extend(LetterC0)
|
315
|
+
r0.extend(LetterC0)
|
313
316
|
@index += 1
|
314
317
|
else
|
315
318
|
terminal_parse_failure('[Cc]')
|
@@ -339,6 +342,7 @@ module Pitch
|
|
339
342
|
if has_terminal?(@regexps[gr = '\A[Dd]'] ||= Regexp.new(gr), :regexp, index)
|
340
343
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
341
344
|
r0.extend(LetterD0)
|
345
|
+
r0.extend(LetterD0)
|
342
346
|
@index += 1
|
343
347
|
else
|
344
348
|
terminal_parse_failure('[Dd]')
|
@@ -368,6 +372,7 @@ module Pitch
|
|
368
372
|
if has_terminal?(@regexps[gr = '\A[Ee]'] ||= Regexp.new(gr), :regexp, index)
|
369
373
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
370
374
|
r0.extend(LetterE0)
|
375
|
+
r0.extend(LetterE0)
|
371
376
|
@index += 1
|
372
377
|
else
|
373
378
|
terminal_parse_failure('[Ee]')
|
@@ -397,6 +402,7 @@ module Pitch
|
|
397
402
|
if has_terminal?(@regexps[gr = '\A[Ff]'] ||= Regexp.new(gr), :regexp, index)
|
398
403
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
399
404
|
r0.extend(LetterF0)
|
405
|
+
r0.extend(LetterF0)
|
400
406
|
@index += 1
|
401
407
|
else
|
402
408
|
terminal_parse_failure('[Ff]')
|
@@ -426,6 +432,7 @@ module Pitch
|
|
426
432
|
if has_terminal?(@regexps[gr = '\A[Gg]'] ||= Regexp.new(gr), :regexp, index)
|
427
433
|
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
428
434
|
r0.extend(LetterG0)
|
435
|
+
r0.extend(LetterG0)
|
429
436
|
@index += 1
|
430
437
|
else
|
431
438
|
terminal_parse_failure('[Gg]')
|
@@ -7,97 +7,56 @@ class NoteSequenceExtractor
|
|
7
7
|
mark_slurring
|
8
8
|
remove_bad_links
|
9
9
|
calculate_offsets
|
10
|
-
|
10
|
+
|
11
11
|
# now, ready to extract sequences!
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def extract_sequences cents_per_step = 10
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
NoteSequenceExtractor.slur_seqs(cur_seq, next_seq)
|
34
|
-
elsif p1 = map[:full_glissandos].key(p2)
|
35
|
-
cur_seq = cur_seqs.find {|x| x.elements.first.pitch == p1 }
|
36
|
-
NoteSequenceExtractor.glissando_seqs(cur_seq, next_seq)
|
37
|
-
elsif p1 = map[:full_portamentos].key(p2)
|
38
|
-
cur_seq = cur_seqs.find {|x| x.elements.first.pitch == p1 }
|
39
|
-
NoteSequenceExtractor.portamento_seqs(cur_seq, next_seq, cents_per_step)
|
15
|
+
completed_seqs = []
|
16
|
+
continuing_sequences = {}
|
17
|
+
|
18
|
+
@notes.each_with_index do |note, idx|
|
19
|
+
offset = @offsets[idx]
|
20
|
+
duration = note.duration
|
21
|
+
attack = NoteSequenceExtractor.note_attack(note.articulation)
|
22
|
+
separation = NoteSequenceExtractor.note_separation(note.articulation, @slurring_flags[idx])
|
23
|
+
|
24
|
+
next_note = (idx == (@notes.size-1)) ? Note.quarter : @notes[idx+1]
|
25
|
+
continuation_map = NoteSequenceExtractor.continuation_map(note, next_note, separation)
|
26
|
+
|
27
|
+
new_continuing_sequences = {}
|
28
|
+
|
29
|
+
note.pitches.each do |p|
|
30
|
+
seq = if continuing_sequences.has_key?(p)
|
31
|
+
continuing_sequences[p].elements += note_pitch_elements(note, p, Attack::NONE, cents_per_step)
|
32
|
+
continuing_sequences.delete(p)
|
40
33
|
else
|
41
|
-
|
34
|
+
NoteSequence.new(offset, separation, note_pitch_elements(note, p, attack, cents_per_step))
|
42
35
|
end
|
43
|
-
end
|
44
|
-
next_seqs = cur_seqs
|
45
|
-
end
|
46
|
-
complete_seqs += next_seqs
|
47
|
-
return complete_seqs
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def self.tie_seqs(cur_seq, next_seq)
|
53
|
-
cur_seq.elements.last.duration += next_seq.elements.first.duration
|
54
|
-
cur_seq.elements += next_seq.elements[1..-1]
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.slur_seqs(cur_seq, next_seq)
|
58
|
-
if next_seq.elements.first.attack == Attack::NORMAL
|
59
|
-
next_seq.elements.first.attack = Attack::NONE
|
60
|
-
end
|
61
|
-
cur_seq.separation = next_seq.separation
|
62
|
-
cur_seq.elements += next_seq.elements
|
63
|
-
end
|
64
36
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
37
|
+
if continuation_map.include?(p)
|
38
|
+
new_continuing_sequences[continuation_map[p]] = seq
|
39
|
+
else
|
40
|
+
completed_seqs.push seq
|
41
|
+
end
|
42
|
+
end
|
71
43
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
cur_seq.elements += next_seq.elements
|
77
|
-
end
|
78
|
-
|
79
|
-
def seqs_from_note(idx, cents_per_step)
|
80
|
-
map = @maps[idx]
|
81
|
-
note = @notes[idx]
|
82
|
-
attack = NoteSequenceExtractor.note_attack(note.articulation)
|
83
|
-
separation = NoteSequenceExtractor.note_separation(note.articulation, @slurring_flags[idx])
|
84
|
-
offset = @offsets[idx]
|
85
|
-
note.pitches.map do |p|
|
86
|
-
if map[:half_glissandos].has_key?(p)
|
87
|
-
NoteSequence.new(offset, separation,
|
88
|
-
GlissandoConverter.glissando_elements(
|
89
|
-
p, map[:half_glissandos][p], note.duration, attack))
|
90
|
-
elsif map[:half_portamentos].has_key?(p)
|
91
|
-
NoteSequence.new(offset, Separation::NONE,
|
92
|
-
PortamentoConverter.portamento_elements(
|
93
|
-
p, map[:half_portamentos][p], cents_per_step, note.duration, attack))
|
94
|
-
else
|
95
|
-
NoteSequence.new(offset, separation,
|
96
|
-
[NoteSequence::Element.new(note.duration, p, attack)])
|
44
|
+
if continuing_sequences.any?
|
45
|
+
require 'pry'
|
46
|
+
binding.pry
|
47
|
+
# raise "Should be no previous continuing sequences remaining"
|
97
48
|
end
|
49
|
+
continuing_sequences = new_continuing_sequences
|
98
50
|
end
|
51
|
+
|
52
|
+
raise "Should be no previous continuing sequences remaining" if continuing_sequences.any?
|
53
|
+
|
54
|
+
completed_seqs.each {|seq| seq.simplify! }
|
55
|
+
return completed_seqs
|
99
56
|
end
|
100
57
|
|
58
|
+
private
|
59
|
+
|
101
60
|
def self.note_attack articulation
|
102
61
|
case articulation
|
103
62
|
when Articulations::NORMAL then Attack::NORMAL
|
@@ -137,7 +96,7 @@ class NoteSequenceExtractor
|
|
137
96
|
def mark_slurring
|
138
97
|
@slurring_flags = []
|
139
98
|
under_slur = false
|
140
|
-
|
99
|
+
|
141
100
|
@slurring_flags = Array.new(@notes.size) do |i|
|
142
101
|
note = @notes[i]
|
143
102
|
|
@@ -162,7 +121,7 @@ class NoteSequenceExtractor
|
|
162
121
|
end
|
163
122
|
end
|
164
123
|
end
|
165
|
-
|
124
|
+
|
166
125
|
def calculate_offsets
|
167
126
|
offset = 0.to_r
|
168
127
|
@offsets = Array.new(@notes.size) do |i|
|
@@ -171,61 +130,50 @@ class NoteSequenceExtractor
|
|
171
130
|
cur_offset
|
172
131
|
end
|
173
132
|
end
|
174
|
-
|
175
|
-
def self.
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
@notes.each_index do |i|
|
187
|
-
map = { :ties => {}, :slurs => {}, :full_glissandos => {},
|
188
|
-
:full_portamentos => {}, :half_glissandos => {},
|
189
|
-
:half_portamentos => {}}
|
190
|
-
note = @notes[i]
|
191
|
-
|
192
|
-
# Create a dummy note (with no pitches) for the last note to "link" to.
|
193
|
-
# This will allow half glissandos and half portamentos from the last note
|
194
|
-
next_note = (i == (@notes.size-1)) ? Note.quarter : @notes[i+1]
|
195
|
-
|
196
|
-
no_separation = NoteSequenceExtractor.no_separation?(note.articulation, @slurring_flags[i])
|
197
|
-
|
198
|
-
linked = note.pitches & note.links.keys
|
199
|
-
linked.each do |p|
|
200
|
-
l = note.links[p]
|
201
|
-
if l.is_a?(Link::Tie)
|
202
|
-
map[:ties][p] = p
|
203
|
-
elsif l.is_a?(Link::Glissando)
|
204
|
-
if next_note.pitches.include?(l.target_pitch)
|
205
|
-
map[:full_glissandos][p] = l.target_pitch
|
206
|
-
else
|
207
|
-
map[:half_glissandos][p] = l.target_pitch
|
208
|
-
end
|
209
|
-
elsif l.is_a?(Link::Portamento)
|
210
|
-
if next_note.pitches.include?(l.target_pitch)
|
211
|
-
map[:full_portamentos][p] = l.target_pitch
|
212
|
-
else
|
213
|
-
map[:half_portamentos][p] = l.target_pitch
|
214
|
-
end
|
215
|
-
end
|
133
|
+
|
134
|
+
def self.continuation_map note, next_note, separation
|
135
|
+
map = {}
|
136
|
+
|
137
|
+
linked = note.pitches & note.links.keys
|
138
|
+
targeted = []
|
139
|
+
linked.each do |p|
|
140
|
+
l = note.links[p]
|
141
|
+
if l.is_a?(Link::Tie)
|
142
|
+
map[p] = p
|
143
|
+
elsif l.is_a?(Link::TargetedLink) && next_note.pitches.include?(l.target_pitch)
|
144
|
+
map[p] = l.target_pitch
|
216
145
|
end
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
146
|
+
end
|
147
|
+
|
148
|
+
if(separation == Separation::NONE)
|
149
|
+
unlinked = note.pitches - linked
|
150
|
+
untargeted = next_note.pitches - map.values
|
151
|
+
Optimization.linking(unlinked, untargeted).each do |pitch,tgt_pitch|
|
152
|
+
map[pitch] = tgt_pitch
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
return map
|
157
|
+
end
|
158
|
+
|
159
|
+
def note_pitch_elements note, pitch, attack, cents_per_step
|
160
|
+
duration = note.duration
|
161
|
+
link = note.links[pitch]
|
162
|
+
elements = if link && link.is_a?(Link::TargetedLink)
|
163
|
+
tgt_pitch = link.target_pitch
|
164
|
+
case link
|
165
|
+
when Link::Glissando
|
166
|
+
GlissandoConverter.glissando_elements(pitch, tgt_pitch, duration, attack)
|
167
|
+
when Link::Portamento
|
168
|
+
PortamentoConverter.portamento_elements(pitch, tgt_pitch, cents_per_step, duration, attack)
|
169
|
+
else
|
170
|
+
raise "Unexpected targeted link type"
|
225
171
|
end
|
226
|
-
|
227
|
-
|
172
|
+
else
|
173
|
+
[ NoteSequence::Element.new(note.duration, pitch, attack) ]
|
228
174
|
end
|
175
|
+
|
176
|
+
return elements
|
229
177
|
end
|
230
178
|
end
|
231
179
|
|
@@ -27,11 +27,30 @@ class NoteSequence
|
|
27
27
|
@elements = elements
|
28
28
|
end
|
29
29
|
|
30
|
+
# any consecutive elements with the same pitch and no attack will be combined
|
31
|
+
def simplify!
|
32
|
+
return if @elements.none?
|
33
|
+
|
34
|
+
prev_element = @elements[0]
|
35
|
+
idx = 1
|
36
|
+
|
37
|
+
while idx < @elements.size
|
38
|
+
element = @elements[idx]
|
39
|
+
if (element.pitch == prev_element.pitch) && (element.attack == Attack::NONE)
|
40
|
+
prev_element.duration += element.duration
|
41
|
+
@elements.delete_at(idx)
|
42
|
+
else
|
43
|
+
prev_element = element
|
44
|
+
idx += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
30
49
|
alias start offset
|
31
|
-
|
50
|
+
|
32
51
|
def offsets
|
33
52
|
raise "contains no elements" if elements.empty?
|
34
|
-
|
53
|
+
|
35
54
|
off = @offset
|
36
55
|
elements.map do |e|
|
37
56
|
x = off
|
@@ -39,7 +58,7 @@ class NoteSequence
|
|
39
58
|
x
|
40
59
|
end
|
41
60
|
end
|
42
|
-
|
61
|
+
|
43
62
|
def stop
|
44
63
|
offsets.last + NoteSequence.adjust_duration(elements.last.duration, separation)
|
45
64
|
end
|
@@ -22,7 +22,7 @@ class Performer
|
|
22
22
|
group = create_part_group parent_group, bundles
|
23
23
|
set_start_volume volume_control_bus, bundles
|
24
24
|
add_volume_control group, aux_audio_bus, volume_control_bus, lead_time, bundles
|
25
|
-
add_volume_changes volume_control_bus, lead_time, bundles
|
25
|
+
add_volume_changes group, volume_control_bus, lead_time, bundles
|
26
26
|
add_part_notes group, aux_audio_bus, lead_time, bundles
|
27
27
|
|
28
28
|
bundles
|
@@ -51,7 +51,7 @@ class Performer
|
|
51
51
|
bundles.push vol_control.bundle_queue(lead_time / 2.0)
|
52
52
|
end
|
53
53
|
|
54
|
-
def add_volume_changes volume_control_bus, lead_time, bundles
|
54
|
+
def add_volume_changes group, volume_control_bus, lead_time, bundles
|
55
55
|
# change part volume
|
56
56
|
part.dynamic_changes.each do |offset,change|
|
57
57
|
case change
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Musicality
|
2
|
+
|
3
|
+
module DrumKits
|
4
|
+
|
5
|
+
SC_DRUM_KIT_01 = DrumKit.new(
|
6
|
+
DrumParts::BASS_DRUM => SuperCollider::SynthDefs::KICK2.settings,
|
7
|
+
DrumParts::SNARE_DRUM => SuperCollider::SynthDefs::SNARE_STEIN.settings,
|
8
|
+
DrumParts::CRASH_CYMBAL => SuperCollider::SynthDefs::CYMBALIC_MCLD.settings,
|
9
|
+
DrumParts::CLOSED_HI_HAT => SuperCollider::SynthDefs::CLOSED_HAT.settings,
|
10
|
+
DrumParts::OPEN_HI_HAT => SuperCollider::SynthDefs::OPEN_HAT.settings,
|
11
|
+
DrumParts::HI_TOM => SuperCollider::SynthDefs::TOM1.settings,
|
12
|
+
DrumParts::MED_TOM => SuperCollider::SynthDefs::TOM1.settings,
|
13
|
+
DrumParts::LOW_TOM => SuperCollider::SynthDefs::TOM1.settings,
|
14
|
+
)
|
15
|
+
|
16
|
+
SC_DRUM_KIT_02 = DrumKit.new(
|
17
|
+
DrumParts::BASS_DRUM => SuperCollider::SynthDefs::KICK_CHIRP.settings,
|
18
|
+
DrumParts::SNARE_DRUM => SuperCollider::SynthDefs::SNARE1.settings,
|
19
|
+
DrumParts::CRASH_CYMBAL => SuperCollider::SynthDefs::CYMBALIC_MCLD.settings,
|
20
|
+
DrumParts::CLOSED_HI_HAT => SuperCollider::SynthDefs::HIHAT1.settings,
|
21
|
+
DrumParts::OPEN_HI_HAT => SuperCollider::SynthDefs::HIHAT1.settings(:release => 0.6),
|
22
|
+
DrumParts::HI_TOM => SuperCollider::SynthDefs::FM_TOM.settings,
|
23
|
+
DrumParts::MED_TOM => SuperCollider::SynthDefs::FM_TOM.settings,
|
24
|
+
DrumParts::LOW_TOM => SuperCollider::SynthDefs::FM_TOM.settings,
|
25
|
+
)
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|