beats 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +4 -4
- data/bin/beats +7 -3
- data/bin/example_song.wav +0 -0
- data/lib/beats.rb +3 -2
- data/lib/kit.rb +3 -6
- data/test/audioengine_test.rb +0 -2
- data/test/audioutils_test.rb +0 -2
- data/test/fixtures/valid/example_mono_16_base_path.txt +33 -0
- data/test/integration_test.rb +29 -17
- data/test/kit_test.rb +0 -2
- data/test/pattern_test.rb +0 -2
- data/test/patternexpander_test.rb +0 -2
- data/test/song_test.rb +0 -2
- data/test/songoptimizer_test.rb +0 -2
- data/test/songparser_test.rb +0 -2
- data/test/track_test.rb +0 -2
- metadata +7 -3
data/README.markdown
CHANGED
@@ -35,16 +35,16 @@ And [here's what it sounds like](http://beatsdrummachine.com/beat.mp3) after get
|
|
35
35
|
Current Status
|
36
36
|
--------------
|
37
37
|
|
38
|
-
The latest stable version of BEATS is 1.2.
|
38
|
+
The latest stable version of BEATS is 1.2.3, released on December 31, 2011. This is a minor release which includes two improvements:
|
39
39
|
|
40
|
-
* Bug fix:
|
41
|
-
*
|
40
|
+
* Bug fix: You can now use `~` in sound file paths, and it will correctly expand to your home folder. (At least on UNIX OSes, I'm not sure if that works on Windows).
|
41
|
+
* The new `--path` option allows setting the base path from which relative sound file paths are searched for.
|
42
42
|
|
43
43
|
|
44
44
|
Installation
|
45
45
|
------------
|
46
46
|
|
47
|
-
To install the latest stable version (1.2.
|
47
|
+
To install the latest stable version (1.2.3) from [rubygems.org](http://rubygems.org/gems/beats), run the following from the command line:
|
48
48
|
|
49
49
|
gem install beats
|
50
50
|
|
data/bin/beats
CHANGED
@@ -20,7 +20,7 @@ require "lib/track"
|
|
20
20
|
USAGE_INSTRUCTIONS = ""
|
21
21
|
|
22
22
|
def parse_options()
|
23
|
-
options = {:split => false
|
23
|
+
options = {:split => false}
|
24
24
|
|
25
25
|
optparse = OptionParser.new do |opts|
|
26
26
|
opts.banner = "usage: beats [options] input_file [output_file]"
|
@@ -32,12 +32,16 @@ def parse_options()
|
|
32
32
|
opts.on('-p', '--pattern PATTERN_NAME', "Output a single pattern instead of the whole song" ) do |p|
|
33
33
|
options[:pattern] = p
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
opts.on('--path BASE_PATH', "The base path used to load sound files with relative paths.") do |base_path|
|
37
|
+
options[:base_path] = base_path
|
38
|
+
end
|
39
|
+
|
36
40
|
opts.on('-v', '--version', "Display version number and exit") do
|
37
41
|
puts "BEATS v#{Beats::BEATS_VERSION}"
|
38
42
|
exit
|
39
43
|
end
|
40
|
-
|
44
|
+
|
41
45
|
opts.on( '-h', '--help', "Display this screen and exit" ) do
|
42
46
|
puts opts
|
43
47
|
exit
|
Binary file
|
data/lib/beats.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Beats
|
2
|
-
BEATS_VERSION = "1.2.
|
2
|
+
BEATS_VERSION = "1.2.3"
|
3
3
|
|
4
4
|
# Each pattern in the song will be split up into sub patterns that have at most this many steps.
|
5
5
|
# In general, audio for several shorter patterns can be generated more quickly than for one long
|
@@ -18,7 +18,8 @@ class Beats
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def run
|
21
|
-
|
21
|
+
base_path = @options[:base_path] || File.dirname(@input_file_name)
|
22
|
+
song, kit = SongParser.new().parse(base_path, File.read(@input_file_name))
|
22
23
|
|
23
24
|
song = normalize_for_pattern_option(song)
|
24
25
|
songs_to_generate = normalize_for_split_option(song)
|
data/lib/kit.rb
CHANGED
@@ -137,18 +137,15 @@ private
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
return path_is_absolute ? sound_file_name : (base_path + File::SEPARATOR + sound_file_name)
|
143
|
-
end
|
144
|
-
|
140
|
+
# Converts relative paths into absolute paths. Note that this will also handle
|
141
|
+
# expanding ~ on platforms that support that.
|
145
142
|
def make_file_names_absolute(kit_items)
|
146
143
|
kit_items.each do |label, sound_file_names|
|
147
144
|
unless sound_file_names.class == Array
|
148
145
|
sound_file_names = [sound_file_names]
|
149
146
|
end
|
150
147
|
|
151
|
-
sound_file_names.map! {|sound_file_name|
|
148
|
+
sound_file_names.map! {|sound_file_name| File.expand_path(sound_file_name, base_path) }
|
152
149
|
kit_items[label] = sound_file_names
|
153
150
|
end
|
154
151
|
|
data/test/audioengine_test.rb
CHANGED
data/test/audioutils_test.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# An example song using mono 16-bit sounds
|
2
|
+
# The sound files in this example do not exist in the given
|
3
|
+
# location relative to this file, so this is intended for testing
|
4
|
+
# when a custom base path is given.
|
5
|
+
|
6
|
+
Song:
|
7
|
+
Tempo: 120
|
8
|
+
Flow:
|
9
|
+
- Verse: x2
|
10
|
+
- Chorus: x4
|
11
|
+
- Verse: x2
|
12
|
+
- Chorus: x4
|
13
|
+
Kit:
|
14
|
+
- bass: bass_mono_16.wav
|
15
|
+
- snare: snare_mono_16.wav
|
16
|
+
- hh_closed: hh_closed_mono_16.wav
|
17
|
+
- agogo: agogo_high_mono_16.wav
|
18
|
+
|
19
|
+
Verse:
|
20
|
+
- bass: X...X...X...X...
|
21
|
+
- snare: ..............X.
|
22
|
+
- hh_closed: X.XXX.XX........
|
23
|
+
- hh_closed: ........X.X.X.X.
|
24
|
+
- agogo: ..............XX
|
25
|
+
|
26
|
+
# Also including non-Kit sounds to test that they work as well:
|
27
|
+
Chorus:
|
28
|
+
- bass: X...X...XX..X...
|
29
|
+
- snare: ....X.......X...
|
30
|
+
- hh_closed: X.XXX.XX........
|
31
|
+
- hh_closed: ........X.XX..X.
|
32
|
+
- tom4_mono_16.wav: ...........X....
|
33
|
+
- tom2_mono_16.wav: ..............X.
|
data/test/integration_test.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
-
|
3
1
|
require 'includes'
|
4
2
|
|
5
3
|
class IntegrationTest < Test::Unit::TestCase
|
6
4
|
TRACK_NAMES = ["bass", "snare", "hh_closed", "hh_closed2", "agogo", "tom4", "tom2"]
|
7
5
|
OUTPUT_FOLDER = "test/integration_output"
|
8
6
|
|
7
|
+
def setup
|
8
|
+
# Make sure no output from previous tests is still around
|
9
|
+
clean_output_folder()
|
10
|
+
end
|
11
|
+
|
9
12
|
def test_bad_song_errors
|
10
13
|
invalid_fixtures = ["bad_tempo.txt",
|
11
14
|
"bad_repeat_count.txt",
|
@@ -17,7 +20,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
17
20
|
|
18
21
|
invalid_fixtures.each do |fixture_name|
|
19
22
|
assert_raise(SongParseError) do
|
20
|
-
beats = Beats.new("test/fixtures/invalid/#{fixture_name}", "doesn't matter", {:split => false
|
23
|
+
beats = Beats.new("test/fixtures/invalid/#{fixture_name}", "doesn't matter", {:split => false})
|
21
24
|
beats.run()
|
22
25
|
end
|
23
26
|
end
|
@@ -27,25 +30,32 @@ class IntegrationTest < Test::Unit::TestCase
|
|
27
30
|
# TODO: Add tests for the -p option
|
28
31
|
# TODO: Add test verify that song generated with and without SongOptimizer are identical.
|
29
32
|
|
33
|
+
def test_base_path
|
34
|
+
run_combined_test("mono", 16, "_base_path", "test/sounds")
|
35
|
+
run_split_test("mono", 16, "_base_path", "test/sounds")
|
36
|
+
end
|
37
|
+
|
30
38
|
def test_generate_combined
|
31
|
-
# Make sure no output from previous tests is still around
|
32
|
-
clean_output_folder()
|
33
|
-
|
34
39
|
run_combined_test("mono", 8)
|
35
40
|
run_combined_test("mono", 16)
|
36
41
|
run_combined_test("stereo", 8)
|
37
42
|
run_combined_test("stereo", 16)
|
38
43
|
end
|
39
44
|
|
40
|
-
def run_combined_test(num_channels, bits_per_sample)
|
45
|
+
def run_combined_test(num_channels, bits_per_sample, suffix="", base_path=nil)
|
41
46
|
# Make sure no output from previous tests is still around
|
42
47
|
assert_equal([".", ".."], Dir.new(OUTPUT_FOLDER).entries)
|
43
48
|
|
44
|
-
song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}.txt"
|
45
|
-
actual_output_file = "#{OUTPUT_FOLDER}/example_combined_#{num_channels}_#{bits_per_sample}.wav"
|
49
|
+
song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}#{suffix}.txt"
|
50
|
+
actual_output_file = "#{OUTPUT_FOLDER}/example_combined_#{num_channels}_#{bits_per_sample}#{suffix}.wav"
|
46
51
|
expected_output_file = "test/fixtures/expected_output/example_combined_#{num_channels}_#{bits_per_sample}.wav"
|
47
52
|
|
48
|
-
|
53
|
+
options = {:split => false}
|
54
|
+
unless base_path == nil
|
55
|
+
options[:base_path] = base_path
|
56
|
+
end
|
57
|
+
|
58
|
+
beats = Beats.new(song_fixture, actual_output_file, options)
|
49
59
|
beats.run()
|
50
60
|
assert(File.exists?(actual_output_file), "Expected file '#{actual_output_file}' to exist, but it doesn't.")
|
51
61
|
|
@@ -59,24 +69,26 @@ class IntegrationTest < Test::Unit::TestCase
|
|
59
69
|
end
|
60
70
|
|
61
71
|
def test_generate_split
|
62
|
-
# Make sure no output from previous tests is still around
|
63
|
-
clean_output_folder()
|
64
|
-
|
65
72
|
run_split_test("mono", 8)
|
66
73
|
run_split_test("mono", 16)
|
67
74
|
run_split_test("stereo", 8)
|
68
75
|
run_split_test("stereo", 16)
|
69
76
|
end
|
70
77
|
|
71
|
-
def run_split_test(num_channels, bits_per_sample)
|
78
|
+
def run_split_test(num_channels, bits_per_sample, suffix="", base_path=nil)
|
72
79
|
# Make sure no output from previous tests is still around
|
73
80
|
assert_equal([".", ".."], Dir.new(OUTPUT_FOLDER).entries)
|
74
81
|
|
75
|
-
song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}.txt"
|
76
|
-
actual_output_prefix = "#{OUTPUT_FOLDER}/example_split_#{num_channels}_#{bits_per_sample}"
|
82
|
+
song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}#{suffix}.txt"
|
83
|
+
actual_output_prefix = "#{OUTPUT_FOLDER}/example_split_#{num_channels}_#{bits_per_sample}#{suffix}"
|
77
84
|
expected_output_prefix = "test/fixtures/expected_output/example_split_#{num_channels}_#{bits_per_sample}"
|
78
85
|
|
79
|
-
|
86
|
+
options = {:split => true}
|
87
|
+
unless base_path == nil
|
88
|
+
options[:base_path] = base_path
|
89
|
+
end
|
90
|
+
|
91
|
+
beats = Beats.new(song_fixture, actual_output_prefix + ".wav", options)
|
80
92
|
beats.run()
|
81
93
|
TRACK_NAMES.each do |track_name|
|
82
94
|
if(track_name.start_with?("tom"))
|
data/test/kit_test.rb
CHANGED
data/test/pattern_test.rb
CHANGED
data/test/song_test.rb
CHANGED
data/test/songoptimizer_test.rb
CHANGED
data/test/songparser_test.rb
CHANGED
data/test/track_test.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: beats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Joel Strait
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2012-01-01 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: wavefile
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/songparser.rb
|
48
48
|
- lib/track.rb
|
49
49
|
- bin/beats
|
50
|
+
- bin/example_song.wav
|
50
51
|
- test/audioengine_test.rb
|
51
52
|
- test/audioutils_test.rb
|
52
53
|
- test/fixtures/expected_output/example_combined_mono_16.wav
|
@@ -94,6 +95,7 @@ files:
|
|
94
95
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
95
96
|
- test/fixtures/invalid/template.txt
|
96
97
|
- test/fixtures/valid/example_mono_16.txt
|
98
|
+
- test/fixtures/valid/example_mono_16_base_path.txt
|
97
99
|
- test/fixtures/valid/example_mono_8.txt
|
98
100
|
- test/fixtures/valid/example_no_kit.txt
|
99
101
|
- test/fixtures/valid/example_stereo_16.txt
|
@@ -225,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
227
|
requirements: []
|
226
228
|
|
227
229
|
rubyforge_project:
|
228
|
-
rubygems_version: 1.8.
|
230
|
+
rubygems_version: 1.8.13
|
229
231
|
signing_key:
|
230
232
|
specification_version: 3
|
231
233
|
summary: A command-line drum machine. Feed it a song notated in YAML, and it will produce a precision-milled Wave file of impeccable timing and feel.
|
@@ -277,6 +279,7 @@ test_files:
|
|
277
279
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
278
280
|
- test/fixtures/invalid/template.txt
|
279
281
|
- test/fixtures/valid/example_mono_16.txt
|
282
|
+
- test/fixtures/valid/example_mono_16_base_path.txt
|
280
283
|
- test/fixtures/valid/example_mono_8.txt
|
281
284
|
- test/fixtures/valid/example_no_kit.txt
|
282
285
|
- test/fixtures/valid/example_stereo_16.txt
|
@@ -385,3 +388,4 @@ test_files:
|
|
385
388
|
- test/sounds/tom4_stereo_8.wav
|
386
389
|
- test/sounds/tone.wav
|
387
390
|
- test/track_test.rb
|
391
|
+
has_rdoc:
|