Class: CarrierWave::AudioWaveform::Waveformer
- Inherits:
-
Object
- Object
- CarrierWave::AudioWaveform::Waveformer
- Defined in:
- lib/carrierwave/audio_waveform/waveformer.rb,
lib/carrierwave/audio_waveform/waveformer.rb
Defined Under Namespace
Classes: ArgumentError, Log, RuntimeError
Constant Summary collapse
- DefaultOptions =
{ :method => :peak, :width => 1800, :height => 280, :background_color => "#666666", :color => "#00ccff", :logger => nil, :type => :png }
- TransparencyMask =
"#00ff00"
- TransparencyAlternate =
in case the mask is the background color!
"#ffff00"
Instance Attribute Summary collapse
-
#source ⇒ Object
readonly
Returns the value of attribute source.
Class Method Summary collapse
-
.generate(source, options = {}) ⇒ Object
Generate a Waveform image at the given filename with the given options.
- .generate_image_filename(source, image_type) ⇒ Object
Instance Attribute Details
#source ⇒ Object (readonly)
Returns the value of attribute source.
22 23 24 |
# File 'lib/carrierwave/audio_waveform/waveformer.rb', line 22 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.
:height => The height (in pixels) of the final waveform image.
Default is 280.
:auto_width => msec per pixel. This will overwrite the width of the
final waveform image depending on the length of the audio file.
Example:
100 => 1 pixel per 100 msec; a one minute audio file will result in a width of 600 pixels
:background_color => Hex code of the background color of the generated
waveform image. Pass :transparent for transparent background.
Default is #666666 (gray).
:color => Hex code of the color to draw the waveform, or can pass
:transparent to render the waveform transparent (use w/ a solid
color background to achieve a "cutout" effect).
Default is #00ccff (cyan-ish).
:sample_width => Integer specifying the sample width. If this
is specified, there will be gaps (minimum of 1px wide, as specified
by :gap_width) between samples that are this wide in pixels.
Default is nil
Minimum is 1 (for anything other than nil)
:gap_width => Integer specifying the gap width. If sample_width
is specified, this will be the size of the gaps between samples in pixels.
Default is nil
Minimum is 1 (for anything other than nil, or when sample_width is present but gap_width is not)
:logger => IOStream to log progress to.
Example:
CarrierWave::AudioWaveform::Waveformer.generate("Kickstart My Heart.wav")
CarrierWave::AudioWaveform::Waveformer.generate("Kickstart My Heart.wav", :method => :rms)
CarrierWave::AudioWaveform::Waveformer.generate("Kickstart My Heart.wav", :color => "#ff00ff", :logger => $stdout)
82 83 84 85 86 87 88 89 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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/carrierwave/audio_waveform/waveformer.rb', line 82 def generate(source, ={}) = DefaultOptions.merge() filename = [:filename] || self.generate_image_filename(source, [:type]) raise ArgumentError.new("No source audio filename given, must be an existing sound file.") unless source raise ArgumentError.new("No destination filename given for waveform") unless filename raise RuntimeError.new("Source audio file '#{source}' not found.") unless File.exist?(source) old_source = source source = generate_wav_source(source) @log = Log.new([:logger]) @log.start! if [:auto_width] RubyAudio::Sound.open(source) do |audio| [:width] = (audio.info.length * 1000 / [:auto_width].to_i).ceil end end # 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, [:width], [:method]).collect do |frame| frame.inject(0.0) { |sum, peak| sum + peak } / frame.size end @log.timed("\nDrawing...") do # Don't remove the file until we're sure the # source was readable if File.exists?(filename) @log.out("Output file #{filename} encountered. Removing.") File.unlink(filename) end image = draw samples, if [:type] == :svg File.open(filename, 'w') do |f| f.puts image end else image.save filename end end if source != old_source @log.out("Removing temporary file at #{source}") FileUtils.rm(source) end @log.done!("Generated waveform '#{filename}'") filename end |
.generate_image_filename(source, image_type) ⇒ Object
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/carrierwave/audio_waveform/waveformer.rb', line 141 def generate_image_filename(source, image_type) ext = File.extname(source) source_file_path_without_extension = File.join File.dirname(source), File.basename(source, ext) if image_type == :svg "#{source_file_path_without_extension}.svg" else "#{source_file_path_without_extension}.png" end end |