class Mml2wav::Wave

Public Class Methods

sine_wave(frequency, sampling_rate, sec, amplitude=0.5) click to toggle source
# File lib/mml2wav/wave.rb, line 65
def sine_wave(frequency, sampling_rate, sec, amplitude=0.5)
  max = sampling_rate * sec
  if frequency == 0
    return Array.new(max) { 0.0 }
  end
  base_x = 2.0 * Math::PI * frequency / sampling_rate
  1.upto(max).collect do |n|
    amplitude * Math.sin(base_x * n)
  end
end
write(soundses, options={}) click to toggle source
# File lib/mml2wav/wave.rb, line 9
def write(soundses, options={})
  if soundses.is_a?(String)
    n_channels = :mono
    soundses = [soundses]
    size = 1
  elsif soundses.size == 1
    n_channels = :mono
    size = 1
  elsif soundses.size == 2
    n_channels = :stereo
    size = soundses.size
  else
    n_channels = soundses.size
    size = soundses.size
  end
  output_path = options[:output] || "doremi.wav"
  sampling_rate = options[:sampling_rate] || 22050

  format = Format.new(n_channels, :pcm_8, sampling_rate)
  Writer.new(output_path, format) do |writer|
    buffer_format = Format.new(n_channels, :float, sampling_rate)
    infoses = []
    soundses.each do |sounds|
      infoses << Parser.new(sounds, sampling_rate, options).parse
    end
    waves = Array.new(soundses.size) { [] }
    0.upto(infoses.collect {|info| info.size }.max) do |infos_index|
      infoses.each_with_index do |infos, infoses_index|
        next unless infos[infos_index]
        wave = sine_wave(infos[infos_index][:frequency],
                         infos[infos_index][:sampling_rate],
                         infos[infos_index][:sec],
                         infos[infos_index][:amplitude])
        waves[infoses_index] += wave
      end
      break if waves.all? {|wave| wave.empty? }
      buffer_size = waves.reject {|wave| wave.empty? }.collect(&:size).min
      break unless buffer_size
      samples = []
      buffer_size.times do
        sample = []
        waves.each do |wave|
          if wave.first
            sample << wave.shift
          else
            sample << 0.0
          end
        end
        samples << sample
      end
      buffer = Buffer.new(samples, buffer_format)
      writer.write(buffer)
    end
  end
end