zgomot 0.1.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/README.rdoc +191 -98
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/zgomot +1 -1
- data/examples/arp_chords.rb +1 -4
- data/examples/delay.rb +16 -0
- data/examples/full_scale_notes.rb +2 -5
- data/examples/inv_chords.rb +1 -4
- data/examples/modes_notes.rb +2 -5
- data/examples/notes.rb +1 -5
- data/examples/percs.rb +4 -8
- data/examples/percs_multi.rb +1 -5
- data/examples/phase_notes.rb +4 -8
- data/examples/prog_chords.rb +2 -5
- data/examples/prog_chords_multi_vel_length.rb +1 -4
- data/examples/prog_chords_rest.rb +1 -4
- data/examples/prog_notes.rb +1 -4
- data/examples/prog_notes_multi_vel_length.rb +1 -4
- data/examples/prog_notes_rest.rb +1 -4
- data/examples/progressive_modes.rb +10 -18
- data/examples/reverse_chords.rb +1 -4
- data/examples/route_chords.rb +22 -0
- data/examples/scale_chords.rb +1 -4
- data/examples/scale_notes.rb +1 -4
- data/examples/scales_notes.rb +1 -5
- data/examples/simple_chords.rb +1 -4
- data/examples/simple_input.rb +21 -0
- data/examples/simple_markov.rb +1 -5
- data/examples/simple_notes.rb +2 -5
- data/examples/zgomot_streams.rb +19 -0
- data/lib/zgomot/boot.rb +5 -31
- data/lib/zgomot/comp/chord.rb +16 -70
- data/lib/zgomot/comp/markov.rb +8 -26
- data/lib/zgomot/comp/mode.rb +9 -32
- data/lib/zgomot/comp/note.rb +1 -16
- data/lib/zgomot/comp/pattern.rb +1 -24
- data/lib/zgomot/comp/permutation.rb +0 -11
- data/lib/zgomot/comp/pitch_class.rb +3 -28
- data/lib/zgomot/comp/progression.rb +15 -49
- data/lib/zgomot/comp/scale.rb +5 -14
- data/lib/zgomot/config.rb +3 -18
- data/lib/zgomot/drivers/core_midi.rb +129 -92
- data/lib/zgomot/drivers/driver.rb +2 -15
- data/lib/zgomot/drivers/mgr.rb +5 -21
- data/lib/zgomot/main.rb +13 -24
- data/lib/zgomot/midi/cc.rb +67 -0
- data/lib/zgomot/midi/channel.rb +20 -50
- data/lib/zgomot/midi/clock.rb +21 -48
- data/lib/zgomot/midi/dispatcher.rb +13 -26
- data/lib/zgomot/midi/note.rb +11 -34
- data/lib/zgomot/midi/stream.rb +82 -43
- data/lib/zgomot/midi.rb +1 -0
- data/lib/zgomot/ui/output.rb +67 -0
- data/lib/zgomot/ui/windows.rb +359 -0
- data/lib/zgomot/ui.rb +3 -0
- data/lib/zgomot.rb +6 -1
- data/lib/{zlive.rb → zgomot_sh.rb} +1 -0
- data/zgomot.gems +14 -0
- data/zgomot.gemspec +26 -14
- metadata +52 -9
- data/default.gems +0 -7
- data/examples/simple_notes_length.rb +0 -17
- data/examples/simple_notes_velocity.rb +0 -17
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use 1.9.
|
1
|
+
rvm use 1.9.3@zgomot
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= zgomot
|
2
2
|
|
3
|
-
zgomot is a DSL for composing MIDI music. It does not do synthesis so to create sound it requires digital audio software such as Apple's
|
3
|
+
zgomot is a DSL for composing MIDI music. It does not do synthesis so to create sound it requires digital audio software such as Apple's GarageBand, Logic or Ableton Live. A program that plays a simple tune only requires a few lines of code.
|
4
4
|
|
5
5
|
# mytune.rb
|
6
6
|
require 'rubygems'
|
@@ -11,18 +11,18 @@ zgomot is a DSL for composing MIDI music. It does not do synthesis so to create
|
|
11
11
|
|
12
12
|
# define a MIDI stream writing to channel 0 which plays the pattern 3 times
|
13
13
|
str 'notes', tune, :lim=>3 do |pattern|
|
14
|
-
|
14
|
+
pattern
|
15
15
|
end
|
16
16
|
|
17
17
|
# write the MIDI stream
|
18
18
|
play
|
19
19
|
|
20
|
-
Now, specify beats per minute, time signature and resolution in <tt>zgomot.yml</tt>.
|
20
|
+
Now, specify beats per minute, time signature and resolution in <tt>zgomot.yml</tt>.
|
21
21
|
|
22
22
|
time_signature: 4/4
|
23
23
|
beats_per_minute: 120
|
24
24
|
resolution: 1/64
|
25
|
-
|
25
|
+
|
26
26
|
Install the gem,
|
27
27
|
|
28
28
|
sudo gem install zgomot
|
@@ -30,67 +30,75 @@ Install the gem,
|
|
30
30
|
Run the program to play the tune,
|
31
31
|
|
32
32
|
ruby mytune.rb
|
33
|
-
|
34
|
-
A simple object model is defined by zgomot that makes it possible to write iterative transformations on note patterns within <tt>str</tt> blocks, which generate MIDI data streams. In the following details of the object model and supported transformations will be described.
|
35
|
-
|
36
|
-
== OSX IAC Driver
|
37
33
|
|
38
|
-
|
39
|
-
|
34
|
+
A simple object model is defined by zgomot that makes it possible to write iterative transformations on note patterns within <tt>str</tt> blocks that generate MIDI data streams. In the following details of the object model and supported transformations will be described.
|
35
|
+
|
36
|
+
== OS X IAC Driver
|
37
|
+
|
38
|
+
For OS X the IAC Driver must be enabled for zgomot programs to communicate with the digital audio software used to render the generated MIDI stream. To enable the IAC Driver open <em>Audio MIDI Setup</em>. Under the <em>Window</em> menu item select <em>Show MIDI Window</em>. Find the <em>IAC Driver</em>, double click it and be sure <em>Device is online</em> is selected and at least one port exists.
|
39
|
+
|
40
|
+
== Supported Platforms
|
41
|
+
|
42
|
+
zgomot has been tested on Ruby 1.8.7, 1.9.1, 1.9.2, 1.9.3. The only OS supported is OS X.
|
43
|
+
|
40
44
|
== Configuration
|
41
45
|
|
42
|
-
Three parameters are defined in the configuration file, <tt>zgomot.yml</tt
|
46
|
+
Three parameters are defined in the configuration file, <tt>zgomot.yml</tt> or programmatically, that specify the timing of a composition.
|
43
47
|
|
44
|
-
* <b>time_signature</b>: Beats per measure.
|
45
|
-
* <b>beats_per_minute</b>: To map to real time the beats per minute are specified.
|
46
|
-
* <b>resolution</b>: Defines the length of a clock tick and is defined by the duration of the shortest note that can be played. In the first example this is a 64'th note. The maximum resolution is 1/1024 if your computer can do it.
|
48
|
+
* <b>time_signature</b>: Beats per measure. The default value is 4/4.
|
49
|
+
* <b>beats_per_minute</b>: To map to real time the beats per minute are specified. The default value 120.
|
50
|
+
* <b>resolution</b>: Defines the length of a clock tick and is defined by the duration of the shortest note that can be played. In the first example this is a 64'th note. The maximum resolution is 1/1024 if your computer can do it. The default value 1/32.
|
51
|
+
|
52
|
+
To set the configuration programmatically use,
|
53
|
+
|
54
|
+
set_config(:beats_per_minute=>120, :time_signature=>"4/4", :resolution=>"1/64")
|
47
55
|
|
48
56
|
== Pitch
|
49
57
|
|
50
58
|
Pitch is defined by a 2 dimensional array specifying the pitch class and octave, For example [:C, 4] would denote the note C at octave 4. Octave is an integer between -1 and 9 and acceptable values for pitch class with enharmonics, where <em>s</em> denotes a sharp, <em>b</em> a flat, and rest by :R are,
|
51
59
|
|
52
|
-
:C, :Bs;
|
60
|
+
:C, :Bs;
|
53
61
|
:Cs, :Db
|
54
62
|
:D
|
55
63
|
:Ds, :Ed
|
56
64
|
:E, :Fd
|
57
65
|
:F, :Es
|
58
66
|
:Fs, :Gb
|
59
|
-
:G,
|
60
|
-
:Gs,
|
67
|
+
:G,
|
68
|
+
:Gs, :Ab
|
61
69
|
:A,
|
62
70
|
:As, :Bb,
|
63
|
-
:B,
|
64
|
-
:R,
|
71
|
+
:B, :Cb,
|
72
|
+
:R,
|
65
73
|
|
66
74
|
== Notes
|
67
75
|
|
68
76
|
A note is defined by,
|
69
77
|
|
70
78
|
n(pitch, opts)
|
71
|
-
|
79
|
+
|
72
80
|
Accepted options are,
|
73
81
|
|
74
82
|
* <tt>:l</tt>: Reciprocal length of note, Accepted values are 1, 2, 4,..., max. Where max is the inverse resolution defined in <tt>zgomot.yml</tt>. Mapping to standard durations gives; 1 a whole note, 2 a half note, 4 a quarter note, 8 and eighth note, ... The default value is 4, a quarter note.
|
75
83
|
* <tt>:v</tt>: The velocity of the note is a number between 0 ad 1 defining its loudness. Low values correspond to piano and larger values forte. The default is 0.6.
|
76
|
-
|
84
|
+
|
77
85
|
An F# half note at octave 5 with velocity 0.5 would be defined by,
|
78
86
|
|
79
87
|
n([:Fs, 5], :l => 2, :v => 0.5)
|
80
|
-
|
88
|
+
|
81
89
|
==== Transforms
|
82
90
|
|
83
91
|
Notes support the following transformations,
|
84
92
|
|
85
93
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the note is played.
|
86
94
|
* <tt>octave!(ocatve)</tt>: change the octave of the note.
|
87
|
-
|
95
|
+
|
88
96
|
== Chords
|
89
97
|
|
90
98
|
A chord is defined by,
|
91
99
|
|
92
100
|
c(root, interval, opts)
|
93
|
-
|
101
|
+
|
94
102
|
Only trichords are supported. Here root is the chord root pitch and interval is the interval type. Accepted values of the interval type are: <tt>:maj</tt>, <tt>:min</tt>, <tt>:dim</tt>, <tt>:aug</tt>, <tt>:sus2</tt>, <tt>:sus4</tt>, representing major, minor, diminished, augmented, suspended second and suspended forth chord intervals respectively. If not specified the default value of interval is <tt>:maj</tt>.
|
95
103
|
|
96
104
|
Accepted options are,
|
@@ -108,7 +116,7 @@ Chords support the following transformations,
|
|
108
116
|
|
109
117
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the chord is played.
|
110
118
|
* <tt>octave!(ocatve)</tt>: change the octave of the chord.
|
111
|
-
* <tt>arp!(length)</tt>: arpeggiate the chord 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.
|
119
|
+
* <tt>arp!(length)</tt>: arpeggiate the chord 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.
|
112
120
|
* <tt>inv!(number)</tt>: Invert the chord. When 0 the chord is unchanged, 1 is the first inversion and 2 is the second. Higher inversions just shift the chord to a higher octave.
|
113
121
|
* <tt>rev!</tt>: Reverse the order in which the notes are played. Only noticeable if the chord is also arpeggiated.
|
114
122
|
|
@@ -116,40 +124,40 @@ Chords support the following transformations,
|
|
116
124
|
|
117
125
|
The General MIDI Percussion Map that maps percussion type to MIDI note is supported.
|
118
126
|
|
119
|
-
:acoustic_bass_drum => [:B,1],
|
127
|
+
:acoustic_bass_drum => [:B,1],
|
120
128
|
:bass_drum_1 => [:C,2], :side_stick => [:Cs,2], :acoustic_snare => [:D,2],
|
121
129
|
:hand_clap => [:Ds,2], :electric_snare => [:E,2], :low_floor_tom => [:F,2],
|
122
130
|
:closed_hi_hat => [:Fs,2], :high_floor_tom => [:G,2], :pedal_hi_hat => [:Gs,2],
|
123
131
|
:low_tom => [:A,2], :open_hi_hat => [:As,2], :low_mid_tom => [:B,2],
|
124
|
-
:high_mid_tom => [:C,3], :crash_cymbal_1 => [:Cs,3], :high_tom => [:D,3],
|
125
|
-
:ride_cymbal_1 => [:Ds,3], :chinese_cymbal => [:E,3], :ride_bell => [:F,3],
|
126
|
-
:tambourine => [:Fs,3], :splash_cymbal => [:G,3], :cowbell => [:Gs,3],
|
132
|
+
:high_mid_tom => [:C,3], :crash_cymbal_1 => [:Cs,3], :high_tom => [:D,3],
|
133
|
+
:ride_cymbal_1 => [:Ds,3], :chinese_cymbal => [:E,3], :ride_bell => [:F,3],
|
134
|
+
:tambourine => [:Fs,3], :splash_cymbal => [:G,3], :cowbell => [:Gs,3],
|
127
135
|
:crash_cymbal_2 => [:A,3], :vibraslap => [:As,3], :ride_cymbal_2 => [:B,3],
|
128
|
-
:high_bongo => [:C,4], :low_bongo => [:Cs,4], :mute_hi_conga => [:D,4],
|
129
|
-
:open_hi_conga => [:Ds,4], :low_conga => [:E,4], :high_timbale => [:F,4],
|
130
|
-
:low_timbale => [:Fs,4], :high_agogo => [:G,4], :low_agogo => [:Gs,4],
|
136
|
+
:high_bongo => [:C,4], :low_bongo => [:Cs,4], :mute_hi_conga => [:D,4],
|
137
|
+
:open_hi_conga => [:Ds,4], :low_conga => [:E,4], :high_timbale => [:F,4],
|
138
|
+
:low_timbale => [:Fs,4], :high_agogo => [:G,4], :low_agogo => [:Gs,4],
|
131
139
|
:cabasa => [:A,4], :maracas => [:As,4], :short_whistle => [:B,4],
|
132
|
-
:long_whistle => [:C,5], :short_guiro => [:Cs,5], :long_guiro => [:D,5],
|
133
|
-
:claves => [:Ds,5], :hi_woodblock => [:E,5], :low_woodblock => [:F,5],
|
134
|
-
:mute_cuica => [:Fs,5], :open_cuica => [:G,5], :mute_triangle => [:Gs,5],
|
140
|
+
:long_whistle => [:C,5], :short_guiro => [:Cs,5], :long_guiro => [:D,5],
|
141
|
+
:claves => [:Ds,5], :hi_woodblock => [:E,5], :low_woodblock => [:F,5],
|
142
|
+
:mute_cuica => [:Fs,5], :open_cuica => [:G,5], :mute_triangle => [:Gs,5],
|
135
143
|
:open_triangle => [:A,5],
|
136
|
-
:R => :R,
|
144
|
+
:R => :R,
|
137
145
|
|
138
146
|
A percussive tone is defined by
|
139
147
|
|
140
148
|
pr(perc, opts)
|
141
|
-
|
142
|
-
Where perc is the General MIDI Percussion code defined above that has a default value of <tt>:acoustic_bass_drum</tt>.
|
143
|
-
|
149
|
+
|
150
|
+
Where perc is the General MIDI Percussion code defined above that has a default value of <tt>:acoustic_bass_drum</tt>.
|
151
|
+
|
144
152
|
Accepted options are,
|
145
153
|
|
146
154
|
* <b>:l</b>: Reciprocal length of note, Accepted values are 1, 2, 4,..., max. Where max is the inverse resolution defined in <tt>zgomot.yml</tt>. Mapping to standard durations gives: 1 a whole note, 2 a half note, 4 a quarter note, 8 and eighth note, ... The default value is 4, a quarter note.
|
147
155
|
* <b>:v</b>: The velocity of the note is a number between 0 ad 1 defining its loudness. Low values correspond to piano and larger values forte. The default is 0.6.
|
148
|
-
|
156
|
+
|
149
157
|
A <tt>:closed_hi_hat</tt> percussive tone of half note length with velocity 0.5 would be defined by,
|
150
158
|
|
151
159
|
pr(:closed_hi_hat, :l => 2, :v => 0.5)
|
152
|
-
|
160
|
+
|
153
161
|
==== Transforms
|
154
162
|
|
155
163
|
Percussion supports the following transformations,
|
@@ -162,7 +170,7 @@ Chord Progressions or Roman Numeral Notation permit the definition of a melody t
|
|
162
170
|
|
163
171
|
A chord progression consisting of the 7 notes of a specified key in a diatonic mode played sequentially will be defined by,
|
164
172
|
|
165
|
-
cp(tonic, mode, opts)
|
173
|
+
cp(tonic, mode, opts)
|
166
174
|
|
167
175
|
Where tonic is the tonic pitch of the key, mode is one of the 7 diatonic modes: <tt>:ionian</tt>, <tt>:dorian</tt>, <tt>:phrygian</tt>, <tt>:lydian</tt>, <tt>:mixolydian</tt>, <tt>:aeolian</tt>, <tt>:locrian</tt> or a number between 0 and 6 mapping sequentially onto the these modes.
|
168
176
|
|
@@ -171,7 +179,7 @@ Accepted options are,
|
|
171
179
|
* <tt>:l</tt>: Reciprocal length of chord, Accepted values are <tt>1, 2, 4,..., max</tt>. Where max is the inverse resolution defined in <tt>zgomot.yml</tt>. Mapping to standard durations gives; 1 a whole note, 2 a half note, 4 a quarter note, 8 and eighth note, ... The default value is 4, a quarter note.
|
172
180
|
* <tt>:v</tt>: The velocity of the note is a number between 0 ad 1 defining its loudness. Low values correspond to piano and larger values forte. The default is 0.6.
|
173
181
|
|
174
|
-
|
182
|
+
A chord progression in a key of F# dorian at octave 5 with notes of half note length and velocity 0.5 would be defined by,
|
175
183
|
|
176
184
|
cp([:Fs, 5], :dorian, :l => 2, :v => 0.5)
|
177
185
|
|
@@ -184,17 +192,17 @@ An chord progression in a key of F# dorian at octave 5 with notes of half note l
|
|
184
192
|
* <tt>length=(v)</tt>: Change the length of all notes in the progression.
|
185
193
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the chord is played.
|
186
194
|
* <tt>octave!(ocatve)</tt>: change the octave of all notes in the progression.
|
187
|
-
* <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.
|
195
|
+
* <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.
|
188
196
|
* <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.
|
189
197
|
* <tt>rev!</tt>: Reverse the order in which the notes are played. Only noticeable if the chords in the progression are also arpeggiated.
|
190
198
|
|
191
|
-
Progressions internally are arrays of notes
|
199
|
+
Progressions internally are arrays of notes. The following array methods are supported: <tt>reverse!, shift, pop, push, unshift</tt>
|
192
200
|
|
193
201
|
== Note Progressions
|
194
202
|
|
195
203
|
Note Progressions are similar to chord progressions but are composed of notes instead of chords. Most of the options and transformation are the same. To define a Note Progression use,
|
196
204
|
|
197
|
-
np(tonic, mode, opts)
|
205
|
+
np(tonic, mode, opts)
|
198
206
|
|
199
207
|
Where tonic is the tonic pitch of the key, mode is one of the 7 diatonic modes: <tt>:ionian</tt>, <tt>:dorian</tt>, <tt>:phrygian</tt>, <tt>:lydian</tt>, <tt>:mixolydian</tt>, <tt>:aeolian</tt>, <tt>:locrian</tt> or a number between 0 and 6 mapping sequentially onto the these modes.
|
200
208
|
|
@@ -217,76 +225,56 @@ An note progression in a key of F# dorian at octave 5 with notes of half note le
|
|
217
225
|
* <tt>bpm!(bpm)</tt>: change the bits per minute at which the chord is played.
|
218
226
|
* <tt>octave!(ocatve)</tt>: change the octave of all notes in the progression.
|
219
227
|
|
220
|
-
Progressions internally are arrays of notes
|
228
|
+
Progressions internally are arrays of notes. The following array methods are supported: <tt>reverse!, shift, pop, push, unshift</tt>
|
221
229
|
|
222
|
-
==
|
223
|
-
|
224
|
-
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. Patterns also support all methods supported by Ruby the <tt>Array</tt> class.
|
225
|
-
|
226
|
-
== MIDI Channels
|
230
|
+
== Progression with Defined Length and Velocity by Note
|
227
231
|
|
228
|
-
|
232
|
+
Different durations and velocities for each note in a progression can be defined by by using arrays for the length and velocity options.
|
229
233
|
|
230
|
-
|
234
|
+
cp([:A,4],nil,:l=>[4,4,8,8,4], :v=>[0.6, 0.4, 0.7, 0.6, 0.4])[7,5,3,3,1]
|
231
235
|
|
232
|
-
|
233
|
-
|
234
|
-
The << operator is used to write patterns to the MIDI IO device.
|
235
|
-
|
236
|
-
Write a note pattern to MIDI channel 1,
|
236
|
+
== Patterns
|
237
237
|
|
238
|
-
|
239
|
-
|
240
|
-
Channels are created within stream blocks which are discussed in the next section.
|
238
|
+
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.
|
241
239
|
|
242
240
|
== Streams
|
243
241
|
|
244
|
-
A stream is used to define iteration on a pattern and outputs a stream of MIDI data.
|
242
|
+
A stream is used to define iteration on a pattern and outputs a stream of MIDI data.
|
245
243
|
|
246
244
|
str(name, pattern, opt, &blk)
|
247
|
-
|
248
|
-
Where name is an identifying string defining, pattern is an initial pattern, which may be nil, and blk is used to define operations on pattern and is yielded pattern.
|
245
|
+
|
246
|
+
Where <tt>name</tt> is an identifying string defining, <tt>pattern</tt> is an initial pattern, which may be nil, and <tt>blk</tt> is used to define operations on pattern and is yielded pattern.
|
249
247
|
|
250
248
|
Accepted options are,
|
251
249
|
|
252
250
|
* <tt>:lim</tt>: The number of iterations performed by the stream. The default value is infinite.
|
251
|
+
* <tt>:del</tt>: The number beats delayed before the stream begins to play. The default value is 0.
|
252
|
+
* <tt>:ch</tt>: The MIDI channel used for output. The default value is 0.
|
253
253
|
|
254
|
-
A program will consist of one or more <tt>str</tt> calls followed by a <tt>play</tt> call. Blocks passed to <tt>str</tt> perform operations on the yielded pattern and write the results to a MIDI channel. On the call to <tt>play</tt> a thread is spawned for each <tt>str</tt> which calls the defined blocks the specified number of times.
|
254
|
+
A program will consist of one or more <tt>str</tt> calls followed by a <tt>play</tt> call. Blocks passed to <tt>str</tt> perform operations on the yielded pattern and write the results to a MIDI channel. On the call to <tt>play</tt> a thread is spawned for each <tt>str</tt> which calls the defined blocks the specified number of times.
|
255
255
|
|
256
|
-
str 'grovin-1', cp([:C,3],:ionian), :lim
|
257
|
-
|
256
|
+
str 'grovin-1', cp([:C,3],:ionian), :lim=>3 do |pattern|
|
257
|
+
do_stuff_1(pattern)
|
258
258
|
end
|
259
259
|
|
260
|
-
str 'grovin-2', cp([:A,5],:dorian), , :
|
261
|
-
|
260
|
+
str 'grovin-2', cp([:A,5],:dorian), :lim=>3, :ch=>1 do |pattern|
|
261
|
+
do_stuff_2(pattern)
|
262
262
|
end
|
263
263
|
|
264
264
|
play
|
265
|
-
|
266
|
-
Within a <tt>str</tt> block the following attributes are available,
|
267
|
-
|
268
|
-
* <tt>count</tt>: Current iteration.
|
269
|
-
* <tt>patterns</tt>: Chronological list of patterns.
|
270
265
|
|
271
|
-
|
272
|
-
|
273
|
-
* <tt>before_start</tt>: called before application starts.
|
274
|
-
|
275
|
-
== Logging
|
276
|
-
|
277
|
-
By default logging is performed to STDOUT with level <tt>Logger::WARN</tt>. This can be changed by defining a new <tt>logger</tt> or specifying a new logger level in <tt>before_start</tt>.
|
278
|
-
|
279
|
-
== Examples
|
266
|
+
Within a <tt>str</tt> block the following attributes are available,
|
280
267
|
|
281
|
-
|
268
|
+
* <tt>count</tt>: Current iteration.
|
269
|
+
* <tt>patterns</tt>: Chronological list of patterns.
|
282
270
|
|
283
|
-
|
271
|
+
== Markov Matrix
|
284
272
|
|
285
273
|
The Markov Matrix randomly plays a list of specified patterns with specified probabilities. The size of the matrix is determined by the number of patterns. For each pattern a list transition probabilities must be defined for all other patterns.
|
286
274
|
|
287
275
|
=== Methods
|
288
|
-
|
289
|
-
* <tt>add(transition_probs, &blk)</tt>: Add a pattern to the Markov matrix. Arguments are: <tt>transitition_probs</tt> a list that defines the transition probabilities between patterns and <tt>blk</tt> is a block in which the pattern is defined.
|
276
|
+
|
277
|
+
* <tt>add(transition_probs, &blk)</tt>: Add a pattern to the Markov matrix. Arguments are: <tt>transitition_probs</tt> a list that defines the transition probabilities between patterns and <tt>blk</tt> is a block in which the pattern is defined.
|
290
278
|
* <tt>next</tt>: Called within a <tt>str</tt> block to return the next random pattern.
|
291
279
|
|
292
280
|
==== Code Sample
|
@@ -302,34 +290,139 @@ A simple Markov Matrix with two patterns.
|
|
302
290
|
end
|
303
291
|
|
304
292
|
str 'markov' do
|
305
|
-
|
293
|
+
m.next
|
306
294
|
end
|
307
295
|
|
308
296
|
play
|
309
297
|
|
310
|
-
|
298
|
+
== Multiple MIDI Channels
|
311
299
|
|
312
300
|
A program can write to multiple MIDI channels with multiple <tt>str</tt> calls. The following example writes the same melody to two different MIDI channels at different bit rates producing a phasing effect.
|
313
301
|
|
314
302
|
str 'melody-1', np([:B,3],nil,:l=>4)[1,4,5,5], :lim=>:inf do |pattern|
|
315
|
-
|
303
|
+
pattern.mode!((count/4) % 7 + 1)
|
316
304
|
end
|
317
305
|
|
318
|
-
str 'melody-2', np([:B,3],:ionian,:l=>4)[1,4,5,5].bpm!(16.0/15.0), :lim=>:inf do |pattern|
|
319
|
-
|
306
|
+
str 'melody-2', np([:B,3],:ionian,:l=>4)[1,4,5,5].bpm!(16.0/15.0), :lim=>:inf, :ch=>1 do |pattern|
|
307
|
+
pattern
|
320
308
|
end
|
321
309
|
|
322
310
|
play
|
323
311
|
|
324
|
-
===
|
312
|
+
=== Chord Note Routing
|
313
|
+
|
314
|
+
The notes of a chord and chord progression can be routed to different MIDI channels to be rendered by different instruments using the <tt>note(note_number)</tt> command. This makes harmonizing instruments easy.
|
315
|
+
The program sample below demonstrates how this is done,
|
325
316
|
|
326
|
-
|
317
|
+
chords = cp([:B,3],:ionian,:l=>4)[1,4,5,5]
|
327
318
|
|
328
|
-
str '
|
329
|
-
|
319
|
+
str 'note-0', chords.note(0), :ch=>0 do |pattern|
|
320
|
+
pattern
|
330
321
|
end
|
331
322
|
|
332
|
-
|
323
|
+
str 'note-1', chords.note(1), :ch=>1 do |pattern|
|
324
|
+
pattern
|
325
|
+
end
|
326
|
+
|
327
|
+
str 'note-2', chords.note(2), :ch=>2 do |pattern|
|
328
|
+
pattern
|
329
|
+
end
|
330
|
+
|
331
|
+
run
|
332
|
+
|
333
|
+
== MIDI Input
|
334
|
+
|
335
|
+
A MIDI input device can be used to send messages to programs. Commands to list MIDI sources, add MIDI inputs devices and assign MIDI CC messages to program variables
|
336
|
+
are available.
|
337
|
+
|
338
|
+
=== MIDI Sources
|
339
|
+
|
340
|
+
The names of MIDI sources are listed with,
|
341
|
+
|
342
|
+
sources
|
343
|
+
|
344
|
+
=== Add Input Device
|
345
|
+
|
346
|
+
A MIDI input device is added with,
|
347
|
+
|
348
|
+
add_input(name)
|
349
|
+
|
350
|
+
where <tt>name</tt> is the name of the MIDI source returned by the <tt>sources</tt> command. To remove a MIDI input use,
|
351
|
+
|
352
|
+
remove_input(name)
|
353
|
+
|
354
|
+
where <tt>name</tt> is the name of the <tt>input</tt>. There can be only one MIDI input. Adding another will automatically remove the <tt>input</tt> added previously.
|
355
|
+
|
356
|
+
=== Input CC Messages
|
357
|
+
|
358
|
+
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
|
+
|
360
|
+
add_cc(name, ch, options)
|
361
|
+
|
362
|
+
Where <tt>name</tt> is the variable name, ,<tt>ch</tt> is the MIDI CC identifier, a number between 0 and 255 and options are the following,
|
363
|
+
|
364
|
+
* <tt>:max</tt>: The maximum value of the CC message. The default is 1.
|
365
|
+
* <tt>:min</tt>: The minimum value of the CC message. The default is 0.
|
366
|
+
* <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.
|
367
|
+
|
368
|
+
To read a variable assigned to a CC message use,
|
369
|
+
|
370
|
+
cc(name, ch)
|
371
|
+
|
372
|
+
where <tt>name</tt> is the variable name and <tt>ch</tt> is the channel number. The default value of <tt>ch</tt> is 1.
|
373
|
+
|
374
|
+
== Shell
|
375
|
+
|
376
|
+
Type <tt>zgomot</tt> to start the shell. The shell uses <tt>pry</tt>, http://pryrepl.org, so <tt>.pryrc</tt> can be used for initialization.
|
377
|
+
|
378
|
+
=== Commands
|
379
|
+
|
380
|
+
All commands and objects described previously are available and can be typed directly into the shell or can be loaded from programs you have written. Additionally the following are useful to manage a composition,
|
381
|
+
|
382
|
+
* <tt>sources</tt>: List the names of all MIDI sources.
|
383
|
+
* <tt>destinations</tt>: List the names of all MIDI destinations.
|
384
|
+
* <tt>output</tt>: Show the name of the current MIDI source assigned as output. This value cannot be changed.
|
385
|
+
* <tt>input</tt>: Show the name of the current MIDI destination assigned as input.
|
386
|
+
* <tt>lstr</tt>: List all loaded stream objects created with the <tt>str</tt> command.
|
387
|
+
* <tt>lcc</tt>: List all loaded MIDI CC definitions created with <tt>add_cc</tt>.
|
388
|
+
* <tt>lconfig</tt>: List the current configuration.
|
389
|
+
* <tt>clk</tt>: Show the current time on the global MIDI clock. Displayed format is <tt>measure:beat:tick</tt>.
|
390
|
+
* <tt>run name</tt>: Play the named stream. If no name is given all <tt>paused</tt> streams are started. <tt>run</tt> is an alias for <tt>play</tt> discussed previously. In the shell <tt>run</tt> must be used since <tt>pry</tt> has a <tt>play</tt> command.
|
391
|
+
* <tt>pause name</tt>: Pause the named stream. If no name is given pause all <tt>playing</tt> streams.
|
392
|
+
* <tt>stop name</tt>: An alias for <tt>pause</tt>.
|
393
|
+
* <tt>tog name</tt>: Toggle the status of the named stream. <tt>name</tt> is required.
|
394
|
+
|
395
|
+
|
396
|
+
=== Dashboard
|
397
|
+
|
398
|
+
The dashboard is started by typing <tt>dash</tt> in the <tt>zgomot</tt> shell. The <tt>dash</tt> shows the current configuration and global time and lists the status of all loaded streams
|
399
|
+
and defined CCs. The time, stream and CC status are updated every beat. Also, streams can be started and stopped. When <tt>dash</tt> is loaded the following control commands are available,
|
400
|
+
|
401
|
+
* <tt>q</tt>: Quit <tt>dash</tt>.
|
402
|
+
* <tt>p</tt>: Play all streams.
|
403
|
+
* <tt>s</tt>: Stop all streams.
|
404
|
+
* <tt>t</tt>: Toggle the <tt>playing/paused</tt> status of a stream. When <tt>t</tt> is entered use the up/down keys to traverse the list of streams and type return to select a stream. Type <tt>t</tt> again to exit without selecting a stream.
|
405
|
+
|
406
|
+
== Callbacks
|
407
|
+
|
408
|
+
When running composition programs callbacks are useful. The following are available,
|
409
|
+
|
410
|
+
* <tt>before_start</tt>: called before application starts.
|
411
|
+
|
412
|
+
== Logging
|
413
|
+
|
414
|
+
By default logging is performed to STDOUT with level <tt>Logger::WARN</tt>. This can be changed by defining a new <tt>logger</tt> or specifying a new logger level in <tt>before_start</tt>.
|
415
|
+
To write <tt>DEBUG</tt> logger statements while in the shell enter,
|
416
|
+
|
417
|
+
Zgomot.logger.level = Logger::DEBUG
|
418
|
+
|
419
|
+
to disable logger statements enter,
|
420
|
+
|
421
|
+
Zgomot.logger.level = Logger::ERROR
|
422
|
+
|
423
|
+
== Examples
|
424
|
+
|
425
|
+
Many examples can be found at https://github.com/troystribling/zgomot/tree/master/examples/.
|
333
426
|
|
334
427
|
== Copyright
|
335
428
|
|
data/Rakefile
CHANGED
@@ -16,6 +16,8 @@ require 'jeweler'
|
|
16
16
|
gem.authors = ["Troy Stribling"]
|
17
17
|
gem.files.include %w(lib/jeweler/templates/.gitignore VERSION)
|
18
18
|
gem.add_dependency('ffi', '~> 1.0.9')
|
19
|
+
gem.add_dependency('rainbow', '~> 1.1.4')
|
20
|
+
gem.add_dependency('pry', '~> 0.9.12.2')
|
19
21
|
end
|
20
22
|
rescue LoadError
|
21
23
|
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
|
-
0.
|
1
|
+
1.0.0
|
data/bin/zgomot
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
|
-
exec "
|
2
|
+
exec "pry -I #{File.dirname($0)}/../lib/ -r zgomot_sh"
|
data/examples/arp_chords.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
#.........................................................................................................
|
10
8
|
str 'arp', cp([:B,3],:ionian,:l=>4)[1,4,5,5].arp!(16), :lim=>1 do |pattern|
|
11
|
-
|
9
|
+
pattern
|
12
10
|
end
|
13
11
|
|
14
|
-
#.........................................................................................................
|
15
12
|
play
|
data/examples/delay.rb
ADDED
@@ -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
|
+
str 'melody-1', np([:B,3],nil,:l=>4)[1,4,5,5], :lim=>6 do |pattern|
|
9
|
+
pattern.mode!((count/4) % 7 + 1)
|
10
|
+
end
|
11
|
+
|
12
|
+
str 'melody-2', np([:B,3],:ionian,:l=>4)[1,4,5,5], :lim=>4, :del=>8 do |pattern|
|
13
|
+
pattern
|
14
|
+
end
|
15
|
+
|
16
|
+
play
|
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
ch << pattern.tonic!(:A, count)
|
8
|
+
str 'full_scale', np(nil,5), :lim=>6 do |pattern|
|
9
|
+
pattern.tonic!([:A, count])
|
12
10
|
end
|
13
11
|
|
14
|
-
#.........................................................................................................
|
15
12
|
play
|
data/examples/inv_chords.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
#.........................................................................................................
|
10
8
|
str 'inversion', cp([:C,3],:ionian,:l=>4).inv!(2), :lim=>1 do |pattern|
|
11
|
-
|
9
|
+
pattern
|
12
10
|
end
|
13
11
|
|
14
|
-
#.........................................................................................................
|
15
12
|
play
|
data/examples/modes_notes.rb
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
str 'modes', [np([:A,4],nil,:l=>4), np([:A,4],nil,:l=>4).reverse!.shift, n(:R)], :lim=>6 do |pattern|
|
8
|
+
str 'modes', [np([:A,4],nil,:l=>8), np([:A,4],nil,:l=>8).reverse!.shift, n(:R)], :lim=>7 do |pattern|
|
11
9
|
Zgomot.logger.info "TONIC: [A,4], MODE: #{count-1}"
|
12
|
-
|
10
|
+
pattern.mode!(count)
|
13
11
|
end
|
14
12
|
|
15
|
-
#.........................................................................................................
|
16
13
|
play
|
data/examples/notes.rb
CHANGED
@@ -1,18 +1,14 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
#.........................................................................................................
|
10
8
|
score = [n([:C,5]), n(:B), n(:R), n(:G), n(:C,:l=>2), n([:E,5],:l=>2)]
|
11
9
|
|
12
|
-
#.........................................................................................................
|
13
10
|
str 'notes', score, :lim=>3 do |pattern|
|
14
|
-
|
11
|
+
pattern
|
15
12
|
end
|
16
13
|
|
17
|
-
#.........................................................................................................
|
18
14
|
play
|
data/examples/percs.rb
CHANGED
@@ -1,20 +1,16 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require "#{File.dirname(__FILE__)}/../lib/zgomot"
|
3
3
|
|
4
|
-
#.........................................................................................................
|
5
4
|
before_start do
|
6
5
|
Zgomot.logger.level = Logger::DEBUG
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
pr(:low_tom), pr(:hand_clap), pr(:ride_cymbal_1), pr(:cowbell)]
|
8
|
+
score = [pr(:acoustic_bass_drum), pr(:bass_drum_1), pr(:acoustic_snare), pr(:electric_snare),
|
9
|
+
pr(:open_hi_hat), pr(:closed_hi_hat), pr(:high_tom), pr(:low_mid_tom),
|
10
|
+
pr(:low_tom), pr(:hand_clap), pr(:ride_cymbal_1), pr(:cowbell)]
|
13
11
|
|
14
|
-
#.........................................................................................................
|
15
12
|
str 'percussion', score, :lim=>:inf do |pattern|
|
16
|
-
|
13
|
+
pattern
|
17
14
|
end
|
18
15
|
|
19
|
-
#.........................................................................................................
|
20
16
|
play
|