musa-dsl 0.14.31 → 0.21.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/Gemfile +0 -1
- data/README.md +5 -1
- data/lib/musa-dsl.rb +54 -11
- data/lib/musa-dsl/core-ext.rb +7 -13
- data/lib/musa-dsl/core-ext/array-explode-ranges.rb +15 -23
- data/lib/musa-dsl/core-ext/arrayfy.rb +30 -12
- data/lib/musa-dsl/core-ext/attribute-builder.rb +194 -0
- data/lib/musa-dsl/core-ext/deep-copy.rb +185 -0
- data/lib/musa-dsl/core-ext/dynamic-proxy.rb +44 -40
- data/lib/musa-dsl/core-ext/inspect-nice.rb +40 -22
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +108 -0
- data/lib/musa-dsl/core-ext/with.rb +26 -0
- data/lib/musa-dsl/datasets.rb +8 -3
- data/lib/musa-dsl/datasets/dataset.rb +3 -0
- data/lib/musa-dsl/datasets/delta-d.rb +12 -0
- data/lib/musa-dsl/datasets/e.rb +61 -0
- data/lib/musa-dsl/datasets/gdv.rb +51 -411
- data/lib/musa-dsl/datasets/gdvd.rb +179 -0
- data/lib/musa-dsl/datasets/helper.rb +41 -0
- data/lib/musa-dsl/datasets/p.rb +68 -0
- data/lib/musa-dsl/datasets/packed-v.rb +19 -0
- data/lib/musa-dsl/datasets/pdv.rb +22 -15
- data/lib/musa-dsl/datasets/ps.rb +113 -0
- data/lib/musa-dsl/datasets/score.rb +210 -0
- data/lib/musa-dsl/datasets/score/queriable.rb +48 -0
- data/lib/musa-dsl/datasets/score/render.rb +31 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +160 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +51 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +153 -0
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +158 -0
- data/lib/musa-dsl/datasets/v.rb +23 -0
- data/lib/musa-dsl/generative.rb +5 -5
- data/lib/musa-dsl/generative/backboner.rb +274 -0
- data/lib/musa-dsl/generative/darwin.rb +102 -96
- data/lib/musa-dsl/generative/generative-grammar.rb +182 -187
- data/lib/musa-dsl/generative/markov.rb +56 -53
- data/lib/musa-dsl/generative/variatio.rb +234 -222
- data/lib/musa-dsl/logger.rb +1 -0
- data/lib/musa-dsl/logger/logger.rb +31 -0
- data/lib/musa-dsl/matrix.rb +1 -0
- data/lib/musa-dsl/matrix/matrix.rb +210 -0
- data/lib/musa-dsl/midi.rb +2 -2
- data/lib/musa-dsl/midi/midi-recorder.rb +54 -52
- data/lib/musa-dsl/midi/midi-voices.rb +187 -182
- data/lib/musa-dsl/music.rb +5 -5
- data/lib/musa-dsl/music/chord-definition.rb +54 -50
- data/lib/musa-dsl/music/chord-definitions.rb +13 -9
- data/lib/musa-dsl/music/chords.rb +236 -238
- data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +187 -183
- data/lib/musa-dsl/music/scales.rb +331 -332
- data/lib/musa-dsl/musicxml.rb +1 -0
- data/lib/musa-dsl/musicxml/builder/attributes.rb +155 -0
- data/lib/musa-dsl/musicxml/builder/backup-forward.rb +45 -0
- data/lib/musa-dsl/musicxml/builder/direction.rb +322 -0
- data/lib/musa-dsl/musicxml/builder/helper.rb +90 -0
- data/lib/musa-dsl/musicxml/builder/measure.rb +137 -0
- data/lib/musa-dsl/musicxml/builder/note-complexities.rb +152 -0
- data/lib/musa-dsl/musicxml/builder/note.rb +577 -0
- data/lib/musa-dsl/musicxml/builder/part-group.rb +44 -0
- data/lib/musa-dsl/musicxml/builder/part.rb +67 -0
- data/lib/musa-dsl/musicxml/builder/pitched-note.rb +126 -0
- data/lib/musa-dsl/musicxml/builder/rest.rb +117 -0
- data/lib/musa-dsl/musicxml/builder/score-partwise.rb +120 -0
- data/lib/musa-dsl/musicxml/builder/typed-text.rb +43 -0
- data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +112 -0
- data/lib/musa-dsl/neumalang.rb +1 -1
- data/lib/musa-dsl/neumalang/datatypes.citrus +79 -0
- data/lib/musa-dsl/neumalang/neuma.citrus +165 -0
- data/lib/musa-dsl/neumalang/neumalang.citrus +32 -242
- data/lib/musa-dsl/neumalang/neumalang.rb +373 -142
- data/lib/musa-dsl/neumalang/process.citrus +21 -0
- data/lib/musa-dsl/neumalang/terminals.citrus +67 -0
- data/lib/musa-dsl/neumalang/vectors.citrus +23 -0
- data/lib/musa-dsl/neumas.rb +5 -0
- data/lib/musa-dsl/neumas/array-to-neumas.rb +34 -0
- data/lib/musa-dsl/neumas/neuma-decoder.rb +63 -0
- data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +57 -0
- data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +15 -0
- data/lib/musa-dsl/neumas/neumas.rb +37 -0
- data/lib/musa-dsl/neumas/string-to-neumas.rb +34 -0
- data/lib/musa-dsl/repl.rb +1 -1
- data/lib/musa-dsl/repl/repl.rb +122 -110
- data/lib/musa-dsl/sequencer.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +163 -136
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +301 -286
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +554 -308
- data/lib/musa-dsl/sequencer/base-sequencer-public.rb +198 -176
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +75 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +75 -0
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +105 -85
- data/lib/musa-dsl/sequencer/timeslots.rb +34 -0
- data/lib/musa-dsl/series.rb +1 -1
- data/lib/musa-dsl/{core-ext → series}/array-to-serie.rb +1 -1
- data/lib/musa-dsl/series/base-series.rb +171 -168
- data/lib/musa-dsl/series/hash-serie-splitter.rb +134 -132
- data/lib/musa-dsl/series/holder-serie.rb +1 -1
- data/lib/musa-dsl/series/main-serie-constructors.rb +6 -1
- data/lib/musa-dsl/series/main-serie-operations.rb +807 -797
- data/lib/musa-dsl/series/proxy-serie.rb +6 -6
- data/lib/musa-dsl/series/queue-serie.rb +5 -5
- data/lib/musa-dsl/series/series.rb +2 -0
- data/lib/musa-dsl/transcription.rb +4 -0
- data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +227 -0
- data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +36 -0
- data/lib/musa-dsl/transcription/from-gdv.rb +17 -0
- data/lib/musa-dsl/transcription/transcription.rb +55 -0
- data/lib/musa-dsl/transport.rb +6 -6
- data/lib/musa-dsl/transport/clock.rb +26 -26
- data/lib/musa-dsl/transport/dummy-clock.rb +32 -30
- data/lib/musa-dsl/transport/external-tick-clock.rb +21 -20
- data/lib/musa-dsl/transport/input-midi-clock.rb +89 -80
- data/lib/musa-dsl/transport/timer-clock.rb +72 -71
- data/lib/musa-dsl/transport/timer.rb +28 -26
- data/lib/musa-dsl/transport/transport.rb +111 -93
- data/musa-dsl.gemspec +3 -3
- metadata +73 -24
- data/lib/musa-dsl/core-ext/array-apply-get.rb +0 -18
- data/lib/musa-dsl/core-ext/array-to-neumas.rb +0 -28
- data/lib/musa-dsl/core-ext/as-context-run.rb +0 -44
- data/lib/musa-dsl/core-ext/duplicate.rb +0 -134
- data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +0 -85
- data/lib/musa-dsl/core-ext/proc-nice.rb +0 -13
- data/lib/musa-dsl/core-ext/send-nice.rb +0 -21
- data/lib/musa-dsl/core-ext/string-to-neumas.rb +0 -27
- data/lib/musa-dsl/datasets/gdv-decorators.rb +0 -221
- data/lib/musa-dsl/generative/rules.rb +0 -282
- data/lib/musa-dsl/neuma.rb +0 -1
- data/lib/musa-dsl/neuma/neuma.rb +0 -181
@@ -0,0 +1,179 @@
|
|
1
|
+
require_relative 'delta-d'
|
2
|
+
require_relative 'gdv'
|
3
|
+
|
4
|
+
require_relative 'helper'
|
5
|
+
|
6
|
+
using Musa::Extension::InspectNice
|
7
|
+
|
8
|
+
module Musa::Datasets
|
9
|
+
module GDVd
|
10
|
+
include DeltaD
|
11
|
+
include DeltaI
|
12
|
+
|
13
|
+
include Helper
|
14
|
+
|
15
|
+
NaturalKeys = (NaturalKeys +
|
16
|
+
[:abs_grade, :abs_sharps, :abs_octave,
|
17
|
+
:delta_grade, :delta_sharps, :delta_interval_sign, :delta_interval, :delta_octave,
|
18
|
+
:abs_velocity, :delta_velocity,
|
19
|
+
:modifiers]).freeze
|
20
|
+
|
21
|
+
attr_reader :base_duration
|
22
|
+
|
23
|
+
def base_duration=(value)
|
24
|
+
factor = value / (@base_duration || 1)
|
25
|
+
@base_duration = value
|
26
|
+
|
27
|
+
self[:abs_duration] *= factor if has_key?(:abs_duration)
|
28
|
+
self[:delta_duration] *= factor if has_key?(:delta_duration)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_gdv(scale, previous:)
|
32
|
+
r = previous.clone.delete_if {|k,_| !GDV::NaturalKeys.include?(k)}.extend GDV
|
33
|
+
|
34
|
+
r.base_duration = @base_duration
|
35
|
+
|
36
|
+
if include?(:abs_grade)
|
37
|
+
if self[:abs_grade] == :silence
|
38
|
+
r[:silence] = true
|
39
|
+
else
|
40
|
+
r.delete :silence
|
41
|
+
r.delete :sharps
|
42
|
+
|
43
|
+
r[:grade] = scale[self[:abs_grade]].wide_grade
|
44
|
+
r[:sharps] = self[:abs_sharps] if include?(:abs_sharps)
|
45
|
+
end
|
46
|
+
|
47
|
+
elsif include?(:delta_grade)
|
48
|
+
r.delete :silence
|
49
|
+
|
50
|
+
r[:grade], r[:sharps] =
|
51
|
+
normalize_to_scale(scale,
|
52
|
+
scale[r[:grade]].wide_grade + self[:delta_grade],
|
53
|
+
(r[:sharps] || 0) + (self[:delta_sharps] || 0))
|
54
|
+
|
55
|
+
r.delete :sharps if r[:sharps].zero?
|
56
|
+
|
57
|
+
elsif include?(:delta_interval)
|
58
|
+
r.delete :silence
|
59
|
+
|
60
|
+
sign = self[:delta_interval_sign] || 1
|
61
|
+
|
62
|
+
r[:grade], r[:sharps] =
|
63
|
+
normalize_to_scale scale,
|
64
|
+
scale[r[:grade]].wide_grade,
|
65
|
+
sign * scale.kind.tuning.scale_system.intervals[self[:delta_interval]]
|
66
|
+
|
67
|
+
r.delete :sharps if r[:sharps].zero?
|
68
|
+
|
69
|
+
elsif include?(:delta_sharps)
|
70
|
+
r.delete :silence
|
71
|
+
|
72
|
+
r[:grade], r[:sharps] =
|
73
|
+
normalize_to_scale scale,
|
74
|
+
scale[r[:grade]].wide_grade,
|
75
|
+
(r[:sharps] || 0) + self[:delta_sharps]
|
76
|
+
|
77
|
+
r.delete :sharps if r[:sharps].zero?
|
78
|
+
end
|
79
|
+
|
80
|
+
if include?(:abs_octave)
|
81
|
+
r[:octave] = self[:abs_octave]
|
82
|
+
elsif include?(:delta_octave)
|
83
|
+
r[:octave] += self[:delta_octave]
|
84
|
+
end
|
85
|
+
|
86
|
+
if include?(:abs_duration)
|
87
|
+
r[:duration] = self[:abs_duration]
|
88
|
+
elsif include?(:delta_duration)
|
89
|
+
r[:duration] += self[:delta_duration]
|
90
|
+
elsif include?(:factor_duration)
|
91
|
+
r[:duration] *= self[:factor_duration]
|
92
|
+
end
|
93
|
+
|
94
|
+
if include?(:abs_velocity)
|
95
|
+
r[:velocity] = self[:abs_velocity]
|
96
|
+
elsif include?(:delta_velocity)
|
97
|
+
r[:velocity] += self[:delta_velocity]
|
98
|
+
end
|
99
|
+
|
100
|
+
if include?(:modifiers)
|
101
|
+
self[:modifiers].each_pair do |k, v|
|
102
|
+
r[k] = v
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
(keys - NaturalKeys).each { |k| r[k] = self[k] }
|
107
|
+
|
108
|
+
r
|
109
|
+
end
|
110
|
+
|
111
|
+
def normalize_to_scale(scale, grade, sharps)
|
112
|
+
note = scale[grade].sharp(sharps)
|
113
|
+
background = note.background_note
|
114
|
+
|
115
|
+
if background
|
116
|
+
return background.wide_grade, note.background_sharps
|
117
|
+
else
|
118
|
+
return note.wide_grade, 0
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_neuma
|
123
|
+
@base_duration ||= Rational(1,4)
|
124
|
+
|
125
|
+
attributes = []
|
126
|
+
|
127
|
+
c = 0
|
128
|
+
|
129
|
+
if include?(:abs_grade)
|
130
|
+
attributes[c] = self[:abs_grade].to_s
|
131
|
+
|
132
|
+
elsif include?(:delta_grade)
|
133
|
+
attributes[c] = positive_sign_of(self[:delta_grade]) + self[:delta_grade].to_s unless self[:delta_grade].zero?
|
134
|
+
|
135
|
+
elsif include?(:delta_interval)
|
136
|
+
|
137
|
+
attributes[c] = self[:delta_interval_sign] if include?(:delta_interval_sign)
|
138
|
+
attributes[c] ||= ''
|
139
|
+
attributes[c] += self[:delta_interval].to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
if include?(:delta_sharps) && !self[:delta_sharps].zero?
|
143
|
+
char = self[:delta_sharps] > 0 ? '#' : '_'
|
144
|
+
sign = attributes[c].nil? ? positive_sign_of(self[:delta_sharps]) : ''
|
145
|
+
|
146
|
+
attributes[c] ||= ''
|
147
|
+
attributes[c] += sign + char * self[:delta_sharps].abs
|
148
|
+
end
|
149
|
+
|
150
|
+
attributes[c] = '.' if attributes[c].nil? || attributes[c].empty?
|
151
|
+
|
152
|
+
if include?(:abs_octave)
|
153
|
+
attributes[c += 1] = 'o' + self[:abs_octave].to_s
|
154
|
+
elsif include?(:delta_octave)
|
155
|
+
attributes[c += 1] = sign_of(self[:delta_octave]) + 'o' + self[:delta_octave].abs.to_s if self[:delta_octave] != 0
|
156
|
+
end
|
157
|
+
|
158
|
+
if include?(:abs_duration)
|
159
|
+
attributes[c += 1] = (self[:abs_duration] / @base_duration).to_s
|
160
|
+
elsif include?(:delta_duration)
|
161
|
+
attributes[c += 1] = positive_sign_of(self[:delta_duration]) + (self[:delta_duration] / @base_duration).to_s
|
162
|
+
elsif include?(:factor_duration)
|
163
|
+
attributes[c += 1] = '*' + self[:factor_duration].to_s
|
164
|
+
end
|
165
|
+
|
166
|
+
if include?(:abs_velocity)
|
167
|
+
attributes[c += 1] = velocity_of(self[:abs_velocity])
|
168
|
+
elsif include?(:delta_velocity)
|
169
|
+
attributes[c += 1] = sign_of(self[:delta_velocity]) + 'f' * self[:delta_velocity].abs
|
170
|
+
end
|
171
|
+
|
172
|
+
(keys - NaturalKeys).each do |k|
|
173
|
+
attributes[c += 1] = modificator_string(k, self[k])
|
174
|
+
end
|
175
|
+
|
176
|
+
'(' + attributes.join(' ') + ')'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Musa::Datasets
|
2
|
+
module Helper
|
3
|
+
protected
|
4
|
+
|
5
|
+
def positive_sign_of(x)
|
6
|
+
x >= 0 ? '+' : ''
|
7
|
+
end
|
8
|
+
|
9
|
+
def sign_of(x)
|
10
|
+
'++-'[x <=> 0]
|
11
|
+
end
|
12
|
+
|
13
|
+
def velocity_of(x)
|
14
|
+
%w[ppp pp p mp mf f ff fff][x + 3]
|
15
|
+
end
|
16
|
+
|
17
|
+
def modificator_string(modificator, parameter_or_parameters)
|
18
|
+
case parameter_or_parameters
|
19
|
+
when true
|
20
|
+
modificator.to_s
|
21
|
+
when Array
|
22
|
+
"#{modificator.to_s}(#{parameter_or_parameters.collect { |p| parameter_to_string(p) }.join(', ')})"
|
23
|
+
else
|
24
|
+
"#{modificator.to_s}(#{parameter_to_string(parameter_or_parameters)})"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def parameter_to_string(parameter)
|
31
|
+
case parameter
|
32
|
+
when String
|
33
|
+
"\"#{parameter}\""
|
34
|
+
when Numeric
|
35
|
+
"#{parameter}"
|
36
|
+
when Symbol
|
37
|
+
"#{parameter}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'dataset'
|
2
|
+
require_relative 'ps'
|
3
|
+
|
4
|
+
require_relative '../sequencer'
|
5
|
+
|
6
|
+
module Musa::Datasets
|
7
|
+
module P
|
8
|
+
include Dataset
|
9
|
+
|
10
|
+
def to_ps_serie(base_duration = nil)
|
11
|
+
base_duration ||= 1/4r
|
12
|
+
|
13
|
+
p = clone
|
14
|
+
|
15
|
+
Musa::Series::E() do
|
16
|
+
(p.size >= 3) ?
|
17
|
+
{ from: p.shift,
|
18
|
+
duration: p.shift * base_duration,
|
19
|
+
to: p.first,
|
20
|
+
right_open: (p.length > 1) }.extend(PS).tap { |_| _.base_duration = base_duration } : nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_score(score: nil,
|
25
|
+
mapper: nil,
|
26
|
+
position: nil,
|
27
|
+
sequencer: nil,
|
28
|
+
beats_per_bar: nil, ticks_per_beat: nil,
|
29
|
+
right_open: nil,
|
30
|
+
do_log: nil,
|
31
|
+
&block)
|
32
|
+
|
33
|
+
raise ArgumentError,
|
34
|
+
"'beats_per_bar' and 'ticks_per_beat' parameters should be both nil or both have values" \
|
35
|
+
unless beats_per_bar && ticks_per_beat || beats_per_bar.nil? && ticks_per_beat.nil?
|
36
|
+
|
37
|
+
raise ArgumentError,
|
38
|
+
"'sequencer' parameter should not be used when 'beats_per_bar' and 'ticks_per_beat' parameters are used" \
|
39
|
+
if sequencer && beats_per_bar
|
40
|
+
|
41
|
+
run_sequencer = sequencer.nil?
|
42
|
+
|
43
|
+
score ||= Musa::Datasets::Score.new
|
44
|
+
|
45
|
+
sequencer ||= Sequencer.new(beats_per_bar, ticks_per_beat, do_log: do_log)
|
46
|
+
|
47
|
+
sequencer.at(position || 1r) do |_|
|
48
|
+
|
49
|
+
_.play to_ps_serie do |_, line|
|
50
|
+
|
51
|
+
line.to_score(sequencer: _,
|
52
|
+
score: score,
|
53
|
+
mapper: mapper,
|
54
|
+
position: _.position,
|
55
|
+
right_open: right_open,
|
56
|
+
&block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if run_sequencer
|
61
|
+
sequencer.run
|
62
|
+
score
|
63
|
+
else
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'e'
|
2
|
+
require_relative 'v'
|
3
|
+
|
4
|
+
module Musa::Datasets
|
5
|
+
module PackedV
|
6
|
+
include AbsI
|
7
|
+
|
8
|
+
def to_V(mapper)
|
9
|
+
case mapper
|
10
|
+
when Hash
|
11
|
+
mapper.collect { |key, default| self[key] || default }.extend(V)
|
12
|
+
when Array
|
13
|
+
mapper.collect { |key| self[key] }.extend(V)
|
14
|
+
else
|
15
|
+
raise ArgumentError, "Expected Hash or Array as mapper but got a #{mapper.class.name}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,44 +1,51 @@
|
|
1
|
-
|
1
|
+
require_relative 'e'
|
2
|
+
require_relative 'gdv'
|
3
|
+
|
4
|
+
require_relative 'helper'
|
2
5
|
|
3
6
|
module Musa::Datasets
|
4
7
|
module PDV
|
5
|
-
include
|
8
|
+
include AbsD
|
9
|
+
include AbsI
|
10
|
+
|
11
|
+
include Helper
|
6
12
|
|
7
|
-
NaturalKeys = [:pitch, :
|
13
|
+
NaturalKeys = (NaturalKeys + [:pitch, :velocity]).freeze
|
8
14
|
|
9
15
|
attr_accessor :base_duration
|
10
16
|
|
11
17
|
def to_gdv(scale)
|
12
|
-
|
13
|
-
|
18
|
+
gdv = {}.extend GDV
|
19
|
+
gdv.base_duration = @base_duration
|
14
20
|
|
15
21
|
if self[:pitch]
|
16
22
|
if self[:pitch] == :silence
|
17
|
-
|
23
|
+
gdv[:grade] = :silence
|
18
24
|
else
|
19
25
|
note = scale.note_of_pitch(self[:pitch], allow_chromatic: true)
|
20
26
|
|
21
27
|
if background_note = note.background_note
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
gdv[:grade] = background_note.grade
|
29
|
+
gdv[:octave] = background_note.octave
|
30
|
+
gdv[:sharps] = note.background_sharps
|
25
31
|
else
|
26
|
-
|
27
|
-
|
32
|
+
gdv[:grade] = note.grade
|
33
|
+
gdv[:octave] = note.octave
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
32
|
-
|
38
|
+
gdv[:duration] = self[:duration] if self[:duration]
|
33
39
|
|
34
40
|
if self[:velocity]
|
35
41
|
# ppp = 16 ... fff = 127
|
36
|
-
|
42
|
+
# TODO create a customizable MIDI velocity to score dynamics bidirectional conversor
|
43
|
+
gdv[:velocity] = [1..1, 2..8, 9..16, 17..33, 34..49, 49..64, 65..80, 81..96, 97..112, 113..127].index { |r| r.cover? self[:velocity] } - 5
|
37
44
|
end
|
38
45
|
|
39
|
-
(keys - NaturalKeys).each { |k|
|
46
|
+
(keys - NaturalKeys).each { |k| gdv[k] = self[k] }
|
40
47
|
|
41
|
-
|
48
|
+
gdv
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require_relative 'e'
|
2
|
+
require_relative 'score'
|
3
|
+
|
4
|
+
require_relative '../sequencer'
|
5
|
+
|
6
|
+
module Musa::Datasets
|
7
|
+
module PS
|
8
|
+
include AbsD
|
9
|
+
|
10
|
+
include Helper
|
11
|
+
|
12
|
+
NaturalKeys = (NaturalKeys + [:from, :to, :right_open]).freeze
|
13
|
+
|
14
|
+
attr_accessor :base_duration
|
15
|
+
|
16
|
+
def to_neuma
|
17
|
+
# TODO ???????
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_pdv
|
21
|
+
# TODO ??????
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_gdv
|
25
|
+
# TODO ?????
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_absI
|
29
|
+
# TODO ?????
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_score(score: nil,
|
33
|
+
mapper: nil,
|
34
|
+
position: nil,
|
35
|
+
sequencer: nil,
|
36
|
+
beats_per_bar: nil, ticks_per_beat: nil,
|
37
|
+
right_open: nil,
|
38
|
+
do_log: nil,
|
39
|
+
&block)
|
40
|
+
|
41
|
+
raise ArgumentError,
|
42
|
+
"'beats_per_bar' and 'ticks_per_beat' parameters should be both nil or both have values" \
|
43
|
+
unless beats_per_bar && ticks_per_beat || beats_per_bar.nil? && ticks_per_beat.nil?
|
44
|
+
|
45
|
+
raise ArgumentError,
|
46
|
+
"'sequencer' parameter should not be used when 'beats_per_bar' and 'ticks_per_beat' parameters are used" \
|
47
|
+
if sequencer && beats_per_bar
|
48
|
+
|
49
|
+
run_sequencer = sequencer.nil?
|
50
|
+
|
51
|
+
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
52
|
+
|
53
|
+
score ||= Musa::Datasets::Score.new
|
54
|
+
|
55
|
+
sequencer ||= Musa::Sequencer::Sequencer.new(beats_per_bar, ticks_per_beat, do_log: do_log)
|
56
|
+
|
57
|
+
ticks_per_bar = sequencer.ticks_per_bar
|
58
|
+
|
59
|
+
from = mapper && self[:from].is_a?(V) ? self[:from].to_packed_V(mapper) : self[:from]
|
60
|
+
to = mapper && self[:to].is_a?(V) ? self[:to].to_packed_V(mapper) : self[:to]
|
61
|
+
|
62
|
+
if right_open.is_a?(Array)
|
63
|
+
right_open = right_open.collect do |v|
|
64
|
+
v.is_a?(Symbol) ? v : mapper[v]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# TODO sequencer step should be 1????
|
69
|
+
#
|
70
|
+
sequencer.at(position || 1r) do |_|
|
71
|
+
_.move from: from,
|
72
|
+
to: to,
|
73
|
+
right_open: right_open,
|
74
|
+
duration: _quantize(self[:duration], ticks_per_bar),
|
75
|
+
step: 1 do
|
76
|
+
| _,
|
77
|
+
value, next_value,
|
78
|
+
duration:,
|
79
|
+
quantized_duration:,
|
80
|
+
position_jitter:, duration_jitter:,
|
81
|
+
started_ago:|
|
82
|
+
|
83
|
+
binder.call value, next_value,
|
84
|
+
position: _.position,
|
85
|
+
duration: duration,
|
86
|
+
quantized_duration: quantized_duration,
|
87
|
+
position_jitter: position_jitter,
|
88
|
+
duration_jitter: duration_jitter,
|
89
|
+
started_ago: started_ago,
|
90
|
+
score: score,
|
91
|
+
logger: _.logger
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if run_sequencer
|
96
|
+
sequencer.run
|
97
|
+
score
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def _quantize(duration, ticks_per_bar)
|
106
|
+
if ticks_per_bar &.< Float::INFINITY
|
107
|
+
((duration.rationalize * ticks_per_bar).round / ticks_per_bar).to_r
|
108
|
+
else
|
109
|
+
duration.rationalize
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|