beats 1.2.0 → 1.2.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 (69) hide show
  1. data/LICENSE +1 -1
  2. data/README.markdown +28 -10
  3. data/bin/beats +9 -7
  4. data/lib/audioengine.rb +172 -0
  5. data/lib/audioutils.rb +73 -0
  6. data/lib/beats.rb +14 -15
  7. data/lib/beatswavefile.rb +17 -37
  8. data/lib/kit.rb +148 -71
  9. data/lib/pattern.rb +20 -117
  10. data/lib/patternexpander.rb +111 -0
  11. data/lib/song.rb +78 -132
  12. data/lib/songoptimizer.rb +29 -33
  13. data/lib/songparser.rb +70 -45
  14. data/lib/track.rb +11 -82
  15. data/test/audioengine_test.rb +261 -0
  16. data/test/audioutils_test.rb +45 -0
  17. data/test/fixtures/expected_output/example_split_mono_16-hh_closed.wav +0 -0
  18. data/test/{examples/split-agogo_high.wav → fixtures/expected_output/example_split_mono_16-hh_closed2.wav} +0 -0
  19. data/test/fixtures/expected_output/example_split_mono_8-hh_closed.wav +0 -0
  20. data/test/{examples/split-tom4.wav → fixtures/expected_output/example_split_mono_8-hh_closed2.wav} +0 -0
  21. data/test/fixtures/expected_output/example_split_stereo_16-hh_closed.wav +0 -0
  22. data/test/fixtures/expected_output/example_split_stereo_16-hh_closed2.wav +0 -0
  23. data/test/fixtures/expected_output/example_split_stereo_8-hh_closed.wav +0 -0
  24. data/test/fixtures/expected_output/example_split_stereo_8-hh_closed2.wav +0 -0
  25. data/test/fixtures/invalid/{bad_structure.txt → bad_flow.txt} +2 -2
  26. data/test/fixtures/invalid/bad_repeat_count.txt +1 -1
  27. data/test/fixtures/invalid/bad_rhythm.txt +1 -1
  28. data/test/fixtures/invalid/bad_tempo.txt +1 -1
  29. data/test/fixtures/invalid/{no_structure.txt → no_flow.txt} +1 -1
  30. data/test/fixtures/invalid/pattern_with_no_tracks.txt +1 -1
  31. data/test/fixtures/invalid/sound_in_kit_not_found.txt +1 -1
  32. data/test/fixtures/invalid/sound_in_kit_wrong_format.txt +10 -0
  33. data/test/fixtures/invalid/sound_in_track_not_found.txt +1 -1
  34. data/test/fixtures/invalid/sound_in_track_wrong_format.txt +8 -0
  35. data/test/fixtures/invalid/template.txt +1 -1
  36. data/test/fixtures/valid/example_mono_16.txt +5 -3
  37. data/test/fixtures/valid/example_mono_8.txt +5 -3
  38. data/test/fixtures/valid/example_no_kit.txt +1 -1
  39. data/test/fixtures/valid/example_stereo_16.txt +7 -4
  40. data/test/fixtures/valid/example_stereo_8.txt +5 -3
  41. data/test/fixtures/valid/example_with_empty_track.txt +1 -1
  42. data/test/fixtures/valid/example_with_kit.txt +1 -1
  43. data/test/fixtures/valid/multiple_tracks_same_sound.txt +33 -0
  44. data/test/fixtures/valid/no_tempo.txt +1 -1
  45. data/test/fixtures/valid/optimize_pattern_collision.txt +28 -0
  46. data/test/fixtures/valid/pattern_with_overflow.txt +1 -1
  47. data/test/fixtures/valid/repeats_not_specified.txt +2 -2
  48. data/test/fixtures/valid/with_structure.txt +10 -0
  49. data/test/fixtures/yaml/song_yaml.txt +5 -5
  50. data/test/includes.rb +4 -2
  51. data/test/integration.rb +3 -3
  52. data/test/kit_test.rb +136 -109
  53. data/test/pattern_test.rb +31 -131
  54. data/test/patternexpander_test.rb +142 -0
  55. data/test/song_test.rb +104 -102
  56. data/test/songoptimizer_test.rb +52 -38
  57. data/test/songparser_test.rb +79 -46
  58. data/test/sounds/composite_snare_mono_8_tom3_mono_16_mono_16.wav +0 -0
  59. data/test/sounds/composite_snare_mono_8_tom3_mono_8_mono_16.wav +0 -0
  60. data/test/sounds/composite_snare_stereo_16_tom3_mono_16_stereo_16.wav +0 -0
  61. data/test/sounds/composite_snare_stereo_8_tom3_mono_16_stereo_16.wav +0 -0
  62. data/test/track_test.rb +30 -185
  63. metadata +56 -24
  64. data/lib/songsplitter.rb +0 -38
  65. data/test/examples/combined.wav +0 -0
  66. data/test/examples/split-bass.wav +0 -0
  67. data/test/examples/split-hh_closed.wav +0 -0
  68. data/test/examples/split-snare.wav +0 -0
  69. data/test/examples/split-tom2.wav +0 -0
@@ -1,7 +1,7 @@
1
1
  # Invalid song, since the number of repeats for pattern Verse is not a number
2
2
  Song:
3
3
  Tempo: 100
4
- Structure:
4
+ Flow:
5
5
  - Verse: x2a
6
6
 
7
7
  Verse:
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 100
5
- Structure:
5
+ Flow:
6
6
  - Verse: x1
7
7
 
8
8
  Verse:
@@ -1,7 +1,7 @@
1
1
  # Invalid song, since the tempo is not a number
2
2
  Song:
3
3
  Tempo: 100a
4
- Structure:
4
+ Flow:
5
5
  - Verse: x2
6
6
 
7
7
  Verse:
@@ -1,4 +1,4 @@
1
- # Invalid song, since it doesn't have a structure section in the header
1
+ # Invalid song, since it doesn't have a Flow section in the header
2
2
  Song:
3
3
  Tempo: 100
4
4
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 100
5
- Structure:
5
+ Flow:
6
6
  - Verse: x1
7
7
  - Chorus: x1
8
8
 
@@ -1,7 +1,7 @@
1
1
  # Invalid song, since the Kit references a non-existent sound
2
2
  Song:
3
3
  Tempo: 100
4
- Structure:
4
+ Flow:
5
5
  - Verse: x1
6
6
  Kit:
7
7
  - bad: test/sounds/i_do_not_exist.wav
@@ -0,0 +1,10 @@
1
+ # Invalid song, since the Kit references a sound that is not a valid *.wav file.
2
+ Song:
3
+ Tempo: 100
4
+ Flow:
5
+ - Verse: x1
6
+ Kit:
7
+ - bad: test/songparser_test.rb
8
+
9
+ Verse:
10
+ - bad: X...X...
@@ -1,7 +1,7 @@
1
1
  # Invalid song, since a track references a non-existent sound
2
2
  Song:
3
3
  Tempo: 100
4
- Structure:
4
+ Flow:
5
5
  - Verse: x1
6
6
 
7
7
  Verse:
@@ -0,0 +1,8 @@
1
+ # Invalid song, since a track references a sound that is not a valid *.wav file.
2
+ Song:
3
+ Tempo: 100
4
+ Flow:
5
+ - Verse: x1
6
+
7
+ Verse:
8
+ - test/songparser_test.rb: X...X...
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 120
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x4
8
8
  - Verse: x2
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 120
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x4
8
8
  - Verse: x2
@@ -16,13 +16,15 @@ Song:
16
16
  Verse:
17
17
  - bass: X...X...X...X...
18
18
  - snare: ..............X.
19
- - hh_closed: X.XXX.XXX.X.X.X.
19
+ - hh_closed: X.XXX.XX........
20
+ - hh_closed: ........X.X.X.X.
20
21
  - agogo: ..............XX
21
22
 
22
23
  # Also including non-Kit sounds to test that they work as well:
23
24
  Chorus:
24
25
  - bass: X...X...XX..X...
25
26
  - snare: ....X.......X...
26
- - hh_closed: X.XXX.XXX.XX..X.
27
+ - hh_closed: X.XXX.XX........
28
+ - hh_closed: ........X.XX..X.
27
29
  - ../../sounds/tom4_mono_16.wav: ...........X....
28
30
  - ../../sounds/tom2_mono_16.wav: ..............X.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 120
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x4
8
8
  - Verse: x2
@@ -16,13 +16,15 @@ Song:
16
16
  Verse:
17
17
  - bass: X...X...X...X...
18
18
  - snare: ..............X.
19
- - hh_closed: X.XXX.XXX.X.X.X.
19
+ - hh_closed: X.XXX.XX........
20
+ - hh_closed: ........X.X.X.X.
20
21
  - agogo: ..............XX
21
22
 
22
23
  # Also including non-Kit sounds to test that they work as well:
23
24
  Chorus:
24
25
  - bass: X...X...XX..X...
25
26
  - snare: ....X.......X...
26
- - hh_closed: X.XXX.XXX.XX..X.
27
+ - hh_closed: X.XXX.XX........
28
+ - hh_closed: ........X.XX..X.
27
29
  - ../../sounds/tom4_mono_8.wav: ...........X....
28
30
  - ../../sounds/tom2_mono_8.wav: ..............X.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 99
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x2
8
8
  - Verse: x2
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 120
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x4
8
8
  - Verse: x2
@@ -16,13 +16,16 @@ Song:
16
16
  Verse:
17
17
  - bass: X...X...X...X...
18
18
  - snare: ..............X.
19
- - hh_closed: X.XXX.XXX.X.X.X.
19
+ - hh_closed: X.XXX.XX........
20
+ - hh_closed: ........X.X.X.X.
20
21
  - agogo: ..............XX
21
22
 
22
23
  # Also including non-Kit sounds to test that they work as well:
23
24
  Chorus:
24
25
  - bass: X...X...XX..X...
25
26
  - snare: ....X.......X...
26
- - hh_closed: X.XXX.XXX.XX..X.
27
+ - hh_closed: X.XXX.XX........
28
+ - hh_closed: ........X.XX..X.
27
29
  - ../../sounds/tom4_stereo_16.wav: ...........X....
28
- - ../../sounds/tom2_stereo_16.wav: ..............X.
30
+ - ../../sounds/tom2_stereo_16.wav: ..............X.
31
+
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 120
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
  - Chorus: x4
8
8
  - Verse: x2
@@ -16,13 +16,15 @@ Song:
16
16
  Verse:
17
17
  - bass: X...X...X...X...
18
18
  - snare: ..............X.
19
- - hh_closed: X.XXX.XXX.X.X.X.
19
+ - hh_closed: X.XXX.XX........
20
+ - hh_closed: ........X.X.X.X.
20
21
  - agogo: ..............XX
21
22
 
22
23
  # Also including non-Kit sounds to test that they work as well:
23
24
  Chorus:
24
25
  - bass: X...X...XX..X...
25
26
  - snare: ....X.......X...
26
- - hh_closed: X.XXX.XXX.XX..X.
27
+ - hh_closed: X.XXX.XX........
28
+ - hh_closed: ........X.XX..X.
27
29
  - ../../sounds/tom4_stereo_8.wav: ...........X....
28
30
  - ../../sounds/tom2_stereo_8.wav: ..............X.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 99
5
- Structure:
5
+ Flow:
6
6
  - Verse: x1
7
7
 
8
8
  Verse:
@@ -7,7 +7,7 @@ Song:
7
7
  - snare: test/sounds/snare_mono_8.wav
8
8
  - hhclosed: test/sounds/hh_closed_mono_8.wav
9
9
  - hhopen: test/sounds/hh_open_mono_8.wav
10
- Structure:
10
+ Flow:
11
11
  - Verse: x2
12
12
  - Chorus: x2
13
13
  - Verse: x2
@@ -0,0 +1,33 @@
1
+ # A song in which a pattern has multiple tracks that use the same sound
2
+ # The output should be the same as example_mono_16.txt
3
+ # TODO: Add integration tests to verify correct output
4
+
5
+ Song:
6
+ Tempo: 120
7
+ Flow:
8
+ - Verse: x2
9
+ - Chorus: x4
10
+ - Verse: x2
11
+ - Chorus: x4
12
+ Kit:
13
+ - bass: test/sounds/bass_mono_16.wav
14
+ - snare: test/sounds/snare_mono_16.wav
15
+ - hh_closed: test/sounds/hh_closed_mono_16.wav
16
+ - agogo: test/sounds/agogo_high_mono_16.wav
17
+
18
+ Verse:
19
+ - bass: X...............
20
+ - bass: ....X...........
21
+ - bass: ........X.......
22
+ - bass: ............X...
23
+ - snare: ..............X.
24
+ - hh_closed: X.XXX.XXX.X.X.X.
25
+ - agogo: ..............XX
26
+
27
+ # Also including non-Kit sounds to test that they work as well:
28
+ Chorus:
29
+ - bass: X...X...XX..X...
30
+ - snare: ....X.......X...
31
+ - hh_closed: X.XXX.XXX.XX..X.
32
+ - test/sounds/tom4_mono_16.wav: ...........X....
33
+ - test/sounds/tom2_mono_16.wav: ..............X.
@@ -1,7 +1,7 @@
1
1
  # Valid song file, despite not having a tempo. Tempo will be set to a default value.
2
2
 
3
3
  Song:
4
- Structure:
4
+ Flow:
5
5
  - Verse: x1
6
6
 
7
7
  Verse:
@@ -0,0 +1,28 @@
1
+ # Test fixture to verify SongOptimizer bug fix.
2
+ #
3
+ # SongOptimizer.subdivide_song_patterns() breaks up patterns into smaller sub-patterns. The bug
4
+ # was that when master patterns had numeric suffixes, new sub-patterns could be given names that
5
+ # collided with other sub-patterns. If they had different rhythms, one sub-pattern would obliterate
6
+ # the other one leading to incorrect song output.
7
+ #
8
+ # In the example below, when sub-dividing patterns with a max size of 4 steps, the new patterns
9
+ # highlighted with !!!! would both be called Verse20, causing a collision.
10
+
11
+
12
+ Song:
13
+ Flow:
14
+ - Verse
15
+ - Verse2
16
+
17
+
18
+ Verse:
19
+ # 0 4 8 12 16 20
20
+ # !!!!
21
+ - test/sounds/bass_mono_8.wav: |X...|X...|X...|X...|X...|X.XX|
22
+
23
+
24
+ Verse2:
25
+ # 0 4 8 12 16 20
26
+ # !!!!
27
+ - test/sounds/bass_mono_8.wav: |X..X|X..X|X..X|X..X|X..X|X..X|
28
+
@@ -2,7 +2,7 @@
2
2
 
3
3
  Song:
4
4
  Tempo: 100
5
- Structure:
5
+ Flow:
6
6
  - Verse: x2
7
7
 
8
8
  Verse:
@@ -1,9 +1,9 @@
1
- # The pattern Verse in the structure doesn't specify how many times it should repeat.
1
+ # The pattern Verse in the flow doesn't specify how many times it should repeat.
2
2
  # This is valid, it causes it to default to 1 repeat.
3
3
 
4
4
  Song:
5
5
  Tempo: 100
6
- Structure:
6
+ Flow:
7
7
  - Verse
8
8
 
9
9
  Verse:
@@ -0,0 +1,10 @@
1
+ # Header contains a "Structure" section instead of a "Flow" section.
2
+ # This is valid for now, but is deprecated.
3
+
4
+ Song:
5
+ Tempo: 100
6
+ Structure:
7
+ - Verse: x2
8
+
9
+ Verse:
10
+ - test/sounds/bass_mono_8.wav: X...X...
@@ -1,6 +1,6 @@
1
1
  Song:
2
2
  Tempo: 99
3
- Structure:
3
+ Flow:
4
4
  - Verse: x2
5
5
  - Chorus: x2
6
6
  - Verse: x2
@@ -8,10 +8,10 @@ Song:
8
8
  - Bridge: x1
9
9
  - Chorus: x4
10
10
  Kit:
11
- - bass: test/sounds/bass_mono_8.wav
12
- - hhclosed: test/sounds/hh_closed_mono_8.wav
13
- - hhopen: test/sounds/hh_open_mono_8.wav
14
- - snare: test/sounds/snare_mono_8.wav
11
+ - bass: bass_mono_8.wav
12
+ - hhclosed: hh_closed_mono_8.wav
13
+ - hhopen: hh_open_mono_8.wav
14
+ - snare: snare_mono_8.wav
15
15
 
16
16
  Bridge:
17
17
  - hhclosed: XX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.X
@@ -5,12 +5,14 @@ require 'rubygems'
5
5
  require 'wavefile'
6
6
 
7
7
  # BEATS classes
8
+ require 'audioengine'
9
+ require 'audioutils'
8
10
  require 'beats'
9
11
  require 'kit'
10
12
  require 'pattern'
13
+ require 'patternexpander'
11
14
  require 'song'
12
15
  require 'songparser'
13
16
  require 'songoptimizer'
14
- require 'songsplitter'
15
17
  require 'track'
16
- require 'beatswavefile'
18
+ require 'beatswavefile'
@@ -3,15 +3,15 @@ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
3
3
  require 'test/includes'
4
4
 
5
5
  class SongParserTest < Test::Unit::TestCase
6
- TRACK_NAMES = ["bass", "snare", "hh_closed", "agogo", "tom4", "tom2"]
6
+ TRACK_NAMES = ["bass", "snare", "hh_closed", "hh_closed2", "agogo", "tom4", "tom2"]
7
7
  OUTPUT_FOLDER = "test/integration_output"
8
8
 
9
9
  def test_bad_song_errors
10
10
  invalid_fixtures = ["bad_tempo.txt",
11
11
  "bad_repeat_count.txt",
12
- "bad_structure.txt",
12
+ "bad_flow.txt",
13
13
  "no_header.txt",
14
- "no_structure.txt",
14
+ "no_flow.txt",
15
15
  "sound_in_kit_not_found.txt",
16
16
  "sound_in_track_not_found.txt"]
17
17
 
@@ -2,125 +2,152 @@ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
2
 
3
3
  require 'test/includes'
4
4
 
5
- class SongTest < Test::Unit::TestCase
5
+ # Kit which allows directly changing the sound bank after initialization, to allows tests
6
+ # to use fixture data directly in the test instead of loading it from the file system.
7
+ class MutableKit < Kit
8
+ attr_accessor :sound_bank
9
+ end
10
+
11
+ class KitTest < Test::Unit::TestCase
6
12
  MIN_SAMPLE_8BIT = 0
7
13
  MAX_SAMPLE_8BIT = 255
8
14
 
9
- def test_valid_add
10
- # Test adding sounds with progressively higher bits per sample and num channels.
11
- # Verify that kit.bits_per_sample and kit.num_channels is ratcheted up.
12
- kit = Kit.new("test/sounds")
13
- assert_equal(16, kit.bits_per_sample)
14
- assert_equal(1, kit.num_channels)
15
- assert_equal(0, kit.size)
16
- kit.add("mono8", "bass_mono_8.wav")
17
- assert_equal(16, kit.bits_per_sample)
18
- assert_equal(1, kit.num_channels)
19
- assert_equal(1, kit.size)
20
- kit.add("mono16", "bass_mono_16.wav")
21
- assert_equal(16, kit.bits_per_sample)
22
- assert_equal(1, kit.num_channels)
23
- assert_equal(2, kit.size)
24
- kit.add("stereo16", "bass_stereo_16.wav")
25
- assert_equal(16, kit.bits_per_sample)
26
- assert_equal(2, kit.num_channels)
27
- assert_equal(3, kit.size)
28
-
29
- # Test adding sounds with progressively lower bits per sample and num channels.
30
- # Verify that kit.bits_per_sample and kit.num_channels doesn't change.
31
- kit = Kit.new("test/sounds")
32
- assert_equal(16, kit.bits_per_sample)
33
- assert_equal(1, kit.num_channels)
34
- kit.add("stereo16", "bass_stereo_16.wav")
35
- assert_equal(16, kit.bits_per_sample)
36
- assert_equal(2, kit.num_channels)
37
- kit.add("mono16", "bass_mono_16.wav")
38
- assert_equal(16, kit.bits_per_sample)
39
- assert_equal(2, kit.num_channels)
40
- kit.add("mono8", "bass_mono_8.wav")
41
- assert_equal(16, kit.bits_per_sample)
42
- assert_equal(2, kit.num_channels)
15
+ def generate_test_data
16
+ kits = {}
17
+
18
+ # Kit with no sounds
19
+ kits[:empty] = Kit.new("test/sounds", {})
20
+
21
+ # Kits which only has simple sounds
22
+ kits[:mono8] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav"})
23
+ kits[:mono16] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
24
+ "mono16" => "bass_mono_16.wav"})
25
+ kits[:stereo8] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
26
+ "stereo8" => "bass_stereo_8.wav"})
27
+ kits[:stereo16] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
28
+ "mono16" => "bass_mono_16.wav",
29
+ "stereo16" => "bass_stereo_16.wav"})
30
+
31
+ # Kits which contain a composite sound
32
+ #kits[:basic_composite] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
33
+ # "composite_mono8" => ["snare_mono_8.wav", "tom3_mono_8.wav"]})
34
+ #kits[:mismatched_bps_composite] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
35
+ # "composite_mono16" => ["snare_mono_8.wav", "tom3_mono_16.wav"]})
36
+ #kits[:mismatched_channels_composite] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
37
+ # "composite_stereo16" => ["snare_stereo_16.wav", "tom3_mono_16.wav"]})
38
+ #kits[:mismatched_everything_composite] = Kit.new("test/sounds", {"mono8" => "bass_mono_8.wav",
39
+ # "composite_stereo16" => ["snare_stereo_8.wav", "tom3_mono_16.wav"]})
40
+
41
+ return kits
43
42
  end
44
43
 
45
- def test_invalid_add
46
- kit = Kit.new("test/sounds")
47
- assert_raise(SoundNotFoundError) { kit.add("i_do_not_exist", "i_do_not_exist.wav") }
44
+ def test_valid_initialization
45
+ kits = generate_test_data()
46
+
47
+ assert_equal(16, kits[:empty].bits_per_sample)
48
+ assert_equal(1, kits[:empty].num_channels)
49
+
50
+ assert_equal(16, kits[:mono8].bits_per_sample)
51
+ assert_equal(1, kits[:mono8].num_channels)
52
+
53
+ assert_equal(16, kits[:mono16].bits_per_sample)
54
+ assert_equal(1, kits[:mono16].num_channels)
55
+
56
+ assert_equal(16, kits[:stereo8].bits_per_sample)
57
+ assert_equal(2, kits[:stereo8].num_channels)
58
+
59
+ assert_equal(16, kits[:stereo16].bits_per_sample)
60
+ assert_equal(2, kits[:stereo16].num_channels)
61
+
62
+ #assert_equal(16, kits[:basic_composite].bits_per_sample)
63
+ #assert_equal(1, kits[:basic_composite].num_channels)
64
+
65
+ #assert_equal(16, kits[:mismatched_bps_composite].bits_per_sample)
66
+ #assert_equal(1, kits[:mismatched_bps_composite].num_channels)
67
+
68
+ #assert_equal(16, kits[:mismatched_channels_composite].bits_per_sample)
69
+ #assert_equal(2, kits[:mismatched_channels_composite].num_channels)
70
+
71
+ #assert_equal(16, kits[:mismatched_everything_composite].bits_per_sample)
72
+ #assert_equal(2, kits[:mismatched_everything_composite].num_channels)
48
73
  end
49
-
74
+
75
+ def test_invalid_initialization
76
+ # Tests for adding non-existant sound file to Kit
77
+ assert_raise(SoundFileNotFoundError) { Kit.new("test/sounds", {"i_do_not_exist" => "i_do_not_exist.wav"}) }
78
+
79
+ assert_raise(SoundFileNotFoundError) { Kit.new("test/sounds", {"mono16" => "bass_mono_16.wav",
80
+ "i_do_not_exist" => "i_do_not_exist.wav"}) }
81
+
82
+ #assert_raise(SoundFileNotFoundError) { Kit.new("test/sounds", {"mono16" => "bass_mono_16.wav",
83
+ # "composite" => ["bass_mono_16.wav", "snare_mono_16.wav"],
84
+ # "i_do_not_exist" => "i_do_not_exist.wav"}) }
85
+
86
+ # Tests for adding invalid sound files to Kit
87
+ assert_raise(InvalidSoundFormatError) { Kit.new("test", {"bad" => "kit_test.rb"}) }
88
+
89
+ assert_raise(InvalidSoundFormatError) { Kit.new("test", {"mono16" => "sounds/bass_mono_16.wav",
90
+ "bad" => "kit_test.rb"}) }
91
+
92
+ #assert_raise(InvalidSoundFormatError) { Kit.new("test", {"mono16" => "sounds/bass_mono_16.wav",
93
+ # "composite" => ["sounds/bass_mono_16.wav", "sounds/snare_mono_16.wav"],
94
+ # "bad" => "kit_test.rb"}) }
95
+ end
96
+
50
97
  def test_get_sample_data
51
- kit = Kit.new("test/sounds")
52
-
53
- assert_raise(StandardError) { kit.get_sample_data("nonexistant") }
54
-
55
- # Test adding sounds with progressively higher bits per sample and num channels.
56
- # Verify that sample data bits per sample and num channels is ratcheted up.
57
- kit.add("mono8", "bass_mono_8.wav")
58
- sample_data = kit.get_sample_data("mono8")
59
- assert(sample_data.max > MAX_SAMPLE_8BIT)
60
- assert(sample_data.min < 0)
61
- all_are_fixnums = true
62
- sample_data.each do |sample|
63
- all_are_fixnums &&= sample.class == Fixnum
64
- end
65
- assert(all_are_fixnums)
66
-
67
- kit.add("mono16", "bass_mono_16.wav")
68
- sample_data = kit.get_sample_data("mono8")
69
- assert(sample_data.max > MAX_SAMPLE_8BIT)
70
- assert(sample_data.min < 0)
71
- all_are_fixnums = true
72
- sample_data.each do |sample|
73
- all_are_fixnums &&= sample.class == Fixnum
98
+ kits = generate_test_data()
99
+ # Should get an error when trying to get a non-existent sound
100
+ assert_raise(StandardError) { kits[:mono8].get_sample_data("nonexistant") }
101
+
102
+ [:mono8, :mono16].each do |kit_name|
103
+ sample_data = kits[kit_name].get_sample_data("mono8")
104
+ # Assert sample data is 16-bit. If max and min samples are outside 0-255 bounds, then it is.
105
+ assert(sample_data.max > MAX_SAMPLE_8BIT)
106
+ assert(sample_data.min < MIN_SAMPLE_8BIT)
107
+ # Assert it has 1 channel. This is true if every item is a Fixnum.
108
+ assert_equal([], sample_data.select {|sample| sample.class != Fixnum})
74
109
  end
75
- assert(all_are_fixnums)
76
-
77
- kit.add("stereo16", "bass_stereo_16.wav")
78
- sample_data = kit.get_sample_data("stereo16")
79
- assert(sample_data.flatten.max > MAX_SAMPLE_8BIT)
80
- assert(sample_data.flatten.min < 0)
81
- all_are_arrays = true
82
- sample_data.each do |sample|
83
- all_are_arrays &&= sample.class == Array
110
+
111
+ [:stereo8, :stereo16].each do |kit_name|
112
+ sample_data = kits[kit_name].get_sample_data("mono8")
113
+ # Assert sample data is 16-bit. If max and min samples are outside 0-255 bounds, then it is.
114
+ assert(sample_data.flatten.max > MAX_SAMPLE_8BIT)
115
+ assert(sample_data.flatten.min < MIN_SAMPLE_8BIT)
116
+ # Assert it has 2 channels. This is true if every item is an Array.
117
+ assert_equal([], sample_data.select {|sample| sample.class != Array})
84
118
  end
85
- assert(all_are_arrays)
86
- assert(sample_data.first.length == 2)
87
119
 
120
+ #actual_sample_data = kits[:basic_composite].get_sample_data("composite_mono8")
121
+ #expected_sample_data = WaveFile.open("test/sounds/composite_snare_mono_8_tom3_mono_8_mono_16.wav").sample_data
122
+ #assert_equal(expected_sample_data, actual_sample_data)
88
123
 
89
- # Test adding sounds with progressively lower bits per sample and num channels.
90
- # Verify that sample data bits per sample and num channels doesn't go down.
91
- kit = Kit.new("test/sounds")
124
+ #actual_sample_data = kits[:mismatched_bps_composite].get_sample_data("composite_mono16")
125
+ #expected_sample_data = WaveFile.open("test/sounds/composite_snare_mono_8_tom3_mono_16_mono_16.wav").sample_data
126
+ #assert_equal(expected_sample_data, actual_sample_data)
92
127
 
93
- kit.add("stereo16", "bass_stereo_16.wav")
94
- sample_data = kit.get_sample_data("stereo16")
95
- assert(sample_data.flatten.max > MAX_SAMPLE_8BIT)
96
- assert(sample_data.flatten.min < 0)
97
- all_are_arrays = true
98
- sample_data.each do |sample|
99
- all_are_arrays &&= sample.class == Array
100
- end
101
- assert(all_are_arrays)
102
- assert(sample_data.first.length == 2)
103
-
104
- kit.add("mono16", "bass_mono_16.wav")
105
- sample_data = kit.get_sample_data("mono16")
106
- assert(sample_data.flatten.max > MAX_SAMPLE_8BIT)
107
- assert(sample_data.flatten.min < 0)
108
- all_are_arrays = true
109
- sample_data.each do |sample|
110
- all_are_arrays &&= sample.class == Array
111
- end
112
- assert(all_are_arrays)
113
- assert(sample_data.first.length == 2)
114
-
115
- kit.add("mono8", "bass_mono_8.wav")
116
- sample_data = kit.get_sample_data("mono8")
117
- assert(sample_data.flatten.max > MAX_SAMPLE_8BIT)
118
- assert(sample_data.flatten.min < 0)
119
- all_are_arrays = true
120
- sample_data.each do |sample|
121
- all_are_arrays &&= sample.class == Array
122
- end
123
- assert(all_are_arrays)
124
- assert(sample_data.first.length == 2)
128
+ #actual_sample_data = kits[:mismatched_channels_composite].get_sample_data("composite_stereo16")
129
+ #expected_sample_data = WaveFile.open("test/sounds/composite_snare_stereo_16_tom3_mono_16_stereo_16.wav").sample_data
130
+ #assert_equal(expected_sample_data, actual_sample_data)
131
+
132
+ #actual_sample_data = kits[:mismatched_everything_composite].get_sample_data("composite_stereo16")
133
+ #expected_sample_data = WaveFile.open("test/sounds/composite_snare_stereo_8_tom3_mono_16_stereo_16.wav").sample_data
134
+ #assert_equal(expected_sample_data[0..10], actual_sample_data[0..10])
135
+ end
136
+
137
+ def test_scale!
138
+ sound_bank = {"a" => [-10, 0, 20], "b" => [], "c" => [12346, 9999]}
139
+
140
+ kit = MutableKit.new(".", {})
141
+ kit.sound_bank = sound_bank
142
+
143
+ kit.scale!(5)
144
+ assert_equal([-2, 0, 4], kit.get_sample_data("a"))
145
+ assert_equal([], kit.get_sample_data("b"))
146
+ assert_equal([2469, 1999], kit.get_sample_data("c"))
147
+
148
+ kit.scale!(2)
149
+ assert_equal([-1, 0, 2], kit.get_sample_data("a"))
150
+ assert_equal([], kit.get_sample_data("b"))
151
+ assert_equal([1234, 999], kit.get_sample_data("c"))
125
152
  end
126
- end
153
+ end