zgomot 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +52 -14
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/examples/cycle.rb +13 -0
- data/examples/cycle_note_list.rb +14 -0
- data/examples/dynamic_length.rb +18 -0
- data/examples/dynamic_length_perc.rb +22 -0
- data/examples/geco_input.rb +16 -0
- data/examples/simple_input.rb +6 -2
- data/examples/simple_note_list.rb +12 -0
- data/examples/zgomot_streams.rb +7 -3
- data/lib/zgomot.rb +1 -0
- data/lib/zgomot/boot.rb +2 -0
- data/lib/zgomot/comp.rb +1 -0
- data/lib/zgomot/comp/chord.rb +8 -2
- data/lib/zgomot/comp/mode.rb +1 -1
- data/lib/zgomot/comp/note_list.rb +68 -0
- data/lib/zgomot/comp/pattern.rb +12 -4
- data/lib/zgomot/comp/perc.rb +34 -64
- data/lib/zgomot/comp/progression.rb +20 -7
- data/lib/zgomot/drivers/core_midi.rb +14 -5
- data/lib/zgomot/main.rb +50 -1
- data/lib/zgomot/midi/cc.rb +15 -9
- data/lib/zgomot/midi/dispatcher.rb +8 -0
- data/lib/zgomot/midi/note.rb +8 -11
- data/lib/zgomot/midi/stream.rb +11 -1
- data/lib/zgomot/ui/windows.rb +139 -66
- data/zgomot.gems +1 -0
- data/zgomot.gemspec +7 -2
- metadata +25 -2
data/README.rdoc
CHANGED
@@ -164,6 +164,22 @@ Percussion supports the following transformations,
|
|
164
164
|
|
165
165
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the note is played.
|
166
166
|
|
167
|
+
== Note List
|
168
|
+
|
169
|
+
A Note List is a set of notes or percussive notes that start playing simultaneously. The Note List may contain any number of notes and its duration is the duration of the longest note in the list. It is defined by,
|
170
|
+
|
171
|
+
nl(n1, n2, ..., nN)
|
172
|
+
|
173
|
+
where <tt>nN</tt> is the <tt>N'th</tt> note in the list.
|
174
|
+
|
175
|
+
==== Transforms
|
176
|
+
|
177
|
+
* <tt>shift</tt>: Remove and return the first note from the progression.
|
178
|
+
* <tt>unshift</tt>: Add a note to the beginning of the progression.
|
179
|
+
* <tt>pop</tt>: Remove and return the last note from the progression.
|
180
|
+
* <tt>push</tt>: Add a note to the end of the progression.
|
181
|
+
* <tt>reverse!</tt>: Reverse the notes in the progression.
|
182
|
+
|
167
183
|
== Chord Progressions
|
168
184
|
|
169
185
|
Chord Progressions or Roman Numeral Notation permit the definition of a melody that is independent of key. Using Chord progressions it is possible to iteratively shift the key of a specified sequence of chords.
|
@@ -188,15 +204,18 @@ A chord progression in a key of F# dorian at octave 5 with notes of half note le
|
|
188
204
|
* <tt>tonic!(tonic)</tt>: Change the tonic pitch of the progression.
|
189
205
|
* <tt>mode!(mode)</tt>: Change the mode of the progression
|
190
206
|
* <tt>[](*args)</tt>: By default when a progression is created it only consists of one each of the notes in the key played sequentially. Using this transformation it is possible to change the the notes played in the progression. For example <tt>cp([:Fs, 5], :dorian)[1,5,5,7]</tt> will play the sequence <tt>1, 5, 5, 7</tt> instead of <tt>1, 2, 3, 4, 5, 6, 7</tt>.
|
191
|
-
* <tt>velocity
|
192
|
-
* <tt>length
|
207
|
+
* <tt>velocity!(v)</tt>: Change the velocity of all notes in the progression.
|
208
|
+
* <tt>length!(v)</tt>: Change the length of all notes in the progression.
|
193
209
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the chord is played.
|
194
210
|
* <tt>octave!(ocatve)</tt>: change the octave of all notes in the progression.
|
195
211
|
* <tt>arp!(length)</tt>: arpeggiate the chords in the progression using the specified length in units of note length. Accepted values are 1, 2, 4, 8, ... resolution, representing arpeggiation by a whole note, half note, quarter note, eighth note up to the specified clock resolution.
|
196
212
|
* <tt>inv!(number)</tt>: The inversion number. A value of zero will leave the chord unchanged, 1 is the first inversion and 2 is the second. Higher inversions just shift the chord to a higher octave.
|
197
213
|
* <tt>rev!</tt>: Reverse the order in which the notes are played. Only noticeable if the chords in the progression are also arpeggiated.
|
198
|
-
|
199
|
-
|
214
|
+
* <tt>shift</tt>: Remove and return the first chord from the progression.
|
215
|
+
* <tt>unshift</tt>: Add a chord to the beginning of the progression.
|
216
|
+
* <tt>pop</tt>: Remove and return the last chord from the progression.
|
217
|
+
* <tt>push</tt>: Add a chord to the end of the progression.
|
218
|
+
* <tt>reverse!</tt>: Reverse the chords in the progression.
|
200
219
|
|
201
220
|
== Note Progressions
|
202
221
|
|
@@ -220,12 +239,15 @@ An note progression in a key of F# dorian at octave 5 with notes of half note le
|
|
220
239
|
* <tt>tonic!(tonic)</tt>: Change the tonic pitch of the progression.
|
221
240
|
* <tt>mode!(mode)</tt>: Change the mode of the progression
|
222
241
|
* <tt>[](*args)</tt>: By default when a progression is created it only consists of one each of the notes in the key played sequentially using this transformation it is possible to change the the notes played in the progression. For example <tt>np([:Fs, 5], :dorian)[1,5,5,7]</tt> will play the sequence 1, 5, 5, 7 instead of 1, 2, 3, 4, 5, 6, 7.
|
223
|
-
* <tt>velocity
|
224
|
-
* <tt>length
|
225
|
-
* <tt>bpm!(bpm)</tt>:
|
226
|
-
* <tt>octave!(ocatve)</tt>:
|
227
|
-
|
228
|
-
|
242
|
+
* <tt>velocity!(v)</tt>: Change the velocity of all notes in the progression.
|
243
|
+
* <tt>length!(v)</tt>: Change the length of all notes in the progression.
|
244
|
+
* <tt>bpm!(bpm)</tt>: Change the bits per minute at which the chord is played.
|
245
|
+
* <tt>octave!(ocatve)</tt>: Change the octave of all notes in the progression.
|
246
|
+
* <tt>shift</tt>: Remove and return the first note from the progression.
|
247
|
+
* <tt>unshift</tt>: Add a note to the beginning of the progression.
|
248
|
+
* <tt>pop</tt>: Remove and return the last note from the progression.
|
249
|
+
* <tt>push</tt>: Add a note to the end of the progression.
|
250
|
+
* <tt>reverse!</tt>: Reverse the notes in the progression.
|
229
251
|
|
230
252
|
== Progression with Defined Length and Velocity by Note
|
231
253
|
|
@@ -237,6 +259,12 @@ Different durations and velocities for each note in a progression can be defined
|
|
237
259
|
|
238
260
|
Patterns are heterogeneous arrays of notes, chords, Chord Progressions and Note Progressions. Operations applied to the pattern will be delegated to the appropriate elements of the pattern array.
|
239
261
|
|
262
|
+
Also, custom transformations can be applied to the items of a pattern using <tt>map</tt>,
|
263
|
+
|
264
|
+
pattern.map do |item|
|
265
|
+
transform(item)
|
266
|
+
end
|
267
|
+
|
240
268
|
== Streams
|
241
269
|
|
242
270
|
A stream is used to define iteration on a pattern and outputs a stream of MIDI data.
|
@@ -357,13 +385,21 @@ where <tt>name</tt> is the name of the <tt>input</tt>. There can be only one MID
|
|
357
385
|
|
358
386
|
MIDI CC messages can be used to assign values to variables that can be read by programs. To assign a CC message to a variable use,
|
359
387
|
|
360
|
-
add_cc(name,
|
388
|
+
add_cc(name, cc, options)
|
361
389
|
|
362
|
-
Where <tt>name</tt> is the variable name, ,<tt>
|
390
|
+
Where <tt>name</tt> is the variable name, ,<tt>cc</tt> is the MIDI CC identifier, a number between 0 and 255 and options are the following,
|
363
391
|
|
364
392
|
* <tt>:max</tt>: The maximum value of the CC message. The default is 1.
|
365
393
|
* <tt>:min</tt>: The minimum value of the CC message. The default is 0.
|
394
|
+
* <tt>:channel</tt>: The CC channel number. The default is 1.
|
366
395
|
* <tt>:type</tt>: The CC message type. Accepted values are <tt>:cont</tt> and <tt>:switch</tt>. <tt>:cont</tt> type varies continuously between <tt>:max</tt> and <tt>:min</tt>. <tt>:switch</tt> type is boolean.
|
396
|
+
* <tt>:init</tt>: The initial value of the CC message. The default is 0 if type is <tt>:cont</tt> and <tt>false</tt> if type is <tt>:switch</tt>.
|
397
|
+
|
398
|
+
A block can also be passed to <tt>add_cc</tt> which is yielded the updated cc parameters. For example a CC which pauses a stream would look like,
|
399
|
+
|
400
|
+
add_cc('pause', 17, :type => :switch) do
|
401
|
+
pause('my_stream')
|
402
|
+
end
|
367
403
|
|
368
404
|
To read a variable assigned to a CC message use,
|
369
405
|
|
@@ -391,7 +427,7 @@ All commands and objects described previously are available and can be typed dir
|
|
391
427
|
* <tt>pause name</tt>: Pause the named stream. If no name is given pause all <tt>playing</tt> streams.
|
392
428
|
* <tt>stop name</tt>: An alias for <tt>pause</tt>.
|
393
429
|
* <tt>tog name</tt>: Toggle the status of the named stream. <tt>name</tt> is required.
|
394
|
-
|
430
|
+
* <tt>watch dir</tt>: Automatically load any new or updated files in <tt>dir</tt>. The default value of <tt>dir</tt> is the current directory.
|
395
431
|
|
396
432
|
=== Dashboard
|
397
433
|
|
@@ -401,7 +437,9 @@ and defined CCs. The time, stream and CC status are updated every beat. Also, st
|
|
401
437
|
* <tt>q</tt>: Quit <tt>dash</tt>.
|
402
438
|
* <tt>p</tt>: Play all streams.
|
403
439
|
* <tt>s</tt>: Stop all streams.
|
404
|
-
* <tt>t</tt>: Toggle the <tt>playing/paused</tt> status of
|
440
|
+
* <tt>t</tt>: Toggle the <tt>playing/paused</tt> status of selected streams. When <tt>t</tt> is entered use the <tt>up/down</tt> keys to traverse the list of streams and type <tt>return</tt> to select a stream. Multiple streams can be selected. Type <tt>t</tt> again to toggle the status of the selected streams.
|
441
|
+
* <tt>d</tt>: Delete selected streams. When <tt>d</tt> is entered use the <tt>up/down</tt> keys to traverse the list of streams and type <tt>return</tt> to select a stream. Multiple streams can be selected. Type <tt>d</tt> again to delete the selected streams.
|
442
|
+
|
405
443
|
|
406
444
|
== Callbacks
|
407
445
|
|
data/Rakefile
CHANGED
@@ -18,6 +18,7 @@ require 'jeweler'
|
|
18
18
|
gem.add_dependency('ffi', '~> 1.0.9')
|
19
19
|
gem.add_dependency('rainbow', '~> 1.1.4')
|
20
20
|
gem.add_dependency('pry', '~> 0.9.12.2')
|
21
|
+
gem.add_dependency('fssm', '~> 0.2.10')
|
21
22
|
end
|
22
23
|
rescue LoadError
|
23
24
|
abort "jeweler is not available. In order to run test, you must: sudo gem install technicalpickles-jeweler --source=http://gems.github.com"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/examples/cycle.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
|
+
|
4
|
+
before_start do
|
5
|
+
Zgomot.logger.level = Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
8
|
+
str 'cycle', np([:Fs, 4], :dorian, :l=>4)[3,1,3,5] do |pattern|
|
9
|
+
pattern.push(pattern.shift.first)
|
10
|
+
end
|
11
|
+
|
12
|
+
play
|
13
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
|
+
|
4
|
+
before_start do
|
5
|
+
Zgomot.logger.level = Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
8
|
+
str 'cycle', [nl(n([:C,5]), n(:B)), nl(n(:G), n(:C,))] do |pattern|
|
9
|
+
notes = pattern.shift
|
10
|
+
pattern.map{|n| n.push(notes.shift)}
|
11
|
+
end
|
12
|
+
|
13
|
+
play
|
14
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
|
+
|
4
|
+
before_start do
|
5
|
+
Zgomot.logger.level = Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
8
|
+
if sources.include?("nanoKONTROL")
|
9
|
+
add_input("nanoKONTROL")
|
10
|
+
add_cc(:mult, 33, :type => :cont, :min => 0, :max => 3, :init => 0)
|
11
|
+
len = 4
|
12
|
+
str 'dynamic', np([:A,4],2,:l=>len)[7,5,3,1] do |pattern|
|
13
|
+
pattern.length!((2**cc(:mult).to_i)*len)
|
14
|
+
end
|
15
|
+
play
|
16
|
+
end
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
|
+
|
4
|
+
before_start do
|
5
|
+
Zgomot.logger.level = Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
8
|
+
if sources.include?("nanoKONTROL")
|
9
|
+
add_input("nanoKONTROL")
|
10
|
+
add_cc(:mult, 33, :type => :cont, :min => 0, :max => 4, :init => 0)
|
11
|
+
len = 4
|
12
|
+
str 'perc', [pr(:low_floor_tom, :l => len),
|
13
|
+
pr(:low_tom, :l => len),
|
14
|
+
n(:R, :l=> len),
|
15
|
+
pr(:high_mid_tom, :l => len)], :ch=>0 do |pattern|
|
16
|
+
pattern.length!((2**cc(:mult).to_i)*len)
|
17
|
+
end
|
18
|
+
play
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
|
+
|
4
|
+
before_start do
|
5
|
+
Zgomot.logger.level = Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
8
|
+
if sources.include?("GECO")
|
9
|
+
add_input("GECO")
|
10
|
+
add_cc(:mode, 17, :type => :cont, :min => 0, :max => 6, :init => 0)
|
11
|
+
str 'simple_input', np([:A,4],2,:l=>4)[7,5,3,1] do |pattern|
|
12
|
+
pattern.mode!(cc(:mode).to_i)
|
13
|
+
end
|
14
|
+
play
|
15
|
+
end
|
16
|
+
|
data/examples/simple_input.rb
CHANGED
@@ -9,11 +9,15 @@ if sources.include?("nanoKONTROL")
|
|
9
9
|
add_input("nanoKONTROL")
|
10
10
|
add_cc(:mode, 17, :type => :cont, :min => 0, :max => 6, :init => 0)
|
11
11
|
add_cc(:reverse, 13, :type => :switch)
|
12
|
+
add_cc(:turn_off, 12, :type => :switch)
|
13
|
+
add_cc(:turn_off, 12, :type => :switch) do
|
14
|
+
tog(:simple_input)
|
15
|
+
end
|
12
16
|
str 'simple_input', np([:A,4],2,:l=>4)[7,5,3,1] do |pattern|
|
13
17
|
if cc(:reverse)
|
14
|
-
pattern.mode!(
|
18
|
+
pattern.mode!(mode.to_i).reverse!
|
15
19
|
else
|
16
|
-
pattern.mode!(
|
20
|
+
pattern.mode!(mode.to_i)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
play
|
data/examples/zgomot_streams.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
set_config(:beats_per_minute=>120, :time_signature=>"4/4", :resolution=>"1/64")
|
2
2
|
|
3
|
-
|
3
|
+
if sources.include?("nanoKONTROL")
|
4
|
+
add_input("nanoKONTROL")
|
5
|
+
end
|
4
6
|
add_cc(:mode, 17, :type => :cont, :min => 0, :max => 6, :init => 0)
|
5
7
|
add_cc(:reverse, 13, :type => :switch)
|
8
|
+
add_cc(:toggle_input, 12, :type => :switch) do
|
9
|
+
tog(:input)
|
10
|
+
end
|
6
11
|
|
7
|
-
|
8
|
-
str 'input', np([:A,4],2,:l=>4)[7,5,3,1], :ch=>0 do |pattern|
|
12
|
+
str 'input', np([:A,4],6,:l=>4)[1,3,7,2], :ch=>0 do |pattern|
|
9
13
|
if cc(:reverse)
|
10
14
|
pattern.mode!(cc(:mode).to_i).reverse!
|
11
15
|
else
|
data/lib/zgomot.rb
CHANGED
data/lib/zgomot/boot.rb
CHANGED
data/lib/zgomot/comp.rb
CHANGED
data/lib/zgomot/comp/chord.rb
CHANGED
@@ -36,8 +36,8 @@ module Zgomot::Comp
|
|
36
36
|
attr_reader :chord_intervals
|
37
37
|
end
|
38
38
|
|
39
|
-
attr_reader :tonic, :chord, :clock, :intervals, :arp, :time_scale, :items, :inversion, :reverse
|
40
|
-
|
39
|
+
attr_reader :tonic, :chord, :clock, :intervals, :arp, :time_scale, :items, :inversion, :reverse,
|
40
|
+
:length, :velocity
|
41
41
|
|
42
42
|
def initialize(args)
|
43
43
|
@length, @velocity, @chord = args[:length], args[:velocity], args[:chord]
|
@@ -82,6 +82,12 @@ module Zgomot::Comp
|
|
82
82
|
def octave!(v)
|
83
83
|
@notes = nil; @octave = v; self
|
84
84
|
end
|
85
|
+
def length!(v)
|
86
|
+
@length = v; self
|
87
|
+
end
|
88
|
+
def valocity!(v)
|
89
|
+
@length = v; self
|
90
|
+
end
|
85
91
|
def length_to_sec
|
86
92
|
time_scale*Zgomot::Midi::Clock.whole_note_sec*(1.0/length + (arp.to_f.eql?(0.0) ? 0.0 : intervals.length.to_f/arp.to_f))
|
87
93
|
end
|
data/lib/zgomot/comp/mode.rb
CHANGED
@@ -19,7 +19,7 @@ module Zgomot::Comp
|
|
19
19
|
def initialize(mode = 1)
|
20
20
|
@mode = case mode
|
21
21
|
when Symbol then self.class.modes.index(mode)+1
|
22
|
-
when Fixnum then mode
|
22
|
+
when Fixnum then mode % 7
|
23
23
|
when nil then 1
|
24
24
|
else raise(Zgomot::Error, "#{mode.inspect} is invalid mode")
|
25
25
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Zgomot::Comp
|
2
|
+
|
3
|
+
class NoteList
|
4
|
+
|
5
|
+
def self.nl(*args)
|
6
|
+
NoteList.new(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :notes, :clock
|
10
|
+
|
11
|
+
def initialize(*notes)
|
12
|
+
unless notes.all?{|n| n.class == Zgomot::Midi::Note or n.class == Zgomot::Comp::Perc}
|
13
|
+
raise(Zgomot::Error, "all arguments must be class Zgomot::Midi::Note Zgomot::Comp::Perc")
|
14
|
+
end
|
15
|
+
@notes = notes
|
16
|
+
end
|
17
|
+
def <<(note)
|
18
|
+
notes << note
|
19
|
+
end
|
20
|
+
def length_to_sec
|
21
|
+
notes.map(&:length_to_sec).max
|
22
|
+
end
|
23
|
+
def to_midi
|
24
|
+
notes.map{|n| n.to_midi}
|
25
|
+
end
|
26
|
+
def channel=(chan)
|
27
|
+
notes.each{|n| n.channel = chan}
|
28
|
+
end
|
29
|
+
def offset=(time)
|
30
|
+
notes.each{|n| n.offset = time}
|
31
|
+
end
|
32
|
+
def velocity!(v)
|
33
|
+
notes.each{|n| n.velocity!(v)}; self
|
34
|
+
end
|
35
|
+
def length!(v)
|
36
|
+
notes.each{|n| n.length!(v)}; self
|
37
|
+
end
|
38
|
+
def bpm!(bpm)
|
39
|
+
notes.each{|n| n.bpm!(bpm)}; self
|
40
|
+
end
|
41
|
+
def octave!(oct)
|
42
|
+
notes.each{|n| n.octave!(oct)}; self
|
43
|
+
end
|
44
|
+
def shift
|
45
|
+
@notes.shift
|
46
|
+
end
|
47
|
+
def unshift(n)
|
48
|
+
@notes.unshift(n); self
|
49
|
+
end
|
50
|
+
def pop
|
51
|
+
@notes.pop
|
52
|
+
end
|
53
|
+
def push(n)
|
54
|
+
@notes.push(n); self
|
55
|
+
end
|
56
|
+
def reverse!
|
57
|
+
@notes.reverse!; self
|
58
|
+
end
|
59
|
+
def time=(time)
|
60
|
+
@clock = Zgomot::Midi::Clock.new
|
61
|
+
clock.update(time)
|
62
|
+
notes.each{|n| n.time = clock.current_time}
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
data/lib/zgomot/comp/pattern.rb
CHANGED
@@ -21,9 +21,9 @@ module Zgomot::Comp
|
|
21
21
|
Progression.new(:item => Chord::Progression.new(:scale), :tonic => tonic, :mode => mode, :length => l, :velocity => v)
|
22
22
|
end
|
23
23
|
|
24
|
-
def pr(
|
24
|
+
def pr(perc = :acoustic_bass_drum, opts = {})
|
25
25
|
l = opts[:l] || 4; v = opts[:v] || 0.6
|
26
|
-
Perc.new(:
|
26
|
+
Perc.new(:perc => perc, :length => l, :velocity => v)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
attr_reader :seq
|
@@ -31,10 +31,18 @@ module Zgomot::Comp
|
|
31
31
|
@seq = [seq].flatten
|
32
32
|
end
|
33
33
|
def method_missing(meth, *args, &blk)
|
34
|
-
|
34
|
+
result = seq.map do |p|
|
35
35
|
p.respond_to?(meth) ? p.send(meth, *args, &blk) : p
|
36
36
|
end
|
37
|
-
|
37
|
+
if [:shift, :pop].include?(meth)
|
38
|
+
result
|
39
|
+
else
|
40
|
+
@seq = result
|
41
|
+
self
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def map(&blk)
|
45
|
+
@seq = seq.map(&blk); self
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
data/lib/zgomot/comp/perc.rb
CHANGED
@@ -1,94 +1,64 @@
|
|
1
|
-
##############################################################################################################
|
2
1
|
module Zgomot::Comp
|
3
|
-
|
4
|
-
#####-------------------------------------------------------------------------------------------------------
|
5
2
|
class Perc
|
6
|
-
|
7
|
-
#.........................................................................................................
|
3
|
+
|
8
4
|
PERC_MAP = {
|
9
|
-
:acoustic_bass_drum => [:B,1],
|
5
|
+
:acoustic_bass_drum => [:B,1],
|
10
6
|
:bass_drum_1 => [:C,2], :side_stick => [:Cs,2], :acoustic_snare => [:D,2],
|
11
7
|
:hand_clap => [:Ds,2], :electric_snare => [:E,2], :low_floor_tom => [:F,2],
|
12
8
|
:closed_hi_hat => [:Fs,2], :high_floor_tom => [:G,2], :pedal_hi_hat => [:Gs,2],
|
13
9
|
:low_tom => [:A,2], :open_hi_hat => [:As,2], :low_mid_tom => [:B,2],
|
14
|
-
:high_mid_tom => [:C,3], :crash_cymbal_1 => [:Cs,3], :high_tom => [:D,3],
|
15
|
-
:ride_cymbal_1 => [:Ds,3], :chinese_cymbal => [:E,3], :ride_bell => [:F,3],
|
16
|
-
:tambourine => [:Fs,3], :splash_cymbal => [:G,3], :cowbell => [:Gs,3],
|
10
|
+
:high_mid_tom => [:C,3], :crash_cymbal_1 => [:Cs,3], :high_tom => [:D,3],
|
11
|
+
:ride_cymbal_1 => [:Ds,3], :chinese_cymbal => [:E,3], :ride_bell => [:F,3],
|
12
|
+
:tambourine => [:Fs,3], :splash_cymbal => [:G,3], :cowbell => [:Gs,3],
|
17
13
|
:crash_cymbal_2 => [:A,3], :vibraslap => [:As,3], :ride_cymbal_2 => [:B,3],
|
18
|
-
:high_bongo => [:C,4], :low_bongo => [:Cs,4], :mute_hi_conga => [:D,4],
|
19
|
-
:open_hi_conga => [:Ds,4], :low_conga => [:E,4], :high_timbale => [:F,4],
|
20
|
-
:low_timbale => [:Fs,4], :high_agogo => [:G,4], :low_agogo => [:Gs,4],
|
14
|
+
:high_bongo => [:C,4], :low_bongo => [:Cs,4], :mute_hi_conga => [:D,4],
|
15
|
+
:open_hi_conga => [:Ds,4], :low_conga => [:E,4], :high_timbale => [:F,4],
|
16
|
+
:low_timbale => [:Fs,4], :high_agogo => [:G,4], :low_agogo => [:Gs,4],
|
21
17
|
:cabasa => [:A,4], :maracas => [:As,4], :short_whistle => [:B,4],
|
22
|
-
:long_whistle => [:C,5], :short_guiro => [:Cs,5], :long_guiro => [:D,5],
|
23
|
-
:claves => [:Ds,5], :hi_woodblock => [:E,5], :low_woodblock => [:F,5],
|
24
|
-
:mute_cuica => [:Fs,5], :open_cuica => [:G,5], :mute_triangle => [:Gs,5],
|
18
|
+
:long_whistle => [:C,5], :short_guiro => [:Cs,5], :long_guiro => [:D,5],
|
19
|
+
:claves => [:Ds,5], :hi_woodblock => [:E,5], :low_woodblock => [:F,5],
|
20
|
+
:mute_cuica => [:Fs,5], :open_cuica => [:G,5], :mute_triangle => [:Gs,5],
|
25
21
|
:open_triangle => [:A,5],
|
26
|
-
:R => :R,
|
22
|
+
:R => :R,
|
27
23
|
}
|
28
24
|
|
29
|
-
#####-------------------------------------------------------------------------------------------------------
|
30
25
|
class << self
|
31
|
-
|
32
|
-
#### self
|
33
|
-
end
|
34
|
-
|
35
|
-
#.........................................................................................................
|
36
|
-
attr_reader :percs, :length, :velocity, :time_scale
|
37
|
-
|
38
|
-
#.........................................................................................................
|
39
|
-
def initialize(args)
|
40
|
-
@length, @velocity, @percs = args[:length], args[:velocity], [args[:percs]].flatten
|
41
|
-
@time_scale = 1.0
|
42
26
|
end
|
43
27
|
|
44
|
-
|
45
|
-
|
46
|
-
|
28
|
+
attr_reader :perc, :length, :velocity, :time_scale
|
29
|
+
|
30
|
+
def initialize(args)
|
31
|
+
@length, @velocity, @perc = args[:length], args[:velocity], args[:perc]
|
47
32
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
Zgomot::Midi::Note.new(:pitch => p, :length => length, :velocity => velocity)
|
53
|
-
end
|
33
|
+
def note
|
34
|
+
@note ||= Zgomot::Midi::Note.new(:pitch => Perc::PERC_MAP[perc],
|
35
|
+
:length => length,
|
36
|
+
:velocity => velocity)
|
54
37
|
end
|
55
|
-
|
56
|
-
|
57
|
-
# transforms
|
58
|
-
#.........................................................................................................
|
59
|
-
def bpm_scale!(v)
|
60
|
-
@time_scale = 1.0/v.to_f; self
|
38
|
+
def bpm!(v)
|
39
|
+
note.bpm!(v); self
|
61
40
|
end
|
62
|
-
|
63
|
-
#.........................................................................................................
|
64
|
-
# channel and dispatch interface
|
65
|
-
#.........................................................................................................
|
66
41
|
def channel=(chan)
|
67
|
-
|
42
|
+
note.channel = chan
|
68
43
|
end
|
69
|
-
|
70
|
-
#.........................................................................................................
|
71
44
|
def offset=(time)
|
72
|
-
|
45
|
+
note.offset = time
|
73
46
|
end
|
74
|
-
|
75
|
-
#.........................................................................................................
|
76
47
|
def time=(time)
|
77
|
-
|
48
|
+
note.time = time
|
49
|
+
end
|
50
|
+
def velocity!(v)
|
51
|
+
note.velocity!(v); self
|
52
|
+
end
|
53
|
+
def length!(v)
|
54
|
+
note.length!(v); self
|
78
55
|
end
|
79
|
-
|
80
|
-
#.........................................................................................................
|
81
56
|
def length_to_sec
|
82
|
-
|
57
|
+
note.length_to_sec
|
83
58
|
end
|
84
|
-
|
85
|
-
#.........................................................................................................
|
86
59
|
def to_midi
|
87
|
-
|
60
|
+
note.to_midi
|
88
61
|
end
|
89
|
-
|
90
|
-
#### Scale
|
91
|
-
end
|
92
62
|
|
93
|
-
|
63
|
+
end
|
94
64
|
end
|