beats 2.1.0 → 2.1.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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +2 -2
  3. data/README.markdown +17 -80
  4. data/bin/beats +2 -7
  5. data/lib/beats.rb +12 -6
  6. data/lib/beats/{audioengine.rb → audio_engine.rb} +7 -8
  7. data/lib/beats/{audioutils.rb → audio_utils.rb} +35 -17
  8. data/lib/beats/{beatsrunner.rb → beats_runner.rb} +2 -2
  9. data/lib/beats/kit.rb +6 -5
  10. data/lib/beats/kit_builder.rb +12 -8
  11. data/lib/beats/pattern.rb +7 -16
  12. data/lib/beats/song.rb +7 -8
  13. data/lib/beats/{songoptimizer.rb → song_optimizer.rb} +11 -8
  14. data/lib/beats/{songparser.rb → song_parser.rb} +46 -48
  15. data/lib/beats/track.rb +14 -17
  16. data/lib/beats/transforms/song_swinger.rb +7 -5
  17. data/lib/wavefile/{cachingwriter.rb → caching_writer.rb} +2 -2
  18. data/test/{audioengine_test.rb → audio_engine_test.rb} +49 -46
  19. data/test/audio_utils_test.rb +86 -0
  20. data/test/{cachingwriter_test.rb → caching_writer_test.rb} +0 -0
  21. data/test/fixtures/invalid/sound_in_kit_wrong_format.txt +1 -1
  22. data/test/fixtures/invalid/sound_in_track_wrong_format.txt +1 -1
  23. data/test/fixtures/valid/empty_kit.txt +14 -0
  24. data/test/fixtures/valid/example_song_header_different_capitalization.txt +21 -0
  25. data/test/fixtures/valid/multiple_patterns_same_name.txt +31 -0
  26. data/test/fixtures/valid/multiple_song_header_sections.txt +29 -0
  27. data/test/includes.rb +0 -9
  28. data/test/kit_builder_test.rb +20 -0
  29. data/test/kit_test.rb +7 -0
  30. data/test/pattern_test.rb +86 -74
  31. data/test/{songoptimizer_test.rb → song_optimizer_test.rb} +5 -8
  32. data/test/{songparser_test.rb → song_parser_test.rb} +109 -13
  33. data/test/song_swinger_test.rb +6 -4
  34. data/test/song_test.rb +32 -14
  35. data/test/sounds/agogo_high_stereo_16.wav +0 -0
  36. data/test/sounds/agogo_low_stereo_16.wav +0 -0
  37. data/test/sounds/bass2_stereo_16.wav +0 -0
  38. data/test/sounds/bass_stereo_16.wav +0 -0
  39. data/test/sounds/clave_high_stereo_16.wav +0 -0
  40. data/test/sounds/clave_low_stereo_16.wav +0 -0
  41. data/test/sounds/conga_high_stereo_16.wav +0 -0
  42. data/test/sounds/conga_low_stereo_16.wav +0 -0
  43. data/test/sounds/cowbell_high_stereo_16.wav +0 -0
  44. data/test/sounds/cowbell_low_stereo_16.wav +0 -0
  45. data/test/sounds/hh_closed_stereo_16.wav +0 -0
  46. data/test/sounds/hh_open_stereo_16.wav +0 -0
  47. data/test/sounds/ride_stereo_16.wav +0 -0
  48. data/test/sounds/rim_stereo_16.wav +0 -0
  49. data/test/sounds/snare2_stereo_16.wav +0 -0
  50. data/test/sounds/snare_stereo_16.wav +0 -0
  51. data/test/sounds/tom1_stereo_16.wav +0 -0
  52. data/test/sounds/tom2_stereo_16.wav +0 -0
  53. data/test/sounds/tom3_stereo_16.wav +0 -0
  54. data/test/sounds/tom4_stereo_16.wav +0 -0
  55. data/test/track_test.rb +51 -5
  56. metadata +184 -176
  57. data/test/audioutils_test.rb +0 -46
@@ -50,12 +50,11 @@ Verse:
50
50
  - snare: ..........X."
51
51
 
52
52
  def self.load_fixture(fixture_name)
53
- SongParser.new.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
53
+ SongParser.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
54
54
  end
55
55
 
56
56
  def test_optimize
57
- parser = SongParser.new
58
- original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML)
57
+ original_song, _ = SongParser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML)
59
58
 
60
59
  optimizer = SongOptimizer.new
61
60
  optimized_song = optimizer.optimize(original_song, 4)
@@ -123,8 +122,7 @@ Verse:
123
122
  end
124
123
 
125
124
  def test_optimize_song_nondivisible_max_pattern_length
126
- parser = SongParser.new
127
- original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
125
+ original_song, _ = SongParser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
128
126
 
129
127
  optimizer = SongOptimizer.new
130
128
  optimized_song = optimizer.optimize(original_song, 7)
@@ -142,7 +140,7 @@ Verse:
142
140
  end
143
141
 
144
142
  def test_pattern_collision
145
- original_song, kit = SongOptimizerTest.load_fixture("valid/optimize_pattern_collision.txt")
143
+ original_song, _ = SongOptimizerTest.load_fixture("valid/optimize_pattern_collision.txt")
146
144
  optimizer = SongOptimizer.new
147
145
  optimized_song = optimizer.optimize(original_song, 4)
148
146
 
@@ -150,8 +148,7 @@ Verse:
150
148
  end
151
149
 
152
150
  def test_optimize_song_containing_empty_pattern
153
- parser = SongParser.new
154
- original_song, kit = parser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
151
+ original_song, _ = SongParser.parse(File.dirname(__FILE__), EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
155
152
 
156
153
  optimizer = SongOptimizer.new
157
154
  optimized_song = optimizer.optimize(original_song, 4)
@@ -24,24 +24,68 @@ class SongParserTest < Minitest::Test
24
24
  :sound_in_kit_wrong_format,
25
25
  :sound_in_track_wrong_format]
26
26
 
27
- # TODO: Add somes tests to validate the Kits
27
+ def test_song_header_different_capitalization
28
+ song, kit = load_fixture("valid/example_song_header_different_capitalization.txt")
29
+
30
+ assert_equal(100, song.tempo)
31
+ assert_equal([:verse, :chorus, :chorus, :verse, :chorus, :chorus], song.flow)
32
+ assert_equal(["bass", "snare", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
33
+ assert_equal(2, song.patterns.length)
34
+ assert_equal(2, song.patterns[:verse].tracks.length)
35
+ assert_equal("X...X...X...X...", song.patterns[:verse].tracks["bass"].rhythm)
36
+ assert_equal("..............X.", song.patterns[:verse].tracks["snare"].rhythm)
37
+ assert_equal(2, song.patterns[:chorus].tracks.length)
38
+ assert_equal("X...X...XX..X...", song.patterns[:chorus].tracks["bass"].rhythm)
39
+ assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
40
+ end
41
+
42
+ def test_multiple_song_headers
43
+ song, kit = load_fixture("valid/multiple_song_header_sections.txt")
44
+
45
+ assert_equal(200, song.tempo)
46
+ assert_equal([:chorus, :chorus, :chorus, :chorus], song.flow)
47
+ assert_equal(["bass", "snare", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
48
+ assert_equal(2, song.patterns.length)
49
+ assert_equal(2, song.patterns[:verse].tracks.length)
50
+ assert_equal("X...X...X...X...", song.patterns[:verse].tracks["bass"].rhythm)
51
+ assert_equal("..............X.", song.patterns[:verse].tracks["snare"].rhythm)
52
+ assert_equal(2, song.patterns[:chorus].tracks.length)
53
+ assert_equal("X...X...XX..X...", song.patterns[:chorus].tracks["bass"].rhythm)
54
+ assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
55
+ end
56
+
57
+ def test_multiple_patterns_same_name
58
+ song, kit = load_fixture("valid/multiple_patterns_same_name.txt")
59
+
60
+ assert_equal(120, song.tempo)
61
+ assert_equal([:verse, :verse, :chorus, :chorus, :verse, :verse, :chorus, :chorus], song.flow)
62
+ assert_equal(["bass", "snare", "hh_closed", "agogo", "test/sounds/tom4_mono_8.wav", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
63
+ assert_equal(2, song.patterns.length)
64
+ assert_equal(3, song.patterns[:verse].tracks.length)
65
+ assert_equal("X.X.X.X.", song.patterns[:verse].tracks["bass"].rhythm)
66
+ assert_equal(".X.X.X.X", song.patterns[:verse].tracks["snare"].rhythm)
67
+ assert_equal("XXXXXX..", song.patterns[:verse].tracks["test/sounds/tom4_mono_8.wav"].rhythm)
68
+ assert_equal(2, song.patterns[:chorus].tracks.length)
69
+ assert_equal("X...X...XX..X...", song.patterns[:chorus].tracks["bass"].rhythm)
70
+ assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
71
+ end
28
72
 
29
73
  def test_no_tempo
30
- song, kit = load_fixture("valid/no_tempo.txt")
74
+ song, _ = load_fixture("valid/no_tempo.txt")
31
75
 
32
76
  assert_equal(120, song.tempo)
33
77
  assert_equal([:verse], song.flow)
34
78
  end
35
79
 
36
80
  def test_fractional_tempo
37
- song, kit = load_fixture("valid/fractional_tempo.txt")
81
+ song, _ = load_fixture("valid/fractional_tempo.txt")
38
82
 
39
83
  assert_equal(95.764, song.tempo)
40
84
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
41
85
  end
42
86
 
43
87
  def test_repeats_not_specified
44
- song, kit = load_fixture("valid/repeats_not_specified.txt")
88
+ song, _ = load_fixture("valid/repeats_not_specified.txt")
45
89
 
46
90
  assert_equal(100, song.tempo)
47
91
  assert_equal([:verse], song.flow)
@@ -51,6 +95,7 @@ class SongParserTest < Minitest::Test
51
95
  song, kit = load_fixture("valid/example_flow_patterns_different_capitalization.txt")
52
96
 
53
97
  assert_equal(100, song.tempo)
98
+ assert_equal(["bass", "snare", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
54
99
  assert_equal([:verse, :chorus, :chorus, :verse, :chorus, :chorus], song.flow)
55
100
  assert_equal(2, song.patterns.length)
56
101
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -61,10 +106,39 @@ class SongParserTest < Minitest::Test
61
106
  assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
62
107
  end
63
108
 
109
+ def test_song_with_empty_kit
110
+ song, kit = load_fixture("valid/empty_kit.txt")
111
+
112
+ assert_equal(100, song.tempo)
113
+ assert_equal(["test/sounds/bass_mono_8.wav", "test/sounds/snare_mono_8.wav", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
114
+ assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
115
+ assert_equal(2, song.patterns.length)
116
+ assert_equal(2, song.patterns[:verse].tracks.length)
117
+ assert_equal("X...X...", song.patterns[:verse].tracks["test/sounds/bass_mono_8.wav"].rhythm)
118
+ assert_equal("..X...X.", song.patterns[:verse].tracks["test/sounds/snare_mono_8.wav"].rhythm)
119
+ assert_equal(2, song.patterns[:chorus].tracks.length)
120
+ assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["test/sounds/bass_mono_8.wav"].rhythm)
121
+ assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/snare_mono_8.wav"].rhythm)
122
+ end
123
+
64
124
  def test_song_with_unused_kit
65
125
  no_kit_song, no_kit_kit = load_fixture("valid/example_no_kit.txt")
66
126
  kit_song, kit_kit = load_fixture("valid/example_with_kit.txt")
67
127
 
128
+ assert_equal(["test/sounds/bass_mono_8.wav",
129
+ "test/sounds/snare_mono_8.wav",
130
+ "test/sounds/hh_closed_mono_8.wav",
131
+ "test/sounds/hh_open_mono_8.wav",
132
+ "test/sounds/ride_mono_8.wav",
133
+ "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], no_kit_kit.labels)
134
+ assert_equal(["bass",
135
+ "snare",
136
+ "hhclosed",
137
+ "hhopen",
138
+ "test/sounds/hh_closed_mono_8.wav",
139
+ "test/sounds/ride_mono_8.wav",
140
+ "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit_kit.labels)
141
+
68
142
  # These two songs should be the same, except that one uses a kit in the song header
69
143
  # and the other doesn't.
70
144
  [no_kit_song, kit_song].each do |song|
@@ -84,7 +158,7 @@ class SongParserTest < Minitest::Test
84
158
  end
85
159
 
86
160
  def test_empty_track
87
- song, kit = load_fixture("valid/example_with_empty_track.txt")
161
+ song, _ = load_fixture("valid/example_with_empty_track.txt")
88
162
 
89
163
  assert_equal(1, song.patterns.length)
90
164
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -93,7 +167,7 @@ class SongParserTest < Minitest::Test
93
167
  end
94
168
 
95
169
  def test_track_with_spaces
96
- song, kit = load_fixture("valid/track_with_spaces.txt")
170
+ song, _ = load_fixture("valid/track_with_spaces.txt")
97
171
 
98
172
  assert_equal(1, song.patterns.length)
99
173
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -102,7 +176,7 @@ class SongParserTest < Minitest::Test
102
176
  end
103
177
 
104
178
  def test_multiple_tracks_same_sound
105
- song, kit = load_fixture("valid/multiple_tracks_same_sound.txt")
179
+ song, _ = load_fixture("valid/multiple_tracks_same_sound.txt")
106
180
 
107
181
  assert_equal(2, song.patterns.length)
108
182
  assert_equal(7, song.patterns[:verse].tracks.length)
@@ -126,7 +200,7 @@ class SongParserTest < Minitest::Test
126
200
  end
127
201
 
128
202
  def test_swung_8
129
- song, kit = load_fixture("valid/example_swung_8th.txt")
203
+ song, _ = load_fixture("valid/example_swung_8th.txt")
130
204
 
131
205
  assert_equal(180, song.tempo)
132
206
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
@@ -140,7 +214,7 @@ class SongParserTest < Minitest::Test
140
214
  end
141
215
 
142
216
  def test_swung_16
143
- song, kit = load_fixture("valid/example_swung_16th.txt")
217
+ song, _ = load_fixture("valid/example_swung_16th.txt")
144
218
 
145
219
  assert_equal(180, song.tempo)
146
220
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
@@ -154,7 +228,7 @@ class SongParserTest < Minitest::Test
154
228
  end
155
229
 
156
230
  def test_unswung_song
157
- song, kit = load_fixture("valid/example_unswung.txt")
231
+ song, _ = load_fixture("valid/example_unswung.txt")
158
232
 
159
233
  assert_equal(120, song.tempo)
160
234
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
@@ -171,6 +245,7 @@ class SongParserTest < Minitest::Test
171
245
  song, kit = load_fixture("valid/track_with_composite_kit_sounds.txt")
172
246
 
173
247
  assert_equal(100, song.tempo)
248
+ assert_equal(["bass", "snare", "hh_closed", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
174
249
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
175
250
  assert_equal(2, song.patterns.length)
176
251
  assert_equal(3, song.patterns[:verse].tracks.length)
@@ -187,6 +262,12 @@ class SongParserTest < Minitest::Test
187
262
  song, kit = load_fixture("valid/track_with_composite_non_kit_sound.txt")
188
263
 
189
264
  assert_equal(100, song.tempo)
265
+ assert_equal(["bass",
266
+ "snare",
267
+ "hh_closed",
268
+ "test/sounds/agogo_high_mono_8.wav",
269
+ "test/sounds/hh_open_mono_8.wav",
270
+ "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
190
271
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
191
272
  assert_equal(2, song.patterns.length)
192
273
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -202,6 +283,11 @@ class SongParserTest < Minitest::Test
202
283
  song, kit = load_fixture("valid/track_with_composite_mix_kit_and_not_kit_sound.txt")
203
284
 
204
285
  assert_equal(100, song.tempo)
286
+ assert_equal(["bass",
287
+ "snare",
288
+ "hh_closed",
289
+ "test/sounds/hh_open_mono_8.wav",
290
+ "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
205
291
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
206
292
  assert_equal(2, song.patterns.length)
207
293
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -217,6 +303,13 @@ class SongParserTest < Minitest::Test
217
303
  song, kit = load_fixture("valid/track_with_composite_mix_kit_and_not_kit_sound_2.txt")
218
304
 
219
305
  assert_equal(100, song.tempo)
306
+ assert_equal(["bass",
307
+ "snare",
308
+ "hihat-hh_closed_mono_8",
309
+ "hihat-hh_open_mono_8",
310
+ "test/sounds/agogo_high_mono_8.wav",
311
+ "test/sounds/agogo_low_mono_8.wav",
312
+ "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
220
313
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
221
314
  assert_equal(2, song.patterns.length)
222
315
  assert_equal(3, song.patterns[:verse].tracks.length)
@@ -235,6 +328,7 @@ class SongParserTest < Minitest::Test
235
328
  song, kit = load_fixture("valid/track_with_composite_single_sound.txt")
236
329
 
237
330
  assert_equal(100, song.tempo)
331
+ assert_equal(["bass", "snare", "hh_closed", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
238
332
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
239
333
  assert_equal(2, song.patterns.length)
240
334
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -249,6 +343,7 @@ class SongParserTest < Minitest::Test
249
343
  song, kit = load_fixture("valid/kit_with_composite_sounds.txt")
250
344
 
251
345
  assert_equal(100, song.tempo)
346
+ assert_equal(["bass", "snare", "hihat-hh_closed_mono_8", "hihat-hh_open_mono_8", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
252
347
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
253
348
  assert_equal(2, song.patterns.length)
254
349
  assert_equal(3, song.patterns[:verse].tracks.length)
@@ -266,6 +361,7 @@ class SongParserTest < Minitest::Test
266
361
  song, kit = load_fixture("valid/kit_with_composite_single_sound.txt")
267
362
 
268
363
  assert_equal(100, song.tempo)
364
+ assert_equal(["bass", "snare", "hihat-hh_closed_mono_8", "empty_track_placeholder_name_234hkj32hjk4hjkhds23"], kit.labels)
269
365
  assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
270
366
  assert_equal(2, song.patterns.length)
271
367
  assert_equal(2, song.patterns[:verse].tracks.length)
@@ -280,18 +376,18 @@ class SongParserTest < Minitest::Test
280
376
  def test_invalid_parse
281
377
  INVALID_FIXTURES.each do |fixture|
282
378
  assert_raises(SongParser::ParseError) do
283
- song, kit = load_fixture("invalid/#{fixture}.txt")
379
+ _, _ = load_fixture("invalid/#{fixture}.txt")
284
380
  end
285
381
  end
286
382
 
287
383
  assert_raises(Track::InvalidRhythmError) do
288
- song, kit = load_fixture("invalid/bad_rhythm.txt")
384
+ _, _ = load_fixture("invalid/bad_rhythm.txt")
289
385
  end
290
386
  end
291
387
 
292
388
  private
293
389
 
294
390
  def load_fixture(fixture_name)
295
- SongParser.new.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
391
+ SongParser.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
296
392
  end
297
393
  end
@@ -3,7 +3,7 @@ require 'includes'
3
3
  class SongSwingerTest < Minitest::Test
4
4
  def test_full_song_swing_rate_8
5
5
  base_path = File.dirname(__FILE__) + "/sounds"
6
- song, kit = SongParser.new.parse(base_path, File.read("test/fixtures/valid/example_mono_16_base_path.txt"))
6
+ song, _ = SongParser.parse(base_path, File.read("test/fixtures/valid/example_mono_16_base_path.txt"))
7
7
 
8
8
  shuffled_song = Transforms::SongSwinger.transform(song, 8)
9
9
 
@@ -47,7 +47,7 @@ class SongSwingerTest < Minitest::Test
47
47
 
48
48
  def test_full_song_swing_rate_16
49
49
  base_path = File.dirname(__FILE__) + "/sounds"
50
- song, kit = SongParser.new.parse(base_path, File.read("test/fixtures/valid/example_mono_16_base_path.txt"))
50
+ song, _ = SongParser.parse(base_path, File.read("test/fixtures/valid/example_mono_16_base_path.txt"))
51
51
 
52
52
  shuffled_song = Transforms::SongSwinger.transform(song, 16)
53
53
 
@@ -157,8 +157,10 @@ class SongSwingerTest < Minitest::Test
157
157
  expectations.each do |original_rhythm, expected_rhythm|
158
158
  song = Song.new
159
159
 
160
- pattern = song.pattern(:my_pattern)
161
- pattern.track("track1", original_rhythm)
160
+ pattern_tracks = [
161
+ Track.new("track1", original_rhythm),
162
+ ]
163
+ pattern = song.pattern(:my_pattern, pattern_tracks)
162
164
 
163
165
  song.pattern(pattern)
164
166
 
@@ -13,25 +13,30 @@ class SongTest < Minitest::Test
13
13
  test_songs[:blank] = Song.new
14
14
 
15
15
  test_songs[:no_flow] = Song.new
16
- verse = test_songs[:no_flow].pattern :verse
17
- verse.track "bass.wav", "X.......X......."
18
- verse.track "snare.wav", "....X.......X..."
19
- verse.track "hh_closed.wav", "X.X.X.X.X.X.X.X."
16
+ verse_tracks = [
17
+ Track.new("bass.wav", "X.......X......."),
18
+ Track.new("snare.wav", "....X.......X..."),
19
+ Track.new("hh_closed.wav", "X.X.X.X.X.X.X.X."),
20
+ ]
21
+ test_songs[:no_flow].pattern(:verse, verse_tracks)
20
22
 
21
- song_parser = SongParser.new
22
23
  FIXTURES.each do |fixture_name|
23
- test_songs[fixture_name], throwaway_kit = song_parser.parse(base_path, File.read("test/fixtures/valid/#{fixture_name}.txt"))
24
+ test_songs[fixture_name], _ = SongParser.parse(base_path, File.read("test/fixtures/valid/#{fixture_name}.txt"))
24
25
  end
25
26
 
26
27
  test_songs[:from_code] = Song.new
27
- verse = test_songs[:from_code].pattern :verse
28
- verse.track "bass.wav", "X.......X......."
29
- verse.track "snare.wav", "....X.......X..."
30
- verse.track "hh_closed.wav", "X.X.X.X.X.X.X.X."
31
- chorus = test_songs[:from_code].pattern :chorus
32
- chorus.track "bass.wav", "X......."
33
- chorus.track "snare.wav", "....X..X"
34
- chorus.track "ride.wav", "X.....X."
28
+ verse_tracks = [
29
+ Track.new("bass.wav", "X.......X......."),
30
+ Track.new("snare.wav", "....X.......X..."),
31
+ Track.new("hh_closed.wav", "X.X.X.X.X.X.X.X."),
32
+ ]
33
+ test_songs[:from_code].pattern(:verse, verse_tracks)
34
+ chorus_tracks = [
35
+ Track.new("bass.wav", "X......."),
36
+ Track.new("snare.wav", "....X..X"),
37
+ Track.new("ride.wav", "X.....X."),
38
+ ]
39
+ test_songs[:from_code].pattern(:chorus, chorus_tracks)
35
40
  test_songs[:from_code].flow = [:verse, :chorus, :verse, :chorus, :chorus]
36
41
 
37
42
  test_songs
@@ -74,6 +79,19 @@ class SongTest < Minitest::Test
74
79
  chorus = song.pattern(:Chorus)
75
80
  assert_equal(2, song.patterns.length)
76
81
  assert_equal({:Chorus => chorus, :Verse => verse2}, song.patterns)
82
+
83
+ tracks = [
84
+ Track.new("track1", "X...X..."),
85
+ Track.new("track2", "X..."),
86
+ ]
87
+ tracks_provided = song.pattern(:Tracks_Provided, tracks)
88
+ assert_equal(3, song.patterns.length)
89
+ assert_equal({:Chorus => chorus, :Tracks_Provided => tracks_provided, :Verse => verse2}, song.patterns)
90
+ assert_equal(["track1", "track2"], song.track_names)
91
+ assert_equal(tracks_provided.tracks["track1"].rhythm, "X...X...")
92
+ assert_equal(tracks_provided.tracks["track1"].name, "track1")
93
+ assert_equal(tracks_provided.tracks["track2"].rhythm, "X.......")
94
+ assert_equal(tracks_provided.tracks["track2"].name, "track2")
77
95
  end
78
96
 
79
97
  def test_total_tracks
@@ -44,13 +44,59 @@ class TrackTest < Minitest::Test
44
44
  assert_equal("..XX..X...X...X.X...X...X...X...", test_tracks[:complicated].rhythm)
45
45
  end
46
46
 
47
+ def test_invalid_name
48
+ assert_raises(ArgumentError) { Track.new(:verse, "X...X...|X...X...") }
49
+ assert_raises(ArgumentError) { Track.new([], "X...X...|X...X...") }
50
+ assert_raises(ArgumentError) { Track.new({ :foo => :bar }, "X...X...|X...X...") }
51
+ end
52
+
53
+ def test_name_is_frozen
54
+ original_name = "Verse"
55
+ track = Track.new(original_name, "X...X...|X...X...")
56
+
57
+ # Track is initialized properly
58
+ assert_equal("Verse", track.name)
59
+ assert_equal("Verse", original_name)
60
+
61
+ # Name is frozen
62
+ assert_raises(RuntimeError) { track.name << "X" }
63
+
64
+ # Changing the original string doesn't modify the track name
65
+ original_name << "2"
66
+ assert_equal("Verse", track.name)
67
+ assert_equal("Verse2", original_name)
68
+ end
69
+
70
+ def test_rhythm_is_frozen
71
+ original_rhythm = "X...X...|X...X..."
72
+ track = Track.new("my_track", original_rhythm)
73
+
74
+ # Track is initialized properly
75
+ assert_equal("X...X...X...X...", track.rhythm)
76
+ assert_equal("X...X...|X...X...", original_rhythm)
77
+
78
+ # Rhythm is frozen
79
+ assert_raises(RuntimeError) { track.rhythm << "X" }
80
+
81
+ # Changing the original string doesn't modify the rhythm
82
+ original_rhythm << "X"
83
+ assert_equal("X...X...X...X...", track.rhythm)
84
+ assert_equal("X...X...|X...X...X", original_rhythm)
85
+ end
86
+
47
87
  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") }
88
+ [nil, 12, [], {}, :"X...X...", "abcde", "X.X.e.X"].each do |bad_rhythm|
89
+ assert_raises(Track::InvalidRhythmError) { Track.new("bad_rhythm", bad_rhythm) }
90
+ end
91
+ end
92
+
93
+ def test_trigger_step_lengths_is_frozen
94
+ track = Track.new("my_track", "X...X...|X...X...")
95
+
96
+ assert_equal([0, 4, 4, 4, 4], track.trigger_step_lengths)
50
97
 
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" }
98
+ assert_raises(RuntimeError) { track.trigger_step_lengths[2] = 5 }
99
+ assert_raises(RuntimeError) { track.trigger_step_lengths << [1] }
54
100
  end
55
101
 
56
102
  def test_step_count