muse 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
data/lib/muse.rb CHANGED
@@ -17,6 +17,7 @@
17
17
  require "parallel"
18
18
  require "#{File.dirname(__FILE__)}/muse/wav"
19
19
  require "#{File.dirname(__FILE__)}/muse/config"
20
+ require "#{File.dirname(__FILE__)}/muse/circularlist"
20
21
 
21
22
  module Muse
22
23
 
@@ -0,0 +1,34 @@
1
+ class CircularList < Array
2
+ def index
3
+ @index ||=0
4
+ @index.abs
5
+ end
6
+
7
+ def current
8
+ @index ||= 0
9
+ get_at(@index)
10
+ end
11
+
12
+ def next(num=1)
13
+ @index ||= 0
14
+ @index += num
15
+ get_at(@index)
16
+ end
17
+
18
+ def previous(num=1)
19
+ @index ||= 0
20
+ @index -= num
21
+ get_at(@index)
22
+ end
23
+
24
+ private
25
+ def get_at(index)
26
+ if index >= 0
27
+ at(index % self.size)
28
+ else
29
+ index = self.size + index
30
+ get_at(index)
31
+ end
32
+ end
33
+
34
+ end
data/lib/muse/version.rb CHANGED
@@ -15,5 +15,5 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  module Muse
18
- VERSION = "0.0.10"
18
+ VERSION = "0.0.11"
19
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: muse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-04-22 00:00:00.000000000 Z
13
+ date: 2012-05-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bindata
@@ -53,13 +53,13 @@ executables: []
53
53
  extensions: []
54
54
  extra_rdoc_files: []
55
55
  files:
56
+ - lib/muse/circularlist.rb
56
57
  - lib/muse/config/chords.rb
57
58
  - lib/muse/config/envelope.rb
58
59
  - lib/muse/config/harmonic.rb
59
60
  - lib/muse/config.rb
60
61
  - lib/muse/version.rb
61
62
  - lib/muse/wav.rb
62
- - lib/muse.old.rb
63
63
  - lib/muse.rb
64
64
  homepage: https://github.com/sausheong/muse
65
65
  licenses: []
data/lib/muse.old.rb DELETED
@@ -1,222 +0,0 @@
1
- # Muse
2
- # Copyright (C) 2012 Chang Sau Sheong
3
- #
4
- # This program is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation, either version 3 of the License, or
7
- # (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
-
17
- require "parallel"
18
- require "#{File.dirname(__FILE__)}/muse/wav"
19
- require "#{File.dirname(__FILE__)}/muse/config"
20
-
21
- module Muse
22
-
23
- NOTES = %w(_ a ais b c cis d dis e f fis g gis)
24
- FREQUENCIES = {
25
- :ais1 => -34, :b1 => -33, :cis2 => -32, :d2 => -31, :dis2 => -30,
26
- :e2 => -29, :f2 => -28, :fis2 => -27, :g2 => -26, :gis2 => -25,
27
- :a2 => -24, :ais2 => -23, :b2 => -22, :c3 => -21, :cis3 => -20,
28
- :d3 => -19, :dis3 => -18, :e3 => -17, :f3 => -16, :fis3 => -15,
29
- :g3 => -14, :gis3 => -13, :a3 => -12, :ais3 => -11, :b3 => -10,
30
- :c4 => -9, :cis4 => -8, :d4 => -7, :dis4 => -6, :e4 => -5,
31
- :f4 => -4, :fis4 => -3, :g4 => -2, :gis4 => -1, :a4 => 0,
32
- :ais4 => 1, :b4 => 2, :c5 => 3, :cis5 => 4, :d5 => 5,
33
- :dis5 => 6, :e5 => 7, :f5 => 8, :fis5 => 9, :g5 => 10,
34
- :gis5 => 11, :a5 => 12, :ais5 => 13, :b5 => 14, :c6 => 15,
35
- :cis6 => 16, :d6 => 17, :dis6 => 18, :e6 => 19, :f6 => 20,
36
- :fis6 => 21, :g6 => 22, :gis6 => 23
37
- }
38
-
39
- class Note
40
- attr :octave, :beat, :bpm, :frequency, :harmonic, :envelope, :volume, :name
41
-
42
- def initialize(name, octave=4, bpm=120, options={})
43
- if options
44
- beat = options[:b].nil? ? (@beat || 1) : options[:b].to_f
45
- volume = (options[:v].nil? ? (@volume.to_i || 5) : options[:v].to_i) * 1000
46
- envelope = options[:a].nil? ? @envelope : 'default'
47
- harmonic = options[:h].nil? ? @harmonic : 'default'
48
- else
49
- beats, volume, envelope, harmonic = (@beats || 1), 5000, @envelope || 'default', @harmonic || 'default'
50
- end
51
- @name, @octave, @bpm = name, octave, bpm
52
- unless name == '_'
53
- @frequency = frequency_of(FREQUENCIES["#{name}#{octave}".to_sym])
54
- else
55
- @frequency = 0
56
- end
57
- end
58
-
59
-
60
- # shifting notes by semitones
61
- def >>()
62
- end
63
-
64
- def to_stream
65
- stream = []
66
- duration = ((60 * WavHeader::SAMPLE_RATE * @beat)/@bpm)/WavHeader::SAMPLE_RATE.to_f
67
- (0.0..duration.to_f).step(1.0/WavHeader::SAMPLE_RATE) do |i|
68
- env = Envelope.send(@envelope.to_sym,i, duration)
69
- har = Harmonic.send(@harmonic.to_sym, @frequency * i)
70
- x = (env * har * @volume).to_i
71
- stream << [x,x]
72
- end
73
- return stream
74
- end
75
-
76
- def to_s
77
- "[#{@name}] -> b: #{@beat}, o: #{@octave} bpm: #{@bpm} e: #{@envelope} h: #{@harmonic}"
78
- end
79
-
80
- def frequency_of(step)
81
- 440.0*(2**(step.to_f/12.0))
82
- end
83
-
84
- end
85
-
86
- class Song
87
-
88
- def self.record(name, options ={}, &block)
89
- start_time = Time.now
90
- puts "Start recording song named #{name}.wav"
91
- @name = name
92
- @bpm = options[:bpm] || 120
93
- @envelope = options[:envelope] || 'default'
94
- @harmonic = options[:harmonic] || 'default'
95
- @bars = {}
96
- puts "Processing ..."
97
- instance_eval &block
98
- save
99
- end_time = Time.now
100
- puts "Total time taken : #{((end_time - start_time)/60.0).round(3)} minutes"
101
- puts "done."
102
- end
103
-
104
- class Bar
105
- attr :bpm, :beats, :envelope, :harmonic
106
- attr_accessor :stream
107
-
108
- def initialize(id, options={})
109
- @bpm = options[:bpm] || 120
110
- @beats = (options[:b] || 1).to_f
111
- @envelope = options[:e] || 'default'
112
- @harmonic = options[:h] || 'default'
113
- @volume = options[:v] || 5
114
- @stream = []
115
- end
116
-
117
- def notes(&block)
118
- instance_eval &block
119
- end
120
-
121
- def chord(notes,options={})
122
- puts "chord with #{notes}"
123
- triad =[]
124
- notes.each do |name|
125
- if name.start_with? *NOTES
126
- octave = name[name.length-1].to_i
127
- note = octave > 0 ? name.chop : name
128
- octave = 4 if octave == 0
129
- n = Note.new(note, octave, @bpm, options)
130
- triad << n.to_stream
131
- end
132
- end
133
- triad.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
134
- end
135
-
136
- def truncate_stream_by(num)
137
- num.times {@stream.pop}
138
- end
139
-
140
- def add_to_stream(str)
141
- @stream += str
142
- end
143
-
144
-
145
- def method_missing(name, *args, &block)
146
- name = name.to_s
147
- if name.start_with? *NOTES
148
- if name.split('_').length > 1
149
- notes = name.split('_')
150
- add_to_stream chord(notes, args[0])
151
- else
152
- octave = name[name.length-1].to_i
153
- note = octave > 0 ? name.chop : name
154
- octave = 4 if octave == 0
155
- add_to_stream Note.new(note, octave, @bpm, options).to_stream
156
- end
157
- end
158
- end
159
- end
160
-
161
- private
162
- class << self
163
- def bar(id, options={})
164
- puts "bar #{id}"
165
- unless @bars[id]
166
- @bars[id] = []
167
- end
168
- options[:bpm] = options[:bpm] || @bpm || 120
169
- options[:envelope] = options[:envelope] || @envelope || 'default'
170
- options[:harmonic] = options[:harmonic] || @harmonic || 'default'
171
- @bars[id] << Bar.new(id, options)
172
- @bars[id].last
173
- end
174
-
175
- def right_size(bars)
176
- container = []
177
- min_bar = bars.min_by {|x| x.stream.length}
178
- bars.map do |bar|
179
- bar.truncate_stream_by(bar.stream.length - min_bar.stream.length)
180
- bar
181
- end
182
- end
183
-
184
- def save
185
- puts "Creating temporary files in parallel ..."
186
-
187
- results = Parallel.each_with_index(@bars.values, :in_processes => Parallel.processor_count) do |item, id|
188
- puts "Writing file - #{id}"
189
- stream = []
190
- container = []
191
- item = right_size item
192
- item.each do |i|
193
- container << i.stream
194
- end
195
- stream += container.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
196
- temp = TempData.new
197
- stream.each_with_index do |s,i|
198
- temp.stream[i].left = s[0]
199
- temp.stream[i].right = s[1]
200
- end
201
- File.open("#{@name}-#{id.to_s.rjust(3,'0')}.tmp", "w") {|file| temp.write(file) }
202
- puts "Completed file - #{id}"
203
- end
204
-
205
- stream_size = results.inject(0) do |memo, bars|
206
- memo + bars.first.stream.size
207
- end
208
-
209
- puts "Combining temporary files ..."
210
- WavHeader.new("#{@name}.wav", stream_size)
211
- tmpfiles = Dir.glob("#{@name}-*.tmp").sort
212
- File.open("#{@name}.wav", "ab+") do |wav|
213
- tmpfiles.each do |file|
214
- File.open(file, "rb") { |tmp| File.copy_stream(tmp, wav) }
215
- File.delete file
216
- end
217
- end
218
-
219
- end
220
- end
221
- end
222
- end