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
@@ -0,0 +1,86 @@
1
+ require 'includes'
2
+
3
+ class AudioUtilsTest < Minitest::Test
4
+ def test_composite
5
+ assert_raises(ArgumentError) { AudioUtils.composite([[100, 200], [300, 400], [500, 600]], 0, 5) }
6
+ assert_raises(ArgumentError) { AudioUtils.composite([[100, 200], [300, 400], [500, 600]], -1, 5) }
7
+
8
+ # Mono empty arrays
9
+ assert_equal([], AudioUtils.composite([], 1))
10
+ assert_equal([], AudioUtils.composite([[]], 1))
11
+ assert_equal([], AudioUtils.composite([[], [], [], []], 1))
12
+
13
+ # Stereo empty arrays
14
+ assert_equal([], AudioUtils.composite([], 2))
15
+ assert_equal([], AudioUtils.composite([[]], 2))
16
+ assert_equal([], AudioUtils.composite([[], [], [], []], 2))
17
+
18
+ # Mono
19
+ assert_equal([10, 20, 30, 40], AudioUtils.composite([[10, 20, 30, 40]], 1))
20
+ assert_equal([10, 20, 30, 40], AudioUtils.composite([[10, 20, 30, 40], []], 1))
21
+ assert_equal([10, 20, 30, 40], AudioUtils.composite([[], [10, 20, 30, 40]], 1))
22
+ assert_equal([30, 50, 70, -10], AudioUtils.composite([[10, 20, 30, 40], [20, 30, 40, -50]], 1))
23
+ assert_equal([30, 50, 70, -10], AudioUtils.composite([[20, 30, 40, -50], [10, 20, 30, 40]], 1))
24
+ assert_equal([70, 80, 60], AudioUtils.composite([[20, 30], [10], [40, 50, 60]], 1))
25
+ assert_equal([70, 80, 60], AudioUtils.composite([[40, 50, 60], [20, 30], [10]], 1))
26
+
27
+ # Stereo
28
+ assert_equal([[10, 20], [30, 40]], AudioUtils.composite([[[10, 20], [30, 40]]], 2))
29
+ assert_equal([[10, 20], [30, 40]], AudioUtils.composite([[[10, 20], [30, 40]], []], 2))
30
+ assert_equal([[10, 20], [30, 40]], AudioUtils.composite([[], [[10, 20], [30, 40]]], 2))
31
+ assert_equal([[30, 50], [70, -10]], AudioUtils.composite([[[10, 20], [30, 40]], [[20, 30], [40, -50]]], 2))
32
+ assert_equal([[30, 50], [70, -10]], AudioUtils.composite([[[20, 30], [40, -50]], [[10, 20], [30, 40]]], 2))
33
+ assert_equal([[90, 120], [120, 140], [100, 110]], AudioUtils.composite([[[20, 30], [40, 50]], [[10, 20]], [[60, 70], [80, 90], [100, 110]]], 2))
34
+ assert_equal([[90, 120], [120, 140], [100, 110]], AudioUtils.composite([[[60, 70], [80, 90], [100, 110]], [[10, 20]], [[20, 30], [40, 50]]], 2))
35
+
36
+ # 3 Channel
37
+ assert_equal([[10, 20, 30], [30, 40, 50]], AudioUtils.composite([[[10, 20, 30], [30, 40, 50]]], 3))
38
+ assert_equal([[10, 20, 30], [30, 40, 50]], AudioUtils.composite([[[10, 20, 30], [30, 40, 50]], []], 3))
39
+ assert_equal([[10, 20, 30], [30, 40, 50]], AudioUtils.composite([[], [[10, 20, 30], [30, 40, 50]]], 3))
40
+ assert_equal([[30, 50, 70], [70, -10, -30]], AudioUtils.composite([[[10, 20, 30], [30, 40, 50]], [[20, 30, 40], [40, -50, -80]]], 3))
41
+ assert_equal([[30, 50, 70], [70, -10, -30]], AudioUtils.composite([[[20, 30, 40], [40, -50, -80]], [[10, 20, 30], [30, 40, 50]]], 3))
42
+ assert_equal([[90, 120, 150], [120, 140, 160], [100, 110, 120]], AudioUtils.composite([[[20, 30, 40], [40, 50, 60]],
43
+ [[10, 20, 30]],
44
+ [[60, 70, 80], [80, 90, 100], [100, 110, 120]]], 3))
45
+ assert_equal([[90, 120, 150], [120, 140, 160], [100, 110, 120]], AudioUtils.composite([[[60, 70, 80], [80, 90, 100], [100, 110, 120]],
46
+ [[10, 20, 30]],
47
+ [[20, 30, 40], [40, 50, 60]]], 3))
48
+ end
49
+
50
+ def test_scale
51
+ assert_equal([], AudioUtils.scale([], 1, 5))
52
+ assert_equal([], AudioUtils.scale([], 2, 5))
53
+ assert_equal([100, 200, 300, 400, 500], AudioUtils.scale([100, 200, 300, 400, 500], 1, 1))
54
+ assert_equal([20, 40, 60, 80, 100], AudioUtils.scale([100, 200, 300, 400, 500], 1, 5))
55
+
56
+ assert_equal([[100, 200], [300, 400], [500, 600]], AudioUtils.scale([[100, 200], [300, 400], [500, 600]], 2, 1))
57
+ assert_equal([[20, 40], [60, 80], [100, 120]], AudioUtils.scale([[100, 200], [300, 400], [500, 600]], 2, 5))
58
+
59
+ assert_equal([[10, 20, 30], [100, 200, 300], [1000, 2000, 3000]], AudioUtils.scale([[10, 20, 30], [100, 200, 300], [1000, 2000, 3000]], 3, 1))
60
+ assert_equal([[5, 10, 15], [50, 100, 150], [500, 1000, 1500]], AudioUtils.scale([[10, 20, 30], [100, 200, 300], [1000, 2000, 3000]], 3, 2))
61
+
62
+ assert_raises(ArgumentError) { AudioUtils.scale([[100, 200], [300, 400], [500, 600]], 0, 5) }
63
+ assert_raises(ArgumentError) { AudioUtils.scale([[100, 200], [300, 400], [500, 600]], -1, 5) }
64
+ end
65
+
66
+ def test_step_sample_length
67
+ assert_equal(6615.0, AudioUtils.step_sample_length(44100, 100))
68
+ assert_equal(3307.5, AudioUtils.step_sample_length(44100, 200))
69
+ assert_equal(3307.5, AudioUtils.step_sample_length(22050, 100))
70
+
71
+ assert_equal(6874.612880831729, AudioUtils.step_sample_length(44100, 96.2236))
72
+ assert_equal(3437.3064404158645, AudioUtils.step_sample_length(22050, 96.2236))
73
+ end
74
+
75
+ def test_step_start_sample
76
+ assert_equal(0, AudioUtils.step_start_sample(0, 100))
77
+ assert_equal(100, AudioUtils.step_start_sample(1, 100))
78
+ assert_equal(200, AudioUtils.step_start_sample(2, 100))
79
+ assert_equal(1500, AudioUtils.step_start_sample(15, 100))
80
+
81
+ assert_equal(0, AudioUtils.step_start_sample(0, 64.8))
82
+ assert_equal(64, AudioUtils.step_start_sample(1, 64.8))
83
+ assert_equal(129, AudioUtils.step_start_sample(2, 64.8))
84
+ assert_equal(972, AudioUtils.step_start_sample(15, 64.8))
85
+ end
86
+ end
@@ -4,7 +4,7 @@ Song:
4
4
  Flow:
5
5
  - Verse: x1
6
6
  Kit:
7
- - bad: test/songparser_test.rb
7
+ - bad: test/song_test.rb
8
8
 
9
9
  Verse:
10
10
  - bad: X...X...
@@ -5,4 +5,4 @@ Song:
5
5
  - Verse: x1
6
6
 
7
7
  Verse:
8
- - test/songparser_test.rb: X...X...
8
+ - test/song_test.rb: X...X...
@@ -0,0 +1,14 @@
1
+ Song:
2
+ Tempo: 100
3
+ # Kit is defined, but has no sounds. This is valid.
4
+ Kit:
5
+ Flow:
6
+ - Verse: x2
7
+ - Chorus: x2
8
+
9
+ Verse:
10
+ - test/sounds/bass_mono_8.wav: X...X...
11
+ - test/sounds/snare_mono_8.wav: ..X...X.
12
+ Chorus:
13
+ - test/sounds/bass_mono_8.wav: XXXXXXXX
14
+ - test/sounds/snare_mono_8.wav: .X.X.X.X
@@ -0,0 +1,21 @@
1
+ # The elements in the "Song" header have different capitalization from the normal examples
2
+ # The element keys should be case-insensitive, so this should be valid.
3
+
4
+ SONg:
5
+ TeMpO: 100
6
+ fLoW:
7
+ - Verse: x1
8
+ - Chorus: x2
9
+ - Verse: x1
10
+ - Chorus: x2
11
+ kIT:
12
+ - bass: test/sounds/bass_mono_8.wav
13
+ - snare: test/sounds/snare_mono_8.wav
14
+
15
+ Verse:
16
+ - bass: X...X...X...X...
17
+ - snare: ..............X.
18
+
19
+ Chorus:
20
+ - bass: X...X...XX..X...
21
+ - snare: ....X.......X...
@@ -0,0 +1,31 @@
1
+ Song:
2
+ Tempo: 120
3
+ Flow:
4
+ - Verse: x2
5
+ - Chorus: x2
6
+ - Verse: x2
7
+ - Chorus: x2
8
+ Kit:
9
+ - bass: test/sounds/bass_mono_8.wav
10
+ - snare: test/sounds/snare_mono_8.wav
11
+ - hh_closed: test/sounds/hh_closed_mono_8.wav
12
+ - agogo: test/sounds/agogo_high_mono_8.wav
13
+
14
+ # This pattern will be ignored because it is overridden by a different
15
+ # 'Verse' pattern later in the file.
16
+ Verse:
17
+ - bass: X...X...X...X...
18
+ - snare: ..............X.
19
+ - hh_closed: X.XXX.XX........
20
+ - hh_closed: ........X.X.X.X.
21
+ - agogo: ..............XX
22
+
23
+ Chorus:
24
+ - bass: X...X...XX..X...
25
+ - snare: ....X.......X...
26
+
27
+ # This is the winner, and should override the earlier 'Verse' definition
28
+ Verse:
29
+ - bass: X.X.X.X.
30
+ - snare: .X.X.X.X
31
+ - test/sounds/tom4_mono_8.wav: XXXXXX..
@@ -0,0 +1,29 @@
1
+ # This song header is ignored, because it is overridden by a subsequent song
2
+ # header at the end of the file
3
+ Song:
4
+ Tempo: 100
5
+ Flow:
6
+ - Verse: x1
7
+ - Chorus: x2
8
+ - Verse: x1
9
+ - Chorus: x2
10
+ Kit:
11
+ - bass: test/sounds/bass_mono_8.wav
12
+ - snare: test/sounds/snare_mono_8.wav
13
+
14
+ Verse:
15
+ - bass: X...X...X...X...
16
+ - snare: ..............X.
17
+
18
+ Chorus:
19
+ - bass: X...X...XX..X...
20
+ - snare: ....X.......X...
21
+
22
+ # This is the actual song header that should be used
23
+ Song:
24
+ Tempo: 200
25
+ Flow:
26
+ - Chorus: x4
27
+ Kit:
28
+ - bass: test/sounds/ride_mono_8.wav
29
+ - snare: test/sounds/snare2_mono_8.wav
@@ -1,12 +1,3 @@
1
- # Standard Ruby libraries
2
1
  require 'minitest/autorun'
3
- require 'yaml'
4
- require 'rubygems'
5
-
6
- # External gems
7
- require 'wavefile'
8
-
9
- # BEATS classes
10
2
  require 'beats'
11
- require 'wavefile/cachingwriter'
12
3
  include Beats
@@ -12,6 +12,26 @@ class KitBuilderTest < Minitest::Test
12
12
  assert_equal(false, kit_builder.has_label?("label2"))
13
13
  end
14
14
 
15
+ def test_add_item
16
+ kit_builder = KitBuilder.new("test/sounds")
17
+
18
+ kit_builder.add_item("bass", "bass_mono_8.wav")
19
+ assert_equal({}, kit_builder.composite_replacements)
20
+
21
+ kit_builder.add_item("snare", ["snare_mono_8.wav", "rim_mono_8.wav"])
22
+ assert_equal({"snare" => ["snare-snare_mono_8", "snare-rim_mono_8"]}, kit_builder.composite_replacements)
23
+
24
+ # Re-adding the same label with different sounds replaces the value in `composite_replacments`
25
+ kit_builder.add_item("snare", ["hhclosed_mono_8.wav", "ride_mono_8.wav"])
26
+ assert_equal({"snare" => ["snare-hhclosed_mono_8", "snare-ride_mono_8"]}, kit_builder.composite_replacements)
27
+
28
+ # Re-adding the same label with a non-composite sounds removes the value from `composite_replacments`
29
+ kit_builder.add_item("snare", "snare_mono_8.wav")
30
+ assert_equal({}, kit_builder.composite_replacements)
31
+
32
+ assert_raises(KitBuilder::SoundFileNotFoundError) { kit_builder.add_item("bass", []) }
33
+ end
34
+
15
35
  def test_build_kit_happy_path
16
36
  kit_builder = KitBuilder.new("test/sounds")
17
37
 
@@ -4,6 +4,7 @@ class KitTest < Minitest::Test
4
4
  def test_kit_with_items
5
5
  kit = Kit.new({'label1' => [1,2,3], 'label2' => [4,5,6], 'label3' => [7,8,9]}, 1, 16)
6
6
 
7
+ assert_equal(["label1", "label2", "label3"], kit.labels)
7
8
  assert_equal([1,2,3], kit.get_sample_data('label1'))
8
9
  assert_equal([4,5,6], kit.get_sample_data('label2'))
9
10
  assert_raises(Kit::LabelNotFoundError) { kit.get_sample_data('nope') }
@@ -12,16 +13,22 @@ class KitTest < Minitest::Test
12
13
 
13
14
  def test_kit_with_no_items
14
15
  kit = Kit.new({}, 1, 16)
16
+
17
+ assert_equal([], kit.labels)
15
18
  assert_raises(Kit::LabelNotFoundError) { kit.get_sample_data('foo') }
16
19
  end
17
20
 
18
21
  def test_num_channels
19
22
  kit = Kit.new({}, 2, 16)
23
+
24
+ assert_equal([], kit.labels)
20
25
  assert_equal(2, kit.num_channels)
21
26
  end
22
27
 
23
28
  def test_bits_per_sample
24
29
  kit = Kit.new({}, 2, 16)
30
+
31
+ assert_equal([], kit.labels)
25
32
  assert_equal(16, kit.bits_per_sample)
26
33
  end
27
34
  end
@@ -10,17 +10,21 @@ class PatternTest < Minitest::Test
10
10
  pattern = Pattern.new :blank
11
11
  test_patterns[:blank] = pattern
12
12
 
13
- pattern = Pattern.new :verse
14
- pattern.track "bass.wav", "X...X...X...XX..X...X...XX..X..."
15
- pattern.track "snare.wav", "..X...X...X...X.X...X...X...X..."
16
- pattern.track "hh_closed.wav", "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X."
17
- pattern.track "hh_open.wav", "X...............X..............X"
13
+ verse_tracks = [
14
+ Track.new("bass.wav", "X...X...X...XX..X...X...XX..X..."),
15
+ Track.new("snare.wav", "..X...X...X...X.X...X...X...X..."),
16
+ Track.new("hh_closed.wav", "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X."),
17
+ Track.new("hh_open.wav", "X...............X..............X"),
18
+ ]
19
+ pattern = Pattern.new(:verse, verse_tracks)
18
20
  test_patterns[:verse] = pattern
19
21
 
20
- pattern = Pattern.new :staircase
21
- pattern.track "bass.wav", "X..."
22
- pattern.track "snare.wav", "X.."
23
- pattern.track "hh_closed.wav", "X."
22
+ staircase_tracks = [
23
+ Track.new("bass.wav", "X..."),
24
+ Track.new("snare.wav", "X.."),
25
+ Track.new("hh_closed.wav", "X."),
26
+ ]
27
+ pattern = Pattern.new(:staircase, staircase_tracks)
24
28
  test_patterns[:staircase] = pattern
25
29
 
26
30
  test_patterns
@@ -40,36 +44,26 @@ class PatternTest < Minitest::Test
40
44
  pattern = test_patterns[:staircase]
41
45
  assert_equal(pattern.name, :staircase)
42
46
  assert_equal(pattern.tracks.length, 3)
43
- end
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
47
 
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........."}})
48
+ tracks = [
49
+ Track.new("track1", "X...X..."),
50
+ Track.new("track2", "X..."),
51
+ ]
52
+ pattern = Pattern.new(:tracks_provided_in_constructor, tracks)
53
+ assert_equal(pattern.name, :tracks_provided_in_constructor)
54
+ assert_equal(pattern.tracks.length, 2)
55
+ assert_pattern_tracks(pattern, {"track1" => {name: "track1", rhythm: "X...X..."},
56
+ "track2" => {name: "track2", rhythm: "X......."}})
57
+
58
+ tracks = [
59
+ Track.new("my_sound", "X...X..."),
60
+ Track.new("my_other_sound", "X..."),
61
+ Track.new("my_sound", ".X.........."),
62
+ Track.new("my_sound2", "..X........."),
63
+ Track.new("my_sound", ".."),
64
+ ]
65
+ pattern = Pattern.new("whatevs", tracks)
71
66
 
72
- pattern.track("my_sound", "..")
73
67
  assert_pattern_tracks(pattern, {"my_sound" => {name: "my_sound", rhythm: "X...X......."},
74
68
  "my_other_sound" => {name: "my_other_sound", rhythm: "X..........."},
75
69
  "my_sound2" => {name: "my_sound", rhythm: ".X.........."},
@@ -77,22 +71,28 @@ class PatternTest < Minitest::Test
77
71
  "my_sound3" => {name: "my_sound", rhythm: "............"},})
78
72
  end
79
73
 
80
- def test_track_unique_name_already_taken
81
- pattern = Pattern.new("whatevs")
82
-
83
- assert_equal({}, pattern.tracks)
74
+ def test_track_array_is_frozen
75
+ tracks = [
76
+ Track.new("my_sound1", "X...X..."),
77
+ Track.new("my_sound2", "X.X.X.X."),
78
+ Track.new("my_sound3", "XXXXXXXX"),
79
+ ]
80
+ pattern = Pattern.new("whatevs", tracks)
84
81
 
85
- pattern.track("my_sound2", "X...X...")
86
- assert_pattern_tracks(pattern, {"my_sound2" => {name: "my_sound2", rhythm: "X...X..."}})
82
+ assert_raises(RuntimeError) { pattern.tracks["my_sound4"] = Track.new("my_sound4", "X...X...") }
83
+ end
87
84
 
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."}})
85
+ def test_track_unique_name_already_taken
86
+ tracks = [
87
+ Track.new("my_sound2", "X...X..."),
88
+ Track.new("my_sound", "X.X.X.X."),
89
+ Track.new("my_sound", "XXXXXXXX"),
90
+ ]
91
+ pattern = Pattern.new("whatevs", tracks)
91
92
 
92
- # The first attempt at a unique name would be "my_sound2", but that is already taken
93
- pattern.track("my_sound", "XXXXXXXX")
94
93
  assert_pattern_tracks(pattern, {"my_sound2" => {name: "my_sound2", rhythm: "X...X..."},
95
94
  "my_sound" => {name: "my_sound", rhythm: "X.X.X.X."},
95
+ # The first attempt at a unique name would be "my_sound2", but that is already taken
96
96
  "my_sound3" => {name: "my_sound", rhythm: "XXXXXXXX"}})
97
97
  end
98
98
 
@@ -105,48 +105,60 @@ class PatternTest < Minitest::Test
105
105
  end
106
106
 
107
107
  def test_same_tracks_as?
108
- left_pattern = Pattern.new("left")
109
- left_pattern.track("bass", "X...X...")
110
- left_pattern.track("snare", "..X...X.")
111
- left_pattern.track("hh_closed", "X.X.X.X.")
112
-
113
- right_pattern = Pattern.new("right")
114
- right_pattern.track("bass", "X...X...")
115
- right_pattern.track("snare", "..X...X.")
116
- right_pattern.track("hh_closed", "X.X.X.X.")
108
+ left_tracks = [
109
+ Track.new("bass", "X...X..."),
110
+ Track.new("snare", "..X...X."),
111
+ Track.new("hh_closed", "X.X.X.X."),
112
+ ]
113
+ left_pattern = Pattern.new("left", left_tracks)
114
+
115
+ right_tracks = [
116
+ Track.new("bass", "X...X..."),
117
+ Track.new("snare", "..X...X."),
118
+ Track.new("hh_closed", "X.X.X.X."),
119
+ ]
120
+ right_pattern = Pattern.new("right", right_tracks)
117
121
  assert(left_pattern.same_tracks_as?(right_pattern))
118
122
  assert(right_pattern.same_tracks_as?(left_pattern))
119
123
 
120
124
  # Now switch up the order. Left and right should still be equal.
121
- right_pattern = Pattern.new("right")
122
- right_pattern.track("snare", "..X...X.")
123
- right_pattern.track("hh_closed", "X.X.X.X.")
124
- right_pattern.track("bass", "X...X...")
125
+ right_tracks = [
126
+ Track.new("snare", "..X...X."),
127
+ Track.new("hh_closed", "X.X.X.X."),
128
+ Track.new("bass", "X...X..."),
129
+ ]
130
+ right_pattern = Pattern.new("right", right_tracks)
125
131
  assert(left_pattern.same_tracks_as?(right_pattern))
126
132
  assert(right_pattern.same_tracks_as?(left_pattern))
127
133
 
128
134
  # Now compare the pattern with same rhythms but different track names. Should not be equal.
129
- different_names_pattern = Pattern.new("different_names")
130
- different_names_pattern.track("tom", "X...X...")
131
- different_names_pattern.track("cymbal", "..X...X.")
132
- different_names_pattern.track("hh_open", "X.X.X.X.")
135
+ different_names_tracks = [
136
+ Track.new("tom", "X...X..."),
137
+ Track.new("cymbal", "..X...X."),
138
+ Track.new("hh_open", "X.X.X.X."),
139
+ ]
140
+ different_names_pattern = Pattern.new("different_names", different_names_tracks)
133
141
  assert_equal(false, left_pattern.same_tracks_as?(different_names_pattern))
134
142
  assert_equal(false, different_names_pattern.same_tracks_as?(left_pattern))
135
143
 
136
144
  # Now compare the pattern with same track names but different rhythms. Should not be equal.
137
- different_beats_pattern = Pattern.new("different_beats")
138
- different_beats_pattern.track("bass", "X...X...")
139
- different_beats_pattern.track("snare", "..X...X.")
140
- different_beats_pattern.track("hh_closed", "X.XXX.X.")
145
+ different_beats_tracks = [
146
+ Track.new("bass", "X...X..."),
147
+ Track.new("snare", "..X...X."),
148
+ Track.new("hh_closed", "X.XXX.X."),
149
+ ]
150
+ different_beats_pattern = Pattern.new("different_beats", different_beats_tracks)
141
151
  assert_equal(false, left_pattern.same_tracks_as?(different_beats_pattern))
142
152
  assert_equal(false, different_beats_pattern.same_tracks_as?(left_pattern))
143
153
 
144
154
  # Now compare a pattern with the same tracks, but with one extra one as well. Should not be equal.
145
- something_extra = Pattern.new("something_extra")
146
- something_extra.track("bass", "X...X...")
147
- something_extra.track("snare", "..X...X.")
148
- something_extra.track("hh_closed", "X.X.X.X.")
149
- something_extra.track("extra", "X..X..X.")
155
+ something_extra_tracks = [
156
+ Track.new("bass", "X...X..."),
157
+ Track.new("snare", "..X...X."),
158
+ Track.new("hh_closed", "X.X.X.X."),
159
+ Track.new("extra", "X..X..X."),
160
+ ]
161
+ something_extra = Pattern.new("something_extra", something_extra_tracks)
150
162
  assert_equal(false, left_pattern.same_tracks_as?(something_extra))
151
163
  assert_equal(false, something_extra.same_tracks_as?(left_pattern))
152
164
  end