beats 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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