Class: Waveformjson

Inherits:
Object
  • Object
show all
Defined in:
lib/waveformjson.rb,
lib/waveformjson.rb,
lib/waveformjson/version.rb

Defined Under Namespace

Classes: Log

Constant Summary collapse

DefaultOptions =
{
  :method => :peak,
  :width => 1800,
  :logger => nil
}
VERSION =
"0.0.2"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#sourceObject (readonly)

Returns the value of attribute source.



12
13
14
# File 'lib/waveformjson.rb', line 12

def source
  @source
end

Class Method Details

.generate(source, options = {}) ⇒ Object

Generate a Waveform image at the given filename with the given options.

Available options (all optional) are:

:method => The method used to read sample frames, available methods
  are peak and rms. peak is probably what you're used to seeing, it uses
  the maximum amplitude per sample to generate the waveform, so the
  waveform looks more dynamic. RMS gives a more fluid waveform and
  probably more accurately reflects what you hear, but isn't as
  pronounced (typically).

  Can be :rms or :peak
  Default is :peak.

:width => The width (in pixels) of the final waveform image.
  Default is 1800.

:logger => IOStream to log progress to.

Example:

Waveformjson.generate("Kickstart My Heart.wav")
Waveformjson.generate("Kickstart My Heart.wav", :method => :rms)
Waveformjson.generate("Kickstart My Heart.wav", :logger => $stdout)

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/waveformjson.rb', line 39

def generate(source, options={})
  options = DefaultOptions.merge(options)
  
  raise ArgumentError.new("No source audio filename given, must be an existing sound file.") unless source
  raise RuntimeError.new("Source audio file '#{source}' not found.") unless File.exist?(source)

  @log = Log.new(options[:logger])
  @log.start!
  
  # Frames gives the amplitudes for each channel, for our waveform we're
  # saying the "visual" amplitude is the average of the amplitude across all
  # the channels. This might be a little weird w/ the "peak" method if the
  # frames are very wide (i.e. the image width is very small) -- I *think*
  # the larger the frames are, the more "peaky" the waveform should get,
  # perhaps to the point of inaccurately reflecting the actual sound.
  samples = frames(source, options[:width], options[:method]).collect do |frame|
    frame.inject(0.0) { |sum, peak| sum + peak } / frame.size
  end

  samples
end