scissor 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ -c
2
+ -fs
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'open4', '>= 1.3.0'
4
+ gem 'ruby-mp3info'
5
+ gem 'riff', '<= 0.3.0'
6
+ gem 'tempdir'
7
+ gem 'streamio-ffmpeg'
8
+
9
+ group :development do
10
+ gem 'rspec', '~> 2.3.0'
11
+ gem 'bundler', '~> 1.0.0'
12
+ gem 'jeweler', '~> 1.6.4'
13
+ gem 'rcov', '>= 0'
14
+ gem 'rdoc'
15
+ gem 'fakeweb'
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,44 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ fakeweb (1.3.0)
6
+ git (1.2.5)
7
+ jeweler (1.6.4)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ json (1.6.5)
12
+ open4 (1.3.0)
13
+ rake (0.9.2.2)
14
+ rcov (0.9.11)
15
+ rdoc (3.12)
16
+ json (~> 1.4)
17
+ riff (0.3)
18
+ rspec (2.3.0)
19
+ rspec-core (~> 2.3.0)
20
+ rspec-expectations (~> 2.3.0)
21
+ rspec-mocks (~> 2.3.0)
22
+ rspec-core (2.3.1)
23
+ rspec-expectations (2.3.0)
24
+ diff-lcs (~> 1.1.2)
25
+ rspec-mocks (2.3.0)
26
+ ruby-mp3info (0.6.16)
27
+ streamio-ffmpeg (0.8.4)
28
+ tempdir (0.0.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ bundler (~> 1.0.0)
35
+ fakeweb
36
+ jeweler (~> 1.6.4)
37
+ open4 (>= 1.3.0)
38
+ rcov
39
+ rdoc
40
+ riff (<= 0.3.0)
41
+ rspec (~> 2.3.0)
42
+ ruby-mp3info
43
+ streamio-ffmpeg
44
+ tempdir
data/Rakefile CHANGED
@@ -1,110 +1,48 @@
1
- require 'rubygems'
2
- gem 'rspec', '< 2'
3
- require 'rake'
4
- require 'rake/clean'
5
- require 'spec/rake/spectask'
6
- require 'rake/packagetask'
7
- require 'rake/gempackagetask'
8
- require 'rake/rdoctask'
9
- require 'rake/contrib/rubyforgepublisher'
10
- require 'rake/contrib/sshpublisher'
11
- require 'fileutils'
12
- include FileUtils
13
-
14
- NAME = "scissor"
15
- AUTHOR = "youpy"
16
- EMAIL = "youpy@buycheapviagraonlinenow.com"
17
- DESCRIPTION = "utility to chop sound files"
18
- RUBYFORGE_PROJECT = "scissor"
19
- HOMEPATH = "http://github.com/youpy/scissor"
20
- BIN_FILES = %w( )
21
- VERS = "0.2.8"
1
+ # encoding: utf-8
22
2
 
23
- REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
- CLEAN.include ['**/.*.sw?', '*.gem', '.config']
25
- RDOC_OPTS = [
26
- '--title', "#{NAME} documentation",
27
- "--charset", "utf-8",
28
- "--opname", "index.html",
29
- "--line-numbers",
30
- "--main", "README.rdoc",
31
- "--inline-source",
32
- ]
33
-
34
- task :default => [:spec]
35
- task :package => [:clean]
36
-
37
- Spec::Rake::SpecTask.new do |t|
38
- t.spec_opts = ['--options', "spec/spec.opts"]
39
- t.spec_files = FileList['spec/*_spec.rb']
40
- t.rcov = true
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
41
11
  end
12
+ require 'rake'
42
13
 
43
- spec = Gem::Specification.new do |s|
44
- s.name = NAME
45
- s.version = VERS
46
- s.platform = Gem::Platform::RUBY
47
- s.has_rdoc = true
48
- s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
49
- s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
50
- s.summary = DESCRIPTION
51
- s.description = DESCRIPTION
52
- s.author = AUTHOR
53
- s.email = EMAIL
54
- s.executables = BIN_FILES
55
- s.rubyforge_project = RUBYFORGE_PROJECT
56
- s.bindir = "bin"
57
- s.require_path = "lib"
58
- s.homepage = HOMEPATH
59
- s.test_files = Dir["test/test_*.rb"]
60
-
61
- s.add_dependency('open4', '>= 1.3.0')
62
- s.add_dependency('ruby-mp3info')
63
- s.add_dependency('riff', '<= 0.3.0')
64
- s.add_dependency('tempdir')
65
- s.add_dependency('streamio-ffmpeg')
66
- s.add_development_dependency('fakeweb')
67
- #s.required_ruby_version = '>= 1.8.2'
68
-
69
- s.files = %w(README.rdoc ChangeLog Rakefile) +
70
- Dir.glob("{bin,doc,test,lib,data,templates,generator,extras,website,script}/**/*") +
71
- Dir.glob("ext/**/*.{h,c,rb}") +
72
- Dir.glob("examples/**/*.rb") +
73
- Dir.glob("tools/*.rb")
74
-
75
- s.extensions = FileList["ext/**/extconf.rb"].to_a
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "scissor"
18
+ gem.summary = %Q{utility to chop sound files}
19
+ gem.description = %Q{utility to chop sound files}
20
+ gem.email = "youpy@buycheapviagraonlinenow.com"
21
+ gem.authors = ["youpy"]
22
+ gem.homepage = "http://github.com/youpy/scissor"
23
+ # dependencies defined in Gemfile
76
24
  end
25
+ Jeweler::RubygemsDotOrgTasks.new
77
26
 
78
- Rake::GemPackageTask.new(spec) do |p|
79
- p.need_tar = true
80
- p.gem_spec = spec
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |spec|
30
+ spec.pattern = FileList['spec/**/*_spec.rb']
81
31
  end
82
32
 
83
- task :install do
84
- name = "#{NAME}-#{VERS}.gem"
85
- sh %{rake package}
86
- sh %{sudo gem install pkg/#{name}}
33
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.rcov = true
87
36
  end
88
37
 
89
- task :uninstall => [:clean] do
90
- sh %{sudo gem uninstall #{NAME}}
91
- end
38
+ task :default => :spec
92
39
 
40
+ require 'rdoc/task'
93
41
  Rake::RDocTask.new do |rdoc|
94
- rdoc.rdoc_dir = 'html'
95
- rdoc.options += RDOC_OPTS
96
- rdoc.template = "resh"
97
- #rdoc.template = "#{ENV['template']}.rb" if ENV['template']
98
- if ENV['DOC_FILES']
99
- rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
100
- else
101
- rdoc.rdoc_files.include('README.rdoc', 'ChangeLog')
102
- rdoc.rdoc_files.include('lib/**/*.rb')
103
- rdoc.rdoc_files.include('ext/**/*.c')
104
- end
105
- end
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
106
43
 
107
- desc 'Show information about the gem.'
108
- task :debug_gem do
109
- puts spec.to_ruby
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "scissor #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
110
48
  end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.9
data/lib/scissor/tape.rb CHANGED
@@ -47,7 +47,11 @@ module Scissor
47
47
  file.flush
48
48
  end
49
49
 
50
- new(file.path)
50
+ tape = new(file.path)
51
+
52
+ # reference tempfile to prevent GC
53
+ tape.instance_variable_set('@__tempfile', file)
54
+ tape
51
55
  end
52
56
 
53
57
  def add_fragment(fragment)
data/scissor.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{scissor}
5
+ s.version = "0.0.24"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["youpy"]
9
+ s.date = %q{2010-04-28}
10
+ s.description = %q{utility to chop sound files}
11
+ s.email = %q{youpy@buycheapviagraonlinenow.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
13
+ s.files = ["README.rdoc", "ChangeLog", "Rakefile", "lib/scissor", "lib/scissor/chunk.rb", "lib/scissor/fragment.rb", "lib/scissor/loggable.rb", "lib/scissor/sequence.rb", "lib/scissor/sound_file.rb", "lib/scissor/writer.rb", "lib/scissor.rb", "data/silence.mp3"]
14
+ s.homepage = %q{http://github.com/youpy/scissor}
15
+ s.rdoc_options = ["--title", "scissor documentation", "--charset", "utf-8", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source", "--exclude", "^(examples|extras)/"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{scissor}
18
+ s.rubygems_version = %q{1.3.6}
19
+ s.summary = %q{utility to chop sound files}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<open4>, [">= 0"])
27
+ s.add_runtime_dependency(%q<ruby-mp3info>, [">= 0"])
28
+ s.add_runtime_dependency(%q<riff>, [">= 0"])
29
+ s.add_runtime_dependency(%q<tempdir>, [">= 0"])
30
+ else
31
+ s.add_dependency(%q<open4>, [">= 0"])
32
+ s.add_dependency(%q<ruby-mp3info>, [">= 0"])
33
+ s.add_dependency(%q<riff>, [">= 0"])
34
+ s.add_dependency(%q<tempdir>, [">= 0"])
35
+ end
36
+ else
37
+ s.add_dependency(%q<open4>, [">= 0"])
38
+ s.add_dependency(%q<ruby-mp3info>, [">= 0"])
39
+ s.add_dependency(%q<riff>, [">= 0"])
40
+ s.add_dependency(%q<tempdir>, [">= 0"])
41
+ end
42
+ end
@@ -0,0 +1 @@
1
+ http://mp34u.muzic.com/posting/6485
@@ -0,0 +1 @@
1
+ foo
Binary file
Binary file
@@ -0,0 +1,97 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Scissor::Fragment do
6
+ before do
7
+ @fragment = Scissor::Fragment.new(fixture('sample.mp3'), 5.5, 12.4)
8
+ end
9
+
10
+ it "should have a filename as an instance of Pathname" do
11
+ @fragment.filename.should be_an_instance_of(Pathname)
12
+ @fragment.filename.should eql(fixture('sample.mp3'))
13
+ end
14
+
15
+ it "should have a filename with absolute path" do
16
+ @fragment.filename.should be_absolute
17
+ end
18
+
19
+ it "should have a start point" do
20
+ @fragment.start.should eql(5.5)
21
+ end
22
+
23
+ it "should have a duration" do
24
+ @fragment.duration.should eql(12.4)
25
+ end
26
+
27
+ it "should freezed" do
28
+ lambda {
29
+ @fragment.instance_eval { @duration = 1 }
30
+ }.should raise_error
31
+ end
32
+
33
+ it "should have a pitch" do
34
+ fragment = Scissor::Fragment.new(fixture('sample.mp3'), 5, 10.5, false, 50)
35
+
36
+ fragment.pitch.should eql(50)
37
+ fragment.duration.should eql(21.0)
38
+ end
39
+
40
+ it "should return new fragment and remaining start point and length" do
41
+ new_fragment, remaining_start, remaining_length = @fragment.create(0.5, 1.0)
42
+ new_fragment.filename.should eql(fixture('sample.mp3'))
43
+ new_fragment.start.should eql(6.0)
44
+ new_fragment.duration.should eql(1.0)
45
+ remaining_start.should eql(0)
46
+ remaining_length.should eql(0)
47
+
48
+ new_fragment, remaining_start, remaining_length = @fragment.create(12.9, 1.0)
49
+ new_fragment.should be_nil
50
+ remaining_start.should eql(0.5)
51
+ remaining_length.should eql(1.0)
52
+
53
+ new_fragment, remaining_start, remaining_length = @fragment.create(11.9, 1.0)
54
+ new_fragment.filename.should eql(fixture('sample.mp3'))
55
+ new_fragment.start.should eql(17.4)
56
+ new_fragment.duration.should eql(0.5)
57
+ remaining_start.should eql(0)
58
+ remaining_length.should eql(0.5)
59
+ end
60
+
61
+ it "should return new fragment and remaining start point and length in half pitch" do
62
+ fragment = Scissor::Fragment.new(fixture('sample.mp3'), 5, 10.5, false, 50)
63
+
64
+ new_fragment, remaining_start, remaining_length = fragment.create(0.5, 1.0)
65
+ new_fragment.filename.should eql(fixture('sample.mp3'))
66
+ new_fragment.start.should eql(5.25)
67
+ new_fragment.duration.should eql(1.0)
68
+ new_fragment.pitch.should eql(50)
69
+ remaining_start.should eql(0)
70
+ remaining_length.should eql(0)
71
+
72
+ new_fragment, remaining_start, remaining_length = fragment.create(10.5, 1.0)
73
+ new_fragment.filename.should eql(fixture('sample.mp3'))
74
+ new_fragment.start.should eql(10.25)
75
+ new_fragment.duration.should eql(1.0)
76
+ new_fragment.pitch.should eql(50)
77
+ remaining_start.should eql(0)
78
+ remaining_length.should eql(0)
79
+
80
+ new_fragment, remaining_start, remaining_length = fragment.create(20, 3)
81
+ new_fragment.start.should eql(15.0)
82
+ new_fragment.duration.should eql(1.0)
83
+ new_fragment.pitch.should eql(50)
84
+ remaining_start.should eql(0)
85
+ remaining_length.should eql(2.0)
86
+
87
+ new_fragment, remaining_start, remaining_length = fragment.create(21, 1.0)
88
+ new_fragment.should be_nil
89
+ remaining_start.should eql(0.0)
90
+ remaining_length.should eql(1.0)
91
+
92
+ new_fragment, remaining_start, remaining_length = fragment.create(22, 1.0)
93
+ new_fragment.should be_nil
94
+ remaining_start.should eql(1.0)
95
+ remaining_length.should eql(1.0)
96
+ end
97
+ end
@@ -0,0 +1,328 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'spec_helper'
4
+ require 'fileutils'
5
+ require 'fakeweb'
6
+
7
+ include FileUtils
8
+
9
+ describe Scissor do
10
+ before do
11
+ FFMPEG.logger.level = Logger::WARN
12
+
13
+ @mp3 = Scissor(fixture('sample.mp3'))
14
+ mkdir '/tmp/scissor-test'
15
+
16
+ FakeWeb.clean_registry
17
+ end
18
+
19
+ after do
20
+ rm_rf '/tmp/scissor-test'
21
+ end
22
+
23
+ it "should create from url" do
24
+ url = 'http://example.com/sample_mp3'
25
+ FakeWeb.register_uri(:get, url, :body => fixture('sample.mp3'), :content_type => 'audio/mpeg')
26
+
27
+ mp3 = Scissor(url)
28
+
29
+ mp3.should be_an_instance_of(Scissor::Tape)
30
+ mp3.duration.should be_within(0.1).of(178.1)
31
+ end
32
+
33
+ it "should expand given path" do
34
+ cp fixture('sample.mp3'), '/tmp/scissor-test'
35
+
36
+ mp3 = Scissor('~/../../../../../../../../../../tmp/scissor-test/sample.mp3')
37
+ mp3.should be_an_instance_of(Scissor::Tape)
38
+ mp3.duration.should be_within(0.1).of(178.1)
39
+ end
40
+
41
+ it "should get duration" do
42
+ @mp3.should respond_to(:duration)
43
+ @mp3.duration.should be_within(0.1).of(178.1)
44
+ end
45
+
46
+ it "should slice" do
47
+ @mp3.should respond_to(:slice)
48
+ @mp3.slice(0, 120).duration.should eql(120.0)
49
+ @mp3.slice(150, 20).duration.should eql(20.0)
50
+ end
51
+
52
+ it "should slice like array" do
53
+ @mp3[0, 120].duration.should eql(120.0)
54
+ @mp3[150, 20].duration.should eql(20.0)
55
+ end
56
+
57
+ it "should cut down if sliced range is out of duration" do
58
+ @mp3.slice(0, 179).duration.should be_within(0.1).of(178.1)
59
+ end
60
+
61
+ it "should concatenate" do
62
+ a = @mp3.slice(0, 120)
63
+ scissor = a.concat(@mp3.slice(150, 20))
64
+ scissor.duration.should eql(140.0)
65
+ a.duration.should eql(140.0)
66
+ end
67
+
68
+ it "should concatenate using double 'less than' operator" do
69
+ a = @mp3.slice(0, 120)
70
+ scissor = a << @mp3.slice(150, 20)
71
+ scissor.duration.should eql(140.0)
72
+ a.duration.should eql(140.0)
73
+ end
74
+
75
+ it "should concat silence" do
76
+ scissor = @mp3.slice(0, 12).concat(Scissor.silence(0.32009))
77
+ scissor.duration.should be_within(0.01).of(12.32)
78
+ end
79
+
80
+ it "should concatenate and create new instance" do
81
+ a = @mp3.slice(0, 120)
82
+ scissor = a + @mp3.slice(150, 20)
83
+ scissor.duration.should eql(140.0)
84
+ a.duration.should eql(120.0)
85
+ end
86
+
87
+ it "should slice concatenated one" do
88
+ scissor = @mp3.slice(0.33, 1).concat(@mp3.slice(0.2, 0.1)).slice(0.9, 0.2)
89
+
90
+ scissor.duration.should be_within(0.001).of(0.2)
91
+ scissor.fragments.size.should eql(2)
92
+ scissor.fragments[0].start.should be_within(0.001).of(1.23)
93
+ scissor.fragments[0].duration.should be_within(0.001).of(0.1)
94
+ scissor.fragments[1].start.should be_within(0.001).of(0.2)
95
+ scissor.fragments[1].duration.should be_within(0.001).of(0.1)
96
+ end
97
+
98
+ it "should loop" do
99
+ scissor = @mp3.slice(0, 10)
100
+ scissor.loop(3).duration.should eql(30.0)
101
+ scissor.duration.should eql(10.0)
102
+ end
103
+
104
+ it "should loop using arithmetic operator" do
105
+ scissor = @mp3.slice(0, 10) * 3
106
+ scissor.duration.should eql(30.0)
107
+ end
108
+
109
+ it "should split" do
110
+ splits = (@mp3.slice(0.33, 1) + @mp3.slice(0.2, 0.1)).split(5)
111
+ splits.length.should eql(5)
112
+ splits.each do |split|
113
+ split.duration.should be_within(0.001).of(0.22)
114
+ end
115
+
116
+ splits[0].fragments.size.should eql(1)
117
+ splits[1].fragments.size.should eql(1)
118
+ splits[2].fragments.size.should eql(1)
119
+ splits[3].fragments.size.should eql(1)
120
+ splits[4].fragments.size.should eql(2)
121
+ end
122
+
123
+ it "should split using arithmetic operator" do
124
+ splits = (@mp3.slice(0.33, 1) + @mp3.slice(0.2, 0.1)) / 5
125
+ splits.length.should eql(5)
126
+ splits.each do |split|
127
+ split.duration.should be_within(0.001).of(0.22)
128
+ end
129
+
130
+ splits[0].fragments.size.should eql(1)
131
+ splits[1].fragments.size.should eql(1)
132
+ splits[2].fragments.size.should eql(1)
133
+ splits[3].fragments.size.should eql(1)
134
+ splits[4].fragments.size.should eql(2)
135
+ end
136
+
137
+ it "should fill" do
138
+ scissor = (@mp3.slice(0, 6) + @mp3.slice(0, 2)).fill(15)
139
+ scissor.duration.should eql(15.0)
140
+ scissor.fragments.size.should eql(4)
141
+ scissor.fragments[0].duration.should eql(6.0)
142
+ scissor.fragments[1].duration.should eql(2.0)
143
+ scissor.fragments[2].duration.should eql(6.0)
144
+ scissor.fragments[3].duration.should eql(1.0)
145
+ end
146
+
147
+ it "should replace" do
148
+ scissor = @mp3.slice(0, 100).replace(60, 30, @mp3.slice(0, 60))
149
+ scissor.duration.should eql(130.0)
150
+ scissor.fragments.size.should eql(3)
151
+ scissor.fragments[0].start.should eql(0.0)
152
+ scissor.fragments[0].duration.should eql(60.0)
153
+ scissor.fragments[1].start.should eql(0.0)
154
+ scissor.fragments[1].duration.should eql(60.0)
155
+ scissor.fragments[2].start.should eql(90.0)
156
+ scissor.fragments[2].duration.should eql(10.0)
157
+ end
158
+
159
+ it "should reverse" do
160
+ scissor = (@mp3.slice(0, 10) + @mp3.slice(0, 5)).reverse
161
+ scissor.duration.should eql(15.0)
162
+ scissor.fragments.size.should eql(2)
163
+ scissor.fragments[0].start.should eql(0.0)
164
+ scissor.fragments[0].duration.should eql(5.0)
165
+ scissor.fragments[0].should be_reversed
166
+ scissor.fragments[1].start.should eql(0.0)
167
+ scissor.fragments[1].duration.should eql(10.0)
168
+ scissor.fragments[0].should be_reversed
169
+ end
170
+
171
+ it "should re-reverse" do
172
+ scissor = (@mp3.slice(0, 10) + @mp3.slice(0, 5)).reverse.reverse
173
+ scissor.duration.should eql(15.0)
174
+ scissor.fragments.size.should eql(2)
175
+ scissor.fragments[0].start.should eql(0.0)
176
+ scissor.fragments[0].duration.should eql(10.0)
177
+ scissor.fragments[0].should_not be_reversed
178
+ scissor.fragments[1].start.should eql(0.0)
179
+ scissor.fragments[1].duration.should eql(5.0)
180
+ scissor.fragments[0].should_not be_reversed
181
+ end
182
+
183
+ it "should change pitch" do
184
+ scissor = @mp3.slice(0, 10) + @mp3.slice(0, 5)
185
+
186
+ scissor.duration.should eql(15.0)
187
+ scissor.pitch(50).duration.should eql(30.0)
188
+ scissor.pitch(50).pitch(50).fragments[0].pitch.should eql(25.0)
189
+ scissor.pitch(50).pitch(50).duration.should eql(60.0)
190
+ end
191
+
192
+ it "should stretch" do
193
+ scissor = @mp3.slice(0, 0.1)
194
+
195
+ scissor.duration.should eql(0.1)
196
+ scissor.pitch((0.1 / 120) * 100, true).duration.should be_within(0.01).of(120.0)
197
+ scissor.stretch((120 / 0.1) * 100).duration.should be_within(0.1).of(120.0)
198
+
199
+ stretched = scissor.stretch((120 / 0.1) * 100).slice(0, 10)
200
+ stretched.fragments.first.should be_stretched
201
+
202
+ stretched1 = scissor.stretch((120 / 0.1) * 100)
203
+ stretched2 = scissor.stretch((120 / 0.1) * 100)
204
+ stretched = (stretched1 + stretched2).slice(100, 50)
205
+ stretched.fragments.first.should be_stretched
206
+
207
+ scissor = (@mp3.slice(0, 10) + @mp3.slice(0, 5)).stretch(200).reverse
208
+ scissor.fragments.first.should be_stretched
209
+ end
210
+
211
+ it "should join instances of scissor" do
212
+ a = @mp3.slice(0, 120)
213
+ b = @mp3.slice(150, 20)
214
+
215
+ scissor = Scissor.join([a, b])
216
+ scissor.duration.should eql(140.0)
217
+ scissor.fragments[0].duration.should eql(120.0)
218
+ end
219
+
220
+ it "should mix instances of scissor" do
221
+ a = @mp3.slice(0, 120)
222
+ b = @mp3.slice(150, 20)
223
+
224
+ scissor = Scissor.mix([a, b], '/tmp/scissor-test/out.mp3')
225
+ scissor.should be_an_instance_of(Scissor::Tape)
226
+ scissor.duration.should be_within(0.1).of(120)
227
+ scissor.fragments.size.should eql(1)
228
+ end
229
+
230
+ it "should raise error if replaced range is out of duration" do
231
+ lambda {
232
+ @mp3.slice(0, 100).replace(60, 41, @mp3.slice(0, 60))
233
+ }.should raise_error(Scissor::Tape::OutOfDuration)
234
+ end
235
+
236
+ it "should write to file and return new instance of Scissor" do
237
+ scissor = @mp3.slice(0, 120) + @mp3.slice(150, 20)
238
+ result = scissor.to_file('/tmp/scissor-test/out.mp3')
239
+ result.should be_an_instance_of(Scissor::Tape)
240
+ result.duration.should be_within(0.1).of(140)
241
+ end
242
+
243
+ it "should write to mp3 file" do
244
+ scissor = @mp3.slice(0, 120) + @mp3.slice(150, 20)
245
+ result = scissor.to_file('/tmp/scissor-test/out.mp3')
246
+ result.duration.should be_within(0.1).of(140)
247
+ end
248
+
249
+ it "should write to expanded path" do
250
+ @mp3.to_file('~/../../../../../../../../../../tmp/scissor-test/sample.mp3')
251
+
252
+ mp3 = Scissor('/tmp/scissor-test/sample.mp3')
253
+ mp3.should be_an_instance_of(Scissor::Tape)
254
+ end
255
+
256
+ it "should write to wav file" do
257
+ scissor = @mp3.slice(0, 120) + @mp3.slice(150, 20)
258
+ result = scissor.to_file('/tmp/scissor-test/out.wav')
259
+ result.duration.should be_within(0.1).of(140)
260
+ end
261
+
262
+ it "should write to file using 'greater than' operator" do
263
+ result = @mp3.slice(0, 120) + @mp3.slice(150, 20) > '/tmp/scissor-test/out.wav'
264
+ result.duration.should be_within(0.1).of(140)
265
+ end
266
+
267
+ it "should write to file with many fragments" do
268
+ scissor = (@mp3.slice(0, 120) / 100).inject(Scissor()){|m, s| m + s } + @mp3.slice(10, 20)
269
+ result = scissor.to_file('/tmp/scissor-test/out.mp3')
270
+ result.should be_an_instance_of(Scissor::Tape)
271
+ result.duration.should be_within(0.1).of(140)
272
+ end
273
+
274
+ it "should overwrite existing file" do
275
+ result = @mp3.slice(0, 10).to_file('/tmp/scissor-test/out.mp3')
276
+ result.duration.should be_within(0.1).of(10)
277
+
278
+ result = @mp3.slice(0, 12).to_file('/tmp/scissor-test/out.mp3',
279
+ :overwrite => true)
280
+ result.duration.should be_within(0.1).of(12)
281
+ end
282
+
283
+ it "should overwrite existing file using double 'greater than' oprator" do
284
+ result = @mp3.slice(0, 10).to_file('/tmp/scissor-test/out.mp3')
285
+ result.duration.should be_within(0.1).of(10)
286
+
287
+ result = @mp3.slice(0, 12) >> '/tmp/scissor-test/out.mp3'
288
+ result.duration.should be_within(0.1).of(12)
289
+ end
290
+
291
+ it "should write to file in the variable pitch" do
292
+ scissor = @mp3.slice(0, 120) + @mp3.slice(150, 20)
293
+
294
+ result = scissor.pitch(50).to_file('/tmp/scissor-test/out.mp3')
295
+ result.duration.should be_within(0.1).of(280)
296
+
297
+ result = scissor.pitch(200).to_file('/tmp/scissor-test/out.mp3', :overwrite => true)
298
+ result.duration.should be_within(0.1).of(70)
299
+ end
300
+
301
+ it "should raise error if overwrite option is false" do
302
+ result = @mp3.slice(0, 10).to_file('/tmp/scissor-test/out.mp3')
303
+ result.duration.should be_within(0.1).of(10)
304
+
305
+ lambda {
306
+ @mp3.slice(0, 10).to_file('/tmp/scissor-test/out.mp3',
307
+ :overwrite => false)
308
+ }.should raise_error(Scissor::Writer::FileExists)
309
+
310
+ lambda {
311
+ @mp3.slice(0, 10).to_file('/tmp/scissor-test/out.mp3')
312
+ }.should raise_error(Scissor::Writer::FileExists)
313
+ end
314
+
315
+ it "should raise error if no fragment are given" do
316
+ lambda {
317
+ Scissor().to_file('/tmp/scissor-test/out.mp3')
318
+ }.should raise_error(Scissor::Writer::EmptyFragment)
319
+ end
320
+
321
+ it "should silence" do
322
+ scissor = @mp3.slice(0, 1.0)
323
+
324
+ Scissor.should_receive(:silence).with(1.0)
325
+
326
+ scissor.silence
327
+ end
328
+ end
@@ -0,0 +1,72 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Scissor::Sequence do
6
+ before do
7
+ @foo = Scissor(fixture('sample.mp3'))
8
+ @bar = Scissor(fixture('sine.wav'))
9
+ end
10
+
11
+ it "should instantiated" do
12
+ seq = Scissor.sequence('ababaab', 1.5)
13
+ seq.should be_an_instance_of(Scissor::Sequence)
14
+ end
15
+
16
+ it "should apply tape as instrument" do
17
+ seq = Scissor.sequence('ababaab ab', 0.5)
18
+ scissor = seq.apply(:a => @foo, :b => @bar)
19
+
20
+ scissor.should be_an_instance_of(Scissor::Tape)
21
+ scissor.duration.should eql(5.0)
22
+ scissor.fragments.size.should eql(10)
23
+
24
+ scissor.fragments.each do |fragment|
25
+ fragment.duration.should eql(0.5)
26
+ end
27
+
28
+ scissor.fragments[0].filename.should eql(fixture('sample.mp3'))
29
+ scissor.fragments[1].filename.should eql(fixture('sine.wav'))
30
+ scissor.fragments[2].filename.should eql(fixture('sample.mp3'))
31
+ scissor.fragments[3].filename.should eql(fixture('sine.wav'))
32
+ scissor.fragments[4].filename.should eql(fixture('sample.mp3'))
33
+ scissor.fragments[5].filename.should eql(fixture('sample.mp3'))
34
+ scissor.fragments[6].filename.should eql(fixture('sine.wav'))
35
+ scissor.fragments[8].filename.should eql(fixture('sample.mp3'))
36
+ scissor.fragments[9].filename.should eql(fixture('sine.wav'))
37
+ end
38
+
39
+ it "should apply proc as instrument" do
40
+ seq = Scissor.sequence('ababaab ab', 0.5)
41
+ scissor = seq.apply(:a => Proc.new { @foo }, :b => Proc.new { @bar })
42
+
43
+ scissor.should be_an_instance_of(Scissor::Tape)
44
+ scissor.duration.should eql(5.0)
45
+ scissor.fragments.size.should eql(10)
46
+
47
+ scissor.fragments.each do |fragment|
48
+ fragment.duration.should eql(0.5)
49
+ end
50
+
51
+ scissor.fragments[0].filename.should eql(fixture('sample.mp3'))
52
+ scissor.fragments[1].filename.should eql(fixture('sine.wav'))
53
+ scissor.fragments[2].filename.should eql(fixture('sample.mp3'))
54
+ scissor.fragments[3].filename.should eql(fixture('sine.wav'))
55
+ scissor.fragments[4].filename.should eql(fixture('sample.mp3'))
56
+ scissor.fragments[5].filename.should eql(fixture('sample.mp3'))
57
+ scissor.fragments[6].filename.should eql(fixture('sine.wav'))
58
+ scissor.fragments[8].filename.should eql(fixture('sample.mp3'))
59
+ scissor.fragments[9].filename.should eql(fixture('sine.wav'))
60
+ end
61
+
62
+ it "should append silence when applied instance does not have enough duration" do
63
+ seq = Scissor.sequence('ba', 1.5)
64
+ scissor = seq.apply(:a => @foo, :b => @bar)
65
+
66
+ scissor.duration.to_s.should eql("3.0")
67
+ scissor.fragments.size.should eql(3)
68
+ scissor.fragments[0].filename.should eql(fixture('sine.wav'))
69
+ scissor.fragments[1].filename.to_s.should match(/silence\.mp3/)
70
+ scissor.fragments[2].filename.should eql(fixture('sample.mp3'))
71
+ end
72
+ end
@@ -0,0 +1,27 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'spec_helper'
4
+ require 'fileutils'
5
+
6
+ include FileUtils
7
+
8
+ describe Scissor::SoundFile do
9
+ before do
10
+ @mp3 = Scissor::SoundFile.new(fixture('sample.mp3'))
11
+ @wav = Scissor::SoundFile.new(fixture('sine.wav'))
12
+ end
13
+
14
+ after do
15
+ end
16
+
17
+ it "raise error if unknown file format" do
18
+ lambda {
19
+ Scissor::SoundFile.new(fixture('foo.bar'))
20
+ }.should raise_error(Scissor::SoundFile::UnknownFormat)
21
+ end
22
+
23
+ it "should get length" do
24
+ @mp3.length.should be_within(0.1).of(178.1)
25
+ @wav.length.should eql(1.0)
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib/'
2
+
3
+ require 'scissor'
4
+
5
+ def fixture(filename)
6
+ Pathname.new(File.dirname(__FILE__) + '/fixtures/' + filename).realpath
7
+ end
metadata CHANGED
@@ -1,12 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scissor
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 5
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 8
9
- version: 0.2.8
9
+ - 9
10
+ segments_generated: true
11
+ version: 0.2.9
10
12
  platform: ruby
11
13
  authors:
12
14
  - youpy
@@ -14,85 +16,184 @@ autorequire:
14
16
  bindir: bin
15
17
  cert_chain: []
16
18
 
17
- date: 2012-01-02 00:00:00 +09:00
19
+ date: 2012-01-19 00:00:00 +09:00
18
20
  default_executable:
19
21
  dependencies:
20
22
  - !ruby/object:Gem::Dependency
21
- name: open4
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
28
+ hash: 27
27
29
  segments:
28
30
  - 1
29
31
  - 3
30
32
  - 0
33
+ segments_generated: true
31
34
  version: 1.3.0
35
+ requirement: *id001
32
36
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: ruby-mp3info
37
+ name: open4
36
38
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
39
+ - !ruby/object:Gem::Dependency
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 3
41
46
  segments:
42
47
  - 0
48
+ segments_generated: true
43
49
  version: "0"
50
+ requirement: *id002
44
51
  type: :runtime
45
- version_requirements: *id002
46
- - !ruby/object:Gem::Dependency
47
- name: riff
52
+ name: ruby-mp3info
48
53
  prerelease: false
49
- requirement: &id003 !ruby/object:Gem::Requirement
54
+ - !ruby/object:Gem::Dependency
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ none: false
50
57
  requirements:
51
58
  - - <=
52
59
  - !ruby/object:Gem::Version
60
+ hash: 19
53
61
  segments:
54
62
  - 0
55
63
  - 3
56
64
  - 0
65
+ segments_generated: true
57
66
  version: 0.3.0
67
+ requirement: *id003
58
68
  type: :runtime
59
- version_requirements: *id003
69
+ name: riff
70
+ prerelease: false
60
71
  - !ruby/object:Gem::Dependency
72
+ version_requirements: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ segments_generated: true
81
+ version: "0"
82
+ requirement: *id004
83
+ type: :runtime
61
84
  name: tempdir
62
85
  prerelease: false
63
- requirement: &id004 !ruby/object:Gem::Requirement
86
+ - !ruby/object:Gem::Dependency
87
+ version_requirements: &id005 !ruby/object:Gem::Requirement
88
+ none: false
64
89
  requirements:
65
90
  - - ">="
66
91
  - !ruby/object:Gem::Version
92
+ hash: 3
67
93
  segments:
68
94
  - 0
95
+ segments_generated: true
69
96
  version: "0"
97
+ requirement: *id005
70
98
  type: :runtime
71
- version_requirements: *id004
72
- - !ruby/object:Gem::Dependency
73
99
  name: streamio-ffmpeg
74
100
  prerelease: false
75
- requirement: &id005 !ruby/object:Gem::Requirement
101
+ - !ruby/object:Gem::Dependency
102
+ version_requirements: &id006 !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 2
110
+ - 3
111
+ - 0
112
+ segments_generated: true
113
+ version: 2.3.0
114
+ requirement: *id006
115
+ type: :development
116
+ name: rspec
117
+ prerelease: false
118
+ - !ruby/object:Gem::Dependency
119
+ version_requirements: &id007 !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ hash: 23
125
+ segments:
126
+ - 1
127
+ - 0
128
+ - 0
129
+ segments_generated: true
130
+ version: 1.0.0
131
+ requirement: *id007
132
+ type: :development
133
+ name: bundler
134
+ prerelease: false
135
+ - !ruby/object:Gem::Dependency
136
+ version_requirements: &id008 !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ hash: 7
142
+ segments:
143
+ - 1
144
+ - 6
145
+ - 4
146
+ segments_generated: true
147
+ version: 1.6.4
148
+ requirement: *id008
149
+ type: :development
150
+ name: jeweler
151
+ prerelease: false
152
+ - !ruby/object:Gem::Dependency
153
+ version_requirements: &id009 !ruby/object:Gem::Requirement
154
+ none: false
76
155
  requirements:
77
156
  - - ">="
78
157
  - !ruby/object:Gem::Version
158
+ hash: 3
79
159
  segments:
80
160
  - 0
161
+ segments_generated: true
81
162
  version: "0"
82
- type: :runtime
83
- version_requirements: *id005
163
+ requirement: *id009
164
+ type: :development
165
+ name: rcov
166
+ prerelease: false
84
167
  - !ruby/object:Gem::Dependency
85
- name: fakeweb
168
+ version_requirements: &id010 !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
175
+ - 0
176
+ segments_generated: true
177
+ version: "0"
178
+ requirement: *id010
179
+ type: :development
180
+ name: rdoc
86
181
  prerelease: false
87
- requirement: &id006 !ruby/object:Gem::Requirement
182
+ - !ruby/object:Gem::Dependency
183
+ version_requirements: &id011 !ruby/object:Gem::Requirement
184
+ none: false
88
185
  requirements:
89
186
  - - ">="
90
187
  - !ruby/object:Gem::Version
188
+ hash: 3
91
189
  segments:
92
190
  - 0
191
+ segments_generated: true
93
192
  version: "0"
193
+ requirement: *id011
94
194
  type: :development
95
- version_requirements: *id006
195
+ name: fakeweb
196
+ prerelease: false
96
197
  description: utility to chop sound files
97
198
  email: youpy@buycheapviagraonlinenow.com
98
199
  executables: []
@@ -100,58 +201,67 @@ executables: []
100
201
  extensions: []
101
202
 
102
203
  extra_rdoc_files:
103
- - README.rdoc
104
204
  - ChangeLog
105
- files:
106
205
  - README.rdoc
206
+ files:
207
+ - .rspec
107
208
  - ChangeLog
209
+ - Gemfile
210
+ - Gemfile.lock
211
+ - README.rdoc
108
212
  - Rakefile
213
+ - VERSION
214
+ - data/silence.mp3
215
+ - lib/scissor.rb
109
216
  - lib/scissor/fragment.rb
110
217
  - lib/scissor/loggable.rb
111
218
  - lib/scissor/sequence.rb
112
219
  - lib/scissor/sound_file.rb
113
220
  - lib/scissor/tape.rb
114
221
  - lib/scissor/writer.rb
115
- - lib/scissor.rb
116
- - data/silence.mp3
222
+ - scissor.gemspec
223
+ - spec/fixtures/about_mp3.txt
224
+ - spec/fixtures/foo.bar
225
+ - spec/fixtures/sample.mp3
226
+ - spec/fixtures/sine.wav
227
+ - spec/fragment_spec.rb
228
+ - spec/scissor_spec.rb
229
+ - spec/sequence_spec.rb
230
+ - spec/sound_file_spec.rb
231
+ - spec/spec_helper.rb
117
232
  has_rdoc: true
118
233
  homepage: http://github.com/youpy/scissor
119
234
  licenses: []
120
235
 
121
236
  post_install_message:
122
- rdoc_options:
123
- - --title
124
- - scissor documentation
125
- - --charset
126
- - utf-8
127
- - --opname
128
- - index.html
129
- - --line-numbers
130
- - --main
131
- - README.rdoc
132
- - --inline-source
133
- - --exclude
134
- - ^(examples|extras)/
237
+ rdoc_options: []
238
+
135
239
  require_paths:
136
240
  - lib
137
241
  required_ruby_version: !ruby/object:Gem::Requirement
242
+ none: false
138
243
  requirements:
139
244
  - - ">="
140
245
  - !ruby/object:Gem::Version
246
+ hash: 3
141
247
  segments:
142
248
  - 0
249
+ segments_generated: true
143
250
  version: "0"
144
251
  required_rubygems_version: !ruby/object:Gem::Requirement
252
+ none: false
145
253
  requirements:
146
254
  - - ">="
147
255
  - !ruby/object:Gem::Version
256
+ hash: 3
148
257
  segments:
149
258
  - 0
259
+ segments_generated: true
150
260
  version: "0"
151
261
  requirements: []
152
262
 
153
- rubyforge_project: scissor
154
- rubygems_version: 1.3.6
263
+ rubyforge_project:
264
+ rubygems_version: 1.3.7
155
265
  signing_key:
156
266
  specification_version: 3
157
267
  summary: utility to chop sound files