tsunami 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -0,0 +1,37 @@
1
+ require 'forwardable'
2
+
3
+ class Tsunami
4
+ class Bucket
5
+ extend ::Forwardable
6
+
7
+ def_delegator :@values, :each, :each_value
8
+ def_delegator :@values, :each_with_index, :each_value_with_index
9
+
10
+ attr_reader :width, :height, :frames
11
+
12
+ def initialize(frames, width, height)
13
+ @values = []
14
+ @frames = frames
15
+ @width = width
16
+ @height = height
17
+ end
18
+
19
+ def set(frame, value)
20
+ values(frame)[:min] = value if value < values(frame)[:min]
21
+
22
+ values(frame)[:max] = value if value > values(frame)[:max]
23
+ end
24
+
25
+ def frames_per_pixel
26
+ @frames_per_pixel ||= frames / @width
27
+ end
28
+
29
+ def index(frame)
30
+ frame / frames_per_pixel
31
+ end
32
+
33
+ def values(frame)
34
+ @values[index(frame)] ||= { :max => -1, :min => 1 }
35
+ end
36
+ end
37
+ end
data/lib/tsunami.rb CHANGED
@@ -3,6 +3,7 @@ require 'rubygems'
3
3
  require 'RMagick'
4
4
  require 'ruby-audio'
5
5
  require 'buffer_ext.rb'
6
+ require 'tsunami/bucket'
6
7
 
7
8
  class Tsunami
8
9
 
@@ -11,26 +12,49 @@ class Tsunami
11
12
  end
12
13
 
13
14
  def create_waveform(image_file, options = {})
14
- @width = options[:width] || 100
15
- @height = options[:height] || 50
15
+ dimensions = {
16
+ :width => options[:width] || 100,
17
+ :height => options[:height] || 50
18
+ }
16
19
 
17
- buckets = fill_buckets
20
+ versions = {
21
+ image_file => dimensions
22
+ }
18
23
 
19
- gc = build_graph buckets
24
+ create_waveforms(versions)
25
+ end
26
+
27
+ def create_waveforms(versions)
28
+ create_buckets versions
29
+ fill_buckets
30
+
31
+ @buckets.each do |key, bucket|
32
+ canvas = draw_waveform_from_bucket(bucket)
33
+ canvas.write(key.to_s)
34
+ end
35
+ end
36
+
37
+ def draw_waveform_from_bucket(bucket)
38
+ gc = build_graph bucket
20
39
 
21
- canvas = Magick::Image.new(@width, @height) { self.background_color = 'transparent' }
40
+ canvas = Magick::Image.new(bucket.width, bucket.height) { self.background_color = 'transparent' }
22
41
 
23
42
  gc.draw(canvas)
24
43
 
25
- canvas.write(image_file)
44
+ canvas
45
+ end
46
+
47
+ def create_buckets(versions)
48
+ @buckets = {}
49
+ versions.each_key do |key|
50
+ @buckets[key] = Bucket.new(total_frames, versions[key][:width], versions[key][:height])
51
+ end
26
52
  end
27
53
 
28
54
  def fill_buckets
29
55
  @audio_file.seek(0,0)
30
- frames = @audio_file.read("float", @audio_file.info.frames)
31
- buckets = []
56
+ frames = @audio_file.read("float", total_frames)
32
57
  frame_index = 0
33
- frames_per_pixel = frames.size / @width
34
58
 
35
59
  frames.each do |channel_frames|
36
60
  if @audio_file.info.channels > 1
@@ -39,29 +63,22 @@ class Tsunami
39
63
  frame = channel_frames
40
64
  end
41
65
 
42
- index = frame_index / frames_per_pixel
43
- buckets[index] ||= { :max => -1, :min => 1 }
44
-
45
- buckets[index][:min] = frame if frame < buckets[index][:min]
46
-
47
- buckets[index][:max] = frame if frame > buckets[index][:max]
66
+ @buckets.values.each { |b| b.set(frame_index, frame) }
48
67
 
49
68
  frame_index += 1
50
69
  end
51
-
52
- return buckets[0, @width]
53
70
  end
54
71
 
55
- def build_graph buckets
72
+ def build_graph bucket
56
73
  gc = Magick::Draw.new
57
74
  gc.stroke('red')
58
75
  gc.stroke_width(1)
59
76
 
60
- mid = @height/2
77
+ mid = bucket.height / 2
61
78
 
62
- buckets.each_with_index do |bucket, i|
63
- low = bucket[:min]
64
- high = bucket[:max]
79
+ bucket.each_value_with_index do |values, i|
80
+ low = values[:min]
81
+ high = values[:max]
65
82
 
66
83
  low_point = mid * ( 1 - low )
67
84
  high_point = mid * ( 1 - high )
@@ -71,4 +88,9 @@ class Tsunami
71
88
 
72
89
  return gc
73
90
  end
91
+
92
+ def total_frames
93
+ @total_frames ||= @audio_file.info.frames
94
+ end
95
+
74
96
  end
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.2.0"
8
+ s.version = "0.3.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-25}
12
+ s.date = %q{2010-04-19}
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 = [
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "lib/buffer_ext.rb",
27
27
  "lib/tsunami.rb",
28
+ "lib/tsunami/bucket.rb",
28
29
  "test/helper.rb",
29
30
  "test/test_tsunami.rb",
30
31
  "tsunami.gemspec"
@@ -32,7 +33,7 @@ Gem::Specification.new do |s|
32
33
  s.homepage = %q{http://github.com/zmack/tsunami}
33
34
  s.rdoc_options = ["--charset=UTF-8"]
34
35
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.5}
36
+ s.rubygems_version = %q{1.3.6}
36
37
  s.summary = %q{It draws waveforms.}
37
38
  s.test_files = [
38
39
  "test/helper.rb",
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsunami
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Andrei Bocan
@@ -9,39 +14,47 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-03-25 00:00:00 +02:00
17
+ date: 2010-04-19 00:00:00 +03:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: rmagick
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
23
29
  version: "0"
24
- version:
30
+ type: :runtime
31
+ version_requirements: *id001
25
32
  - !ruby/object:Gem::Dependency
26
33
  name: ruby-audio
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
39
+ segments:
40
+ - 1
41
+ - 0
42
+ - 0
33
43
  version: 1.0.0
34
- version:
44
+ type: :runtime
45
+ version_requirements: *id002
35
46
  - !ruby/object:Gem::Dependency
36
47
  name: thoughtbot-shoulda
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
40
50
  requirements:
41
51
  - - ">="
42
52
  - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
43
55
  version: "0"
44
- version:
56
+ type: :development
57
+ version_requirements: *id003
45
58
  description: For reals, it draws waveforms, man
46
59
  email: zmaxor@gmail.com
47
60
  executables: []
@@ -60,6 +73,7 @@ files:
60
73
  - VERSION
61
74
  - lib/buffer_ext.rb
62
75
  - lib/tsunami.rb
76
+ - lib/tsunami/bucket.rb
63
77
  - test/helper.rb
64
78
  - test/test_tsunami.rb
65
79
  - tsunami.gemspec
@@ -76,18 +90,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
90
  requirements:
77
91
  - - ">="
78
92
  - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
79
95
  version: "0"
80
- version:
81
96
  required_rubygems_version: !ruby/object:Gem::Requirement
82
97
  requirements:
83
98
  - - ">="
84
99
  - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
85
102
  version: "0"
86
- version:
87
103
  requirements: []
88
104
 
89
105
  rubyforge_project:
90
- rubygems_version: 1.3.5
106
+ rubygems_version: 1.3.6
91
107
  signing_key:
92
108
  specification_version: 3
93
109
  summary: It draws waveforms.