tsunami 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/tsunami.rb +31 -70
- data/tsunami.gemspec +5 -5
- metadata +3 -3
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ begin
|
|
11
11
|
gem.homepage = "http://github.com/zmack/tsunami"
|
12
12
|
gem.authors = ["Andrei Bocan"]
|
13
13
|
gem.add_dependency "rmagick", ">= 0"
|
14
|
-
gem.add_dependency "
|
14
|
+
gem.add_dependency "ruby-audio", ">= 0"
|
15
15
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
16
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
17
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/tsunami.rb
CHANGED
@@ -1,103 +1,64 @@
|
|
1
1
|
#this class was inspired by rjp's awesome http://github.com/rjp/cdcover
|
2
2
|
require 'rubygems'
|
3
3
|
require 'RMagick'
|
4
|
-
require '
|
4
|
+
require 'audio/sndfile'
|
5
5
|
|
6
6
|
class Tsunami
|
7
7
|
|
8
8
|
def initialize audio_file
|
9
|
-
|
10
|
-
@bitrate = '500'
|
11
|
-
@offset = 5
|
12
|
-
@audio_file = audio_file
|
9
|
+
@audio_file = Audio::Soundfile.new audio_file
|
13
10
|
end
|
14
11
|
|
15
|
-
def create_waveform(image_file, options)
|
16
|
-
@width = options[:width]
|
17
|
-
@height = options[:height]
|
12
|
+
def create_waveform(image_file, options = {})
|
13
|
+
@width = options[:width] || 100
|
14
|
+
@height = options[:height] || 50
|
18
15
|
|
19
16
|
buckets = fill_buckets
|
20
17
|
|
21
18
|
gc = build_graph buckets
|
22
19
|
|
23
|
-
|
24
|
-
canvas = Magick::Image.new(@width + 2*@offset, @height) { self.background_color = 'transparent' }
|
20
|
+
canvas = Magick::Image.new(@width, @height) { self.background_color = 'transparent' }
|
25
21
|
|
26
|
-
# canvas = Magick::ImageList.new('images/waveform.png')
|
27
22
|
gc.draw(canvas)
|
28
23
|
|
29
24
|
canvas.write(image_file)
|
30
25
|
end
|
31
26
|
|
32
|
-
#fill the buckets
|
33
27
|
def fill_buckets
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
bucket_size = (((bytes.size-1).to_f / @width)+0.5).to_i + 1
|
40
|
-
|
41
|
-
(0..bytes.total-1).each do |i|
|
42
|
-
value = bytes[i]
|
43
|
-
index = i/bucket_size
|
44
|
-
#minimum
|
45
|
-
buckets[index,0] = value if value < buckets[index,0]
|
46
|
-
#maximum
|
47
|
-
buckets[index,1] = value if value > buckets[index,1]
|
48
|
-
#total value
|
49
|
-
#buckets[index,2] += value
|
50
|
-
#count
|
51
|
-
#buckets[index,3] += 1
|
52
|
-
#negative total
|
53
|
-
#buckets[index,4] += value if value < 0
|
54
|
-
#positive total
|
55
|
-
#buckets[index,5] += value if value > 0
|
56
|
-
end
|
28
|
+
frames = @audio_file.read_float(@audio_file.frames).channel(0)
|
29
|
+
buckets = []
|
30
|
+
frame_index = 0
|
31
|
+
frames_per_pixel = frames.length / @width
|
57
32
|
|
58
|
-
|
59
|
-
|
33
|
+
frames.each do |frame|
|
34
|
+
index = frame_index / frames_per_pixel
|
35
|
+
buckets[index] ||= { :max => -1, :min => 1 }
|
60
36
|
|
61
|
-
|
62
|
-
|
63
|
-
|
37
|
+
buckets[index][:min] = frame if frame < buckets[index][:min]
|
38
|
+
|
39
|
+
buckets[index][:max] = frame if frame > buckets[index][:max]
|
64
40
|
|
65
|
-
|
66
|
-
def sox_get_bytes channels = 1
|
67
|
-
x=nil
|
68
|
-
# read a 16 bit linear raw PCM file
|
69
|
-
sox_command = [ 'sox', @audio_file, '-t', 'raw', '-r', @bitrate, '-c', channels.to_s, '-s', '-L', '-' ]
|
70
|
-
# we have to fork/exec to get a clean commandline
|
71
|
-
IO.popen('-') { |p|
|
72
|
-
if p.nil? then
|
73
|
-
$stderr.close
|
74
|
-
# raw 16 bit linear PCM one channel
|
75
|
-
exec *sox_command
|
76
|
-
end
|
77
|
-
x = p.read
|
78
|
-
}
|
79
|
-
if x.size == 0 then
|
80
|
-
puts "sox returned no data, command was\n> #{sox_command.join(' ')}"
|
81
|
-
exit 1
|
41
|
+
frame_index += 1
|
82
42
|
end
|
83
|
-
|
43
|
+
|
44
|
+
return buckets
|
84
45
|
end
|
85
46
|
|
86
|
-
#build the waveform graph
|
87
47
|
def build_graph buckets
|
88
48
|
gc = Magick::Draw.new
|
49
|
+
gc.stroke('red')
|
50
|
+
gc.stroke_width(1)
|
51
|
+
|
52
|
+
mid = @height/2
|
53
|
+
|
54
|
+
buckets.each_with_index do |bucket, i|
|
55
|
+
low = bucket[:min]
|
56
|
+
high = bucket[:max]
|
57
|
+
|
58
|
+
low_point = mid * ( 1 - low )
|
59
|
+
high_point = mid * ( 1 - high )
|
89
60
|
|
90
|
-
|
91
|
-
midpoint = @height/2
|
92
|
-
|
93
|
-
(0..(buckets.size/2)-1).each do |i|
|
94
|
-
low = buckets[i,0]
|
95
|
-
high = buckets[i,1]
|
96
|
-
gc.stroke('red')
|
97
|
-
gc.stroke_width(1)
|
98
|
-
low_point = midpoint+low/scale
|
99
|
-
high_point = midpoint+high/scale
|
100
|
-
gc.line(i+@offset, low_point.to_i, i+@offset, high_point.to_i)
|
61
|
+
gc.line(i, low_point.to_i, i, high_point.to_i)
|
101
62
|
end
|
102
63
|
|
103
64
|
return gc
|
data/tsunami.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tsunami}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrei Bocan"]
|
12
|
-
s.date = %q{2010-03-
|
12
|
+
s.date = %q{2010-03-10}
|
13
13
|
s.description = %q{For reals, it draws waveforms, man}
|
14
14
|
s.email = %q{zmaxor@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -44,16 +44,16 @@ Gem::Specification.new do |s|
|
|
44
44
|
|
45
45
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
46
|
s.add_runtime_dependency(%q<rmagick>, [">= 0"])
|
47
|
-
s.add_runtime_dependency(%q<
|
47
|
+
s.add_runtime_dependency(%q<ruby-audio>, [">= 0"])
|
48
48
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
49
49
|
else
|
50
50
|
s.add_dependency(%q<rmagick>, [">= 0"])
|
51
|
-
s.add_dependency(%q<
|
51
|
+
s.add_dependency(%q<ruby-audio>, [">= 0"])
|
52
52
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
53
53
|
end
|
54
54
|
else
|
55
55
|
s.add_dependency(%q<rmagick>, [">= 0"])
|
56
|
-
s.add_dependency(%q<
|
56
|
+
s.add_dependency(%q<ruby-audio>, [">= 0"])
|
57
57
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
58
58
|
end
|
59
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tsunami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Bocan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-10 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -23,7 +23,7 @@ dependencies:
|
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
26
|
+
name: ruby-audio
|
27
27
|
type: :runtime
|
28
28
|
version_requirement:
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|