beats 1.2.2 → 1.2.3
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/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:
|