zgomot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/.document +5 -0
  2. data/LICENSE +22 -0
  3. data/README.rdoc +7 -0
  4. data/Rakefile +24 -0
  5. data/VERSION +1 -0
  6. data/bin/zgomot +2 -0
  7. data/examples/arp_chords.rb +15 -0
  8. data/examples/full_scale_notes.rb +15 -0
  9. data/examples/inv_chords.rb +15 -0
  10. data/examples/modes_notes.rb +16 -0
  11. data/examples/notes.rb +18 -0
  12. data/examples/percs.rb +20 -0
  13. data/examples/percs_multi.rb +18 -0
  14. data/examples/phase_notes.rb +20 -0
  15. data/examples/prog_chords.rb +15 -0
  16. data/examples/prog_chords_multi_vel_length.rb +15 -0
  17. data/examples/prog_chords_rest.rb +15 -0
  18. data/examples/prog_notes.rb +15 -0
  19. data/examples/prog_notes_multi_vel_length.rb +15 -0
  20. data/examples/prog_notes_rest.rb +15 -0
  21. data/examples/progressive_modes.rb +51 -0
  22. data/examples/reverse_chords.rb +15 -0
  23. data/examples/scale_chords.rb +15 -0
  24. data/examples/scale_notes.rb +15 -0
  25. data/examples/scales_notes.rb +19 -0
  26. data/examples/simple_chords.rb +15 -0
  27. data/examples/simple_markov.rb +24 -0
  28. data/examples/simple_notes.rb +15 -0
  29. data/examples/simple_notes_length.rb +17 -0
  30. data/examples/simple_notes_velocity.rb +17 -0
  31. data/examples/zgomot.yml +3 -0
  32. data/lib/zgomot/boot.rb +56 -0
  33. data/lib/zgomot/comp/chord.rb +171 -0
  34. data/lib/zgomot/comp/markov.rb +60 -0
  35. data/lib/zgomot/comp/mode.rb +66 -0
  36. data/lib/zgomot/comp/note.rb +29 -0
  37. data/lib/zgomot/comp/pattern.rb +63 -0
  38. data/lib/zgomot/comp/perc.rb +94 -0
  39. data/lib/zgomot/comp/permutation.rb +17 -0
  40. data/lib/zgomot/comp/pitch_class.rb +63 -0
  41. data/lib/zgomot/comp/progression.rb +132 -0
  42. data/lib/zgomot/comp/scale.rb +32 -0
  43. data/lib/zgomot/comp.rb +11 -0
  44. data/lib/zgomot/config.rb +51 -0
  45. data/lib/zgomot/main.rb +51 -0
  46. data/lib/zgomot/midi/channel.rb +92 -0
  47. data/lib/zgomot/midi/clock.rb +101 -0
  48. data/lib/zgomot/midi/dispatcher.rb +92 -0
  49. data/lib/zgomot/midi/interface.rb +29 -0
  50. data/lib/zgomot/midi/note.rb +104 -0
  51. data/lib/zgomot/midi/stream.rb +76 -0
  52. data/lib/zgomot/midi.rb +6 -0
  53. data/lib/zgomot/patches/object.rb +11 -0
  54. data/lib/zgomot/patches/time.rb +10 -0
  55. data/lib/zgomot/patches.rb +2 -0
  56. data/lib/zgomot.rb +14 -0
  57. data/lib/zlive.rb +7 -0
  58. metadata +178 -0
@@ -0,0 +1,171 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Chord
6
+
7
+ #####-------------------------------------------------------------------------------------------------------
8
+ # progession interface
9
+ #####-------------------------------------------------------------------------------------------------------
10
+ class Progression
11
+
12
+ #.........................................................................................................
13
+ attr_reader :chord
14
+
15
+ #.........................................................................................................
16
+ def initialize(chord)
17
+ @chord = chord || :scale
18
+ end
19
+
20
+ #.........................................................................................................
21
+ def notes(prog)
22
+ chords = prog.mode.chords(chord); count = -1
23
+ prog.items.select do |d|
24
+ d.eql?(:R) || chords[d-1]
25
+ end.map do |d|
26
+ count += 1; idx_length, idx_velocity = count % prog.length.length, count % prog.velocity.length
27
+ unless d.eql?(:R)
28
+ Chord.new(:tonic => prog.pitches[d-1], :chord => chords[d-1], :length => prog.length[idx_length], :velocity => prog.velocity[idx_velocity])
29
+ else
30
+ Zgomot::Midi::Note.new(:pitch => :R, :length => prog.length[idx_length], :velocity => prog.velocity[idx_velocity])
31
+ end
32
+ end
33
+ end
34
+
35
+ #### Progression
36
+ end
37
+
38
+ #.........................................................................................................
39
+ @chord_intervals = {
40
+ :maj => [4,7],
41
+ :min => [3,7],
42
+ :dim => [3,6],
43
+ :aug => [4,8],
44
+ :sus2 => [2,7],
45
+ :sus4 => [5,7]
46
+ }
47
+
48
+ #####-------------------------------------------------------------------------------------------------------
49
+ class << self
50
+
51
+ #.........................................................................................................
52
+ attr_reader :chord_intervals
53
+
54
+ #### self
55
+ end
56
+
57
+ #.........................................................................................................
58
+ attr_reader :tonic, :chord, :clock, :intervals, :arp, :time_scale, :items, :inversion, :reverse
59
+ attr_accessor :length, :velocity
60
+
61
+ #.........................................................................................................
62
+ def initialize(args)
63
+ @length, @velocity, @chord = args[:length], args[:velocity], args[:chord]
64
+ (@intervals = Chord.chord_intervals[chord]) || raise(Zgomot::Error, "#{chord.inspect} is invalid")
65
+ @time_scale, @inversion, @reverse = 1.0, 0, false
66
+ @tonic = case args[:tonic]
67
+ when Array then args[:tonic]
68
+ when Symbol then [args[:tonic], 4]
69
+ when nil then [:C,4]
70
+ else raise(Zgomot::Error, "#{args[:tonic].inspect} is invalid tonic")
71
+ end
72
+ end
73
+
74
+ #.........................................................................................................
75
+ def pitches
76
+ last_pitch, octave = tonic; pitches = [tonic]
77
+ intervals.each_index{|i| pitches << PitchClass.next(tonic.first, intervals[i])}
78
+ nts = pitches[1..-1].map do |p|
79
+ octave += 1 if p < last_pitch; last_pitch = p.value; [last_pitch, octave]
80
+ end.unshift(tonic)
81
+ @reverse ? invert(nts).reverse : invert(nts)
82
+ end
83
+
84
+ #.........................................................................................................
85
+ def notes
86
+ @notes ||= pitches.map do |p|
87
+ Zgomot::Midi::Note.new(:pitch => p, :length => length, :velocity => velocity)
88
+ end
89
+ end
90
+
91
+ #.........................................................................................................
92
+ # transforms
93
+ #.........................................................................................................
94
+ def arp!(v)
95
+ @notes = nil; @arp = v; self
96
+ end
97
+
98
+ #.........................................................................................................
99
+ def inv!(v)
100
+ @notes = nil; @inversion = v; self
101
+ end
102
+
103
+ #.........................................................................................................
104
+ def rev!
105
+ @reverse = true; self
106
+ end
107
+
108
+ #.........................................................................................................
109
+ def bpm!(v)
110
+ @time_scale = 1.0/v.to_f; self
111
+ end
112
+
113
+ #.........................................................................................................
114
+ def octave!(v)
115
+ @notes = nil; @octave = v; self
116
+ end
117
+
118
+ #.........................................................................................................
119
+ # channel and dispatch interface
120
+ #.........................................................................................................
121
+ def length_to_sec
122
+ 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))
123
+ end
124
+
125
+ #.........................................................................................................
126
+ def to_midi
127
+ notes.map{|n| n.to_midi}
128
+ end
129
+
130
+ #.........................................................................................................
131
+ def channel=(chan)
132
+ notes.each{|n| n.channel = chan}
133
+ end
134
+
135
+ #.........................................................................................................
136
+ def offset_time=(time)
137
+ notes.each{|n| n.offset_time = time}
138
+ end
139
+
140
+ #.........................................................................................................
141
+ def time=(time)
142
+ @clock = Zgomot::Midi::Clock.new
143
+ clock.update(time)
144
+ notes.each do |n|
145
+ n.time = clock.current_time
146
+ clock.update(Zgomot::Midi::Clock.whole_note_sec/arp.to_f) if arp.to_f > 0.0
147
+ end
148
+ end
149
+
150
+ #.........................................................................................................
151
+ # private
152
+ #.........................................................................................................
153
+ def sum(a)
154
+ a.inject(0) {|s,n| s+n}
155
+ end
156
+
157
+ #.........................................................................................................
158
+ def invert(p)
159
+ inversion.times do |i|
160
+ n = p.shift; p.push([n.first, (n.last.eql?(9) ? n.last : n.last+1)])
161
+ end; p
162
+ end
163
+
164
+ #.........................................................................................................
165
+ private :sum, :invert
166
+
167
+ #### Chord
168
+ end
169
+
170
+ #### Zgomot::Comp
171
+ end
@@ -0,0 +1,60 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Markov
6
+
7
+ #####-------------------------------------------------------------------------------------------------------
8
+ class << self
9
+
10
+ #.........................................................................................................
11
+ def mark
12
+ new
13
+ end
14
+
15
+ #### self
16
+ end
17
+
18
+ #.........................................................................................................
19
+ attr_reader :current_state, :states
20
+
21
+ #.........................................................................................................
22
+ def initialize
23
+ @current_state, @states = 0, []
24
+ end
25
+
26
+ #.........................................................................................................
27
+ def add(trans, &blk)
28
+ @states << {:trans=>sum_trans(trans), :blk => blk}
29
+ end
30
+
31
+ #.........................................................................................................
32
+ def init(state, args={})
33
+ @current_state = state
34
+ states[@current_state][:blk].call(args)
35
+ end
36
+
37
+ #.........................................................................................................
38
+ def next(args={})
39
+ r, state = rand, states[@current_state]
40
+ @current_state = state[:trans].select{|t| r >= t}.count
41
+ Zgomot.logger.info "CURRENT MARKOV STATE: #{current_state}"
42
+ blk = states[@current_state][:blk]
43
+ blk.arity > 0 ? blk.call(args) : blk.call
44
+ end
45
+
46
+ #.........................................................................................................
47
+ # private
48
+ #.........................................................................................................
49
+ def sum_trans(trans)
50
+ sums = []; trans.each_index{|i| sums[i] = trans[0..i].inject(0){|s,v| s+v}}; sums
51
+ end
52
+
53
+ #.........................................................................................................
54
+ private :sum_trans
55
+
56
+ #### Markov
57
+ end
58
+
59
+ #### Zgomot::Comp
60
+ end
@@ -0,0 +1,66 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Mode
6
+
7
+ #.........................................................................................................
8
+ @modes = [:ionian, :dorian, :phrygian, :lydian, :mixolydian, :aeolian, :locrian]
9
+ @intervals = [2,2,1,2,2,2,1]
10
+ @chords = {:scale => [:maj, :min, :min, :maj, :maj, :min, :dim],
11
+ :maj => [:maj, nil, nil, :maj, :maj, nil, nil],
12
+ :min => [nil, :min, :min, nil, nil, :min, nil],
13
+ :dim => [nil, nil, nil, nil, nil, nil, :dim],
14
+ :sus2 => [:sus2, :sus2, nil, :sus2, :sus2, :sus2, nil],
15
+ :sus4 => [:sus4, :sus4, :sus4, nil, :sus4, :sus4, nil],
16
+ :aug => [nil, nil, nil, nil, nil, nil, nil]}
17
+
18
+ #####-------------------------------------------------------------------------------------------------------
19
+ class << self
20
+
21
+ #.........................................................................................................
22
+ attr_reader :modes, :intervals, :chords
23
+
24
+ #### self
25
+ end
26
+
27
+ #####-------------------------------------------------------------------------------------------------------
28
+ attr_reader :scale, :mode
29
+
30
+ #.........................................................................................................
31
+ def initialize(mode = 1)
32
+ @mode = case mode
33
+ when Symbol then self.class.modes.index(mode)+1
34
+ when Fixnum then mode
35
+ when nil then 1
36
+ else raise(Zgomot::Error, "#{mode.inspect} is invalid mode")
37
+ end
38
+ raise(Zgomot::Error, "'#{mode}' is invalid mode") if @mode.nil?
39
+ @scale = Scale.new(self.class.intervals, @mode)
40
+ end
41
+
42
+ #.........................................................................................................
43
+ def chords(chord = :scale)
44
+ cycle_chords(Mode.chords[chord].clone)
45
+ end
46
+
47
+ #.........................................................................................................
48
+ def method_missing(meth, *args, &blk )
49
+ scale.send(meth, *args, &blk)
50
+ end
51
+
52
+ #.........................................................................................................
53
+ # private
54
+ #.........................................................................................................
55
+ def cycle_chords(cs)
56
+ (mode-1).times{cs.push(cs.shift)}; cs
57
+ end
58
+
59
+ #.........................................................................................................
60
+ private :cycle_chords
61
+
62
+ #### Mode
63
+ end
64
+
65
+ #### Zgomot::Comp
66
+ end
@@ -0,0 +1,29 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Note
6
+
7
+ #####-------------------------------------------------------------------------------------------------------
8
+ # progession interface
9
+ #####-------------------------------------------------------------------------------------------------------
10
+ class Progression
11
+
12
+ #.........................................................................................................
13
+ def notes(prog)
14
+ count = -1
15
+ prog.items.map do |d|
16
+ count += 1; idx_length, idx_velocity = count % prog.length.length, count % prog.velocity.length
17
+ pitch = d.eql?(:R) ? :R : prog.pitches[d-1]
18
+ Zgomot::Midi::Note.new(:pitch => pitch, :length => prog.length[idx_length], :velocity => prog.velocity[idx_velocity])
19
+ end
20
+ end
21
+
22
+ #### Progression
23
+ end
24
+
25
+ #### Note
26
+ end
27
+
28
+ #### Zgomot::Comp
29
+ end
@@ -0,0 +1,63 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Pattern
6
+
7
+ #####-------------------------------------------------------------------------------------------------------
8
+ class << self
9
+
10
+ #.......................................................................................................
11
+ def n(p=[:C,4], opts = {})
12
+ l = opts[:l] || 4; v = opts[:v] || 0.6
13
+ Zgomot::Midi::Note.new(:pitch => p, :length => l, :velocity => v)
14
+ end
15
+
16
+ #.........................................................................................................
17
+ def c(tonic, chord = :maj, opts = {})
18
+ l = opts[:l] || 4; v = opts[:v] || 0.6
19
+ Chord.new(:tonic => tonic, :chord => chord, :length => l, :velocity => v)
20
+ end
21
+
22
+ #.........................................................................................................
23
+ def np(tonic=[:C,4], mode=0, opts = {})
24
+ l = opts[:l] || 4; v = opts[:v] || 0.6
25
+ Progression.new(:item => Note::Progression.new, :tonic => tonic, :mode => mode, :length => l, :velocity => v)
26
+ end
27
+
28
+ #.........................................................................................................
29
+ def cp(tonic=[:C,4], mode=0, opts = {})
30
+ l = opts[:l] || 4; v = opts[:v] || 0.6
31
+ Progression.new(:item => Chord::Progression.new(:scale), :tonic => tonic, :mode => mode, :length => l, :velocity => v)
32
+ end
33
+
34
+ #.........................................................................................................
35
+ def pr(percs = acoustic_bass_drum, opts = {})
36
+ l = opts[:l] || 4; v = opts[:v] || 0.6
37
+ Perc.new(:percs => percs, :length => l, :velocity => v)
38
+ end
39
+
40
+ #### self
41
+ end
42
+
43
+ #...........................................................................................................
44
+ attr_reader :seq
45
+
46
+ #...........................................................................................................
47
+ def initialize(seq)
48
+ @seq = [seq].flatten
49
+ end
50
+
51
+ #.........................................................................................................
52
+ def method_missing(meth, *args, &blk )
53
+ @seq = seq.map do |p|
54
+ p.respond_to?(meth) ? p.send(meth, *args, &blk) : p
55
+ end
56
+ self
57
+ end
58
+
59
+ #### Pattern
60
+ end
61
+
62
+ #### Zgomot ::Comp
63
+ end
@@ -0,0 +1,94 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Perc
6
+
7
+ #.........................................................................................................
8
+ PERC_MAP = {
9
+ :acoustic_bass_drum => [:B,1],
10
+ :bass_drum_1 => [:C,2], :side_stick => [:Cs,2], :acoustic_snare => [:D,2],
11
+ :hand_clap => [:Ds,2], :electric_snare => [:E,2], :low_floor_tom => [:F,2],
12
+ :closed_hi_hat => [:Fs,2], :high_floor_tom => [:G,2], :pedal_hi_hat => [:Gs,2],
13
+ :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],
17
+ :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],
21
+ :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],
25
+ :open_triangle => [:A,5],
26
+ :R => :R,
27
+ }
28
+
29
+ #####-------------------------------------------------------------------------------------------------------
30
+ 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
+ end
43
+
44
+ #.........................................................................................................
45
+ def pitches
46
+ percs.inject([]){|p,r| (m = Perc::PERC_MAP[r]).nil? ? p : p << m}
47
+ end
48
+
49
+ #.........................................................................................................
50
+ def notes
51
+ @notes ||= pitches.map do |p|
52
+ Zgomot::Midi::Note.new(:pitch => p, :length => length, :velocity => velocity)
53
+ end
54
+ end
55
+
56
+ #.........................................................................................................
57
+ # transforms
58
+ #.........................................................................................................
59
+ def bpm_scale!(v)
60
+ @time_scale = 1.0/v.to_f; self
61
+ end
62
+
63
+ #.........................................................................................................
64
+ # channel and dispatch interface
65
+ #.........................................................................................................
66
+ def channel=(chan)
67
+ notes.each{|n| n.channel = chan}
68
+ end
69
+
70
+ #.........................................................................................................
71
+ def offset_time=(time)
72
+ notes.each{|n| n.offset_time = time}
73
+ end
74
+
75
+ #.........................................................................................................
76
+ def time=(time)
77
+ notes.each{|n| n.time = time}
78
+ end
79
+
80
+ #.........................................................................................................
81
+ def length_to_sec
82
+ time_scale*Zgomot::Midi::Clock.whole_note_sec/length
83
+ end
84
+
85
+ #.........................................................................................................
86
+ def to_midi
87
+ notes.map{|n| n.to_midi}
88
+ end
89
+
90
+ #### Scale
91
+ end
92
+
93
+ #### Zgomot::Comp
94
+ end
@@ -0,0 +1,17 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Permutation
6
+
7
+ #.........................................................................................................
8
+
9
+ #.........................................................................................................
10
+ def initialize
11
+ end
12
+
13
+ #### Markov
14
+ end
15
+
16
+ #### Zgomot::Comp
17
+ end
@@ -0,0 +1,63 @@
1
+ ##############################################################################################################
2
+ module Zgomot::Comp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class PitchClass
6
+
7
+ #.........................................................................................................
8
+ PITCH_CLASS = {
9
+ :C => 0,
10
+ :Cs => 1,
11
+ :D => 2,
12
+ :Ds => 3,
13
+ :E => 4,
14
+ :F => 5,
15
+ :Fs => 6,
16
+ :G => 7,
17
+ :Gs => 8,
18
+ :A => 9,
19
+ :As => 10,
20
+ :B => 11
21
+ }
22
+
23
+ #####-------------------------------------------------------------------------------------------------------
24
+ class << self
25
+
26
+ #.........................................................................................................
27
+ def next(pc, interval)
28
+ start_pos = PITCH_CLASS[to_value(pc)]
29
+ new(PITCH_CLASS.inject([]){|r,(c,p)| p.eql?((start_pos+interval) % 12) ? r << c : r}.first) if start_pos
30
+ end
31
+
32
+ #.........................................................................................................
33
+ def to_value(p)
34
+ p.kind_of?(PitchClass) ? p.value : p
35
+ end
36
+
37
+ #### self
38
+ end
39
+
40
+ #.........................................................................................................
41
+ attr_reader :value
42
+
43
+ #.........................................................................................................
44
+ def initialize(p)
45
+ raise(Zgomot::Error, "#{p} is invalid pitch class") unless PITCH_CLASS.include?(p)
46
+ @value = p
47
+ end
48
+
49
+ #.........................................................................................................
50
+ def <(p)
51
+ PITCH_CLASS[value] < PITCH_CLASS[self.class.to_value(p)]
52
+ end
53
+
54
+ #.........................................................................................................
55
+ def >(p)
56
+ PITCH_CLASS[value] > PITCH_CLASS[self.class.to_value(p)]
57
+ end
58
+
59
+ #### PitchClass
60
+ end
61
+
62
+ #### Zgomot::Comp
63
+ end