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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.markdown +22 -42
  4. data/bin/beats +6 -7
  5. data/lib/beats.rb +2 -1
  6. data/lib/beats/audioengine.rb +13 -13
  7. data/lib/beats/beatsrunner.rb +7 -8
  8. data/lib/beats/kit.rb +12 -156
  9. data/lib/beats/kit_builder.rb +74 -0
  10. data/lib/beats/pattern.rb +2 -22
  11. data/lib/beats/song.rb +5 -55
  12. data/lib/beats/songoptimizer.rb +3 -3
  13. data/lib/beats/songparser.rb +25 -46
  14. data/lib/beats/track.rb +20 -31
  15. data/lib/beats/transforms/song_swinger.rb +2 -4
  16. data/lib/wavefile/cachingwriter.rb +2 -2
  17. data/test/audioengine_test.rb +22 -24
  18. data/test/audioutils_test.rb +1 -1
  19. data/test/cachingwriter_test.rb +13 -12
  20. data/test/fixtures/invalid/leading_bar_line.txt +15 -0
  21. data/test/fixtures/{valid → invalid}/with_structure.txt +2 -2
  22. data/test/fixtures/valid/multiple_tracks_same_sound.txt +2 -1
  23. data/test/fixtures/valid/optimize_pattern_collision.txt +4 -5
  24. data/test/fixtures/valid/track_with_spaces.txt +13 -0
  25. data/test/includes.rb +1 -4
  26. data/test/integration_test.rb +5 -5
  27. data/test/kit_builder_test.rb +52 -0
  28. data/test/kit_test.rb +18 -141
  29. data/test/pattern_test.rb +66 -1
  30. data/test/song_swinger_test.rb +2 -2
  31. data/test/song_test.rb +9 -33
  32. data/test/songoptimizer_test.rb +18 -18
  33. data/test/songparser_test.rb +20 -10
  34. data/test/track_test.rb +23 -9
  35. metadata +26 -31
  36. data/ext/mkrf_conf.rb +0 -28
  37. data/test/fixtures/invalid/template.txt +0 -31
  38. data/test/fixtures/valid/foo.txt +0 -18
  39. data/test/sounds/bass.wav +0 -0
  40. data/test/sounds/bass2.wav +0 -0
  41. data/test/sounds/sine-mono-8bit.wav +0 -0
  42. data/test/sounds/tone.wav +0 -0
@@ -1,6 +1,6 @@
1
1
  require 'includes'
2
2
 
3
- class PatternTest < Test::Unit::TestCase
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
@@ -1,6 +1,6 @@
1
1
  require 'includes'
2
2
 
3
- class SongSwingerTest < Test::Unit::TestCase
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
- assert_raise(Transforms::InvalidSwingRateError) do
148
+ assert_raises(Transforms::SongSwinger::InvalidSwingRateError) do
149
149
  song = Transforms::SongSwinger.transform(song, invalid_swing_rate)
150
150
  end
151
151
  end
@@ -1,6 +1,6 @@
1
1
  require 'includes'
2
2
 
3
- class SongTest < Test::Unit::TestCase
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
- assert_raise(InvalidTempoError) do
58
- song.tempo = -1
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 :Verse
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 :Verse
69
+ verse2 = song.pattern(:Verse)
82
70
  assert_equal(:Verse, verse2.name)
83
71
  assert_equal({:Verse => verse2}, song.patterns)
84
- assert_not_equal(verse1, verse2)
72
+ refute_equal(verse1, verse2)
85
73
 
86
- chorus = song.pattern :Chorus
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
- assert_not_equal(cloned_song, original_song)
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
@@ -6,7 +6,7 @@ class MockSongOptimizer < SongOptimizer
6
6
  end
7
7
  end
8
8
 
9
- class SongOptimizerTest < Test::Unit::TestCase
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/bass.wav
22
- - snare: sounds/snare.wav
23
- - hh_closed: sounds/hh_closed.wav
24
- - agogo: sounds/agogo_high.wav
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/tom4.wav: ...........X....
37
- - sounds/tom2.wav: ..............X."
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/bass.wav
46
- - snare: sounds/snare.wav
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__) + "/..", EXAMPLE_SONG_YAML)
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/tom4.wav"])
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/tom4.wav"].rhythm, "...X")
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/tom2.wav"])
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/tom2.wav"].rhythm, "..X.")
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__) + "/..", EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
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__) + "/..", EXAMPLE_SONG_YAML_EMPTY_SUB_PATTERN)
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(["placeholder"], pattern.tracks.keys.sort)
165
- assert_equal("....", pattern.tracks["placeholder"].rhythm)
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)
@@ -1,6 +1,6 @@
1
1
  require 'includes'
2
2
 
3
- class SongParserTest < Test::Unit::TestCase
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
- song = test_songs[:with_structure]
101
- assert_equal([:verse, :verse], song.flow)
102
- assert_equal(1, song.patterns.length)
103
- assert_equal(1, song.patterns[:verse].tracks.length)
104
- assert_equal("X...X...", song.patterns[:verse].tracks["test/sounds/bass_mono_8.wav"].rhythm)
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
- assert_raise(SongParseError) do
152
+ assert_raises(SongParser::ParseError) do
143
153
  song = SongParserTest.load_fixture("invalid/#{fixture}.txt")
144
154
  end
145
155
  end
146
156
 
147
- assert_raise(InvalidRhythmError) do
157
+ assert_raises(Track::InvalidRhythmError) do
148
158
  song = SongParserTest.load_fixture("invalid/bad_rhythm.txt")
149
159
  end
150
160
  end
@@ -1,6 +1,6 @@
1
1
  require 'includes'
2
2
 
3
- class TrackTest < Test::Unit::TestCase
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...X.X...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].beats)
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].beats)
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].beats)
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].beats)
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[:placeholder].beats)
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, 4, 4, 4, 2, 4, 4, 4, 4], test_tracks[:complicated].beats)
39
- assert_equal("..X...X...X...X.X...X...X...X...", test_tracks[:complicated].rhythm)
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: 1.3.0
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: 2014-03-05 00:00:00.000000000 Z
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.6.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.6.0
27
- description: A command-line drum machine. Feed it a song notated in YAML, and it will
28
- produce a precision-milled Wave file of impeccable timing and feel.
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/template.txt
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/with_structure.txt
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: '0'
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.2.2
236
+ rubygems_version: 2.6.13
239
237
  signing_key:
240
238
  specification_version: 4
241
- summary: A command-line drum machine. Feed it a song notated in YAML, and it will
242
- produce a precision-milled Wave file of impeccable timing and feel.
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/template.txt
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/with_structure.txt
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