beats 1.3.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.markdown +22 -42
- data/bin/beats +6 -7
- data/lib/beats.rb +2 -1
- data/lib/beats/audioengine.rb +13 -13
- data/lib/beats/beatsrunner.rb +7 -8
- data/lib/beats/kit.rb +12 -156
- data/lib/beats/kit_builder.rb +74 -0
- data/lib/beats/pattern.rb +2 -22
- data/lib/beats/song.rb +5 -55
- data/lib/beats/songoptimizer.rb +3 -3
- data/lib/beats/songparser.rb +25 -46
- data/lib/beats/track.rb +20 -31
- data/lib/beats/transforms/song_swinger.rb +2 -4
- data/lib/wavefile/cachingwriter.rb +2 -2
- data/test/audioengine_test.rb +22 -24
- data/test/audioutils_test.rb +1 -1
- data/test/cachingwriter_test.rb +13 -12
- data/test/fixtures/invalid/leading_bar_line.txt +15 -0
- data/test/fixtures/{valid → invalid}/with_structure.txt +2 -2
- data/test/fixtures/valid/multiple_tracks_same_sound.txt +2 -1
- data/test/fixtures/valid/optimize_pattern_collision.txt +4 -5
- data/test/fixtures/valid/track_with_spaces.txt +13 -0
- data/test/includes.rb +1 -4
- data/test/integration_test.rb +5 -5
- data/test/kit_builder_test.rb +52 -0
- data/test/kit_test.rb +18 -141
- data/test/pattern_test.rb +66 -1
- data/test/song_swinger_test.rb +2 -2
- data/test/song_test.rb +9 -33
- data/test/songoptimizer_test.rb +18 -18
- data/test/songparser_test.rb +20 -10
- data/test/track_test.rb +23 -9
- metadata +26 -31
- data/ext/mkrf_conf.rb +0 -28
- data/test/fixtures/invalid/template.txt +0 -31
- data/test/fixtures/valid/foo.txt +0 -18
- data/test/sounds/bass.wav +0 -0
- data/test/sounds/bass2.wav +0 -0
- data/test/sounds/sine-mono-8bit.wav +0 -0
- data/test/sounds/tone.wav +0 -0
data/test/pattern_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'includes'
|
2
2
|
|
3
|
-
class PatternTest < Test
|
3
|
+
class PatternTest < Minitest::Test
|
4
4
|
SAMPLE_RATE = 44100
|
5
5
|
SECONDS_IN_MINUTE = 60.0
|
6
6
|
|
@@ -42,6 +42,60 @@ class PatternTest < Test::Unit::TestCase
|
|
42
42
|
assert_equal(pattern.tracks.length, 3)
|
43
43
|
end
|
44
44
|
|
45
|
+
def test_track
|
46
|
+
pattern = Pattern.new("whatevs")
|
47
|
+
|
48
|
+
assert_equal({}, pattern.tracks)
|
49
|
+
|
50
|
+
pattern.track("my_sound", "X...X...")
|
51
|
+
assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X..."}})
|
52
|
+
|
53
|
+
# Rhythm is shorter than length of current longer rhythm, so should be made same length
|
54
|
+
pattern.track("my_other_sound", "X...")
|
55
|
+
assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X..."},
|
56
|
+
"my_other_sound" => {name: "my_other_sound", rhythm: "X......."}})
|
57
|
+
|
58
|
+
# Track has same name as previous track, and longer rhythm than previous tracks.
|
59
|
+
# Track should have expected name, but pattern key be unique.
|
60
|
+
# The rhythm of other existing tracks should be lengthened.
|
61
|
+
pattern.track("my_sound", ".X..........")
|
62
|
+
assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X......."},
|
63
|
+
"my_other_sound" => {name: "my_other_sound", rhythm: "X..........."},
|
64
|
+
"my_sound2" => {name: "my_sound", rhythm: ".X.........."}})
|
65
|
+
|
66
|
+
pattern.track("my_sound2", "..X.........")
|
67
|
+
assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X......."},
|
68
|
+
"my_other_sound" => {name: "my_other_sound", rhythm: "X..........."},
|
69
|
+
"my_sound2" => {name: "my_sound", rhythm: ".X.........."},
|
70
|
+
"my_sound22" => {name: "my_sound2", rhythm: "..X........."}})
|
71
|
+
|
72
|
+
pattern.track("my_sound", "..")
|
73
|
+
assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X......."},
|
74
|
+
"my_other_sound" => {name: "my_other_sound", rhythm: "X..........."},
|
75
|
+
"my_sound2" => {name: "my_sound", rhythm: ".X.........."},
|
76
|
+
"my_sound22" => {name: "my_sound2", rhythm: "..X........."},
|
77
|
+
"my_sound3" => {name: "my_sound", rhythm: "............"},})
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_track_unique_name_already_taken
|
81
|
+
pattern = Pattern.new("whatevs")
|
82
|
+
|
83
|
+
assert_equal({}, pattern.tracks)
|
84
|
+
|
85
|
+
pattern.track("my_sound2", "X...X...")
|
86
|
+
assert_pattern_tracks(pattern, {"my_sound2" => {name: "my_sound2", rhythm: "X...X..."}})
|
87
|
+
|
88
|
+
pattern.track("my_sound", "X.X.X.X.")
|
89
|
+
assert_pattern_tracks(pattern, {"my_sound2" => {name: "my_sound2", rhythm: "X...X..."},
|
90
|
+
"my_sound" => {name: "my_sound", rhythm: "X.X.X.X."}})
|
91
|
+
|
92
|
+
# The first attempt at a unique name would be "my_sound2", but that is already taken
|
93
|
+
pattern.track("my_sound", "XXXXXXXX")
|
94
|
+
assert_pattern_tracks(pattern, {"my_sound2" => {name: "my_sound2", rhythm: "X...X..."},
|
95
|
+
"my_sound" => {name: "my_sound", rhythm: "X.X.X.X."},
|
96
|
+
"my_sound3" => {name: "my_sound", rhythm: "XXXXXXXX"}})
|
97
|
+
end
|
98
|
+
|
45
99
|
def test_step_count
|
46
100
|
test_patterns = generate_test_data
|
47
101
|
|
@@ -96,4 +150,15 @@ class PatternTest < Test::Unit::TestCase
|
|
96
150
|
assert_equal(false, left_pattern.same_tracks_as?(something_extra))
|
97
151
|
assert_equal(false, something_extra.same_tracks_as?(left_pattern))
|
98
152
|
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def assert_pattern_tracks(pattern, expected_pattern_structure)
|
157
|
+
assert_equal(expected_pattern_structure.keys, pattern.tracks.keys)
|
158
|
+
|
159
|
+
expected_pattern_structure.each do |pattern_key, expected_track|
|
160
|
+
assert_equal(expected_track[:name], pattern.tracks[pattern_key].name)
|
161
|
+
assert_equal(expected_track[:rhythm], pattern.tracks[pattern_key].rhythm)
|
162
|
+
end
|
163
|
+
end
|
99
164
|
end
|
data/test/song_swinger_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'includes'
|
2
2
|
|
3
|
-
class SongSwingerTest < Test
|
3
|
+
class SongSwingerTest < Minitest::Test
|
4
4
|
def test_full_song_swing_rate_8
|
5
5
|
base_path = File.dirname(__FILE__) + "/sounds"
|
6
6
|
song, kit = SongParser.new.parse(base_path, File.read("test/fixtures/valid/example_mono_16_base_path.txt"))
|
@@ -145,7 +145,7 @@ class SongSwingerTest < Test::Unit::TestCase
|
|
145
145
|
song = Song.new
|
146
146
|
song.tempo = 100
|
147
147
|
|
148
|
-
|
148
|
+
assert_raises(Transforms::SongSwinger::InvalidSwingRateError) do
|
149
149
|
song = Transforms::SongSwinger.transform(song, invalid_swing_rate)
|
150
150
|
end
|
151
151
|
end
|
data/test/song_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'includes'
|
2
2
|
|
3
|
-
class SongTest < Test
|
3
|
+
class SongTest < Minitest::Test
|
4
4
|
FIXTURES = [:repeats_not_specified,
|
5
5
|
:pattern_with_overflow,
|
6
6
|
:example_no_kit,
|
@@ -50,40 +50,28 @@ class SongTest < Test::Unit::TestCase
|
|
50
50
|
|
51
51
|
song.tempo = 150
|
52
52
|
assert_equal(150, song.tempo)
|
53
|
-
|
53
|
+
|
54
54
|
song.tempo = 145.854
|
55
55
|
assert_equal(145.854, song.tempo)
|
56
56
|
|
57
|
-
|
58
|
-
song.tempo =
|
59
|
-
end
|
60
|
-
|
61
|
-
assert_raise(InvalidTempoError) do
|
62
|
-
song.tempo = -1.0
|
63
|
-
end
|
64
|
-
|
65
|
-
assert_raise(InvalidTempoError) do
|
66
|
-
song.tempo = "abc"
|
67
|
-
end
|
68
|
-
|
69
|
-
assert_raise(InvalidTempoError) do
|
70
|
-
song.tempo = "150"
|
57
|
+
[-1, -1.0, "abc", "150"].each do |invalid_tempo|
|
58
|
+
assert_raises(Song::InvalidTempoError) { song.tempo = invalid_tempo }
|
71
59
|
end
|
72
60
|
end
|
73
61
|
|
74
62
|
def test_pattern
|
75
63
|
song = Song.new
|
76
|
-
verse1 = song.pattern
|
64
|
+
verse1 = song.pattern(:Verse)
|
77
65
|
|
78
66
|
assert_equal(:Verse, verse1.name)
|
79
67
|
assert_equal({:Verse => verse1}, song.patterns)
|
80
68
|
|
81
|
-
verse2 = song.pattern
|
69
|
+
verse2 = song.pattern(:Verse)
|
82
70
|
assert_equal(:Verse, verse2.name)
|
83
71
|
assert_equal({:Verse => verse2}, song.patterns)
|
84
|
-
|
72
|
+
refute_equal(verse1, verse2)
|
85
73
|
|
86
|
-
chorus = song.pattern
|
74
|
+
chorus = song.pattern(:Chorus)
|
87
75
|
assert_equal(2, song.patterns.length)
|
88
76
|
assert_equal({:Chorus => chorus, :Verse => verse2}, song.patterns)
|
89
77
|
end
|
@@ -128,7 +116,7 @@ class SongTest < Test::Unit::TestCase
|
|
128
116
|
original_song = test_songs[:example_no_kit]
|
129
117
|
cloned_song = original_song.copy_ignoring_patterns_and_flow
|
130
118
|
|
131
|
-
|
119
|
+
refute_equal(cloned_song, original_song)
|
132
120
|
assert_equal(cloned_song.tempo, original_song.tempo)
|
133
121
|
assert_equal([], cloned_song.flow)
|
134
122
|
assert_equal({}, cloned_song.patterns)
|
@@ -178,16 +166,4 @@ class SongTest < Test::Unit::TestCase
|
|
178
166
|
assert_equal(3, test_songs[:example_no_kit].patterns.length)
|
179
167
|
assert_equal(Hash, test_songs[:example_no_kit].patterns.class)
|
180
168
|
end
|
181
|
-
|
182
|
-
def test_to_yaml
|
183
|
-
test_songs = generate_test_data
|
184
|
-
kit = Kit.new("test/sounds", {"bass" => "bass_mono_8.wav",
|
185
|
-
"snare" => "snare_mono_8.wav",
|
186
|
-
"hhclosed" => "hh_closed_mono_8.wav",
|
187
|
-
"hhopen" => "hh_open_mono_8.wav"})
|
188
|
-
|
189
|
-
result = test_songs[:example_with_kit].to_yaml(kit)
|
190
|
-
|
191
|
-
assert_equal(File.read("test/fixtures/yaml/song_yaml.txt"), result)
|
192
|
-
end
|
193
169
|
end
|
data/test/songoptimizer_test.rb
CHANGED
@@ -6,7 +6,7 @@ class MockSongOptimizer < SongOptimizer
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
class SongOptimizerTest < Test
|
9
|
+
class SongOptimizerTest < Minitest::Test
|
10
10
|
FIXTURE_BASE_PATH = File.dirname(__FILE__) + "/.."
|
11
11
|
|
12
12
|
EXAMPLE_SONG_YAML = "
|
@@ -18,10 +18,10 @@ Song:
|
|
18
18
|
- Verse: x2
|
19
19
|
- Chorus: x4
|
20
20
|
Kit:
|
21
|
-
- bass: sounds/
|
22
|
-
- snare: sounds/
|
23
|
-
- hh_closed: sounds/
|
24
|
-
- agogo: sounds/
|
21
|
+
- bass: sounds/bass_mono_8.wav
|
22
|
+
- snare: sounds/snare_mono_8.wav
|
23
|
+
- hh_closed: sounds/hh_closed_mono_8.wav
|
24
|
+
- agogo: sounds/agogo_high_mono_8.wav
|
25
25
|
|
26
26
|
Verse:
|
27
27
|
- bass: X...X...X...X...
|
@@ -33,8 +33,8 @@ Chorus:
|
|
33
33
|
- bass: X...X...XX..X...
|
34
34
|
- snare: ....X.......X...
|
35
35
|
- hh_closed: X.XXX.XXX.XX..X.
|
36
|
-
- sounds/
|
37
|
-
- sounds/
|
36
|
+
- sounds/tom4_mono_8.wav: ...........X....
|
37
|
+
- sounds/tom2_mono_8.wav: ..............X."
|
38
38
|
|
39
39
|
EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN = "
|
40
40
|
Song:
|
@@ -42,8 +42,8 @@ Song:
|
|
42
42
|
Flow:
|
43
43
|
- Verse: x1
|
44
44
|
Kit:
|
45
|
-
- bass: sounds/
|
46
|
-
- snare: sounds/
|
45
|
+
- bass: sounds/bass_mono_8.wav
|
46
|
+
- snare: sounds/snare_mono_8.wav
|
47
47
|
|
48
48
|
Verse:
|
49
49
|
- bass: X.......X...
|
@@ -55,7 +55,7 @@ Verse:
|
|
55
55
|
|
56
56
|
def test_optimize
|
57
57
|
parser = SongParser.new
|
58
|
-
original_song, kit = parser.parse(File.dirname(__FILE__)
|
58
|
+
original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML)
|
59
59
|
|
60
60
|
optimizer = SongOptimizer.new
|
61
61
|
optimized_song = optimizer.optimize(original_song, 4)
|
@@ -96,17 +96,17 @@ Verse:
|
|
96
96
|
assert_equal(pattern.tracks["hh_closed"].rhythm, "X.XX")
|
97
97
|
|
98
98
|
pattern = optimized_song.patterns[:chorus_8]
|
99
|
-
assert_equal(pattern.tracks.keys.sort, ["bass", "hh_closed", "sounds/
|
99
|
+
assert_equal(pattern.tracks.keys.sort, ["bass", "hh_closed", "sounds/tom4_mono_8.wav"])
|
100
100
|
assert_equal(pattern.tracks["bass"].rhythm, "XX..")
|
101
101
|
assert_equal(pattern.tracks["hh_closed"].rhythm, "X.XX")
|
102
|
-
assert_equal(pattern.tracks["sounds/
|
102
|
+
assert_equal(pattern.tracks["sounds/tom4_mono_8.wav"].rhythm, "...X")
|
103
103
|
|
104
104
|
pattern = optimized_song.patterns[:chorus_12]
|
105
|
-
assert_equal(pattern.tracks.keys.sort, ["bass", "hh_closed", "snare", "sounds/
|
105
|
+
assert_equal(pattern.tracks.keys.sort, ["bass", "hh_closed", "snare", "sounds/tom2_mono_8.wav"])
|
106
106
|
assert_equal(pattern.tracks["bass"].rhythm, "X...")
|
107
107
|
assert_equal(pattern.tracks["snare"].rhythm, "X...")
|
108
108
|
assert_equal(pattern.tracks["hh_closed"].rhythm, "..X.")
|
109
|
-
assert_equal(pattern.tracks["sounds/
|
109
|
+
assert_equal(pattern.tracks["sounds/tom2_mono_8.wav"].rhythm, "..X.")
|
110
110
|
|
111
111
|
assert_equal(optimized_song.flow, [:chorus_0, :chorus_0, :verse_8, :verse_12,
|
112
112
|
:chorus_0, :chorus_0, :verse_8, :verse_12,
|
@@ -124,7 +124,7 @@ Verse:
|
|
124
124
|
|
125
125
|
def test_optimize_song_nondivisible_max_pattern_length
|
126
126
|
parser = SongParser.new
|
127
|
-
original_song, kit = parser.parse(File.dirname(__FILE__)
|
127
|
+
original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
|
128
128
|
|
129
129
|
optimizer = SongOptimizer.new
|
130
130
|
optimized_song = optimizer.optimize(original_song, 7)
|
@@ -151,7 +151,7 @@ Verse:
|
|
151
151
|
|
152
152
|
def test_optimize_song_containing_empty_pattern
|
153
153
|
parser = SongParser.new
|
154
|
-
original_song, kit = parser.parse(File.dirname(__FILE__)
|
154
|
+
original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
|
155
155
|
|
156
156
|
optimizer = SongOptimizer.new
|
157
157
|
optimized_song = optimizer.optimize(original_song, 4)
|
@@ -161,8 +161,8 @@ Verse:
|
|
161
161
|
assert_equal("X...", pattern.tracks["bass"].rhythm)
|
162
162
|
|
163
163
|
pattern = optimized_song.patterns[:verse_4]
|
164
|
-
assert_equal([
|
165
|
-
assert_equal("....", pattern.tracks[
|
164
|
+
assert_equal([Kit::PLACEHOLDER_TRACK_NAME], pattern.tracks.keys.sort)
|
165
|
+
assert_equal("....", pattern.tracks[Kit::PLACEHOLDER_TRACK_NAME].rhythm)
|
166
166
|
|
167
167
|
pattern = optimized_song.patterns[:verse_8]
|
168
168
|
assert_equal(["bass", "snare"], pattern.tracks.keys.sort)
|
data/test/songparser_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'includes'
|
2
2
|
|
3
|
-
class SongParserTest < Test
|
3
|
+
class SongParserTest < Minitest::Test
|
4
4
|
FIXTURE_BASE_PATH = File.dirname(__FILE__) + "/.."
|
5
5
|
|
6
6
|
# TODO: Add fixture for track with no rhythm
|
@@ -11,8 +11,8 @@ class SongParserTest < Test::Unit::TestCase
|
|
11
11
|
:example_no_kit,
|
12
12
|
:example_with_kit,
|
13
13
|
:example_with_empty_track,
|
14
|
+
:track_with_spaces,
|
14
15
|
:multiple_tracks_same_sound,
|
15
|
-
:with_structure,
|
16
16
|
:example_swung_8th,
|
17
17
|
:example_swung_16th,
|
18
18
|
:example_unswung]
|
@@ -24,7 +24,9 @@ class SongParserTest < Test::Unit::TestCase
|
|
24
24
|
:bad_swing_rate_2,
|
25
25
|
:no_header,
|
26
26
|
:no_flow,
|
27
|
+
:with_structure,
|
27
28
|
:pattern_with_no_tracks,
|
29
|
+
:leading_bar_line,
|
28
30
|
:sound_in_kit_not_found,
|
29
31
|
:sound_in_track_not_found,
|
30
32
|
:sound_in_kit_wrong_format,
|
@@ -84,6 +86,12 @@ class SongParserTest < Test::Unit::TestCase
|
|
84
86
|
assert_equal("........", song.patterns[:verse].tracks["test/sounds/bass_mono_8.wav"].rhythm)
|
85
87
|
assert_equal("X...X...", song.patterns[:verse].tracks["test/sounds/snare_mono_8.wav"].rhythm)
|
86
88
|
|
89
|
+
song = test_songs[:track_with_spaces]
|
90
|
+
assert_equal(1, song.patterns.length)
|
91
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
92
|
+
assert_equal("X...X...X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
93
|
+
assert_equal("....X.......X...", song.patterns[:verse].tracks["snare"].rhythm)
|
94
|
+
|
87
95
|
song = test_songs[:multiple_tracks_same_sound]
|
88
96
|
assert_equal(2, song.patterns.length)
|
89
97
|
assert_equal(7, song.patterns[:verse].tracks.length)
|
@@ -96,12 +104,14 @@ class SongParserTest < Test::Unit::TestCase
|
|
96
104
|
assert_equal("..............X.", song.patterns[:verse].tracks["snare"].rhythm)
|
97
105
|
assert_equal("X.XXX.XXX.X.X.X.", song.patterns[:verse].tracks["hh_closed"].rhythm)
|
98
106
|
assert_equal("..............XX", song.patterns[:verse].tracks["agogo"].rhythm)
|
99
|
-
|
100
|
-
|
101
|
-
assert_equal(
|
102
|
-
assert_equal(
|
103
|
-
assert_equal(
|
104
|
-
assert_equal("X
|
107
|
+
assert_equal(["bass", "bass2", "hh_closed", "snare", "test/sounds/tom2_mono_16.wav", "test/sounds/tom4_mono_16.wav"],
|
108
|
+
song.patterns[:chorus].tracks.keys.sort)
|
109
|
+
assert_equal("X...X...XX..X...", song.patterns[:chorus].tracks["bass"].rhythm)
|
110
|
+
assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
|
111
|
+
assert_equal("X.XXX.XXX.XX..X.", song.patterns[:chorus].tracks["hh_closed"].rhythm)
|
112
|
+
assert_equal("..X..X..X..X..X.", song.patterns[:chorus].tracks["bass2"].rhythm)
|
113
|
+
assert_equal("...........X....", song.patterns[:chorus].tracks["test/sounds/tom4_mono_16.wav"].rhythm)
|
114
|
+
assert_equal("..............X.", song.patterns[:chorus].tracks["test/sounds/tom2_mono_16.wav"].rhythm)
|
105
115
|
|
106
116
|
song = test_songs[:example_swung_8th]
|
107
117
|
assert_equal(180, song.tempo)
|
@@ -139,12 +149,12 @@ class SongParserTest < Test::Unit::TestCase
|
|
139
149
|
|
140
150
|
def test_invalid_parse
|
141
151
|
INVALID_FIXTURES.each do |fixture|
|
142
|
-
|
152
|
+
assert_raises(SongParser::ParseError) do
|
143
153
|
song = SongParserTest.load_fixture("invalid/#{fixture}.txt")
|
144
154
|
end
|
145
155
|
end
|
146
156
|
|
147
|
-
|
157
|
+
assert_raises(Track::InvalidRhythmError) do
|
148
158
|
song = SongParserTest.load_fixture("invalid/bad_rhythm.txt")
|
149
159
|
end
|
150
160
|
end
|
data/test/track_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'includes'
|
2
2
|
|
3
|
-
class TrackTest < Test
|
3
|
+
class TrackTest < Minitest::Test
|
4
4
|
def generate_test_data
|
5
5
|
test_tracks = {}
|
6
6
|
|
@@ -8,8 +8,9 @@ class TrackTest < Test::Unit::TestCase
|
|
8
8
|
test_tracks[:solo] = Track.new("bass", "X")
|
9
9
|
test_tracks[:with_overflow] = Track.new("bass", "...X")
|
10
10
|
test_tracks[:with_barlines] = Track.new("bass", "|X.X.|X.X.|")
|
11
|
+
test_tracks[:with_spaces] = Track.new("bass", " X... X.X. ")
|
11
12
|
test_tracks[:placeholder] = Track.new("bass", "....")
|
12
|
-
test_tracks[:complicated] = Track.new("bass", "..X...X...X
|
13
|
+
test_tracks[:complicated] = Track.new("bass", "..XX..X...X...X.X...X...X...X...")
|
13
14
|
|
14
15
|
test_tracks
|
15
16
|
end
|
@@ -17,26 +18,39 @@ class TrackTest < Test::Unit::TestCase
|
|
17
18
|
def test_initialize
|
18
19
|
test_tracks = generate_test_data
|
19
20
|
|
20
|
-
assert_equal([0], test_tracks[:blank].
|
21
|
+
assert_equal([0], test_tracks[:blank].trigger_step_lengths)
|
21
22
|
assert_equal("bass", test_tracks[:blank].name)
|
22
23
|
assert_equal("", test_tracks[:blank].rhythm)
|
23
24
|
|
24
|
-
assert_equal([0, 1], test_tracks[:solo].
|
25
|
+
assert_equal([0, 1], test_tracks[:solo].trigger_step_lengths)
|
25
26
|
assert_equal("bass", test_tracks[:solo].name)
|
26
27
|
assert_equal("X", test_tracks[:solo].rhythm)
|
27
28
|
|
28
|
-
assert_equal([3, 1], test_tracks[:with_overflow].
|
29
|
+
assert_equal([3, 1], test_tracks[:with_overflow].trigger_step_lengths)
|
29
30
|
assert_equal("...X", test_tracks[:with_overflow].rhythm)
|
30
31
|
|
31
|
-
assert_equal([0, 2, 2, 2, 2], test_tracks[:with_barlines].
|
32
|
+
assert_equal([0, 2, 2, 2, 2], test_tracks[:with_barlines].trigger_step_lengths)
|
32
33
|
# Bar lines should be removed from rhythm:
|
33
34
|
assert_equal("X.X.X.X.", test_tracks[:with_barlines].rhythm)
|
34
35
|
|
35
|
-
assert_equal([4], test_tracks[:
|
36
|
+
assert_equal([0, 4, 2, 2], test_tracks[:with_spaces].trigger_step_lengths)
|
37
|
+
# Spaces should be removed from rhythm:
|
38
|
+
assert_equal("X...X.X.", test_tracks[:with_spaces].rhythm)
|
39
|
+
|
40
|
+
assert_equal([4], test_tracks[:placeholder].trigger_step_lengths)
|
36
41
|
assert_equal("....", test_tracks[:placeholder].rhythm)
|
37
42
|
|
38
|
-
assert_equal([2,
|
39
|
-
assert_equal("..X...X...X
|
43
|
+
assert_equal([2, 1, 3, 4, 4, 2, 4, 4, 4, 4], test_tracks[:complicated].trigger_step_lengths)
|
44
|
+
assert_equal("..XX..X...X...X.X...X...X...X...", test_tracks[:complicated].rhythm)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_invalid_rhythm
|
48
|
+
assert_raises(Track::InvalidRhythmError) { Track.new("bad_rhythm", "abcde") }
|
49
|
+
assert_raises(Track::InvalidRhythmError) { Track.new("bad_rhythm", "X.X.e.X") }
|
50
|
+
|
51
|
+
track = Track.new("test", "X...")
|
52
|
+
assert_raises(Track::InvalidRhythmError) { track.rhythm = "abcde" }
|
53
|
+
assert_raises(Track::InvalidRhythmError) { track.rhythm = "X.X.e.X" }
|
40
54
|
end
|
41
55
|
|
42
56
|
def test_step_count
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Strait
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: wavefile
|
@@ -16,33 +16,32 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.8.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
27
|
-
description: A command-line drum machine.
|
28
|
-
|
26
|
+
version: 0.8.1
|
27
|
+
description: A command-line drum machine. Takes a song notated in a YAML file as input,
|
28
|
+
and outputs a *.wav sound file.
|
29
29
|
email: joel dot strait at Google's popular web mail service
|
30
30
|
executables:
|
31
31
|
- beats
|
32
|
-
extensions:
|
33
|
-
- ext/mkrf_conf.rb
|
32
|
+
extensions: []
|
34
33
|
extra_rdoc_files: []
|
35
34
|
files:
|
36
35
|
- LICENSE
|
37
36
|
- README.markdown
|
38
37
|
- Rakefile
|
39
38
|
- bin/beats
|
40
|
-
- ext/mkrf_conf.rb
|
41
39
|
- lib/beats.rb
|
42
40
|
- lib/beats/audioengine.rb
|
43
41
|
- lib/beats/audioutils.rb
|
44
42
|
- lib/beats/beatsrunner.rb
|
45
43
|
- lib/beats/kit.rb
|
44
|
+
- lib/beats/kit_builder.rb
|
46
45
|
- lib/beats/pattern.rb
|
47
46
|
- lib/beats/song.rb
|
48
47
|
- lib/beats/songoptimizer.rb
|
@@ -91,6 +90,7 @@ files:
|
|
91
90
|
- test/fixtures/invalid/bad_swing_rate_1.txt
|
92
91
|
- test/fixtures/invalid/bad_swing_rate_2.txt
|
93
92
|
- test/fixtures/invalid/bad_tempo.txt
|
93
|
+
- test/fixtures/invalid/leading_bar_line.txt
|
94
94
|
- test/fixtures/invalid/no_flow.txt
|
95
95
|
- test/fixtures/invalid/no_header.txt
|
96
96
|
- test/fixtures/invalid/pattern_with_no_tracks.txt
|
@@ -98,7 +98,7 @@ files:
|
|
98
98
|
- test/fixtures/invalid/sound_in_kit_wrong_format.txt
|
99
99
|
- test/fixtures/invalid/sound_in_track_not_found.txt
|
100
100
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
101
|
-
- test/fixtures/invalid/
|
101
|
+
- test/fixtures/invalid/with_structure.txt
|
102
102
|
- test/fixtures/valid/example_mono_16.txt
|
103
103
|
- test/fixtures/valid/example_mono_16_base_path.txt
|
104
104
|
- test/fixtures/valid/example_mono_8.txt
|
@@ -110,17 +110,17 @@ files:
|
|
110
110
|
- test/fixtures/valid/example_unswung.txt
|
111
111
|
- test/fixtures/valid/example_with_empty_track.txt
|
112
112
|
- test/fixtures/valid/example_with_kit.txt
|
113
|
-
- test/fixtures/valid/foo.txt
|
114
113
|
- test/fixtures/valid/fractional_tempo.txt
|
115
114
|
- test/fixtures/valid/multiple_tracks_same_sound.txt
|
116
115
|
- test/fixtures/valid/no_tempo.txt
|
117
116
|
- test/fixtures/valid/optimize_pattern_collision.txt
|
118
117
|
- test/fixtures/valid/pattern_with_overflow.txt
|
119
118
|
- test/fixtures/valid/repeats_not_specified.txt
|
120
|
-
- test/fixtures/valid/
|
119
|
+
- test/fixtures/valid/track_with_spaces.txt
|
121
120
|
- test/fixtures/yaml/song_yaml.txt
|
122
121
|
- test/includes.rb
|
123
122
|
- test/integration_test.rb
|
123
|
+
- test/kit_builder_test.rb
|
124
124
|
- test/kit_test.rb
|
125
125
|
- test/pattern_test.rb
|
126
126
|
- test/song_swinger_test.rb
|
@@ -135,8 +135,6 @@ files:
|
|
135
135
|
- test/sounds/agogo_low_mono_8.wav
|
136
136
|
- test/sounds/agogo_low_stereo_16.wav
|
137
137
|
- test/sounds/agogo_low_stereo_8.wav
|
138
|
-
- test/sounds/bass.wav
|
139
|
-
- test/sounds/bass2.wav
|
140
138
|
- test/sounds/bass2_mono_16.wav
|
141
139
|
- test/sounds/bass2_mono_8.wav
|
142
140
|
- test/sounds/bass2_stereo_16.wav
|
@@ -189,7 +187,6 @@ files:
|
|
189
187
|
- test/sounds/rim_mono_8.wav
|
190
188
|
- test/sounds/rim_stereo_16.wav
|
191
189
|
- test/sounds/rim_stereo_8.wav
|
192
|
-
- test/sounds/sine-mono-8bit.wav
|
193
190
|
- test/sounds/snare2_mono_16.wav
|
194
191
|
- test/sounds/snare2_mono_8.wav
|
195
192
|
- test/sounds/snare2_stereo_16.wav
|
@@ -214,32 +211,33 @@ files:
|
|
214
211
|
- test/sounds/tom4_mono_8.wav
|
215
212
|
- test/sounds/tom4_stereo_16.wav
|
216
213
|
- test/sounds/tom4_stereo_8.wav
|
217
|
-
- test/sounds/tone.wav
|
218
214
|
- test/track_test.rb
|
219
215
|
homepage: http://beatsdrummachine.com/
|
220
|
-
licenses:
|
216
|
+
licenses:
|
217
|
+
- MIT
|
221
218
|
metadata: {}
|
222
|
-
post_install_message:
|
219
|
+
post_install_message: Thanks for installing Beats Drum Machine! For information on
|
220
|
+
how to use Beats, or to download some drum sounds to use with Beats, visit http://beatsdrummachine.com
|
223
221
|
rdoc_options: []
|
224
222
|
require_paths:
|
225
223
|
- lib
|
226
224
|
required_ruby_version: !ruby/object:Gem::Requirement
|
227
225
|
requirements:
|
228
|
-
- -
|
226
|
+
- - ">="
|
229
227
|
- !ruby/object:Gem::Version
|
230
|
-
version:
|
228
|
+
version: 1.9.3
|
231
229
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
230
|
requirements:
|
233
|
-
- -
|
231
|
+
- - ">="
|
234
232
|
- !ruby/object:Gem::Version
|
235
233
|
version: '0'
|
236
234
|
requirements: []
|
237
235
|
rubyforge_project:
|
238
|
-
rubygems_version: 2.
|
236
|
+
rubygems_version: 2.6.13
|
239
237
|
signing_key:
|
240
238
|
specification_version: 4
|
241
|
-
summary: A command-line drum machine.
|
242
|
-
|
239
|
+
summary: A command-line drum machine. Takes a song notated in a YAML file as input,
|
240
|
+
and outputs a *.wav sound file.
|
243
241
|
test_files:
|
244
242
|
- test/audioengine_test.rb
|
245
243
|
- test/audioutils_test.rb
|
@@ -282,6 +280,7 @@ test_files:
|
|
282
280
|
- test/fixtures/invalid/bad_swing_rate_1.txt
|
283
281
|
- test/fixtures/invalid/bad_swing_rate_2.txt
|
284
282
|
- test/fixtures/invalid/bad_tempo.txt
|
283
|
+
- test/fixtures/invalid/leading_bar_line.txt
|
285
284
|
- test/fixtures/invalid/no_flow.txt
|
286
285
|
- test/fixtures/invalid/no_header.txt
|
287
286
|
- test/fixtures/invalid/pattern_with_no_tracks.txt
|
@@ -289,7 +288,7 @@ test_files:
|
|
289
288
|
- test/fixtures/invalid/sound_in_kit_wrong_format.txt
|
290
289
|
- test/fixtures/invalid/sound_in_track_not_found.txt
|
291
290
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
292
|
-
- test/fixtures/invalid/
|
291
|
+
- test/fixtures/invalid/with_structure.txt
|
293
292
|
- test/fixtures/valid/example_mono_16.txt
|
294
293
|
- test/fixtures/valid/example_mono_16_base_path.txt
|
295
294
|
- test/fixtures/valid/example_mono_8.txt
|
@@ -301,17 +300,17 @@ test_files:
|
|
301
300
|
- test/fixtures/valid/example_unswung.txt
|
302
301
|
- test/fixtures/valid/example_with_empty_track.txt
|
303
302
|
- test/fixtures/valid/example_with_kit.txt
|
304
|
-
- test/fixtures/valid/foo.txt
|
305
303
|
- test/fixtures/valid/fractional_tempo.txt
|
306
304
|
- test/fixtures/valid/multiple_tracks_same_sound.txt
|
307
305
|
- test/fixtures/valid/no_tempo.txt
|
308
306
|
- test/fixtures/valid/optimize_pattern_collision.txt
|
309
307
|
- test/fixtures/valid/pattern_with_overflow.txt
|
310
308
|
- test/fixtures/valid/repeats_not_specified.txt
|
311
|
-
- test/fixtures/valid/
|
309
|
+
- test/fixtures/valid/track_with_spaces.txt
|
312
310
|
- test/fixtures/yaml/song_yaml.txt
|
313
311
|
- test/includes.rb
|
314
312
|
- test/integration_test.rb
|
313
|
+
- test/kit_builder_test.rb
|
315
314
|
- test/kit_test.rb
|
316
315
|
- test/pattern_test.rb
|
317
316
|
- test/song_swinger_test.rb
|
@@ -326,8 +325,6 @@ test_files:
|
|
326
325
|
- test/sounds/agogo_low_mono_8.wav
|
327
326
|
- test/sounds/agogo_low_stereo_16.wav
|
328
327
|
- test/sounds/agogo_low_stereo_8.wav
|
329
|
-
- test/sounds/bass.wav
|
330
|
-
- test/sounds/bass2.wav
|
331
328
|
- test/sounds/bass2_mono_16.wav
|
332
329
|
- test/sounds/bass2_mono_8.wav
|
333
330
|
- test/sounds/bass2_stereo_16.wav
|
@@ -380,7 +377,6 @@ test_files:
|
|
380
377
|
- test/sounds/rim_mono_8.wav
|
381
378
|
- test/sounds/rim_stereo_16.wav
|
382
379
|
- test/sounds/rim_stereo_8.wav
|
383
|
-
- test/sounds/sine-mono-8bit.wav
|
384
380
|
- test/sounds/snare2_mono_16.wav
|
385
381
|
- test/sounds/snare2_mono_8.wav
|
386
382
|
- test/sounds/snare2_stereo_16.wav
|
@@ -405,5 +401,4 @@ test_files:
|
|
405
401
|
- test/sounds/tom4_mono_8.wav
|
406
402
|
- test/sounds/tom4_stereo_16.wav
|
407
403
|
- test/sounds/tom4_stereo_8.wav
|
408
|
-
- test/sounds/tone.wav
|
409
404
|
- test/track_test.rb
|