Class: Muse::Song::Bar

Inherits:
Object
  • Object
show all
Defined in:
lib/muse.rb

Constant Summary collapse

NOTES =
%w(_ a ais b c cis d dis e f fis g gis)
FREQUENCIES =
{
  :ais1 => -34, :b1   => -33, :cis2 => -32,  :d2   => -31, :dis2 => -30,
  :e2   => -29, :f2   => -28, :fis2 => -27,  :g2   => -26, :gis2 => -25,
  :a2   => -24, :ais2 => -23, :b2   => -22,  :c3   => -21, :cis3 => -20, 
  :d3   => -19, :dis3 => -18, :e3   => -17,  :f3   => -16, :fis3 => -15, 
  :g3   => -14, :gis3 => -13, :a3   => -12,  :ais3 => -11, :b3   => -10, 
  :c4   => -9,  :cis4 => -8,  :d4   => -7,   :dis4 => -6,  :e4   => -5,  
  :f4   => -4,  :fis4 => -3,  :g4   => -2,   :gis4 => -1,  :a4   => 0,
  :ais4 => 1,   :b4   => 2,   :c5   => 3,    :cis5 => 4,   :d5   => 5, 
  :dis5 => 6,   :e5   => 7,   :f5   => 8,    :fis5 => 9,   :g5   => 10,   
  :gis5 => 11,  :a5   => 12,  :ais5 => 13,   :b5   => 14,  :c6   => 15,
  :cis6 => 16,  :d6   => 17,  :dis6 => 18,   :e6   => 19,  :f6   => 20,
  :fis6 => 21,  :g6   => 22,  :gis6 => 23
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, options = {}) ⇒ Bar

Returns a new instance of Bar.



60
61
62
63
64
65
66
# File 'lib/muse.rb', line 60

def initialize(id, options={})
  @bpm = options[:bpm] || 120
  @beats = (options[:b] || 1).to_f
  @envelope = options[:envelope] || 'default'
  @harmonic = options[:harmonic] || 'default'
  @stream = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/muse.rb', line 125

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

Instance Attribute Details

#beatsObject (readonly)

Returns the value of attribute beats.



41
42
43
# File 'lib/muse.rb', line 41

def beats
  @beats
end

#bpmObject (readonly)

Returns the value of attribute bpm.



41
42
43
# File 'lib/muse.rb', line 41

def bpm
  @bpm
end

#envelopeObject (readonly)

Returns the value of attribute envelope.



41
42
43
# File 'lib/muse.rb', line 41

def envelope
  @envelope
end

#harmonicObject (readonly)

Returns the value of attribute harmonic.



41
42
43
# File 'lib/muse.rb', line 41

def harmonic
  @harmonic
end

#streamObject

Returns the value of attribute stream.



42
43
44
# File 'lib/muse.rb', line 42

def stream
  @stream
end

Instance Method Details

#add_to_stream(str) ⇒ Object



121
122
123
# File 'lib/muse.rb', line 121

def add_to_stream(str)
  @stream += str
end

#chord(notes, options = {}) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/muse.rb', line 76

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

#frequency_of(step) ⇒ Object



72
73
74
# File 'lib/muse.rb', line 72

def frequency_of(step)
  440.0*(2**(step.to_f/12.0))
end

#note_data(note, octave = 3, options = {}) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/muse.rb', line 90

def note_data(note, octave=3, options={})
  stream = []
  if options
    beats  = options[:b].nil?  ? (@beats || 1) : options[:b].to_f
    volume = (options[:v].nil? ? 5 : options[:v].to_i) * 1000
    envelope = options[:a].nil? ? @envelope : 'default'
    harmonic = options[:h].nil? ? @harmonic : 'default'
  else
    beats, volume, envelope, harmonic = (@beats || 1), 5000, @envelope || 'default', @harmonic || 'default'
  end
  puts "[#{note}] -> beats : #{beats}, octave : #{octave} bpm: #{@bpm} envelope: #{envelope} harmonic : #{harmonic}"
  duration = ((60 * WavHeader::SAMPLE_RATE * beats)/@bpm)/WavHeader::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/WavHeader::SAMPLE_RATE) do |i|
    env = Envelope.send(envelope.to_sym,i, duration)
    har = Harmonic.send(harmonic.to_sym, freq * i)
    x = (env * volume * har).to_i
    stream << [x,x]
  end  
  return stream           
end

#notes(&block) ⇒ Object



68
69
70
# File 'lib/muse.rb', line 68

def notes(&block)
  instance_eval &block
end

#truncate_stream_by(num) ⇒ Object



117
118
119
# File 'lib/muse.rb', line 117

def truncate_stream_by(num)
  num.times {@stream.pop}
end