Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1 from ngty/master

Gemified muse
  • Loading branch information...
commit d7b84575afe52c8599f214960023553311b0a82b 2 parents 005cf12 + eafe665
@sausheong sausheong authored
View
5 .gitignore
@@ -0,0 +1,5 @@
+*.gem
+*.swp
+.bundle
+Gemfile.lock
+pkg/*
View
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in muse.gemspec
+gemspec
View
1  Rakefile
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
View
3  lib/config/adsr.rb
@@ -1,3 +0,0 @@
-def default(input)
- Math.cos(2* Math::PI*input).to_f
-end
View
25 lib/config/chords.rb
@@ -1,25 +0,0 @@
-# major
-def _CM(options={})
- add_to_stream chord(%w(c2 e2 g2), options)
-end
-
-def _FM(options={})
- add_to_stream chord(%w(f2 a2 c3), options)
-end
-
-
-
-
-# minor
-def _Dm(options={})
- add_to_stream chord(%w(d2 f2 a2), options)
-end
-
-# dominant 7th
-def _C7(options={})
- add_to_stream chord(%w(c2 e2 g2 ais2), options)
-end
-
-def _BbM(options={})
- add_to_stream chord(%w(ais2 d3 f3), options)
-end
View
145 lib/muse copy.rb
@@ -1,145 +0,0 @@
-require "#{File.dirname(__FILE__)}/wav"
-require "#{File.dirname(__FILE__)}/config/adsr"
-require "#{File.dirname(__FILE__)}/config/chords"
-
-class Song
- attr :wav_file, :bars
-
- def self.record(name, &block)
- puts "Start recording song named #{name}.wav"
- @wav_file = Wav.new(name + ".wav")
- @bars = {}
- puts "Processing ..."
- instance_eval &block
- save
- puts "done."
- end
-
- class Bar
- attr :bpm, :beats, :octave, :adsr
- attr_accessor :stream
-
- NOTES = %w(_ a ais b c cis d dis e f fis g gis)
- FREQUENCIES = {
- :a2 => -24, :ais2 => -23, :b2 => -22, :c2 => -21, :cis2 => -20,
- :d2 => -19, :dis2 => -18, :e2 => -17, :f2 => -16, :fis2 => -15,
- :g2 => -14, :gis2 => -13, :a3 => -12, :ais3 => -11, :b3 => -10,
- :c3 => -9, :cis3 => -8, :d3 => -7, :dis3 => -6, :e3 => -5,
- :f3 => -4, :fis3 => -3, :g3 => -2, :gis3 => -1, :a4 => 0,
- :ais4 => 1, :b4 => 2, :c4 => 3, :cis4 => 4, :d4 => 5,
- :dis4 => 6, :e4 => 7, :f4 => 8, :fis4 => 9, :g4 => 10,
- :gis4 => 11, :a5 => 12, :ais5 => 13, :b5 => 14, :c5 => 15,
- :cis5 => 16, :d5 => 17, :dis5 => 18, :e5 => 19, :f5 => 20,
- :fis5 => 21, :g5 => 22, :gis5 => 23
- }
-
- def initialize(id, options={})
- @bpm = options[:bpm] || 120
- @beats = (options[:b] || 1).to_f
- @octave = options[:o].to_i + 3
- @adsr = options[:adsr] || 'default'
- @stream = []
- end
-
- def notes(&block)
- instance_eval &block
- end
-
- def frequency_of(step)
- 440.0*(2**(step.to_f/12.0))
- end
-
- def chord(notes,options={})
- puts "chord with #{notes}"
- triad =[]
- notes.each do |name|
- if name.to_s.start_with? *NOTES
- note = name.to_s
- triad << note_data(note, options)
- end
- end
- triad.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
- end
-
- def note_data(note, options={})
- stream = []
- if options
- beats = options[:b].nil? ? (@beats || 1) : options[:b].to_f
- volume = (options[:v].nil? ? 10 : options[:v].to_i) * 1000
- octave = options[:o].nil? ? @octave : options[:o].to_i + 3
- adsr = options[:a].nil? ? @adsr : 'default'
- else
- beats, volume, octave, adsr = (@beats || 1), 10000, @octave, 'default'
- end
- puts "[#{note}] -> beats : #{beats}, :octave : #{octave}"
- duration = ((60 * Wav::SAMPLE_RATE * beats)/@bpm)/Wav::SAMPLE_RATE.to_f
- note_frequency = note + octave.to_s
- unless note == '_'
- freq = frequency_of(FREQUENCIES[note_frequency.to_sym])
- else
- freq = 0
- end
- (0.0..duration.to_f).step(1.0/Wav::SAMPLE_RATE) do |i|
- x = (send(adsr.to_sym,i)*volume * Math.sin(2 * Math::PI * freq * i)).to_i
- stream << [x,x]
- end
- return stream
- end
-
- def truncate_stream_by(num)
- num.times {@stream.pop}
- end
-
- def add_to_stream(str)
- @stream += str
- end
-
- def method_missing(name, *args, &block)
- if name.to_s.start_with? *NOTES
- note = name.to_s
- if note.split('_').length > 1
- notes = note.split('_')
- add_to_stream chord(notes, args[0])
- else
- add_to_stream note_data(note, args[0])
- end
- end
- end
- end
-
- private
- class << self
- def bar(id, options={})
- puts "bar #{id}"
- unless @bars[id]
- @bars[id] = []
- end
- @bars[id] << Bar.new(id, options)
- @bars[id].last
- end
-
- def right_size(bars)
- container = []
- min_bar = bars.min_by {|x| x.stream.length}
- bars.map do |bar|
- bar.truncate_stream_by(bar.stream.length - min_bar.stream.length)
- bar
- end
- end
-
- def save
- puts "Saving music file"
- stream = []
- @bars.each do |id, item|
- container = []
- item = right_size item
- item.each do |i|
- container << i.stream
- end
- stream += container.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
- end
- @wav_file.write(stream)
- @wav_file.close
- end
- end
-end
View
247 lib/muse.rb
@@ -1,148 +1,149 @@
-require "#{File.dirname(__FILE__)}/wav"
-require "#{File.dirname(__FILE__)}/config/adsr"
-require "#{File.dirname(__FILE__)}/config/chords"
+require "#{File.dirname(__FILE__)}/muse/wav"
+require "#{File.dirname(__FILE__)}/muse/config"
-class Song
- attr :wav_file, :bars
+module Muse
+ class Song
+ attr :wav_file, :bars
- def self.record(name, &block)
- puts "Start recording song named #{name}.wav"
- @wav_file = Wav.new(name + ".wav")
- @bars = {}
- puts "Processing ..."
- instance_eval &block
- save
- puts "done."
- end
+ def self.record(name, &block)
+ puts "Start recording song named #{name}.wav"
+ @wav_file = Wav.new(name + ".wav")
+ @bars = {}
+ puts "Processing ..."
+ instance_eval &block
+ save
+ puts "done."
+ end
- class Bar
- attr :bpm, :beats, :adsr
- attr_accessor :stream
-
- NOTES = %w(_ a ais b c cis d dis e f fis g gis)
- FREQUENCIES = {
- :a2 => -24, :ais2 => -23, :b2 => -22, :c2 => -21, :cis2 => -20,
- :d2 => -19, :dis2 => -18, :e2 => -17, :f2 => -16, :fis2 => -15,
- :g2 => -14, :gis2 => -13, :a3 => -12, :ais3 => -11, :b3 => -10,
- :c3 => -9, :cis3 => -8, :d3 => -7, :dis3 => -6, :e3 => -5,
- :f3 => -4, :fis3 => -3, :g3 => -2, :gis3 => -1, :a4 => 0,
- :ais4 => 1, :b4 => 2, :c4 => 3, :cis4 => 4, :d4 => 5,
- :dis4 => 6, :e4 => 7, :f4 => 8, :fis4 => 9, :g4 => 10,
- :gis4 => 11, :a5 => 12, :ais5 => 13, :b5 => 14, :c5 => 15,
- :cis5 => 16, :d5 => 17, :dis5 => 18, :e5 => 19, :f5 => 20,
- :fis5 => 21, :g5 => 22, :gis5 => 23
- }
+ class Bar
+ attr :bpm, :beats, :adsr
+ attr_accessor :stream
+
+ NOTES = %w(_ a ais b c cis d dis e f fis g gis)
+ FREQUENCIES = {
+ :a2 => -24, :ais2 => -23, :b2 => -22, :c2 => -21, :cis2 => -20,
+ :d2 => -19, :dis2 => -18, :e2 => -17, :f2 => -16, :fis2 => -15,
+ :g2 => -14, :gis2 => -13, :a3 => -12, :ais3 => -11, :b3 => -10,
+ :c3 => -9, :cis3 => -8, :d3 => -7, :dis3 => -6, :e3 => -5,
+ :f3 => -4, :fis3 => -3, :g3 => -2, :gis3 => -1, :a4 => 0,
+ :ais4 => 1, :b4 => 2, :c4 => 3, :cis4 => 4, :d4 => 5,
+ :dis4 => 6, :e4 => 7, :f4 => 8, :fis4 => 9, :g4 => 10,
+ :gis4 => 11, :a5 => 12, :ais5 => 13, :b5 => 14, :c5 => 15,
+ :cis5 => 16, :d5 => 17, :dis5 => 18, :e5 => 19, :f5 => 20,
+ :fis5 => 21, :g5 => 22, :gis5 => 23
+ }
- def initialize(id, options={})
- @bpm = options[:bpm] || 120
- @beats = (options[:b] || 1).to_f
- @adsr = options[:adsr] || 'default'
- @stream = []
- end
+ def initialize(id, options={})
+ @bpm = options[:bpm] || 120
+ @beats = (options[:b] || 1).to_f
+ @adsr = options[:adsr] || 'default'
+ @stream = []
+ end
- def notes(&block)
- instance_eval &block
- end
+ def notes(&block)
+ instance_eval &block
+ end
- def frequency_of(step)
- 440.0*(2**(step.to_f/12.0))
- end
+ def frequency_of(step)
+ 440.0*(2**(step.to_f/12.0))
+ end
- def chord(notes,options={})
- puts "chord with #{notes}"
- triad =[]
- notes.each do |name|
- if name.start_with? *NOTES
- octave = name[name.length-1].to_i
- note = octave > 0 ? name.chop : name
- octave = 3 if octave == 0
- triad << note_data(note, octave, options)
+ def chord(notes,options={})
+ puts "chord with #{notes}"
+ triad =[]
+ notes.each do |name|
+ if name.start_with? *NOTES
+ octave = name[name.length-1].to_i
+ note = octave > 0 ? name.chop : name
+ octave = 3 if octave == 0
+ triad << note_data(note, octave, options)
+ end
end
+ triad.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
end
- triad.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
- end
- def note_data(note, octave=3, options={})
- stream = []
- if options
- beats = options[:b].nil? ? (@beats || 1) : options[:b].to_f
- volume = (options[:v].nil? ? 10 : options[:v].to_i) * 1000
- adsr = options[:a].nil? ? @adsr : 'default'
- else
- beats, volume, adsr = (@beats || 1), 10000, 'default'
+ def note_data(note, octave=3, options={})
+ stream = []
+ if options
+ beats = options[:b].nil? ? (@beats || 1) : options[:b].to_f
+ volume = (options[:v].nil? ? 10 : options[:v].to_i) * 1000
+ adsr = options[:a].nil? ? @adsr : 'default'
+ else
+ beats, volume, adsr = (@beats || 1), 10000, 'default'
+ end
+ puts "[#{note}] -> beats : #{beats}, :octave : #{octave}"
+ duration = ((60 * Wav::SAMPLE_RATE * beats)/@bpm)/Wav::SAMPLE_RATE.to_f
+ note_frequency = note + octave.to_s
+ unless note == '_'
+ freq = frequency_of(FREQUENCIES[note_frequency.to_sym])
+ else
+ freq = 0
+ end
+ (0.0..duration.to_f).step(1.0/Wav::SAMPLE_RATE) do |i|
+ x = (Config.send(adsr.to_sym,i) * volume * Math.sin(2 * Math::PI * freq * i)).to_i
+ stream << [x,x]
+ end
+ return stream
end
- puts "[#{note}] -> beats : #{beats}, :octave : #{octave}"
- duration = ((60 * Wav::SAMPLE_RATE * beats)/@bpm)/Wav::SAMPLE_RATE.to_f
- note_frequency = note + octave.to_s
- unless note == '_'
- freq = frequency_of(FREQUENCIES[note_frequency.to_sym])
- else
- freq = 0
- end
- (0.0..duration.to_f).step(1.0/Wav::SAMPLE_RATE) do |i|
- x = (send(adsr.to_sym,i) * volume * Math.sin(2 * Math::PI * freq * i)).to_i
- stream << [x,x]
- end
- return stream
- end
- def truncate_stream_by(num)
- num.times {@stream.pop}
- end
+ def truncate_stream_by(num)
+ num.times {@stream.pop}
+ end
- def add_to_stream(str)
- @stream += str
- end
+ def add_to_stream(str)
+ @stream += str
+ end
- def method_missing(name, *args, &block)
- name = name.to_s
- if name.start_with? *NOTES
- if name.split('_').length > 1
- notes = name.split('_')
- add_to_stream chord(notes, args[0])
- else
- octave = name[name.length-1].to_i
- note = octave > 0 ? name.chop : name
- octave = 3 if octave == 0
- add_to_stream note_data(note, octave, args[0])
+ def method_missing(name, *args, &block)
+ name = name.to_s
+ if name.start_with? *NOTES
+ if name.split('_').length > 1
+ notes = name.split('_')
+ add_to_stream chord(notes, args[0])
+ else
+ octave = name[name.length-1].to_i
+ note = octave > 0 ? name.chop : name
+ octave = 3 if octave == 0
+ add_to_stream note_data(note, octave, args[0])
+ end
end
end
end
- end
- private
- class << self
- def bar(id, options={})
- puts "bar #{id}"
- unless @bars[id]
- @bars[id] = []
+ private
+ class << self
+ def bar(id, options={})
+ puts "bar #{id}"
+ unless @bars[id]
+ @bars[id] = []
+ end
+ @bars[id] << Bar.new(id, options)
+ @bars[id].last
end
- @bars[id] << Bar.new(id, options)
- @bars[id].last
- end
-
- def right_size(bars)
- container = []
- min_bar = bars.min_by {|x| x.stream.length}
- bars.map do |bar|
- bar.truncate_stream_by(bar.stream.length - min_bar.stream.length)
- bar
+
+ def right_size(bars)
+ container = []
+ min_bar = bars.min_by {|x| x.stream.length}
+ bars.map do |bar|
+ bar.truncate_stream_by(bar.stream.length - min_bar.stream.length)
+ bar
+ end
end
- end
- def save
- puts "Saving music file"
- stream = []
- @bars.each do |id, item|
- container = []
- item = right_size item
- item.each do |i|
- container << i.stream
+ def save
+ puts "Saving music file"
+ stream = []
+ @bars.each do |id, item|
+ container = []
+ item = right_size item
+ item.each do |i|
+ container << i.stream
+ end
+ stream += container.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
end
- stream += container.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
+ @wav_file.write(stream)
+ @wav_file.close
end
- @wav_file.write(stream)
- @wav_file.close
end
end
-end
+end
View
1  lib/muse/config.rb
@@ -0,0 +1 @@
+Dir["#{File.dirname(__FILE__)}/config/*.rb"].each{|f| require f }
View
9 lib/muse/config/adsr.rb
@@ -0,0 +1,9 @@
+module Muse
+ module Config
+ class << self
+ def default(input)
+ Math.cos(2* Math::PI*input).to_f
+ end
+ end
+ end
+end
View
30 lib/muse/config/chords.rb
@@ -0,0 +1,30 @@
+module Muse
+ module Config
+ class << self
+
+ # major
+ def _CM(options={})
+ add_to_stream chord(%w(c2 e2 g2), options)
+ end
+
+ def _FM(options={})
+ add_to_stream chord(%w(f2 a2 c3), options)
+ end
+
+ # minor
+ def _Dm(options={})
+ add_to_stream chord(%w(d2 f2 a2), options)
+ end
+
+ # dominant 7th
+ def _C7(options={})
+ add_to_stream chord(%w(c2 e2 g2 ais2), options)
+ end
+
+ def _BbM(options={})
+ add_to_stream chord(%w(ais2 d3 f3), options)
+ end
+
+ end
+ end
+end
View
3  lib/muse/version.rb
@@ -0,0 +1,3 @@
+module Muse
+ VERSION = "0.0.1"
+end
View
79 lib/muse/wav.rb
@@ -0,0 +1,79 @@
+require 'bindata'
+
+module Muse
+ class RiffChunk < BinData::Record
+ int32be :chunk_id
+ int32le :chunk_size
+ int32be :format
+ end
+
+ class FormatChunk < BinData::Record
+ int32be :chunk_id
+ int32le :chunk_size
+ int16le :audio_format
+ int16le :num_channels
+ int32le :sample_rate
+ int32le :byte_rate
+ int16le :block_align
+ int16le :bits_per_sample
+ end
+
+ class DataChunk < BinData::Record
+ int32be :chunk_id
+ int32le :chunk_size
+ array :stream do
+ int16le :left
+ int16le :right
+ end
+ end
+
+ class WavFormat < BinData::Record
+ riff_chunk :riff_chunk
+ format_chunk :format_chunk
+ data_chunk :data_chunk
+ end
+
+ class Wav
+ SAMPLE_RATE = 44100
+ attr :wav, :file, :sample_rate, :format_chunk, :riff_chunk, :data_chunk
+
+ def initialize(filename)
+ @sample_rate = SAMPLE_RATE
+ @file = File.open(filename, "wb")
+
+ @riff_chunk = RiffChunk.new
+ @riff_chunk.chunk_id = "RIFF".unpack("N").first
+ @riff_chunk.format = "WAVE".unpack("N").first
+
+ @format_chunk = FormatChunk.new
+ @format_chunk.chunk_id = "fmt ".unpack("N").first
+ @format_chunk.chunk_size = 16
+ @format_chunk.audio_format = 1
+ @format_chunk.num_channels = 2
+ @format_chunk.bits_per_sample = 16
+ @format_chunk.sample_rate = @sample_rate
+ @format_chunk.byte_rate = @format_chunk.sample_rate * @format_chunk.num_channels * @format_chunk.bits_per_sample/2
+ @format_chunk.block_align = @format_chunk.num_channels * @format_chunk.bits_per_sample/2
+ @data_chunk = DataChunk.new
+ @data_chunk.chunk_id = "data".unpack("N").first
+ end
+
+ def write(stream_data)
+ stream_data.each_with_index do |s,i|
+ @data_chunk.stream[i].left = s[0]
+ @data_chunk.stream[i].right = s[1]
+ end
+ @data_chunk.chunk_size = stream_data.length * @format_chunk.num_channels * @format_chunk.bits_per_sample/8
+ @riff_chunk.chunk_size = 36 + @data_chunk.chunk_size
+ @wav = WavFormat.new
+ @wav.riff_chunk = @riff_chunk
+ @wav.format_chunk = @format_chunk
+ @wav.data_chunk = @data_chunk
+ @wav.write(@file)
+ end
+
+ def close
+ @file.close
+ end
+ end
+end
View
147 lib/muse_copy.rb
@@ -0,0 +1,147 @@
+require "#{File.dirname(__FILE__)}/wav"
+require "#{File.dirname(__FILE__)}/config/adsr"
+require "#{File.dirname(__FILE__)}/config/chords"
+
+module Muse
+ class Song
+ attr :wav_file, :bars
+
+ def self.record(name, &block)
+ puts "Start recording song named #{name}.wav"
+ @wav_file = Wav.new(name + ".wav")
+ @bars = {}
+ puts "Processing ..."
+ instance_eval &block
+ save
+ puts "done."
+ end
+
+ class Bar
+ attr :bpm, :beats, :octave, :adsr
+ attr_accessor :stream
+
+ NOTES = %w(_ a ais b c cis d dis e f fis g gis)
+ FREQUENCIES = {
+ :a2 => -24, :ais2 => -23, :b2 => -22, :c2 => -21, :cis2 => -20,
+ :d2 => -19, :dis2 => -18, :e2 => -17, :f2 => -16, :fis2 => -15,
+ :g2 => -14, :gis2 => -13, :a3 => -12, :ais3 => -11, :b3 => -10,
+ :c3 => -9, :cis3 => -8, :d3 => -7, :dis3 => -6, :e3 => -5,
+ :f3 => -4, :fis3 => -3, :g3 => -2, :gis3 => -1, :a4 => 0,
+ :ais4 => 1, :b4 => 2, :c4 => 3, :cis4 => 4, :d4 => 5,
+ :dis4 => 6, :e4 => 7, :f4 => 8, :fis4 => 9, :g4 => 10,
+ :gis4 => 11, :a5 => 12, :ais5 => 13, :b5 => 14, :c5 => 15,
+ :cis5 => 16, :d5 => 17, :dis5 => 18, :e5 => 19, :f5 => 20,
+ :fis5 => 21, :g5 => 22, :gis5 => 23
+ }
+
+ def initialize(id, options={})
+ @bpm = options[:bpm] || 120
+ @beats = (options[:b] || 1).to_f
+ @octave = options[:o].to_i + 3
+ @adsr = options[:adsr] || 'default'
+ @stream = []
+ end
+
+ def notes(&block)
+ instance_eval &block
+ end
+
+ def frequency_of(step)
+ 440.0*(2**(step.to_f/12.0))
+ end
+
+ def chord(notes,options={})
+ puts "chord with #{notes}"
+ triad =[]
+ notes.each do |name|
+ if name.to_s.start_with? *NOTES
+ note = name.to_s
+ triad << note_data(note, options)
+ end
+ end
+ triad.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
+ end
+
+ def note_data(note, options={})
+ stream = []
+ if options
+ beats = options[:b].nil? ? (@beats || 1) : options[:b].to_f
+ volume = (options[:v].nil? ? 10 : options[:v].to_i) * 1000
+ octave = options[:o].nil? ? @octave : options[:o].to_i + 3
+ adsr = options[:a].nil? ? @adsr : 'default'
+ else
+ beats, volume, octave, adsr = (@beats || 1), 10000, @octave, 'default'
+ end
+ puts "[#{note}] -> beats : #{beats}, :octave : #{octave}"
+ duration = ((60 * Wav::SAMPLE_RATE * beats)/@bpm)/Wav::SAMPLE_RATE.to_f
+ note_frequency = note + octave.to_s
+ unless note == '_'
+ freq = frequency_of(FREQUENCIES[note_frequency.to_sym])
+ else
+ freq = 0
+ end
+ (0.0..duration.to_f).step(1.0/Wav::SAMPLE_RATE) do |i|
+ x = (send(adsr.to_sym,i)*volume * Math.sin(2 * Math::PI * freq * i)).to_i
+ stream << [x,x]
+ end
+ return stream
+ end
+
+ def truncate_stream_by(num)
+ num.times {@stream.pop}
+ end
+
+ def add_to_stream(str)
+ @stream += str
+ end
+
+ def method_missing(name, *args, &block)
+ if name.to_s.start_with? *NOTES
+ note = name.to_s
+ if note.split('_').length > 1
+ notes = note.split('_')
+ add_to_stream chord(notes, args[0])
+ else
+ add_to_stream note_data(note, args[0])
+ end
+ end
+ end
+ end
+
+ private
+ class << self
+ def bar(id, options={})
+ puts "bar #{id}"
+ unless @bars[id]
+ @bars[id] = []
+ end
+ @bars[id] << Bar.new(id, options)
+ @bars[id].last
+ end
+
+ def right_size(bars)
+ container = []
+ min_bar = bars.min_by {|x| x.stream.length}
+ bars.map do |bar|
+ bar.truncate_stream_by(bar.stream.length - min_bar.stream.length)
+ bar
+ end
+ end
+
+ def save
+ puts "Saving music file"
+ stream = []
+ @bars.each do |id, item|
+ container = []
+ item = right_size item
+ item.each do |i|
+ container << i.stream
+ end
+ stream += container.transpose.map {|x| x.transpose.map {|y| y.reduce(:+)}}
+ end
+ @wav_file.write(stream)
+ @wav_file.close
+ end
+ end
+ end
+end
View
77 lib/wav.rb
@@ -1,77 +0,0 @@
-require 'bindata'
-
-class RiffChunk < BinData::Record
- int32be :chunk_id
- int32le :chunk_size
- int32be :format
-end
-
-class FormatChunk < BinData::Record
- int32be :chunk_id
- int32le :chunk_size
- int16le :audio_format
- int16le :num_channels
- int32le :sample_rate
- int32le :byte_rate
- int16le :block_align
- int16le :bits_per_sample
-end
-
-class DataChunk < BinData::Record
- int32be :chunk_id
- int32le :chunk_size
- array :stream do
- int16le :left
- int16le :right
- end
-end
-
-class WavFormat < BinData::Record
- riff_chunk :riff_chunk
- format_chunk :format_chunk
- data_chunk :data_chunk
-end
-
-class Wav
- SAMPLE_RATE = 44100
- attr :wav, :file, :sample_rate, :format_chunk, :riff_chunk, :data_chunk
-
- def initialize(filename)
- @sample_rate = SAMPLE_RATE
- @file = File.open(filename, "wb")
-
- @riff_chunk = RiffChunk.new
- @riff_chunk.chunk_id = "RIFF".unpack("N").first
- @riff_chunk.format = "WAVE".unpack("N").first
-
- @format_chunk = FormatChunk.new
- @format_chunk.chunk_id = "fmt ".unpack("N").first
- @format_chunk.chunk_size = 16
- @format_chunk.audio_format = 1
- @format_chunk.num_channels = 2
- @format_chunk.bits_per_sample = 16
- @format_chunk.sample_rate = @sample_rate
- @format_chunk.byte_rate = @format_chunk.sample_rate * @format_chunk.num_channels * @format_chunk.bits_per_sample/2
- @format_chunk.block_align = @format_chunk.num_channels * @format_chunk.bits_per_sample/2
- @data_chunk = DataChunk.new
- @data_chunk.chunk_id = "data".unpack("N").first
- end
-
- def write(stream_data)
- stream_data.each_with_index do |s,i|
- @data_chunk.stream[i].left = s[0]
- @data_chunk.stream[i].right = s[1]
- end
- @data_chunk.chunk_size = stream_data.length * @format_chunk.num_channels * @format_chunk.bits_per_sample/8
- @riff_chunk.chunk_size = 36 + @data_chunk.chunk_size
- @wav = WavFormat.new
- @wav.riff_chunk = @riff_chunk
- @wav.format_chunk = @format_chunk
- @wav.data_chunk = @data_chunk
- @wav.write(@file)
- end
-
- def close
- @file.close
- end
-end
View
19 muse.gemspec
@@ -0,0 +1,19 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "muse/version"
+
+Gem::Specification.new do |s|
+ s.name = "muse"
+ s.version = Muse::VERSION
+ s.authors = ["pls fix me asap"]
+ s.email = ["plsfix@me.asap"]
+ s.homepage = "https://github.com/sausheong/muse"
+ s.summary = %q{use is a Ruby DSL for making music}
+ s.description = %q{}
+
+ s.files = Dir["#{File.dirname(__FILE__)}/lib/**/*.rb"]
+ s.test_files = Dir["#{File.dirname(__FILE__)}/spec/**/*.rb"]
+ s.require_paths = [File.expand_path('../lib', __FILE__)]
+
+ s.add_dependency 'bindata'
+end
View
1  muse.rb
@@ -1 +0,0 @@
-require "#{File.dirname(__FILE__)}/lib/muse"
View
8 songs/done_x4.rb
@@ -0,0 +1,8 @@
+require "#{File.dirname(__FILE__)}/../lib/muse"
+include Muse
+
+# "DONE x4" is the piece we play at the end of our daily standup :D
+
+Song.record 'done_x4' do
+ bar(1,b:0.5).notes { a4; a4; a4; f3 b:2.5; }
+end
View
BIN  songs/done_x4.wav
Binary file not shown
View
3  songs/music_box_dancer.rb
@@ -1,4 +1,5 @@
-require '../muse'
+require "#{File.dirname(__FILE__)}/../lib/muse"
+include Muse
# "Music Box Dancer" is an instrumental piece by Canadian musician
# Frank Mills that was an international hit in the late 1970s. It
View
BIN  songs/music_box_dancer.wav
Binary file not shown
View
5 songs/test.rb
@@ -1,6 +1,7 @@
-require '../muse'
+require "#{File.dirname(__FILE__)}/../lib/muse"
+include Muse
Song.record 'test_file' do
bar(1,b:0.5).notes { a; b b:1;}
-end
+end
View
3  songs/turkish_march.rb
@@ -1,4 +1,5 @@
-require '../muse'
+require "#{File.dirname(__FILE__)}/../lib/muse"
+include Muse
# Mozart's Piano Sonata No. 11 3rd Movement (All Turca)
# more popularly known as the 'Turkish March' or 'Turkish Rondo'
Please sign in to comment.
Something went wrong with that request. Please try again.