speak_slow 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in speak_slow.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Yoichiro Hasebe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # SpeakSlow
2
+
3
+ ## Description
4
+
5
+ SpeakSlow modifies audio files adding pauses and/or altering speed to suit for language study
6
+
7
+ ## Installation
8
+
9
+ *SpeakSlow requires [SoX - Sound eXchange](http://sox.sourceforge.net/) with LAME support installed to the system. Then `gem install`*
10
+
11
+ $ gem install speak_slow
12
+
13
+ ## Usage
14
+
15
+ Usage: speak_slow [options] <input file> <output file>
16
+ where: <input file> and <output file> are paths to a wav or mp3 file
17
+
18
+ [options]:
19
+ --speed, -s <f>: Speed of output file [0.1 - 100] (default: 1.0)
20
+ --silence, -i <i>: Length (secondes) of a pause added to each utterance [0.1 - 120]
21
+ (default: 1)
22
+ --version, -v: Print version and exit
23
+ --help, -h: Show this message
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push "lib"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
+ require 'rubygems'
6
+ require 'trollop'
7
+ require 'speak_slow'
8
+
9
+ ################ parse options ##########
10
+
11
+ opts = Trollop::options do
12
+ version SpeakSlow::VERSION
13
+ banner <<-EOS
14
+
15
+ SpeakSlow modifies audio files adding pauses and/or altering speed to suit for language study
16
+
17
+ Usage: speak_slow [options] <input file> <output file>
18
+ where: <input file> and <output file> are paths to a wav or mp3 file
19
+
20
+ [options]:
21
+ EOS
22
+
23
+ opt :speed, "Speed of output file [0.1 - 100]", :default => 1.0
24
+ opt :silence, "Length (secondes) of a pause added to each utterance [0.1 - 120]", :default=> 1
25
+
26
+ end
27
+ Trollop::die :speed, "must between 0.1 to 100" unless opts[:speed] >= 0.1 and opts[:speed] <= 100
28
+ Trollop::die :silence, "must be 0 to 120" unless opts[:silence] >= 0.1 and opts[:silence] <= 120
29
+
30
+ ############### main program ###############
31
+
32
+ if ARGV.size != 2
33
+ puts "Both input and output file paths must be specified"
34
+ exit
35
+ end
36
+
37
+ infile = ARGV[0]
38
+ outfile = ARGV[1]
39
+ speed = opts[:speed]
40
+ silence = opts[:silence]
41
+
42
+ speakslow = SpeakSlow::Converter.new(infile, outfile)
43
+ speakslow.execute(speed, silence)
Binary file
Binary file
@@ -0,0 +1,159 @@
1
+ require "speak_slow/version"
2
+ require "rubygems"
3
+ require "progressbar"
4
+
5
+ SOX = "/usr/local/bin/sox"
6
+ SOXI = "/usr/local/bin/soxi"
7
+
8
+ module SpeakSlow
9
+ DATA_DIR = File.expand_path(File.dirname(__FILE__) + "/../data")
10
+
11
+ class Converter
12
+ def initialize(in_filepath, out_filepath)
13
+
14
+ @sox = check_command(SOX)
15
+ @soxi = check_command(SOXI)
16
+
17
+ if /([^\/]+)\.([^\.]+)\z/ =~ in_filepath and File.exists?(in_filepath)
18
+ @in_filepath = in_filepath
19
+ @basename = File.basename(in_filepath, ".*")
20
+ @in_format = $2
21
+ else
22
+ puts "The filename does not exist or not have a valid format"
23
+ exit
24
+ end
25
+
26
+ if /([^\/]+)\.([^\.]+)\z/ =~ out_filepath
27
+ @out_filepath = out_filepath
28
+ @out_format = $2
29
+ @outdir = File.dirname(out_filepath)
30
+ else
31
+ puts "The filename does not have a valid format"
32
+ exit
33
+ end
34
+
35
+ unless File.exists?(@outdir) && File::ftype(@outdir) == "directory"
36
+ puts "The output directory does not exist"
37
+ exit
38
+ end
39
+
40
+ unless ["wav", "mp3"].index @out_format
41
+ puts "The output format specified is not available"
42
+ exit
43
+ end
44
+ end
45
+
46
+ def execute(speed = 1, silence = 0)
47
+ @silence = silence
48
+ @speed = speed
49
+ temp_wav_original = @outdir + "/" + @basename + "-temp-original.wav"
50
+ temp_wav_result = @outdir + "/" + @basename + "-temp-result.wav"
51
+ if @in_format != "wav" # @in_format == "mp3"
52
+ convert_to_wav(@in_filepath, temp_wav_original)
53
+ elsif @in_format == "wav"
54
+ `cp #{@in_filepath} #{temp_wav_original}`
55
+ end
56
+
57
+ apply_sox_to_wav(temp_wav_original, temp_wav_result)
58
+ # split_wav(temp_wav_original)
59
+ # merge_wav(temp_wav_result)
60
+
61
+ if @out_format == "mp3"
62
+ convert_to_mp3(temp_wav_result, @out_filepath)
63
+ `rm #{temp_wav_original} #{temp_wav_result}`
64
+ elsif @out_format == "wav"
65
+ `mv #{temp_wav_result} #{@out_filepath}; rm #{temp_wav_original}`
66
+ end
67
+ end
68
+
69
+ # def split_wav(in_filepath)
70
+ # puts "Splitting WAV to segments"
71
+ # result = `#{@sox} #{in_filepath} #{@outdir}/split-.wav silence 0 1 0.3 -32d : newfile : restart`
72
+ # end
73
+ #
74
+ # def merge_wav(out_filepath)
75
+ # temp_filepath = @outdir + "/temp.wav"
76
+ # files = []
77
+ # Dir.foreach(@outdir) do |file|
78
+ # next unless /^split\-\d+\.wav$/ =~ file
79
+ # files << @outdir + "/" + file
80
+ # end
81
+ # index = 0
82
+ # puts "Merging segments back to one WAV file"
83
+ # bar = ProgressBar.new(@basename, files.size)
84
+ # files.sort.each do |filepath|
85
+ # length = `#{@soxi} -D #{filepath}`.to_f
86
+ # num_seconds = @silence == "auto" ? length.to_i + 1 : @silence.to_i
87
+ # index += 1
88
+ # bar.inc(1)
89
+ # if index == 1
90
+ # File.rename(filepath, out_filepath)
91
+ # next
92
+ # end
93
+ #
94
+ # if length == 0 or @silence.to_f == 0
95
+ # `#{@sox} #{out_filepath} #{filepath} #{temp_filepath} ; mv #{temp_filepath} #{out_filepath} ; rm #{filepath}`
96
+ # else
97
+ # if @silence == "auto"
98
+ # silence_length = length
99
+ # elsif @speed and @speed != 1
100
+ # silence_length = @silence.to_f / @speed * 1
101
+ # else
102
+ # silence_length = @silence
103
+ # end
104
+ # `#{@sox} #{out_filepath} -p pad 0 #{silence_length} | #{@sox} - #{filepath} #{temp_filepath} ; mv #{temp_filepath} #{out_filepath} ; rm #{filepath}`
105
+ # end
106
+ # end
107
+ # print "\n"
108
+ # puts "Changing speed of the resulting WAV"
109
+ # if @speed and @speed.to_f != 1.0
110
+ # `#{@sox} #{out_filepath} #{temp_filepath} tempo -s #{@speed}`
111
+ # `mv #{temp_filepath} #{out_filepath}`
112
+ # end
113
+ # end
114
+
115
+ def apply_sox_to_wav(in_filepath, out_filepath)
116
+ puts "Applying SoX functions to WAV (this might take a few minutes or more)"
117
+ # silence = "silence 0 1 0.3 -32d"
118
+ # silence = "silence 1 0.005 -32d 1 0.3 -32d"
119
+ silence = "silence 1 0.01 1% 1 0.3 1%"
120
+ if @speed and @speed != 1
121
+ speed = "tempo -s #{@speed}"
122
+ pad = "pad 0 #{@silence.to_f * @speed}"
123
+ `#{@sox} #{in_filepath} -p #{silence} #{pad} : restart | #{@sox} - -p | #{@sox} - #{out_filepath} #{speed}`
124
+ else
125
+ pad = "pad 0 #{@silence.to_f}"
126
+ `#{@sox} #{in_filepath} -p #{silence} #{pad} : restart | #{@sox} - #{out_filepath} `
127
+ end
128
+ end
129
+
130
+ def convert_to_wav(in_filepath, out_filepath)
131
+ basename = File.basename(in_filepath )
132
+ puts "Converting to WAV: #{basename}"
133
+ `#{@sox} #{in_filepath} #{out_filepath}`
134
+ end
135
+
136
+ def convert_to_mp3(in_filepath, out_filepath)
137
+ basename = File.basename(out_filepath)
138
+ puts "Converting WAV to MP3: #{basename}"
139
+ `#{@sox} #{in_filepath} #{out_filepath}`
140
+ end
141
+
142
+ def check_command(command)
143
+ basename = File.basename(command)
144
+ path = ""
145
+ print "Checking #{basename} command: "
146
+ if open("| which #{command} 2>/dev/null"){ |f| path = f.gets }
147
+ puts "detected at #{path}"
148
+ return path.strip
149
+ elsif open("| which #{basename} 2>/dev/null"){ |f| path = f.gets }
150
+ puts "detected at #{path}"
151
+ return path.strip
152
+ else
153
+ puts "not installed to the system"
154
+ exit
155
+ end
156
+ end
157
+
158
+ end # of class
159
+ end # of module
@@ -0,0 +1,3 @@
1
+ module SpeakSlow
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'speak_slow/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "speak_slow"
8
+ gem.version = SpeakSlow::VERSION
9
+ gem.authors = ["Yoichiro Hasebe"]
10
+ gem.email = ["yohasebe@gmail.com"]
11
+ gem.description = "SpeakSlow modifies audio files adding pauses and/or altering speed to suit for language study"
12
+ gem.summary = "SpeakSlow modify audio files changing speed and adding pauses"
13
+ gem.homepage = "http://github.com/yohasebe/speak_slow"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_development_dependency "minitest"
20
+ gem.add_runtime_dependency "progressbar"
21
+ gem.add_runtime_dependency "trollop"
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'minitest/autorun'
2
+ require 'speak_slow'
3
+
4
+ class TestSpeakSlow < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ @infile = SpeakSlow::DATA_DIR + "/MLK_Dream.mp3"
8
+ @outdir = File.expand_path(File.dirname(__FILE__)) + "/result"
9
+ `rm -rf #{@outdir}` if File.exists? @outdir
10
+ `mkdir #{@outdir}` unless File.exists? @outdir
11
+ @outfile = @outdir + "/result.mp3"
12
+ @speakslow = SpeakSlow::Converter.new(@infile, @outfile)
13
+ end
14
+
15
+ def test_execution
16
+ @speakslow.execute(speed = 1.5, silence = 2)
17
+ end
18
+
19
+ def teardown
20
+ # `rm -rf #{@outdir}` if File.exists?(@outdir)
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: speak_slow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yoichiro Hasebe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: progressbar
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: trollop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: SpeakSlow modifies audio files adding pauses and/or altering speed to
63
+ suit for language study
64
+ email:
65
+ - yohasebe@gmail.com
66
+ executables:
67
+ - speak_slow
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - bin/speak_slow
77
+ - data/MLK_Dream.mp3
78
+ - data/MLK_Dream.wav
79
+ - lib/speak_slow.rb
80
+ - lib/speak_slow/version.rb
81
+ - speak_slow.gemspec
82
+ - test/speak_slow_test.rb
83
+ homepage: http://github.com/yohasebe/speak_slow
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: SpeakSlow modify audio files changing speed and adding pauses
107
+ test_files:
108
+ - test/speak_slow_test.rb