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