sfzer 0.4
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/COPYING +674 -0
- data/History.txt +39 -0
- data/Manifest.txt +14 -0
- data/README.txt +67 -0
- data/Rakefile +18 -0
- data/bin/sfzer +13 -0
- data/lib/DirectoryProcessor.rb +174 -0
- data/lib/Multisample.rb +320 -0
- data/lib/NamedSample.rb +70 -0
- data/lib/Sample.rb +83 -0
- data/lib/sfzer.rb +128 -0
- data/test/MultisampleTest.rb +115 -0
- data/test/NamedSampleTest.rb +55 -0
- data/test/test_sfzer.rb +12 -0
- metadata +79 -0
data/lib/NamedSample.rb
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# This file is part of SFZer.
|
|
2
|
+
#
|
|
3
|
+
# SFZer is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# SFZer is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with SFZer. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# A Sample with a note value (such as A1, C#4, F5, etc) in the filename.
|
|
19
|
+
class NamedSample < Sample
|
|
20
|
+
include Comparable # instant sortability; I love Mixins!
|
|
21
|
+
|
|
22
|
+
# Instantiate the NamedSample.
|
|
23
|
+
def initialize( sample, path=false )
|
|
24
|
+
super( sample, path )
|
|
25
|
+
@value = NamedSample.value( sample )
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# returns true if the String name is a NamedSample.
|
|
30
|
+
def NamedSample.sample?( name )
|
|
31
|
+
name =~ /^.*(#{regexp}).*\.#{Sample.suffix_regexp}$/i
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# returns the RegExp used to test for a NamedSample.
|
|
36
|
+
def NamedSample.regexp
|
|
37
|
+
/[ABCDEFG](#)?\d/
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# returns the numeric value of a NamedSample
|
|
42
|
+
def NamedSample.value( string )
|
|
43
|
+
result = false
|
|
44
|
+
|
|
45
|
+
if( string =~ /([ABCDEFG])(#)?(\d)/i )
|
|
46
|
+
notes = { 'C'=>0, 'D'=>2, 'E'=>4, 'F'=>5, 'G'=>7, 'A'=>9, 'B'=>11}
|
|
47
|
+
note = $1
|
|
48
|
+
sharp = 0
|
|
49
|
+
if $2 == "#" then
|
|
50
|
+
sharp = 1
|
|
51
|
+
end
|
|
52
|
+
octave = $3.to_i
|
|
53
|
+
result = ((octave * 12) + 12) + notes[note] + sharp
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
result
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# returns the numeric value of this instance of NamedSample
|
|
61
|
+
def value
|
|
62
|
+
@value
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# required by the Comparable mixin; allows sorting
|
|
67
|
+
def <=>(anOther)
|
|
68
|
+
value <=> anOther.value
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/Sample.rb
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# This file is part of SFZer.
|
|
2
|
+
#
|
|
3
|
+
# SFZer is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# SFZer is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with SFZer. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
# An SFZ Sample is a file that represents a single note.
|
|
17
|
+
class Sample
|
|
18
|
+
attr_reader :path, :sample
|
|
19
|
+
# sample = full path to sample
|
|
20
|
+
def initialize( sample, path=false )
|
|
21
|
+
@sample = sample
|
|
22
|
+
@path = path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# ----------------------------------------------
|
|
26
|
+
# static methods
|
|
27
|
+
# ----------------------------------------------
|
|
28
|
+
|
|
29
|
+
# yields all the sample suffixes that SFZ supports
|
|
30
|
+
def Sample.suffixes
|
|
31
|
+
['wav', 'ogg', 'aif', 'aiff'].each do |type|
|
|
32
|
+
yield type
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# returns a regexp string for all possible sample suffixes
|
|
38
|
+
def Sample.suffix_regexp
|
|
39
|
+
# build filename suffix types
|
|
40
|
+
types = "("
|
|
41
|
+
Sample.suffixes do |s|
|
|
42
|
+
types = types + "#{s}|"
|
|
43
|
+
end
|
|
44
|
+
types.chop!
|
|
45
|
+
types = types + ")"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# returns a Dir glob string for all possible sample suffixes
|
|
50
|
+
def Sample.suffix_glob
|
|
51
|
+
# build filename suffix types
|
|
52
|
+
types = "{"
|
|
53
|
+
Sample.suffixes do |s|
|
|
54
|
+
types = types + "#{s},"
|
|
55
|
+
end
|
|
56
|
+
types.chop!
|
|
57
|
+
types = types + "}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def Sample.sample?( name )
|
|
61
|
+
name =~ /*.#{Sample.suffix_regexp}$/i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def note
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def value
|
|
72
|
+
false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def to_s
|
|
76
|
+
if @path
|
|
77
|
+
"#{@path}#{SFZer::SEPARATOR}#{@sample}"
|
|
78
|
+
else
|
|
79
|
+
"#{@sample}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
data/lib/sfzer.rb
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# This file is part of SFZer.
|
|
2
|
+
#
|
|
3
|
+
# SFZer is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# SFZer is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with SFZer. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Program Requirements
|
|
18
|
+
require 'optparse'
|
|
19
|
+
|
|
20
|
+
require 'Sample'
|
|
21
|
+
require 'NamedSample'
|
|
22
|
+
require 'Multisample'
|
|
23
|
+
require 'DirectoryProcessor'
|
|
24
|
+
|
|
25
|
+
# Parses the command line options and sets the program into motion.
|
|
26
|
+
class SFZer
|
|
27
|
+
|
|
28
|
+
# Version information
|
|
29
|
+
VERSION = '0.4'
|
|
30
|
+
VERSION_DATE = "08 Feb 2009"
|
|
31
|
+
URL = "http://sfzer.rubyforge.org"
|
|
32
|
+
NAME = "SFZer"
|
|
33
|
+
SEPARATOR = "\\"
|
|
34
|
+
|
|
35
|
+
#Exit codes
|
|
36
|
+
EXITSTATUS_COMPLETE = 0
|
|
37
|
+
EXITSTATUS_NO_MULTISAMPLES_FOUND = 1
|
|
38
|
+
EXITSTATUS_ARG_ERROR = 2
|
|
39
|
+
EXITSTATUS_USER_ABORT = 3
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Execute the SFZer program
|
|
43
|
+
def do( argv )
|
|
44
|
+
sfzer = process_options( argv )
|
|
45
|
+
sfzer.scan_dirs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Processes each command line option and returns a configured Directory Processor.
|
|
53
|
+
def process_options( argv )
|
|
54
|
+
sfzer = DirectoryProcessor.new
|
|
55
|
+
exit_now = false
|
|
56
|
+
|
|
57
|
+
begin
|
|
58
|
+
argv.options{ |opt|
|
|
59
|
+
|
|
60
|
+
# help message banner and usage instructions
|
|
61
|
+
opt.banner = "A script by Chris Tessmer that creates SFZ files from multisamples.\n"
|
|
62
|
+
opt.banner += "version #{SFZer::VERSION}, #{SFZer::VERSION_DATE}.\n"
|
|
63
|
+
opt.banner += "\n"
|
|
64
|
+
opt.banner += "Usage: sfzer.rb [options] directorie(s)\n"
|
|
65
|
+
opt.banner += "\n"
|
|
66
|
+
|
|
67
|
+
# defining options
|
|
68
|
+
opt.on( "Options:" )
|
|
69
|
+
opt.on( "\n" )
|
|
70
|
+
opt.on( "Mapping:" )
|
|
71
|
+
opt.on( "--xfade", "-x", "Map crossfades between region keycenters *" ) {
|
|
72
|
+
sfzer.mapping = Multisample::XFADE
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
opt.on( "--strictkeys", "-s", "Map regions on a 1:1 key:sample basis" ) {
|
|
76
|
+
sfzer.mapping = Multisample::STRICTKEYS
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
opt.on( "\n" )
|
|
81
|
+
opt.on( "File placement:" )
|
|
82
|
+
opt.on( "--top-dir", "-t", "Create SFZ files in topmost directory *" ){
|
|
83
|
+
sfzer.generate_in_top_dir = true
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
opt.on( "--each-dir", "-e", "Create each SFZ file with its own Samples"){
|
|
87
|
+
sfzer.generate_in_top_dir = false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
opt.on( "\n" )
|
|
91
|
+
opt.on( "Decoration:" )
|
|
92
|
+
opt.on( "--message 'TEXT'", "-m", "Add TEXT to each generated SFZ file header" ) {
|
|
93
|
+
|text|
|
|
94
|
+
sfzer.message = text
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
opt.on( "--help", "-h", "This text" ) {
|
|
98
|
+
puts opt
|
|
99
|
+
exit_now = true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
opt.parse!
|
|
103
|
+
|
|
104
|
+
# Exit with help message if no arguments are given
|
|
105
|
+
if( argv.length == 0 )
|
|
106
|
+
puts opt
|
|
107
|
+
exit_now = true
|
|
108
|
+
end
|
|
109
|
+
}
|
|
110
|
+
rescue Exception => e
|
|
111
|
+
STDERR.puts "\n#{e.class}"
|
|
112
|
+
STDERR.puts "\t#{e}\n"
|
|
113
|
+
STDERR.puts "Since this messed up the arguments, I am ABORTING THE PROGRAM. Sorry.\n\n"
|
|
114
|
+
exit EXITSTATUS_ARG_ERROR
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Handle graceful exit (couldn't put in opt block because of rescue clause)
|
|
118
|
+
if exit_now
|
|
119
|
+
exit EXITSTATUS_COMPLETE
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
argv.each{ |arg|
|
|
123
|
+
sfzer.dirs.push( arg )
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
sfzer
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
class MultisampleTest < Test::Unit::TestCase
|
|
2
|
+
# def setup
|
|
3
|
+
# end
|
|
4
|
+
|
|
5
|
+
# def teardown
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
def name
|
|
9
|
+
"Multisample tests"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# SFZ *REQUIRES* that path separators follow the DOS convention (i.e., lean forward)
|
|
14
|
+
def test_default_path_file_seperators_are_dos
|
|
15
|
+
test_paths = [
|
|
16
|
+
'test/path',
|
|
17
|
+
'./test/path/with/dot',
|
|
18
|
+
'../test/path/with/twodots',
|
|
19
|
+
'../test/path/with\\twodots'
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
test_paths.each{ |path|
|
|
23
|
+
m = Multisample.new( path, "Default Path Test Multisample" )
|
|
24
|
+
m.default_path = path
|
|
25
|
+
sfz = m.to_sfz
|
|
26
|
+
line = /^(default_path=.*)$/.match( sfz )[1]
|
|
27
|
+
assert_no_match( /\//, line, "\"#{line}\" does NOT contain only DOS path separators." )
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Tests that A1.wav through G#8.wav are valid filenames
|
|
35
|
+
def test_simple_named_note_filenames
|
|
36
|
+
# construct notes
|
|
37
|
+
notes = Array.new
|
|
38
|
+
['A', 'B', 'C', 'D', 'E', 'F', 'G'].each do |a|
|
|
39
|
+
['1','2','3','4','5','6','7','8'].each do |n|
|
|
40
|
+
Sample.suffixes do |s|
|
|
41
|
+
notes.push "#{a}#{n}.#{s}" # natural
|
|
42
|
+
notes.push "#{a}##{n}.#{s}" # sharp
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
notes.each do |note|
|
|
48
|
+
assert( Multisample.multisample_filename?( note ) ,
|
|
49
|
+
"\"#{note}\" is NOT a valid named note name.")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_simple_numeric_note_filenames
|
|
56
|
+
(0..127).each do |i|
|
|
57
|
+
# Note 001.wav
|
|
58
|
+
n = sprintf "%03d", i
|
|
59
|
+
Sample.suffixes do |s|
|
|
60
|
+
note = "#{n}.#{s}"
|
|
61
|
+
assert( Multisample.multisample_filename?( note ) ,
|
|
62
|
+
"\"#{note}\" is NOT a valid 3-digit numeric note name.")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Note 01.wav
|
|
66
|
+
n = sprintf "%02d", i
|
|
67
|
+
Sample.suffixes do |s|
|
|
68
|
+
note = "#{n}.#{s}"
|
|
69
|
+
assert( Multisample.multisample_filename?( note ) ,
|
|
70
|
+
"\"#{note}\" is NOT a valid 2-to-3-digit numeric note name.")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_real_filenames
|
|
78
|
+
# Names of real files that should succeed
|
|
79
|
+
names = [ 'NRGK4ObBass F#1.wav',
|
|
80
|
+
'OBX-SoundTrk_03B2.wav',
|
|
81
|
+
'Bass06_C2.wav',
|
|
82
|
+
]
|
|
83
|
+
for name in names
|
|
84
|
+
assert( Multisample.multisample_filename?( name ),
|
|
85
|
+
"\"#{name}\"is NOT a valid multisample filename" )
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
#Names of real files that should fail
|
|
89
|
+
#badnames = ['119F#001.wav']
|
|
90
|
+
#for name in badnames
|
|
91
|
+
# assert( Multisample.multisample_filename?( name ) == false ,
|
|
92
|
+
# "\"#{name}\" IS a valid multisample filename, but shouldn't be!" )
|
|
93
|
+
#end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_banner_line_lengths
|
|
98
|
+
message = "(The GPL License, version 3) Copyright (c) 2008 Chris Tessmer This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>."
|
|
99
|
+
m = Multisample.new( "" )
|
|
100
|
+
m.message = message
|
|
101
|
+
max_line_length = 80
|
|
102
|
+
biggest_line_length_yet = 0
|
|
103
|
+
|
|
104
|
+
s = m.sfz_banner
|
|
105
|
+
s.each_line{ |x|
|
|
106
|
+
if x.length > biggest_line_length_yet
|
|
107
|
+
biggest_line_length_yet = x.length
|
|
108
|
+
end
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
assert_operator biggest_line_length_yet, :<=, max_line_length , "SFZ banner lines exceed #{max_line_length} characters per line:\n\n#{s}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class NamedSampleTest < Test::Unit::TestCase
|
|
2
|
+
def name
|
|
3
|
+
"NamedSample tests"
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def test_for_named_samples_files
|
|
7
|
+
names = [
|
|
8
|
+
'Bassy01(C3).wav',
|
|
9
|
+
'D#2.wav',
|
|
10
|
+
'Bass10_C1.wav'
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
names.each do |name|
|
|
14
|
+
assert( NamedSample.sample?( name ) ,
|
|
15
|
+
"\"#{name}\" is NOT a valid note name.")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_for_named_sample_values
|
|
21
|
+
sample_values = {
|
|
22
|
+
'C4.ogg' => 60,
|
|
23
|
+
'Bassy01(C3).wav' => 48,
|
|
24
|
+
'D#2.wav' => 39,
|
|
25
|
+
'Bass10_C1.wav' => 24
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
sample_values.each do |sample, value|
|
|
29
|
+
assert_equal( value, NamedSample.value( sample ),
|
|
30
|
+
"The value of \"#{sample}\" is NOT \"#{value}\".")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_named_sample_comparables
|
|
36
|
+
c3 = NamedSample.new( "Bassy01(C3).wav" )
|
|
37
|
+
assert_equal( 48, c3.value )
|
|
38
|
+
|
|
39
|
+
d2 = NamedSample.new( 'D#2.aif' )
|
|
40
|
+
assert_equal( 39, d2.value )
|
|
41
|
+
|
|
42
|
+
c3o = NamedSample.new( "C3.ogg" )
|
|
43
|
+
assert_equal( 48, c3o.value )
|
|
44
|
+
|
|
45
|
+
# Since
|
|
46
|
+
c1 = NamedSample.new( "C1.wav" ) #24
|
|
47
|
+
|
|
48
|
+
b1 = NamedSample.new( "B1.wav" ) #35
|
|
49
|
+
|
|
50
|
+
assert_operator b1, :>, c1, "#{b1} > #{c1}"
|
|
51
|
+
assert_operator d2, :<, c3, "#{d2} < #{c3}"
|
|
52
|
+
assert_operator c3, :==, c3o, "#{c3} = #{c3o}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
data/test/test_sfzer.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sfzer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: "0.4"
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Chris Tessmer
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-02-11 00:00:00 +00:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: hoe
|
|
17
|
+
type: :development
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 1.8.3
|
|
24
|
+
version:
|
|
25
|
+
description: SFZer recursively scans through directories of Multisamples (.wav, .aiff, .ogg, etc) and automagically generates SFZ soundfonts from what it finds.
|
|
26
|
+
email:
|
|
27
|
+
- http://christessmer.com
|
|
28
|
+
executables:
|
|
29
|
+
- sfzer
|
|
30
|
+
extensions: []
|
|
31
|
+
|
|
32
|
+
extra_rdoc_files:
|
|
33
|
+
- History.txt
|
|
34
|
+
- Manifest.txt
|
|
35
|
+
- README.txt
|
|
36
|
+
files:
|
|
37
|
+
- History.txt
|
|
38
|
+
- Manifest.txt
|
|
39
|
+
- README.txt
|
|
40
|
+
- COPYING
|
|
41
|
+
- Rakefile
|
|
42
|
+
- bin/sfzer
|
|
43
|
+
- lib/sfzer.rb
|
|
44
|
+
- lib/DirectoryProcessor.rb
|
|
45
|
+
- lib/Sample.rb
|
|
46
|
+
- lib/NamedSample.rb
|
|
47
|
+
- lib/Multisample.rb
|
|
48
|
+
- test/test_sfzer.rb
|
|
49
|
+
- test/NamedSampleTest.rb
|
|
50
|
+
- test/MultisampleTest.rb
|
|
51
|
+
has_rdoc: true
|
|
52
|
+
homepage: http://sfzer.rubyforge.org
|
|
53
|
+
post_install_message:
|
|
54
|
+
rdoc_options:
|
|
55
|
+
- --main
|
|
56
|
+
- README.txt
|
|
57
|
+
require_paths:
|
|
58
|
+
- lib
|
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: "0"
|
|
64
|
+
version:
|
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: "0"
|
|
70
|
+
version:
|
|
71
|
+
requirements: []
|
|
72
|
+
|
|
73
|
+
rubyforge_project: sfzer
|
|
74
|
+
rubygems_version: 1.3.1
|
|
75
|
+
signing_key:
|
|
76
|
+
specification_version: 2
|
|
77
|
+
summary: SFZer recursively scans through directories of Multisamples (.wav, .aiff, .ogg, etc) and automagically generates SFZ soundfonts from what it finds.
|
|
78
|
+
test_files:
|
|
79
|
+
- test/test_sfzer.rb
|