waveform 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6ce38fd32793bd0e734bdd4a4d5fc35d1b23fd61bc7b3336b7cf2e4a3fedfe76
4
+ data.tar.gz: ed342c1ad243cab828bd48e85ded1d68ef837c5ca7a845779a81cc1d0f1debc5
5
+ SHA512:
6
+ metadata.gz: 5de7b29d02d0d8fc2890c4dd6e685e3140067c7b24bc48d3a97327d1c3b2dbb75fd386878da0f31035a7f9ba567f1293003d3ccb4119732fb717fedf412e7b3c
7
+ data.tar.gz: 3c02222c54dbc8561b7ddf5c41c47caebe93e45d8e3e298a32d2737d9e04152b256da595fdcb740a47aeb192f1d8bf30a5a4295aff364b70868f4ba774903aa0
data/README.md CHANGED
@@ -14,10 +14,12 @@ Then:
14
14
 
15
15
  $ sudo gem install waveform
16
16
 
17
- Image creation depends on `chunky_png`, which has a faster native library called `oily_png` which will be used if availble.
17
+ Image creation depends on `chunky_png`, which has a faster native library called `oily_png` which will be used if available.
18
18
 
19
19
  $ sudo gem install oily_png
20
20
 
21
+ NOTE: If `ruby-audio` fails to compile and you have `libsndfile` available, it may be because of this: http://stackoverflow.com/questions/19919640/ruby-audio-1-6-1-install-error-with-installed-libsndfile-1-0-25
22
+
21
23
  CLI Usage
22
24
  =========
23
25
 
@@ -76,7 +78,7 @@ Tests
76
78
  =====
77
79
 
78
80
  $ rake
79
-
81
+
80
82
  If you get an error about not being able to find ruby-audio gem (and you have ruby-audio gem) you might need to let rake know how to load your gems -- if you're using rubygems:
81
83
 
82
84
  $ export RUBYOPT="rubygems"
@@ -87,6 +89,10 @@ Sample sound file used in tests is in the Public Domain from soundbible.com: <ht
87
89
  Changes
88
90
  =======
89
91
 
92
+ 0.1.3
93
+ -----
94
+ * Update for ruby 3.2 (replace `File.exists?` w/ `File.exist?`)
95
+
90
96
  0.1.2
91
97
  -----
92
98
  * Added more helpful deprecation notice for non-WAV audio files
data/bin/waveform CHANGED
@@ -4,9 +4,9 @@ require "optparse"
4
4
 
5
5
  options = Waveform::DefaultOptions
6
6
  optparse = OptionParser.new do |o|
7
- o.banner = "Usage: waveform [options] source_audio [ouput.png]"
7
+ o.banner = "Usage: waveform [options] source_audio [output.png]"
8
8
  o.version = Waveform::VERSION
9
-
9
+
10
10
  o.on("-W", "--width WIDTH", "Width (in pixels) of generated waveform image -- Default #{Waveform::DefaultOptions[:width]}.") do |width|
11
11
  options[:width] = width.to_i
12
12
  end
@@ -15,6 +15,10 @@ optparse = OptionParser.new do |o|
15
15
  options[:height] = height.to_i
16
16
  end
17
17
 
18
+ o.on("-a", "--autowidth MSEC", "Sets the width of the waveform based on the audio length, using a resolution of the given msec per pixel.") do |msec|
19
+ options[:auto_width] = msec.to_i
20
+ end
21
+
18
22
  o.on("-c", "--color COLOR", "Color (hex code) to draw the waveform. Can also pass 'transparent' to cut it out of the background -- Default #{Waveform::DefaultOptions[:color]}.") do |color|
19
23
  if color == "transparent"
20
24
  options[:color] = :transparent
@@ -41,7 +45,7 @@ optparse = OptionParser.new do |o|
41
45
  end
42
46
 
43
47
  options[:force] = false
44
- o.on("-F", "--force", "Force generationg of waveform if file exists") do
48
+ o.on("-F", "--force", "Force generation of waveform if file exists") do
45
49
  options[:force] = true
46
50
  end
47
51
 
@@ -1,3 +1,3 @@
1
1
  class Waveform
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/waveform.rb CHANGED
@@ -17,38 +17,43 @@ class Waveform
17
17
  :force => false,
18
18
  :logger => nil
19
19
  }
20
-
20
+
21
21
  TransparencyMask = "#00ff00"
22
22
  TransparencyAlternate = "#ffff00" # in case the mask is the background color!
23
-
23
+
24
24
  attr_reader :source
25
-
25
+
26
26
  # Scope these under Waveform so you can catch the ones generated by just this
27
27
  # class.
28
28
  class RuntimeError < ::RuntimeError;end;
29
29
  class ArgumentError < ::ArgumentError;end;
30
-
31
- class << self
30
+
31
+ class << self
32
32
  # Generate a Waveform image at the given filename with the given options.
33
- #
33
+ #
34
34
  # Available options (all optional) are:
35
- #
35
+ #
36
36
  # :method => The method used to read sample frames, available methods
37
37
  # are peak and rms. peak is probably what you're used to seeing, it uses
38
38
  # the maximum amplitude per sample to generate the waveform, so the
39
39
  # waveform looks more dynamic. RMS gives a more fluid waveform and
40
40
  # probably more accurately reflects what you hear, but isn't as
41
41
  # pronounced (typically).
42
- #
42
+ #
43
43
  # Can be :rms or :peak
44
44
  # Default is :peak.
45
- #
45
+ #
46
46
  # :width => The width (in pixels) of the final waveform image.
47
47
  # Default is 1800.
48
- #
48
+ #
49
49
  # :height => The height (in pixels) of the final waveform image.
50
50
  # Default is 280.
51
- #
51
+ #
52
+ # :auto_width => msec per pixel. This will overwrite the width of the
53
+ # final waveform image depending on the length of the audio file.
54
+ # Example:
55
+ # 100 => 1 pixel per 100 msec; a one minute audio file will result in a width of 600 pixels
56
+ #
52
57
  # :background_color => Hex code of the background color of the generated
53
58
  # waveform image.
54
59
  # Default is #666666 (gray).
@@ -59,7 +64,7 @@ class Waveform
59
64
  # Default is #00ccff (cyan-ish).
60
65
  #
61
66
  # :force => Force generation of waveform, overwriting WAV or PNG file.
62
- #
67
+ #
63
68
  # :logger => IOStream to log progress to.
64
69
  #
65
70
  # Example:
@@ -69,15 +74,21 @@ class Waveform
69
74
  #
70
75
  def generate(source, filename, options={})
71
76
  options = DefaultOptions.merge(options)
72
-
77
+
73
78
  raise ArgumentError.new("No source audio filename given, must be an existing sound file.") unless source
74
79
  raise ArgumentError.new("No destination filename given for waveform") unless filename
75
80
  raise RuntimeError.new("Source audio file '#{source}' not found.") unless File.exist?(source)
76
- raise RuntimeError.new("Destination file #{filename} exists. Use --force if you want to automatically remove it.") if File.exists?(filename) && !options[:force] === true
81
+ raise RuntimeError.new("Destination file #{filename} exists. Use --force if you want to automatically remove it.") if File.exist?(filename) && !options[:force] === true
77
82
 
78
83
  @log = Log.new(options[:logger])
79
84
  @log.start!
80
-
85
+
86
+ if options[:auto_width]
87
+ RubyAudio::Sound.open(source) do |audio|
88
+ options[:width] = (audio.info.length * 1000 / options[:auto_width].to_i).ceil
89
+ end
90
+ end
91
+
81
92
  # Frames gives the amplitudes for each channel, for our waveform we're
82
93
  # saying the "visual" amplitude is the average of the amplitude across all
83
94
  # the channels. This might be a little weird w/ the "peak" method if the
@@ -87,30 +98,30 @@ class Waveform
87
98
  samples = frames(source, options[:width], options[:method]).collect do |frame|
88
99
  frame.inject(0.0) { |sum, peak| sum + peak } / frame.size
89
100
  end
90
-
101
+
91
102
  @log.timed("\nDrawing...") do
92
103
  # Don't remove the file even if force is true until we're sure the
93
104
  # source was readable
94
- if File.exists?(filename) && options[:force] === true
105
+ if File.exist?(filename) && options[:force] === true
95
106
  @log.out("Output file #{filename} encountered. Removing.")
96
107
  File.unlink(filename)
97
108
  end
98
-
109
+
99
110
  image = draw samples, options
100
111
  image.save filename
101
112
  end
102
-
103
- @log.done!("Generated waveform '#{filename}'")
113
+
114
+ @log.done!("Generated waveform '#{filename}'")
104
115
  end
105
-
116
+
106
117
  private
107
-
118
+
108
119
  # Returns a sampling of frames from the given RubyAudio::Sound using the
109
120
  # given method the sample size is determined by the given pixel width --
110
121
  # we want one sample frame per horizontal pixel.
111
122
  def frames(source, width, method = :peak)
112
123
  raise ArgumentError.new("Unknown sampling method #{method}") unless [ :peak, :rms ].include?(method)
113
-
124
+
114
125
  frames = []
115
126
 
116
127
  RubyAudio::Sound.open(source) do |audio|
@@ -125,19 +136,19 @@ class Waveform
125
136
  end
126
137
  end
127
138
  end
128
-
139
+
129
140
  frames
130
141
  rescue RubyAudio::Error => e
131
142
  raise e unless e.message == "File contains data in an unknown format."
132
143
  raise Waveform::RuntimeError.new("Source audio file #{source} could not be read by RubyAudio library -- Hint: non-WAV files are no longer supported, convert to WAV first using something like ffmpeg (RubyAudio: #{e.message})")
133
144
  end
134
-
145
+
135
146
  # Draws the given samples using the given options, returns a ChunkyPNG::Image.
136
- def draw(samples, options)
147
+ def draw(samples, options)
137
148
  image = ChunkyPNG::Image.new(options[:width], options[:height],
138
149
  options[:background_color] == :transparent ? ChunkyPNG::Color::TRANSPARENT : options[:background_color]
139
150
  )
140
-
151
+
141
152
  if options[:color] == :transparent
142
153
  color = transparent = ChunkyPNG::Color.from_hex(
143
154
  # Have to do this little bit because it's possible the color we were
@@ -152,7 +163,7 @@ class Waveform
152
163
  # Calling "zero" the middle of the waveform, like there's positive and
153
164
  # negative amplitude
154
165
  zero = options[:height] / 2.0
155
-
166
+
156
167
  samples.each_with_index do |sample, x|
157
168
  # Half the amplitude goes above zero, half below
158
169
  amplitude = sample * options[:height].to_f / 2.0
@@ -160,7 +171,7 @@ class Waveform
160
171
  # go haywire.
161
172
  image.line(x, (zero - amplitude).round, x, (zero + amplitude).round, color)
162
173
  end
163
-
174
+
164
175
  # Simple transparency masking, it just loops over every pixel and makes
165
176
  # ones which match the transparency mask color completely clear.
166
177
  if transparent
@@ -170,10 +181,10 @@ class Waveform
170
181
  end
171
182
  end
172
183
  end
173
-
184
+
174
185
  image
175
186
  end
176
-
187
+
177
188
  # Returns an array of the peak of each channel for the given collection of
178
189
  # frames -- the peak is individual to the channel, and the returned collection
179
190
  # of peaks are not (necessarily) from the same frame(s).
@@ -194,10 +205,10 @@ class Waveform
194
205
  end
195
206
  rms_frame
196
207
  end
197
-
208
+
198
209
  # Returns the peak voltage reached on the given channel in the given collection
199
210
  # of frames.
200
- #
211
+ #
201
212
  # TODO: Could lose some resolution and only sample every other frame, would
202
213
  # likely still generate the same waveform as the waveform is so comparitively
203
214
  # low resolution to the original input (in most cases), and would increase
@@ -223,7 +234,7 @@ end
223
234
  class Waveform
224
235
  # A simple class for logging + benchmarking, nice to have good feedback on a
225
236
  # long batch operation.
226
- #
237
+ #
227
238
  # There's probably 10,000,000 other bechmarking classes, but writing this was
228
239
  # easier than using Google.
229
240
  class Log
@@ -245,7 +256,7 @@ class Waveform
245
256
  end
246
257
 
247
258
  # Starts a new benchmark clock and returns the index of the new clock.
248
- #
259
+ #
249
260
  # If .start! is called again before .end! then the time returned will be
250
261
  # the elapsed time from the next call to start!, and calling .end! again
251
262
  # will return the time from *this* call to start! (that is, the clocks are
@@ -279,4 +290,4 @@ class Waveform
279
290
  done!
280
291
  end
281
292
  end
282
- end
293
+ end
@@ -4,14 +4,14 @@ require "test/unit"
4
4
  require "fileutils"
5
5
 
6
6
  module Helpers
7
- def fixture(file)
7
+ def fixture_asset(file)
8
8
  File.join(File.dirname(__FILE__), "fixtures", file)
9
9
  end
10
-
10
+
11
11
  def output(file)
12
12
  File.join(File.dirname(__FILE__), "output", file)
13
13
  end
14
-
14
+
15
15
  def open_png(file)
16
16
  ChunkyPNG::Image.from_datastream(ChunkyPNG::Datastream.from_file(file))
17
17
  end
@@ -26,19 +26,19 @@ class WaveformTest < Test::Unit::TestCase
26
26
  Dir[output("*.*")].each{ |f| FileUtils.rm(f) }
27
27
  FileUtils.mkdir_p(output(""))
28
28
  end
29
-
29
+
30
30
  def test_generates_waveform
31
- Waveform.generate(fixture("sample.wav"), output("waveform_from_audio_source.png"))
32
- assert File.exists?(output("waveform_from_audio_source.png"))
33
-
31
+ Waveform.generate(fixture_asset("sample.wav"), output("waveform_from_audio_source.png"))
32
+ assert File.exist?(output("waveform_from_audio_source.png"))
33
+
34
34
  image = open_png(output("waveform_from_audio_source.png"))
35
35
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), image[60, 120]
36
36
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:background_color]), image[0, 0]
37
37
  end
38
-
38
+
39
39
  def test_generates_waveform_from_mono_audio_source_via_peak
40
- Waveform.generate(fixture("mono_sample.wav"), output("waveform_from_mono_audio_source_via_peak.png"))
41
- assert File.exists?(output("waveform_from_mono_audio_source_via_peak.png"))
40
+ Waveform.generate(fixture_asset("mono_sample.wav"), output("waveform_from_mono_audio_source_via_peak.png"))
41
+ assert File.exist?(output("waveform_from_mono_audio_source_via_peak.png"))
42
42
 
43
43
  image = open_png(output("waveform_from_mono_audio_source_via_peak.png"))
44
44
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), image[60, 120]
@@ -46,126 +46,134 @@ class WaveformTest < Test::Unit::TestCase
46
46
  end
47
47
 
48
48
  def test_generates_waveform_from_mono_audio_source_via_rms
49
- Waveform.generate(fixture("mono_sample.wav"), output("waveform_from_mono_audio_source_via_rms.png"), :method => :rms)
50
- assert File.exists?(output("waveform_from_mono_audio_source_via_rms.png"))
49
+ Waveform.generate(fixture_asset("mono_sample.wav"), output("waveform_from_mono_audio_source_via_rms.png"), :method => :rms)
50
+ assert File.exist?(output("waveform_from_mono_audio_source_via_rms.png"))
51
51
 
52
52
  image = open_png(output("waveform_from_mono_audio_source_via_rms.png"))
53
53
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), image[60, 120]
54
54
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:background_color]), image[0, 0]
55
55
  end
56
-
56
+
57
57
  def test_logs_to_given_io
58
58
  File.open(output("waveform.log"), "w") do |io|
59
- Waveform.generate(fixture("sample.wav"), output("logged.png"), :logger => io)
59
+ Waveform.generate(fixture_asset("sample.wav"), output("logged.png"), :logger => io)
60
60
  end
61
-
61
+
62
62
  assert_match /Generated waveform/, File.read(output("waveform.log"))
63
63
  end
64
-
64
+
65
65
  def test_uses_rms_instead_of_peak
66
- Waveform.generate(fixture("sample.wav"), output("peak.png"))
67
- Waveform.generate(fixture("sample.wav"), output("rms.png"), :method => :rms)
66
+ Waveform.generate(fixture_asset("sample.wav"), output("peak.png"))
67
+ Waveform.generate(fixture_asset("sample.wav"), output("rms.png"), :method => :rms)
68
68
 
69
69
  rms = open_png(output("rms.png"))
70
70
  peak = open_png(output("peak.png"))
71
-
71
+
72
72
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), peak[44, 43]
73
73
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:background_color]), rms[44, 43]
74
74
  assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), rms[60, 120]
75
75
  end
76
-
76
+
77
77
  def test_is_900px_wide
78
- Waveform.generate(fixture("sample.wav"), output("width-900.png"), :width => 900)
79
-
78
+ Waveform.generate(fixture_asset("sample.wav"), output("width-900.png"), :width => 900)
79
+
80
80
  image = open_png(output("width-900.png"))
81
-
81
+
82
82
  assert_equal 900, image.width
83
83
  end
84
-
84
+
85
85
  def test_is_100px_tall
86
- Waveform.generate(fixture("sample.wav"), output("height-100.png"), :height => 100)
87
-
86
+ Waveform.generate(fixture_asset("sample.wav"), output("height-100.png"), :height => 100)
87
+
88
88
  image = open_png(output("height-100.png"))
89
-
89
+
90
90
  assert_equal 100, image.height
91
91
  end
92
-
92
+
93
+ def test_has_auto_width
94
+ Waveform.generate(fixture_asset("sample.wav"), output("width-auto.png"), :auto_width => 10)
95
+
96
+ image = open_png(output("width-auto.png"))
97
+
98
+ assert_equal 209, image.width
99
+ end
100
+
93
101
  def test_has_red_background_color
94
- Waveform.generate(fixture("sample.wav"), output("background_color-#ff0000.png"), :background_color => "#ff0000")
95
-
102
+ Waveform.generate(fixture_asset("sample.wav"), output("background_color-#ff0000.png"), :background_color => "#ff0000")
103
+
96
104
  image = open_png(output("background_color-#ff0000.png"))
97
-
105
+
98
106
  assert_equal ChunkyPNG::Color.from_hex("#ff0000"), image[0, 0]
99
107
  end
100
-
108
+
101
109
  def test_has_transparent_background_color
102
- Waveform.generate(fixture("sample.wav"), output("background_color-transparent.png"), :background_color => :transparent)
103
-
110
+ Waveform.generate(fixture_asset("sample.wav"), output("background_color-transparent.png"), :background_color => :transparent)
111
+
104
112
  image = open_png(output("background_color-transparent.png"))
105
-
113
+
106
114
  assert_equal ChunkyPNG::Color::TRANSPARENT, image[0, 0]
107
115
  end
108
-
116
+
109
117
  def test_has_black_foreground_color
110
- Waveform.generate(fixture("sample.wav"), output("color-#000000.png"), :color => "#000000")
111
-
118
+ Waveform.generate(fixture_asset("sample.wav"), output("color-#000000.png"), :color => "#000000")
119
+
112
120
  image = open_png(output("color-#000000.png"))
113
-
121
+
114
122
  assert_equal ChunkyPNG::Color.from_hex("#000000"), image[60, 120]
115
123
  end
116
-
124
+
117
125
  def test_has_red_background_color_with_transparent_foreground_cutout
118
- Waveform.generate(fixture("sample.wav"), output("background_color-#ff0000+color-transparent.png"), :background_color => "#ff0000", :color => :transparent)
119
-
126
+ Waveform.generate(fixture_asset("sample.wav"), output("background_color-#ff0000+color-transparent.png"), :background_color => "#ff0000", :color => :transparent)
127
+
120
128
  image = open_png(output("background_color-#ff0000+color-transparent.png"))
121
-
129
+
122
130
  assert_equal ChunkyPNG::Color.from_hex("#ff0000"), image[0, 0]
123
131
  assert_equal ChunkyPNG::Color::TRANSPARENT, image[60, 120]
124
132
  end
125
-
133
+
126
134
  # Bright green is our transparency mask color, so this test ensures that we
127
135
  # don't destroy the image if the background also uses the transparency mask
128
136
  # color
129
137
  def test_has_transparent_foreground_on_bright_green_background
130
- Waveform.generate(fixture("sample.wav"), output("background_color-#00ff00+color-transparent.png"), :background_color => "#00ff00", :color => :transparent)
131
-
138
+ Waveform.generate(fixture_asset("sample.wav"), output("background_color-#00ff00+color-transparent.png"), :background_color => "#00ff00", :color => :transparent)
139
+
132
140
  image = open_png(output("background_color-#00ff00+color-transparent.png"))
133
-
141
+
134
142
  assert_equal ChunkyPNG::Color.from_hex("#00ff00"), image[0, 0]
135
143
  assert_equal ChunkyPNG::Color::TRANSPARENT, image[60, 120]
136
144
  end
137
-
145
+
138
146
  def test_raises_error_if_not_given_readable_audio_source
139
147
  assert_raise(Waveform::RuntimeError) do
140
- Waveform.generate(fixture("sample.txt"), output("shouldnt_exist.png"))
148
+ Waveform.generate(fixture_asset("sample.txt"), output("shouldnt_exist.png"))
141
149
  end
142
150
  end
143
-
151
+
144
152
  def test_overwrites_existing_waveform_if_force_is_true_and_file_exists
145
153
  FileUtils.touch output("overwritten.png")
146
154
 
147
- Waveform.generate(fixture("sample.wav"), output("overwritten.png"), :force => true)
155
+ Waveform.generate(fixture_asset("sample.wav"), output("overwritten.png"), :force => true)
148
156
  end
149
157
 
150
158
  def test_raises_exception_if_waveform_exists_and_force_is_false
151
159
  FileUtils.touch output("wont_be_overwritten.png")
152
-
160
+
153
161
  assert_raises Waveform::RuntimeError do
154
- Waveform.generate(fixture("sample.wav"), output("wont_be_overwritten.png"), :force => false)
162
+ Waveform.generate(fixture_asset("sample.wav"), output("wont_be_overwritten.png"), :force => false)
155
163
  end
156
164
  end
157
-
165
+
158
166
  def test_raises_exception_if_waveform_exists
159
167
  FileUtils.touch output("wont_be_overwritten_by_default.png")
160
-
168
+
161
169
  assert_raises Waveform::RuntimeError do
162
- Waveform.generate(fixture("sample.wav"), output("wont_be_overwritten_by_default.png"))
170
+ Waveform.generate(fixture_asset("sample.wav"), output("wont_be_overwritten_by_default.png"))
163
171
  end
164
172
  end
165
-
173
+
166
174
  def test_raises_deprecation_exception_if_ruby_audio_fails_to_read_source_file
167
175
  begin
168
- Waveform.generate(fixture("sample.txt"), output("shouldnt_exist.png"))
176
+ Waveform.generate(fixture_asset("sample.txt"), output("shouldnt_exist.png"))
169
177
  rescue Waveform::RuntimeError => e
170
178
  assert_match /Hint: non-WAV files are no longer supported, convert to WAV first using something like ffmpeg/, e.message
171
179
  end
metadata CHANGED
@@ -1,38 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waveform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 0.1.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ben Alavi
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-29 00:00:00.000000000 Z
11
+ date: 2023-03-22 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ruby-audio
16
- requirement: &70419740 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70419740
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: chunky_png
27
- requirement: &70419500 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *70419500
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  description: Generate waveform images from audio files. Includes a Waveform class
37
42
  for generating waveforms in your code as well as a simple command-line program called
38
43
  'waveform' for generating on the command line.
@@ -45,33 +50,31 @@ extra_rdoc_files: []
45
50
  files:
46
51
  - README.md
47
52
  - Rakefile
48
- - lib/waveform/version.rb
53
+ - bin/waveform
49
54
  - lib/waveform.rb
50
- - waveform.gemspec
55
+ - lib/waveform/version.rb
51
56
  - test/waveform_test.rb
52
- - bin/waveform
57
+ - waveform.gemspec
53
58
  homepage: http://github.com/benalavi/waveform
54
59
  licenses: []
55
- post_install_message:
60
+ metadata: {}
61
+ post_install_message:
56
62
  rdoc_options: []
57
63
  require_paths:
58
64
  - lib
59
65
  required_ruby_version: !ruby/object:Gem::Requirement
60
- none: false
61
66
  requirements:
62
- - - ! '>='
67
+ - - ">="
63
68
  - !ruby/object:Gem::Version
64
69
  version: '0'
65
70
  required_rubygems_version: !ruby/object:Gem::Requirement
66
- none: false
67
71
  requirements:
68
- - - ! '>='
72
+ - - ">="
69
73
  - !ruby/object:Gem::Version
70
74
  version: '0'
71
75
  requirements: []
72
- rubyforge_project:
73
- rubygems_version: 1.8.11
74
- signing_key:
75
- specification_version: 3
76
+ rubygems_version: 3.3.26
77
+ signing_key:
78
+ specification_version: 4
76
79
  summary: Generate waveform images from audio files
77
80
  test_files: []