waveform 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,6 +6,26 @@ combine it with jPlayer to make a soundcloud.com style MP3 player. It also
6
6
  comes with a handy CLI you can use to generate waveform images on the command
7
7
  line.
8
8
 
9
+ Installation
10
+ ============
11
+
12
+ Build libsndfile (http://www.mega-nerd.com/libsndfile/), or install it via `apt`
13
+ (`sudo apt-get install libsndfile1-dev`), or `libsndfile` in macports.
14
+
15
+ $ sudo gem install waveform
16
+
17
+ You might also want to, but don't have to:
18
+
19
+ $ sudo gem install oily_png
20
+
21
+ to make things a bit faster, and:
22
+
23
+ $ sudo apt-get install ffmpeg
24
+
25
+ if you want Waveform to convert non WAV audio for you.
26
+
27
+ _See Requirements below for more info_
28
+
9
29
  CLI Usage
10
30
  =========
11
31
 
@@ -23,11 +43,11 @@ There are some nifty options you can supply to switch things up:
23
43
  'peak' or 'rms'. 'peak' is probably what you want because it looks
24
44
  cooler, but 'rms' is closer to what you actually hear.
25
45
 
26
- There's also some less-nifty options:
46
+ There are also some less-nifty options:
27
47
 
28
48
  -q will generate your waveform without printing out a bunch of stuff.
29
49
  -h will prit out a help screen with all this info.
30
-
50
+
31
51
  Generating a small waveform "cut out" of a white background is pretty useful,
32
52
  then you can overlay it on a web-gradient on the website for your new startup
33
53
  and it will look really cool. To make it you could use:
@@ -68,18 +88,15 @@ format converters to convert your files to WAV before generating waveforms.
68
88
 
69
89
  Or you could be all retro and use WAV audio for everything in the first place.
70
90
 
71
- Some notes
72
- ==========
91
+ Tests
92
+ =====
73
93
 
74
- I threw the original version of this together in a day, and then made this
75
- second version in another couple. During those days I committed a cardinal sin
76
- and didn't write any tests, because decoding sound files and drawing pictures
77
- of them is more fun than writing tests. `ChunkyPNG` is cool though and will let
78
- you read raw pixel data, so it should be pretty easy to write some tests that
79
- actually read the pixel data of a waveform generated from a known source and
80
- ensure everything went according to plan. I'll do that later.
94
+ Tests require `contest` gem & `ffmpeg` (to test conversion), run via:
81
95
 
82
- Also, please refactor this/make it faster.
96
+ $ rake
97
+
98
+ Sample sound file is in Public Domain from soundbible.com.
99
+ <http://soundbible.com/1598-Electronic-Chime.html>
83
100
 
84
101
  References
85
102
  ==========
@@ -92,10 +109,22 @@ References
92
109
  License
93
110
  =======
94
111
 
95
- Copyright (c) 2010 Ben Alavi
96
-
97
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
98
-
99
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
100
-
101
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
112
+ Copyright (c) 2010-2011 Ben Alavi
113
+
114
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
115
+ this software and associated documentation files (the "Software"), to deal in
116
+ the Software without restriction, including without limitation the rights to
117
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
118
+ of the Software, and to permit persons to whom the Software is furnished to do
119
+ so, subject to the following conditions:
120
+
121
+ The above copyright notice and this permission notice shall be included in all
122
+ copies or substantial portions of the Software.
123
+
124
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
125
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
126
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
127
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
128
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
129
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
130
+ SOFTWARE.
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  task :default => :test
2
2
 
3
3
  task :test do
4
- system "cutest test/*.rb"
4
+ system "ruby test/*.rb"
5
5
  end
@@ -7,7 +7,7 @@ rescue LoadError
7
7
  end
8
8
 
9
9
  class Waveform
10
- VERSION = "0.0.1"
10
+ VERSION = "0.0.2"
11
11
 
12
12
  DefaultOptions = {
13
13
  :method => :peak,
@@ -0,0 +1,119 @@
1
+ require "contest"
2
+ require "fileutils"
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "waveform"))
4
+
5
+ class WaveformTest < Test::Unit::TestCase
6
+ def self.fixture(file)
7
+ File.join(File.dirname(__FILE__), "fixtures", file)
8
+ end
9
+ def fixture(file);self.class.fixture(file);end;
10
+
11
+ def self.output(file)
12
+ File.join(File.dirname(__FILE__), "output", file)
13
+ end
14
+ def output(file);self.class.output(file);end;
15
+
16
+ def open_png(file)
17
+ ChunkyPNG::Image.from_datastream(ChunkyPNG::Datastream.from_file(file))
18
+ end
19
+
20
+ puts "Removing existing testing artifacts..."
21
+ FileUtils.rm_rf(output("")) if File.exists?(output(""))
22
+ FileUtils.mkdir(output(""))
23
+ sample_wav = fixture("sample_mp3.wav")
24
+ FileUtils.rm(sample_wav) if File.exists?(sample_wav)
25
+
26
+ context "generating waveform" do
27
+ setup do
28
+ @waveform = Waveform.new(fixture("sample.wav"))
29
+ end
30
+
31
+ should "generate waveform from audio source" do
32
+ @waveform.generate(output("waveform_from_audio_source.png"))
33
+ assert File.exists?(output("waveform_from_audio_source.png"))
34
+
35
+ image = open_png(output("waveform_from_audio_source.png"))
36
+ assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), image[60, 120]
37
+ assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:background_color]), image[0, 0]
38
+ end
39
+
40
+ should "convert non-wav audio source before generation" do
41
+ Waveform.new(fixture("sample_mp3.mp3")).generate(output("from_mp3.png"))
42
+
43
+ assert File.exists?(output("from_mp3.png"))
44
+ end
45
+
46
+ should "log to given io" do
47
+ File.open(output("waveform.log"), "w") do |io|
48
+ Waveform.new(fixture("sample.wav"), io).generate(output("logged.png"))
49
+ end
50
+
51
+ assert_match /Generated waveform/, File.read(output("waveform.log"))
52
+ end
53
+
54
+ should "generate waveform using rms method instead of peak" do
55
+ @waveform.generate(output("peak.png"))
56
+ @waveform.generate(output("rms.png"), :method => :rms)
57
+ rms = open_png(output("rms.png"))
58
+ peak = open_png(output("peak.png"))
59
+
60
+ assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), peak[44, 43]
61
+ assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:background_color]), rms[44, 43]
62
+ assert_equal ChunkyPNG::Color.from_hex(Waveform::DefaultOptions[:color]), rms[60, 120]
63
+ end
64
+
65
+ should "generate waveform 900px wide" do
66
+ @waveform.generate(output("width-900.png"), :width => 900)
67
+ image = open_png(output("width-900.png"))
68
+
69
+ assert_equal 900, image.width
70
+ end
71
+
72
+ should "generate waveform 100px tall" do
73
+ @waveform.generate(output("height-100.png"), :height => 100)
74
+ image = open_png(output("height-100.png"))
75
+
76
+ assert_equal 100, image.height
77
+ end
78
+
79
+ should "generate waveform on red background color" do
80
+ @waveform.generate(output("background_color-#ff0000.png"), :background_color => "#ff0000")
81
+ image = open_png(output("background_color-#ff0000.png"))
82
+
83
+ assert_equal ChunkyPNG::Color.from_hex("#ff0000"), image[0, 0]
84
+ end
85
+
86
+ should "generate waveform on transparent background color" do
87
+ @waveform.generate(output("background_color-transparent.png"), :background_color => :transparent)
88
+ image = open_png(output("background_color-transparent.png"))
89
+
90
+ assert_equal ChunkyPNG::Color::TRANSPARENT, image[0, 0]
91
+ end
92
+
93
+ should "generate waveform in black foreground color" do
94
+ @waveform.generate(output("color-#000000.png"), :color => "#000000")
95
+ image = open_png(output("color-#000000.png"))
96
+
97
+ assert_equal ChunkyPNG::Color.from_hex("#000000"), image[60, 120]
98
+ end
99
+
100
+ should "generate waveform on red background color with transparent foreground cut-out" do
101
+ @waveform.generate(output("background_color-#ff0000+color-transparent.png"), :background_color => "#ff0000", :color => :transparent)
102
+ image = open_png(output("background_color-#ff0000+color-transparent.png"))
103
+
104
+ assert_equal ChunkyPNG::Color.from_hex("#ff0000"), image[0, 0]
105
+ assert_equal ChunkyPNG::Color::TRANSPARENT, image[60, 120]
106
+ end
107
+
108
+ # Bright green is our transparency mask color, so this test ensures that we
109
+ # don't destroy the image if the background also uses the transparency mask
110
+ # color
111
+ should "generate waveform with transparent foreground on bright green background" do
112
+ @waveform.generate(output("background_color-#00ff00+color-transparent.png"), :background_color => "#00ff00", :color => :transparent)
113
+ image = open_png(output("background_color-#00ff00+color-transparent.png"))
114
+
115
+ assert_equal ChunkyPNG::Color.from_hex("#00ff00"), image[0, 0]
116
+ assert_equal ChunkyPNG::Color::TRANSPARENT, image[60, 120]
117
+ end
118
+ end
119
+ end
@@ -23,4 +23,6 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_dependency "ruby-audio"
25
25
  s.add_dependency "chunky_png"
26
+
27
+ s.add_development_dependency "contest"
26
28
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: waveform
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ben Alavi
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-16 00:00:00 Z
13
+ date: 2011-07-18 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ruby-audio
@@ -34,6 +34,17 @@ dependencies:
34
34
  version: "0"
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: contest
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
37
48
  description: Generate waveform images from WAV and MP3 files -- in your code or via included CLI.
38
49
  email:
39
50
  - benalavi@gmail.com
@@ -48,6 +59,7 @@ files:
48
59
  - Rakefile
49
60
  - lib/waveform.rb
50
61
  - waveform.gemspec
62
+ - test/waveform_test.rb
51
63
  - bin/waveform
52
64
  homepage: http://github.com/benalavi/waveform
53
65
  licenses: []