muse 0.0.10 → 0.0.11

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.
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