beats 2.0.0 → 2.1.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.
- checksums.yaml +4 -4
- data/README.markdown +67 -2
- data/lib/beats.rb +1 -1
- data/lib/beats/kit_builder.rb +20 -2
- data/lib/beats/songoptimizer.rb +1 -2
- data/lib/beats/songparser.rb +57 -39
- data/test/fixtures/invalid/kit_with_composite_empty_sound.txt +16 -0
- data/test/fixtures/invalid/kit_with_composite_nested_sounds.txt +16 -0
- data/test/fixtures/invalid/kit_with_composite_non_existent_sound.txt +17 -0
- data/test/fixtures/invalid/track_with_composite_empty_sound.txt +16 -0
- data/test/fixtures/invalid/track_with_composite_nested_sounds.txt +16 -0
- data/test/fixtures/invalid/track_with_composite_non_existent_sound.txt +16 -0
- data/test/fixtures/valid/example_flow_patterns_different_capitalization.txt +20 -0
- data/test/fixtures/valid/kit_with_composite_single_sound.txt +16 -0
- data/test/fixtures/valid/kit_with_composite_sounds.txt +16 -0
- data/test/fixtures/valid/track_with_composite_kit_sounds.txt +16 -0
- data/test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound.txt +16 -0
- data/test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound_2.txt +16 -0
- data/test/fixtures/valid/track_with_composite_non_kit_sound.txt +16 -0
- data/test/fixtures/valid/track_with_composite_single_sound.txt +16 -0
- data/test/songparser_test.rb +181 -45
- metadata +30 -4
- data/test/fixtures/yaml/song_yaml.txt +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b76857d49851dc03ef574dadcbbc01aff5aaea9f
|
4
|
+
data.tar.gz: df598d61cfaa1a0ecb8f1bd493dc8b1f0436869e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59bd59d74a085c9d60c0f4584a9a6704c58aa05e4856d24884e4e5de622e578cd9e7a1a47edb35e172b8b1ff2f67c0386b7d99db238dcaf11d3f366a57ec42d7
|
7
|
+
data.tar.gz: 7ab6c3283977bcda76772ae287e67d2d120fdd8623fe777364dfc70bd6a1250b3c50e96bec6e047d7da199dd6ec6877b02cbf4e0b7d9009a480becdf92498656
|
data/README.markdown
CHANGED
@@ -35,7 +35,7 @@ For more, check out [beatsdrummachine.com](http://beatsdrummachine.com)
|
|
35
35
|
Installation
|
36
36
|
------------
|
37
37
|
|
38
|
-
To install the latest stable version (2.
|
38
|
+
To install the latest stable version (2.1.0) from [rubygems.org](http://rubygems.org/gems/beats), run the following from the command line:
|
39
39
|
|
40
40
|
gem install beats
|
41
41
|
|
@@ -57,7 +57,72 @@ Check out [this tutorial at beatsdrummachine.com](http://beatsdrummachine.com/tu
|
|
57
57
|
What's New
|
58
58
|
----------
|
59
59
|
|
60
|
-
The latest
|
60
|
+
The latest version of Beats is 2.1.0, released on September 9, 2017.
|
61
|
+
|
62
|
+
This version adds support for *composite sounds*. That is, sounds that are made by combining two or more sounds together. They are a more succinct way of writing songs where multiple tracks play the same rhythm.
|
63
|
+
|
64
|
+
Composite sounds can be defined in the Kit by putting multiple sound files in an array:
|
65
|
+
|
66
|
+
Kit:
|
67
|
+
- bass: bass.wav # A traditional non-composite sound
|
68
|
+
- combo_snare: [clap.wav, 808_snare.wav] # A composite sound
|
69
|
+
|
70
|
+
The `combo_snare` sound above is a composite sound made by combining `clap.wav` and `808_snare.wav` together. It can then be used in a pattern:
|
71
|
+
|
72
|
+
Verse:
|
73
|
+
- bass: X.......X.......
|
74
|
+
- combo_snare: ....X.......X...
|
75
|
+
|
76
|
+
This is equivalent to the following song:
|
77
|
+
|
78
|
+
Kit:
|
79
|
+
- bass: bass.wav
|
80
|
+
- clap: clap.wav
|
81
|
+
- snare: 808_snare.wav
|
82
|
+
|
83
|
+
Verse:
|
84
|
+
- bass: X.......X.......
|
85
|
+
- clap: ....X.......X...
|
86
|
+
- snare: ....X.......X...
|
87
|
+
|
88
|
+
When using the `-s` command-line option to write each track to its own *.wav file, each sub-sound in a composite sound will be written to its own file. For example, this song:
|
89
|
+
|
90
|
+
Kit:
|
91
|
+
- combo_snare: [clap.wav, 808_snare.wav]
|
92
|
+
|
93
|
+
Verse:
|
94
|
+
- combo_snare: X...X...X...X...
|
95
|
+
|
96
|
+
...will be written to two different files, `combo_snare-clap.wav` and `combo_snare-808_snare.wav`, when using the `-s` option.
|
97
|
+
|
98
|
+
Finally, when defining a track in a pattern, multiple sounds can be given in an array as a composite sound. Kit sounds and non-Kit sounds can be used together:
|
99
|
+
|
100
|
+
Kit:
|
101
|
+
- bass: bass.wav
|
102
|
+
- combo_snare: [clap.wav, 808_snare.wav]
|
103
|
+
|
104
|
+
Verse:
|
105
|
+
- [bass, combo_snare, other_sound.wav]: X...X...X...X...
|
106
|
+
|
107
|
+
This is a equivalent to:
|
108
|
+
|
109
|
+
Kit:
|
110
|
+
- bass: bass.wav
|
111
|
+
- clap: clap.wav
|
112
|
+
- snare: 808_snare.wav
|
113
|
+
|
114
|
+
Verse:
|
115
|
+
- bass: X...X...X...X...
|
116
|
+
- clap: X...X...X...X...
|
117
|
+
- snare: X...X...X...X...
|
118
|
+
- other_sound.wav: X...X...X...X...
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
What's Slightly Less New
|
123
|
+
------------------------
|
124
|
+
|
125
|
+
The previous version of Beats is 2.0.0, released on September 4, 2017. It is primarily a modernization release, and contains some relatively small backwards incompatible changes.
|
61
126
|
|
62
127
|
* Track rhythms can now have spaces in them. For example, `X... .... X... ....` is now a valid rhythm. Spaces are ignored, and don't affect the rhythm. For example, `X... X...` is treated as the same rhythm as `X...X...`
|
63
128
|
* Wave files using `WAVEFORMATEXTENSIBLE` format can now be used, due to upgrading the WaveFile gem dependency to v0.8.1 behind the scenes.
|
data/lib/beats.rb
CHANGED
data/lib/beats/kit_builder.rb
CHANGED
@@ -14,10 +14,26 @@ module Beats
|
|
14
14
|
def initialize(base_path)
|
15
15
|
@base_path = base_path
|
16
16
|
@labels_to_filenames = {}
|
17
|
+
@composite_replacements = {}
|
17
18
|
end
|
18
19
|
|
19
|
-
def add_item(label,
|
20
|
-
|
20
|
+
def add_item(label, filenames)
|
21
|
+
if filenames.is_a?(Array)
|
22
|
+
if filenames.empty?
|
23
|
+
raise SoundFileNotFoundError, "Kit sound '#{label}' has an empty composite pattern (i.e. \"[]\"), which is not valid."
|
24
|
+
end
|
25
|
+
|
26
|
+
filenames.each do |filename|
|
27
|
+
unless filename.is_a?(String)
|
28
|
+
raise SoundFileNotFoundError, "The Kit sound '#{label}' contains an invalid file: '#{filename}'"
|
29
|
+
end
|
30
|
+
@labels_to_filenames["#{label}-#{File.basename(filename, ".*")}"] = absolute_file_name(filename)
|
31
|
+
end
|
32
|
+
|
33
|
+
@composite_replacements[label] = filenames.map {|filename| "#{label}-#{File.basename(filename, ".*")}" }
|
34
|
+
else
|
35
|
+
@labels_to_filenames[label] = absolute_file_name(filenames)
|
36
|
+
end
|
21
37
|
end
|
22
38
|
|
23
39
|
def has_label?(label)
|
@@ -45,6 +61,8 @@ module Beats
|
|
45
61
|
Kit.new(labels_to_buffers, num_channels, BITS_PER_SAMPLE)
|
46
62
|
end
|
47
63
|
|
64
|
+
attr_reader :composite_replacements
|
65
|
+
|
48
66
|
private
|
49
67
|
|
50
68
|
# Converts relative path into absolute path. Note that this will also handle
|
data/lib/beats/songoptimizer.rb
CHANGED
@@ -137,8 +137,7 @@ module Beats
|
|
137
137
|
replacements = {}
|
138
138
|
|
139
139
|
# Pattern names are sorted to ensure predictable pattern replacement. Makes tests easier to write.
|
140
|
-
|
141
|
-
pattern_names = patterns.keys.sort {|x, y| x.to_s <=> y.to_s }
|
140
|
+
pattern_names = patterns.keys.sort
|
142
141
|
|
143
142
|
# Detect duplicates
|
144
143
|
pattern_names.each do |pattern_name|
|
data/lib/beats/songparser.rb
CHANGED
@@ -11,11 +11,11 @@ module Beats
|
|
11
11
|
NO_SONG_HEADER_ERROR_MSG =
|
12
12
|
"Song must have a header. Here's an example:
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
Song:
|
15
|
+
Tempo: 120
|
16
|
+
Flow:
|
17
|
+
- Verse: x2
|
18
|
+
- Chorus: x2"
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
end
|
@@ -30,8 +30,9 @@ module Beats
|
|
30
30
|
end
|
31
31
|
|
32
32
|
song = Song.new
|
33
|
+
kit_builder = KitBuilder.new(base_path)
|
33
34
|
|
34
|
-
#
|
35
|
+
# Set tempo
|
35
36
|
begin
|
36
37
|
unless raw_song_components[:tempo].nil?
|
37
38
|
song.tempo = raw_song_components[:tempo]
|
@@ -40,26 +41,26 @@ module Beats
|
|
40
41
|
raise ParseError, "#{detail}"
|
41
42
|
end
|
42
43
|
|
43
|
-
#
|
44
|
+
# Add sounds defined in the Kit section
|
44
45
|
begin
|
45
|
-
|
46
|
+
add_kit_sounds_from_kit(kit_builder, raw_song_components[:kit])
|
46
47
|
rescue KitBuilder::SoundFileNotFoundError => detail
|
47
48
|
raise ParseError, "#{detail}"
|
48
49
|
rescue KitBuilder::InvalidSoundFormatError => detail
|
49
50
|
raise ParseError, "#{detail}"
|
50
51
|
end
|
51
52
|
|
52
|
-
#
|
53
|
-
add_patterns_to_song(song, raw_song_components[:patterns])
|
53
|
+
# Load patterns
|
54
|
+
add_patterns_to_song(song, kit_builder, raw_song_components[:patterns])
|
54
55
|
|
55
|
-
#
|
56
|
+
# Set flow
|
56
57
|
if raw_song_components[:flow].nil?
|
57
58
|
raise ParseError, "Song must have a Flow section in the header."
|
58
59
|
else
|
59
60
|
set_song_flow(song, raw_song_components[:flow])
|
60
61
|
end
|
61
62
|
|
62
|
-
#
|
63
|
+
# Swing, if swing flag is set
|
63
64
|
if raw_song_components[:swing]
|
64
65
|
begin
|
65
66
|
song = Transforms::SongSwinger.transform(song, raw_song_components[:swing])
|
@@ -68,6 +69,16 @@ module Beats
|
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
72
|
+
# Build the final kit
|
73
|
+
begin
|
74
|
+
add_kit_sounds_from_patterns(kit_builder, song.patterns)
|
75
|
+
kit = kit_builder.build_kit
|
76
|
+
rescue KitBuilder::SoundFileNotFoundError => detail
|
77
|
+
raise ParseError, "#{detail}"
|
78
|
+
rescue KitBuilder::InvalidSoundFormatError => detail
|
79
|
+
raise ParseError, "#{detail}"
|
80
|
+
end
|
81
|
+
|
71
82
|
return song, kit
|
72
83
|
end
|
73
84
|
|
@@ -104,9 +115,7 @@ module Beats
|
|
104
115
|
return raw_song_components
|
105
116
|
end
|
106
117
|
|
107
|
-
def
|
108
|
-
kit_builder = KitBuilder.new(base_path)
|
109
|
-
|
118
|
+
def add_kit_sounds_from_kit(kit_builder, raw_kit)
|
110
119
|
# Add sounds defined in the Kit section of the song header
|
111
120
|
# Converts [{a=>1}, {b=>2}, {c=>3}] from raw YAML to {a=>1, b=>2, c=>3}
|
112
121
|
# TODO: Raise error is same name is defined more than once in the Kit
|
@@ -115,45 +124,54 @@ module Beats
|
|
115
124
|
kit_builder.add_item(kit_item.keys.first, kit_item.values.first)
|
116
125
|
end
|
117
126
|
end
|
127
|
+
end
|
118
128
|
|
129
|
+
def add_kit_sounds_from_patterns(kit_builder, patterns)
|
119
130
|
# Add sounds not defined in Kit section, but used in individual tracks
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
unless track_list.nil?
|
124
|
-
track_list.each do |track_definition|
|
125
|
-
track_name = track_definition.keys.first
|
126
|
-
track_path = track_name
|
131
|
+
patterns.each do |pattern_name, pattern|
|
132
|
+
pattern.tracks.each do |track_name, track|
|
133
|
+
track_path = track.name
|
127
134
|
|
128
|
-
|
129
|
-
|
130
|
-
end
|
135
|
+
if !kit_builder.has_label?(track.name)
|
136
|
+
kit_builder.add_item(track.name, track_path)
|
131
137
|
end
|
132
138
|
end
|
133
139
|
end
|
134
|
-
|
135
|
-
kit_builder.build_kit
|
136
140
|
end
|
137
141
|
|
138
|
-
def add_patterns_to_song(song, raw_patterns)
|
139
|
-
raw_patterns.
|
140
|
-
|
141
|
-
|
142
|
-
track_list = raw_patterns[key]
|
143
|
-
|
144
|
-
if track_list.nil?
|
142
|
+
def add_patterns_to_song(song, kit_builder, raw_patterns)
|
143
|
+
raw_patterns.each do |pattern_name, raw_tracks|
|
144
|
+
if raw_tracks.nil?
|
145
145
|
# TODO: Use correct capitalization of pattern name in error message
|
146
146
|
# TODO: Possibly allow if pattern not referenced in the Flow, or has 0 repeats?
|
147
|
-
raise ParseError, "Pattern '#{
|
147
|
+
raise ParseError, "Pattern '#{pattern_name}' has no tracks. It needs at least one."
|
148
148
|
end
|
149
149
|
|
150
|
-
|
151
|
-
|
150
|
+
new_pattern = song.pattern(pattern_name.to_sym)
|
151
|
+
|
152
|
+
raw_tracks.each do |raw_track|
|
153
|
+
track_names = raw_track.keys.first
|
154
|
+
rhythm = raw_track.values.first
|
152
155
|
|
153
156
|
# Handle case where no track rhythm is specified (i.e. "- foo.wav:" instead of "- foo.wav: X.X.X.X.")
|
154
|
-
|
157
|
+
rhythm = "" if rhythm.nil?
|
155
158
|
|
156
|
-
|
159
|
+
track_names = Array(track_names)
|
160
|
+
if track_names.empty?
|
161
|
+
raise ParseError, "Pattern '#{pattern_name}' has an empty composite pattern (i.e. \"[]\"), which is not valid."
|
162
|
+
end
|
163
|
+
|
164
|
+
track_names.map! do |track_name|
|
165
|
+
unless track_name.is_a?(String)
|
166
|
+
raise ParseError, "'#{track_name}' in pattern '#{pattern_name}' is not a valid track sound"
|
167
|
+
end
|
168
|
+
kit_builder.composite_replacements[track_name] || track_name
|
169
|
+
end
|
170
|
+
track_names.flatten!
|
171
|
+
|
172
|
+
track_names.each do |track_name|
|
173
|
+
new_pattern.track track_name, rhythm
|
174
|
+
end
|
157
175
|
end
|
158
176
|
end
|
159
177
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hihat: [] # Empty composite sounds aren't allowed
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- hihat: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: [test/sounds/hh_closed_mono_8.wav, [test/sounds/hh_open_mono_8.wav]]
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- hh_closed: .X.X.X.X
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hihat: [test/sounds/hh_closed_mono_8.wav, test/sounds/missing.wav] # "missing.wav" is a non-existent file
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, hihat]: .X.X.X.X
|
17
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- []: .X.X.X.X # Empty composite sounds aren't allowed
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- [bass, [hh_closed]]: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, [bass, hh_closed]]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, missing]: .X.X.X.X # "missing" is not a valid file, and is not defined in the kit
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# The patterns in the Flow have different capitalization from how the patterns are defined
|
2
|
+
|
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...
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hihat: [test/sounds/hh_closed_mono_8.wav]
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- hihat: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, hihat]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hihat: [test/sounds/hh_closed_mono_8.wav, test/sounds/hh_open_mono_8.wav]
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- hihat: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, hihat]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- [bass, hh_closed]: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare, bass]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [hh_closed, test/sounds/hh_open_mono_8.wav]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hihat: [test/sounds/hh_closed_mono_8.wav, test/sounds/hh_open_mono_8.wav]
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- hihat: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [test/sounds/agogo_high_mono_8.wav, hihat, test/sounds/agogo_low_mono_8.wav]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [test/sounds/agogo_high_mono_8.wav, test/sounds/hh_open_mono_8.wav]: .X.X.X.X
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Song:
|
2
|
+
Tempo: 100
|
3
|
+
Kit:
|
4
|
+
- bass: test/sounds/bass_mono_8.wav
|
5
|
+
- snare: test/sounds/snare_mono_8.wav
|
6
|
+
- hh_closed: test/sounds/hh_closed_mono_8.wav
|
7
|
+
Flow:
|
8
|
+
- Verse: x2
|
9
|
+
- Chorus: x2
|
10
|
+
|
11
|
+
Verse:
|
12
|
+
- bass: X...X...
|
13
|
+
- snare: ..X...X.
|
14
|
+
Chorus:
|
15
|
+
- bass: XXXXXXXX
|
16
|
+
- [snare]: .X.X.X.X
|
data/test/songparser_test.rb
CHANGED
@@ -3,20 +3,6 @@ require 'includes'
|
|
3
3
|
class SongParserTest < Minitest::Test
|
4
4
|
FIXTURE_BASE_PATH = File.dirname(__FILE__) + "/.."
|
5
5
|
|
6
|
-
# TODO: Add fixture for track with no rhythm
|
7
|
-
VALID_FIXTURES = [:no_tempo,
|
8
|
-
:fractional_tempo,
|
9
|
-
:repeats_not_specified,
|
10
|
-
:pattern_with_overflow,
|
11
|
-
:example_no_kit,
|
12
|
-
:example_with_kit,
|
13
|
-
:example_with_empty_track,
|
14
|
-
:track_with_spaces,
|
15
|
-
:multiple_tracks_same_sound,
|
16
|
-
:example_swung_8th,
|
17
|
-
:example_swung_16th,
|
18
|
-
:example_unswung]
|
19
|
-
|
20
6
|
INVALID_FIXTURES = [:bad_repeat_count,
|
21
7
|
:bad_flow,
|
22
8
|
:bad_tempo,
|
@@ -26,46 +12,62 @@ class SongParserTest < Minitest::Test
|
|
26
12
|
:no_flow,
|
27
13
|
:with_structure,
|
28
14
|
:pattern_with_no_tracks,
|
15
|
+
:track_with_composite_non_existent_sound,
|
16
|
+
:kit_with_composite_non_existent_sound,
|
17
|
+
:track_with_composite_empty_sound,
|
18
|
+
:kit_with_composite_empty_sound,
|
19
|
+
:track_with_composite_nested_sounds,
|
20
|
+
:kit_with_composite_nested_sounds,
|
29
21
|
:leading_bar_line,
|
30
22
|
:sound_in_kit_not_found,
|
31
23
|
:sound_in_track_not_found,
|
32
24
|
:sound_in_kit_wrong_format,
|
33
25
|
:sound_in_track_wrong_format]
|
34
26
|
|
35
|
-
|
36
|
-
SongParser.new.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
|
37
|
-
end
|
27
|
+
# TODO: Add somes tests to validate the Kits
|
38
28
|
|
39
|
-
def
|
40
|
-
|
41
|
-
test_kits = {}
|
29
|
+
def test_no_tempo
|
30
|
+
song, kit = load_fixture("valid/no_tempo.txt")
|
42
31
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
test_kits[fixture_name] = kit
|
47
|
-
end
|
32
|
+
assert_equal(120, song.tempo)
|
33
|
+
assert_equal([:verse], song.flow)
|
34
|
+
end
|
48
35
|
|
49
|
-
|
36
|
+
def test_fractional_tempo
|
37
|
+
song, kit = load_fixture("valid/fractional_tempo.txt")
|
38
|
+
|
39
|
+
assert_equal(95.764, song.tempo)
|
40
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
50
41
|
end
|
51
42
|
|
52
|
-
|
53
|
-
|
54
|
-
test_songs, test_kits = SongParserTest.generate_test_data
|
43
|
+
def test_repeats_not_specified
|
44
|
+
song, kit = load_fixture("valid/repeats_not_specified.txt")
|
55
45
|
|
56
|
-
assert_equal(
|
57
|
-
assert_equal([:verse],
|
46
|
+
assert_equal(100, song.tempo)
|
47
|
+
assert_equal([:verse], song.flow)
|
48
|
+
end
|
58
49
|
|
59
|
-
|
60
|
-
|
50
|
+
def test_flow_patterns_different_capitalization
|
51
|
+
song, kit = load_fixture("valid/example_flow_patterns_different_capitalization.txt")
|
61
52
|
|
62
|
-
assert_equal(100,
|
63
|
-
assert_equal([:verse
|
53
|
+
assert_equal(100, song.tempo)
|
54
|
+
assert_equal([:verse, :chorus, :chorus, :verse, :chorus, :chorus], song.flow)
|
55
|
+
assert_equal(2, song.patterns.length)
|
56
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
57
|
+
assert_equal("X...X...X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
58
|
+
assert_equal("..............X.", song.patterns[:verse].tracks["snare"].rhythm)
|
59
|
+
assert_equal(2, song.patterns[:chorus].tracks.length)
|
60
|
+
assert_equal("X...X...XX..X...", song.patterns[:chorus].tracks["bass"].rhythm)
|
61
|
+
assert_equal("....X.......X...", song.patterns[:chorus].tracks["snare"].rhythm)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_song_with_unused_kit
|
65
|
+
no_kit_song, no_kit_kit = load_fixture("valid/example_no_kit.txt")
|
66
|
+
kit_song, kit_kit = load_fixture("valid/example_with_kit.txt")
|
64
67
|
|
65
68
|
# These two songs should be the same, except that one uses a kit in the song header
|
66
69
|
# and the other doesn't.
|
67
|
-
[
|
68
|
-
song = test_songs[song_key]
|
70
|
+
[no_kit_song, kit_song].each do |song|
|
69
71
|
assert_equal([:verse, :verse,
|
70
72
|
:chorus, :chorus,
|
71
73
|
:verse, :verse,
|
@@ -79,20 +81,29 @@ class SongParserTest < Minitest::Test
|
|
79
81
|
assert_equal(5, song.patterns[:chorus].tracks.length)
|
80
82
|
assert_equal(1, song.patterns[:bridge].tracks.length)
|
81
83
|
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_empty_track
|
87
|
+
song, kit = load_fixture("valid/example_with_empty_track.txt")
|
82
88
|
|
83
|
-
song = test_songs[:example_with_empty_track]
|
84
89
|
assert_equal(1, song.patterns.length)
|
85
90
|
assert_equal(2, song.patterns[:verse].tracks.length)
|
86
91
|
assert_equal("........", song.patterns[:verse].tracks["test/sounds/bass_mono_8.wav"].rhythm)
|
87
92
|
assert_equal("X...X...", song.patterns[:verse].tracks["test/sounds/snare_mono_8.wav"].rhythm)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_track_with_spaces
|
96
|
+
song, kit = load_fixture("valid/track_with_spaces.txt")
|
88
97
|
|
89
|
-
song = test_songs[:track_with_spaces]
|
90
98
|
assert_equal(1, song.patterns.length)
|
91
99
|
assert_equal(2, song.patterns[:verse].tracks.length)
|
92
100
|
assert_equal("X...X...X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
93
101
|
assert_equal("....X.......X...", song.patterns[:verse].tracks["snare"].rhythm)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_multiple_tracks_same_sound
|
105
|
+
song, kit = load_fixture("valid/multiple_tracks_same_sound.txt")
|
94
106
|
|
95
|
-
song = test_songs[:multiple_tracks_same_sound]
|
96
107
|
assert_equal(2, song.patterns.length)
|
97
108
|
assert_equal(7, song.patterns[:verse].tracks.length)
|
98
109
|
assert_equal(["agogo", "bass", "bass2", "bass3", "bass4", "hh_closed", "snare"],
|
@@ -112,8 +123,11 @@ class SongParserTest < Minitest::Test
|
|
112
123
|
assert_equal("..X..X..X..X..X.", song.patterns[:chorus].tracks["bass2"].rhythm)
|
113
124
|
assert_equal("...........X....", song.patterns[:chorus].tracks["test/sounds/tom4_mono_16.wav"].rhythm)
|
114
125
|
assert_equal("..............X.", song.patterns[:chorus].tracks["test/sounds/tom2_mono_16.wav"].rhythm)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_swung_8
|
129
|
+
song, kit = load_fixture("valid/example_swung_8th.txt")
|
115
130
|
|
116
|
-
song = test_songs[:example_swung_8th]
|
117
131
|
assert_equal(180, song.tempo)
|
118
132
|
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
119
133
|
assert_equal(2, song.patterns.length)
|
@@ -123,8 +137,11 @@ class SongParserTest < Minitest::Test
|
|
123
137
|
assert_equal(2, song.patterns[:chorus].tracks.length)
|
124
138
|
assert_equal("X.X.XXX.X.XX", song.patterns[:chorus].tracks["bass"].rhythm)
|
125
139
|
assert_equal("..X..X..X..X", song.patterns[:chorus].tracks["snare"].rhythm)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_swung_16
|
143
|
+
song, kit = load_fixture("valid/example_swung_16th.txt")
|
126
144
|
|
127
|
-
song = test_songs[:example_swung_16th]
|
128
145
|
assert_equal(180, song.tempo)
|
129
146
|
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
130
147
|
assert_equal(2, song.patterns.length)
|
@@ -134,8 +151,11 @@ class SongParserTest < Minitest::Test
|
|
134
151
|
assert_equal(2, song.patterns[:chorus].tracks.length)
|
135
152
|
assert_equal("X.XX.XX.XX.X", song.patterns[:chorus].tracks["bass"].rhythm)
|
136
153
|
assert_equal("..X..X..X..X", song.patterns[:chorus].tracks["snare"].rhythm)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_unswung_song
|
157
|
+
song, kit = load_fixture("valid/example_unswung.txt")
|
137
158
|
|
138
|
-
song = test_songs[:example_unswung]
|
139
159
|
assert_equal(120, song.tempo)
|
140
160
|
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
141
161
|
assert_equal(2, song.patterns.length)
|
@@ -147,15 +167,131 @@ class SongParserTest < Minitest::Test
|
|
147
167
|
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["snare"].rhythm)
|
148
168
|
end
|
149
169
|
|
170
|
+
def test_track_with_composite_kit_sounds
|
171
|
+
song, kit = load_fixture("valid/track_with_composite_kit_sounds.txt")
|
172
|
+
|
173
|
+
assert_equal(100, song.tempo)
|
174
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
175
|
+
assert_equal(2, song.patterns.length)
|
176
|
+
assert_equal(3, song.patterns[:verse].tracks.length)
|
177
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
178
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hh_closed"].rhythm)
|
179
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
180
|
+
assert_equal(3, song.patterns[:chorus].tracks.length)
|
181
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
182
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["snare"].rhythm)
|
183
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["bass2"].rhythm)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_track_with_composite_non_kit_sound
|
187
|
+
song, kit = load_fixture("valid/track_with_composite_non_kit_sound.txt")
|
188
|
+
|
189
|
+
assert_equal(100, song.tempo)
|
190
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
191
|
+
assert_equal(2, song.patterns.length)
|
192
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
193
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
194
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
195
|
+
assert_equal(3, song.patterns[:chorus].tracks.length)
|
196
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
197
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/agogo_high_mono_8.wav"].rhythm)
|
198
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/hh_open_mono_8.wav"].rhythm)
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_track_with_composite_mix_kit_and_not_kit_sound
|
202
|
+
song, kit = load_fixture("valid/track_with_composite_mix_kit_and_not_kit_sound.txt")
|
203
|
+
|
204
|
+
assert_equal(100, song.tempo)
|
205
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
206
|
+
assert_equal(2, song.patterns.length)
|
207
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
208
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
209
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
210
|
+
assert_equal(3, song.patterns[:chorus].tracks.length)
|
211
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
212
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hh_closed"].rhythm)
|
213
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/hh_open_mono_8.wav"].rhythm)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_track_with_composite_mix_kit_and_not_kit_sound_2
|
217
|
+
song, kit = load_fixture("valid/track_with_composite_mix_kit_and_not_kit_sound_2.txt")
|
218
|
+
|
219
|
+
assert_equal(100, song.tempo)
|
220
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
221
|
+
assert_equal(2, song.patterns.length)
|
222
|
+
assert_equal(3, song.patterns[:verse].tracks.length)
|
223
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hihat-hh_closed_mono_8"].rhythm)
|
224
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hihat-hh_open_mono_8"].rhythm)
|
225
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
226
|
+
assert_equal(5, song.patterns[:chorus].tracks.length)
|
227
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
228
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/agogo_high_mono_8.wav"].rhythm)
|
229
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hihat-hh_closed_mono_8"].rhythm)
|
230
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hihat-hh_open_mono_8"].rhythm)
|
231
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["test/sounds/agogo_low_mono_8.wav"].rhythm)
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_track_with_composite_single_sound
|
235
|
+
song, kit = load_fixture("valid/track_with_composite_single_sound.txt")
|
236
|
+
|
237
|
+
assert_equal(100, song.tempo)
|
238
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
239
|
+
assert_equal(2, song.patterns.length)
|
240
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
241
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["bass"].rhythm)
|
242
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
243
|
+
assert_equal(2, song.patterns[:chorus].tracks.length)
|
244
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
245
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["snare"].rhythm)
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_kit_with_composite_sounds
|
249
|
+
song, kit = load_fixture("valid/kit_with_composite_sounds.txt")
|
250
|
+
|
251
|
+
assert_equal(100, song.tempo)
|
252
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
253
|
+
assert_equal(2, song.patterns.length)
|
254
|
+
assert_equal(3, song.patterns[:verse].tracks.length)
|
255
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hihat-hh_closed_mono_8"].rhythm)
|
256
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hihat-hh_open_mono_8"].rhythm)
|
257
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
258
|
+
assert_equal(4, song.patterns[:chorus].tracks.length)
|
259
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
260
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["snare"].rhythm)
|
261
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hihat-hh_closed_mono_8"].rhythm)
|
262
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hihat-hh_open_mono_8"].rhythm)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_kit_with_composite_single_sound
|
266
|
+
song, kit = load_fixture("valid/kit_with_composite_single_sound.txt")
|
267
|
+
|
268
|
+
assert_equal(100, song.tempo)
|
269
|
+
assert_equal([:verse, :verse, :chorus, :chorus], song.flow)
|
270
|
+
assert_equal(2, song.patterns.length)
|
271
|
+
assert_equal(2, song.patterns[:verse].tracks.length)
|
272
|
+
assert_equal("X...X...", song.patterns[:verse].tracks["hihat-hh_closed_mono_8"].rhythm)
|
273
|
+
assert_equal("..X...X.", song.patterns[:verse].tracks["snare"].rhythm)
|
274
|
+
assert_equal(3, song.patterns[:chorus].tracks.length)
|
275
|
+
assert_equal("XXXXXXXX", song.patterns[:chorus].tracks["bass"].rhythm)
|
276
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["snare"].rhythm)
|
277
|
+
assert_equal(".X.X.X.X", song.patterns[:chorus].tracks["hihat-hh_closed_mono_8"].rhythm)
|
278
|
+
end
|
279
|
+
|
150
280
|
def test_invalid_parse
|
151
281
|
INVALID_FIXTURES.each do |fixture|
|
152
282
|
assert_raises(SongParser::ParseError) do
|
153
|
-
song =
|
283
|
+
song, kit = load_fixture("invalid/#{fixture}.txt")
|
154
284
|
end
|
155
285
|
end
|
156
286
|
|
157
287
|
assert_raises(Track::InvalidRhythmError) do
|
158
|
-
song =
|
288
|
+
song, kit = load_fixture("invalid/bad_rhythm.txt")
|
159
289
|
end
|
160
290
|
end
|
291
|
+
|
292
|
+
private
|
293
|
+
|
294
|
+
def load_fixture(fixture_name)
|
295
|
+
SongParser.new.parse(FIXTURE_BASE_PATH, File.read("test/fixtures/#{fixture_name}"))
|
296
|
+
end
|
161
297
|
end
|
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: 2.
|
4
|
+
version: 2.1.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: 2017-09-
|
11
|
+
date: 2017-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: wavefile
|
@@ -90,6 +90,9 @@ files:
|
|
90
90
|
- test/fixtures/invalid/bad_swing_rate_1.txt
|
91
91
|
- test/fixtures/invalid/bad_swing_rate_2.txt
|
92
92
|
- test/fixtures/invalid/bad_tempo.txt
|
93
|
+
- test/fixtures/invalid/kit_with_composite_empty_sound.txt
|
94
|
+
- test/fixtures/invalid/kit_with_composite_nested_sounds.txt
|
95
|
+
- test/fixtures/invalid/kit_with_composite_non_existent_sound.txt
|
93
96
|
- test/fixtures/invalid/leading_bar_line.txt
|
94
97
|
- test/fixtures/invalid/no_flow.txt
|
95
98
|
- test/fixtures/invalid/no_header.txt
|
@@ -98,7 +101,11 @@ files:
|
|
98
101
|
- test/fixtures/invalid/sound_in_kit_wrong_format.txt
|
99
102
|
- test/fixtures/invalid/sound_in_track_not_found.txt
|
100
103
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
104
|
+
- test/fixtures/invalid/track_with_composite_empty_sound.txt
|
105
|
+
- test/fixtures/invalid/track_with_composite_nested_sounds.txt
|
106
|
+
- test/fixtures/invalid/track_with_composite_non_existent_sound.txt
|
101
107
|
- test/fixtures/invalid/with_structure.txt
|
108
|
+
- test/fixtures/valid/example_flow_patterns_different_capitalization.txt
|
102
109
|
- test/fixtures/valid/example_mono_16.txt
|
103
110
|
- test/fixtures/valid/example_mono_16_base_path.txt
|
104
111
|
- test/fixtures/valid/example_mono_8.txt
|
@@ -111,13 +118,19 @@ files:
|
|
111
118
|
- test/fixtures/valid/example_with_empty_track.txt
|
112
119
|
- test/fixtures/valid/example_with_kit.txt
|
113
120
|
- test/fixtures/valid/fractional_tempo.txt
|
121
|
+
- test/fixtures/valid/kit_with_composite_single_sound.txt
|
122
|
+
- test/fixtures/valid/kit_with_composite_sounds.txt
|
114
123
|
- test/fixtures/valid/multiple_tracks_same_sound.txt
|
115
124
|
- test/fixtures/valid/no_tempo.txt
|
116
125
|
- test/fixtures/valid/optimize_pattern_collision.txt
|
117
126
|
- test/fixtures/valid/pattern_with_overflow.txt
|
118
127
|
- test/fixtures/valid/repeats_not_specified.txt
|
128
|
+
- test/fixtures/valid/track_with_composite_kit_sounds.txt
|
129
|
+
- test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound.txt
|
130
|
+
- test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound_2.txt
|
131
|
+
- test/fixtures/valid/track_with_composite_non_kit_sound.txt
|
132
|
+
- test/fixtures/valid/track_with_composite_single_sound.txt
|
119
133
|
- test/fixtures/valid/track_with_spaces.txt
|
120
|
-
- test/fixtures/yaml/song_yaml.txt
|
121
134
|
- test/includes.rb
|
122
135
|
- test/integration_test.rb
|
123
136
|
- test/kit_builder_test.rb
|
@@ -280,6 +293,9 @@ test_files:
|
|
280
293
|
- test/fixtures/invalid/bad_swing_rate_1.txt
|
281
294
|
- test/fixtures/invalid/bad_swing_rate_2.txt
|
282
295
|
- test/fixtures/invalid/bad_tempo.txt
|
296
|
+
- test/fixtures/invalid/kit_with_composite_empty_sound.txt
|
297
|
+
- test/fixtures/invalid/kit_with_composite_nested_sounds.txt
|
298
|
+
- test/fixtures/invalid/kit_with_composite_non_existent_sound.txt
|
283
299
|
- test/fixtures/invalid/leading_bar_line.txt
|
284
300
|
- test/fixtures/invalid/no_flow.txt
|
285
301
|
- test/fixtures/invalid/no_header.txt
|
@@ -288,7 +304,11 @@ test_files:
|
|
288
304
|
- test/fixtures/invalid/sound_in_kit_wrong_format.txt
|
289
305
|
- test/fixtures/invalid/sound_in_track_not_found.txt
|
290
306
|
- test/fixtures/invalid/sound_in_track_wrong_format.txt
|
307
|
+
- test/fixtures/invalid/track_with_composite_empty_sound.txt
|
308
|
+
- test/fixtures/invalid/track_with_composite_nested_sounds.txt
|
309
|
+
- test/fixtures/invalid/track_with_composite_non_existent_sound.txt
|
291
310
|
- test/fixtures/invalid/with_structure.txt
|
311
|
+
- test/fixtures/valid/example_flow_patterns_different_capitalization.txt
|
292
312
|
- test/fixtures/valid/example_mono_16.txt
|
293
313
|
- test/fixtures/valid/example_mono_16_base_path.txt
|
294
314
|
- test/fixtures/valid/example_mono_8.txt
|
@@ -301,13 +321,19 @@ test_files:
|
|
301
321
|
- test/fixtures/valid/example_with_empty_track.txt
|
302
322
|
- test/fixtures/valid/example_with_kit.txt
|
303
323
|
- test/fixtures/valid/fractional_tempo.txt
|
324
|
+
- test/fixtures/valid/kit_with_composite_single_sound.txt
|
325
|
+
- test/fixtures/valid/kit_with_composite_sounds.txt
|
304
326
|
- test/fixtures/valid/multiple_tracks_same_sound.txt
|
305
327
|
- test/fixtures/valid/no_tempo.txt
|
306
328
|
- test/fixtures/valid/optimize_pattern_collision.txt
|
307
329
|
- test/fixtures/valid/pattern_with_overflow.txt
|
308
330
|
- test/fixtures/valid/repeats_not_specified.txt
|
331
|
+
- test/fixtures/valid/track_with_composite_kit_sounds.txt
|
332
|
+
- test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound.txt
|
333
|
+
- test/fixtures/valid/track_with_composite_mix_kit_and_not_kit_sound_2.txt
|
334
|
+
- test/fixtures/valid/track_with_composite_non_kit_sound.txt
|
335
|
+
- test/fixtures/valid/track_with_composite_single_sound.txt
|
309
336
|
- test/fixtures/valid/track_with_spaces.txt
|
310
|
-
- test/fixtures/yaml/song_yaml.txt
|
311
337
|
- test/includes.rb
|
312
338
|
- test/integration_test.rb
|
313
339
|
- test/kit_builder_test.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
Song:
|
2
|
-
Tempo: 99
|
3
|
-
Flow:
|
4
|
-
- Verse: x2
|
5
|
-
- Chorus: x2
|
6
|
-
- Verse: x2
|
7
|
-
- Chorus: x4
|
8
|
-
- Bridge: x1
|
9
|
-
- Chorus: x4
|
10
|
-
Kit:
|
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
|
-
|
16
|
-
Bridge:
|
17
|
-
- hhclosed: XX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.X
|
18
|
-
|
19
|
-
Chorus:
|
20
|
-
- bass: X...X...XXXXXXXXX...X...X...X...
|
21
|
-
- hhopen: ........X.......X.......X.......
|
22
|
-
- snare: ...................X...X...X...X
|
23
|
-
- test/sounds/hh_closed_mono_8.wav: X.X.XXX.X.X.XXX.X.X.XXX.X.X.XXX.
|
24
|
-
- test/sounds/ride_mono_8.wav: ....X...................X.......
|
25
|
-
|
26
|
-
Verse:
|
27
|
-
- bass: X...X...X...XX..X...X...XX..X...
|
28
|
-
- hhclosed: X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.
|
29
|
-
- hhopen: X...............X..............X
|
30
|
-
- snare: ..X...X...X...X.X...X...X...X...
|