scissor 0.2.8 → 0.2.9

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/.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