@hraness/dawg 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/DAWG.md +343 -116
  3. package/README.md +27 -25
  4. package/core/autotune.ts +1119 -0
  5. package/core/chords.ts +271 -23
  6. package/core/clips.ts +499 -0
  7. package/core/diff.ts +182 -104
  8. package/core/expression.ts +15 -0
  9. package/core/fx.ts +99 -29
  10. package/core/instruments.ts +19 -0
  11. package/core/keys.ts +3 -3
  12. package/core/loop.ts +5 -0
  13. package/core/lyrics.ts +297 -0
  14. package/core/master.ts +3 -3
  15. package/core/resonators.ts +16 -2
  16. package/core/routing.ts +165 -0
  17. package/core/score.ts +832 -13
  18. package/core/sdk/eval-child.ts +7 -2
  19. package/core/sdk/eval.ts +35 -6
  20. package/core/sdk/print.ts +276 -3
  21. package/core/sdk/sync-lyrics.ts +49 -0
  22. package/core/sdk/v1.ts +1849 -42
  23. package/core/sections.ts +292 -26
  24. package/core/sing.ts +815 -0
  25. package/core/style-provenance.ts +80 -0
  26. package/core/styles/africa-mena-southasia.ts +2893 -0
  27. package/core/styles/americas.ts +3810 -0
  28. package/core/styles/art.ts +4993 -0
  29. package/core/styles/base.ts +123 -0
  30. package/core/styles/cycles.ts +106 -0
  31. package/core/styles/electronic.ts +2723 -0
  32. package/core/styles/europe-asia-pacific.ts +2838 -0
  33. package/core/styles/excerpt.ts +29 -0
  34. package/core/styles/gamelan.ts +283 -0
  35. package/core/styles/generate.ts +2199 -0
  36. package/core/styles/index.ts +515 -0
  37. package/core/styles/parts.ts +106 -0
  38. package/core/styles/pop.ts +3189 -0
  39. package/core/styles/rock.ts +2993 -0
  40. package/core/styles/roots.ts +4175 -0
  41. package/core/styles/schema.ts +429 -0
  42. package/core/styles/taxonomy.ts +940 -0
  43. package/core/styles/validate.ts +528 -0
  44. package/core/tempo.ts +32 -2
  45. package/core/tuning.ts +19 -3
  46. package/core/vocoder.ts +524 -0
  47. package/guides/agent.md +29 -0
  48. package/guides/arrange.md +30 -0
  49. package/guides/audition.md +20 -14
  50. package/guides/automation.md +12 -7
  51. package/guides/chords.md +15 -15
  52. package/guides/effects.md +17 -16
  53. package/guides/faders.md +20 -16
  54. package/guides/files.md +13 -9
  55. package/guides/getting-started.md +15 -11
  56. package/guides/keys.md +19 -15
  57. package/guides/media.md +17 -12
  58. package/guides/mix.md +12 -6
  59. package/guides/music.md +23 -8
  60. package/guides/notes.md +15 -9
  61. package/guides/performance.md +15 -13
  62. package/guides/play.md +21 -13
  63. package/guides/project.md +25 -8
  64. package/guides/providers.md +20 -14
  65. package/guides/resample.md +15 -9
  66. package/guides/rhythm.md +17 -13
  67. package/guides/sessions.md +17 -7
  68. package/guides/show-me.md +31 -0
  69. package/guides/sound.md +25 -9
  70. package/guides/sounds.md +15 -13
  71. package/guides/styles.md +31 -0
  72. package/guides/tempo.md +15 -10
  73. package/guides/tracks.md +15 -10
  74. package/guides/tuning.md +32 -0
  75. package/guides/voice.md +31 -0
  76. package/guides/web-search.md +18 -8
  77. package/native/prebuilt/darwin-arm64/libdawg_sink.dylib +0 -0
  78. package/native/prebuilt/darwin-x64/libdawg_sink.dylib +0 -0
  79. package/native/prebuilt/linux-arm64/libdawg_sink.so +0 -0
  80. package/native/prebuilt/linux-x64/libdawg_sink.so +0 -0
  81. package/native/prebuilt/manifest.json +21 -0
  82. package/package.json +5 -2
  83. package/src/agent/agent.ts +126 -14
  84. package/src/agent/calibration-tools.ts +53 -0
  85. package/src/agent/clip-tools.ts +453 -0
  86. package/src/agent/command-agent.ts +369 -0
  87. package/src/agent/drum-tools.ts +2 -2
  88. package/src/agent/expression-tools.ts +1 -1
  89. package/src/agent/gateway.ts +246 -60
  90. package/src/agent/models.ts +53 -12
  91. package/src/agent/ops.ts +12 -1
  92. package/src/agent/pack-tools.ts +1 -1
  93. package/src/agent/planner.ts +13 -0
  94. package/src/agent/portable-schema.ts +80 -0
  95. package/src/agent/preview-tool.ts +4 -1
  96. package/src/agent/provider.ts +22 -8
  97. package/src/agent/rhythm-tools.ts +1 -1
  98. package/src/agent/section-tools.ts +1 -1
  99. package/src/agent/show-me.ts +497 -0
  100. package/src/agent/steer.ts +15 -0
  101. package/src/agent/style-tools.ts +217 -0
  102. package/src/agent/tool-error.ts +12 -0
  103. package/src/agent/tools.ts +108 -23
  104. package/src/agent/usage.ts +2 -2
  105. package/src/agent/voice-tools.ts +925 -0
  106. package/src/agent/xcb-agent.ts +11 -7
  107. package/src/argv.ts +38 -0
  108. package/src/audio/analysis.ts +253 -0
  109. package/src/audio/arrange.ts +37 -3
  110. package/src/audio/autotune-engine.ts +101 -0
  111. package/src/audio/autotune.ts +640 -0
  112. package/src/audio/clips.ts +240 -0
  113. package/src/audio/doctor.ts +86 -0
  114. package/src/audio/dsp/bandbank.ts +138 -0
  115. package/src/audio/dsp/envelope.ts +10 -0
  116. package/src/audio/dsp/follow.ts +120 -0
  117. package/src/audio/dsp/formant.ts +427 -0
  118. package/src/audio/dsp/glottal.ts +243 -0
  119. package/src/audio/dsp/interp.ts +7 -2
  120. package/src/audio/dsp/lpc.ts +50 -0
  121. package/src/audio/dsp/periodicity.ts +59 -0
  122. package/src/audio/dsp/pitch.ts +995 -0
  123. package/src/audio/dsp/psola.ts +199 -0
  124. package/src/audio/effects/chain.ts +3 -1
  125. package/src/audio/effects/common.ts +43 -0
  126. package/src/audio/effects/convolution.ts +7 -4
  127. package/src/audio/effects/filter.ts +48 -69
  128. package/src/audio/effects/formant.ts +263 -0
  129. package/src/audio/engine.ts +160 -28
  130. package/src/audio/fit.ts +35 -3
  131. package/src/audio/instrument-check.ts +59 -43
  132. package/src/audio/instruments.ts +4 -0
  133. package/src/audio/keys/calibration.ts +56 -0
  134. package/src/audio/keys/electric.ts +8 -1
  135. package/src/audio/keys/engine.ts +13 -1
  136. package/src/audio/keys/piano.ts +22 -2
  137. package/src/audio/kits.ts +135 -6
  138. package/src/audio/live.ts +114 -20
  139. package/src/audio/native.ts +615 -0
  140. package/src/audio/preview.ts +30 -2
  141. package/src/audio/render-worker.ts +2 -0
  142. package/src/audio/renderer.ts +2 -0
  143. package/src/audio/resample.ts +2 -1
  144. package/src/audio/sampler.ts +85 -4
  145. package/src/audio/samples.ts +20 -2
  146. package/src/audio/sing/analysis.ts +193 -0
  147. package/src/audio/sing/engine.ts +949 -0
  148. package/src/audio/strings/bow.ts +48 -5
  149. package/src/audio/strings/engine.ts +8 -2
  150. package/src/audio/synth/oscillators.ts +31 -21
  151. package/src/audio/synth/voice.ts +34 -1
  152. package/src/audio/vocoder/bank.ts +314 -0
  153. package/src/audio/vocoder/carrier.ts +165 -0
  154. package/src/audio/vocoder/control.ts +68 -0
  155. package/src/audio/vocoder/detect.ts +50 -0
  156. package/src/audio/vocoder/index.ts +304 -0
  157. package/src/audio/vocoder/talkbox.ts +143 -0
  158. package/src/audio/wav.ts +500 -77
  159. package/src/audio/winds/engine.ts +5 -1
  160. package/src/audio/winds/trim.ts +28 -4
  161. package/src/audio/winds/trims1.ts +297 -0
  162. package/src/audio/winds/voice.ts +15 -2
  163. package/src/auth/cli.ts +38 -36
  164. package/src/auth/credentials.ts +30 -1
  165. package/src/auth/login.ts +15 -9
  166. package/src/auth/tui.ts +19 -10
  167. package/src/commands/arrange.ts +44 -29
  168. package/src/commands/autotune.ts +421 -0
  169. package/src/commands/calibration.ts +74 -0
  170. package/src/commands/clips.ts +887 -0
  171. package/src/commands/drums.ts +3 -2
  172. package/src/commands/edit.ts +11 -4
  173. package/src/commands/expression.ts +1 -1
  174. package/src/commands/formant.ts +221 -0
  175. package/src/commands/fx.ts +101 -32
  176. package/src/commands/grammar.ts +558 -0
  177. package/src/commands/help.ts +610 -380
  178. package/src/commands/history.ts +18 -0
  179. package/src/commands/keys.ts +8 -8
  180. package/src/commands/modal.ts +1 -1
  181. package/src/commands/music.ts +1 -1
  182. package/src/commands/nearest.ts +53 -0
  183. package/src/commands/pack.ts +9 -2
  184. package/src/commands/param-range.ts +56 -0
  185. package/src/commands/parses.ts +130 -0
  186. package/src/commands/progression.ts +170 -0
  187. package/src/commands/rhythm.ts +3 -0
  188. package/src/commands/rig.ts +3 -24
  189. package/src/commands/sing.ts +478 -0
  190. package/src/commands/strum.ts +13 -1
  191. package/src/commands/style.ts +415 -0
  192. package/src/commands/time.ts +6 -3
  193. package/src/commands/tuning.ts +3 -3
  194. package/src/commands/vocal-pitch.ts +616 -0
  195. package/src/commands/vocal.ts +147 -0
  196. package/src/commands/vocoder.ts +627 -0
  197. package/src/commands/wind.ts +2 -2
  198. package/src/fs/durable.ts +50 -0
  199. package/src/lang/glossary.ts +493 -0
  200. package/src/launch-args.ts +163 -0
  201. package/src/main.ts +1397 -253
  202. package/src/media/cli.ts +20 -3
  203. package/src/media/import.ts +3 -1
  204. package/src/project/check.ts +21 -2
  205. package/src/project/clip-pins.ts +72 -0
  206. package/src/project/init.ts +23 -8
  207. package/src/project/sync.ts +418 -86
  208. package/src/render.ts +20 -1
  209. package/src/session/daemon.ts +3 -0
  210. package/src/session/meta.ts +14 -0
  211. package/src/session/origin.ts +154 -0
  212. package/src/session/port.ts +22 -4
  213. package/src/session/presence.ts +34 -4
  214. package/src/session/protocol.ts +5 -1
  215. package/src/session/rebase.ts +18 -5
  216. package/src/session/receipt.ts +258 -0
  217. package/src/session/store.ts +65 -43
  218. package/src/tui/arrange-menu.ts +65 -31
  219. package/src/tui/audition.ts +1 -1
  220. package/src/tui/euclid.ts +18 -13
  221. package/src/tui/fader.ts +228 -41
  222. package/src/tui/granular-menu.ts +2 -4
  223. package/src/tui/menu-clips.ts +297 -0
  224. package/src/tui/menu-time.ts +20 -13
  225. package/src/tui/menu-voice.ts +405 -0
  226. package/src/tui/menu.ts +759 -177
  227. package/src/tui/modal-menu.ts +6 -6
  228. package/src/tui/performance-menu.ts +5 -2
  229. package/src/tui/play-chords.ts +4 -2
  230. package/src/tui/play-mode.ts +15 -1
  231. package/src/tui/play-session.ts +47 -7
  232. package/src/tui/sing-menu.ts +278 -0
  233. package/src/tui/style-menu.ts +104 -0
  234. package/src/tui/vocoder-menu.ts +244 -0
  235. package/src/tui/wind-menu.ts +3 -3
  236. package/src/version.ts +8 -0
  237. package/src/web/fetch.ts +115 -29
  238. package/tui/activity.ts +180 -9
  239. package/tui/app.ts +274 -40
  240. package/tui/clip-row.ts +132 -0
  241. package/tui/delight.ts +144 -0
  242. package/tui/drawer.ts +70 -22
  243. package/tui/frame-gate.ts +76 -0
  244. package/tui/grammar.ts +112 -63
  245. package/tui/guide.ts +42 -4
  246. package/tui/highway.ts +269 -25
  247. package/tui/hints.ts +192 -0
  248. package/tui/input.ts +60 -9
  249. package/tui/keys.ts +1 -1
  250. package/tui/play-strip.ts +68 -14
  251. package/tui/prompt.ts +1 -1
  252. package/tui/screen.ts +144 -14
  253. package/tui/theme.ts +27 -0
@@ -0,0 +1,3189 @@
1
+ /**
2
+ * Pop, hip hop and breakbeat bass (quality-08 family `pop`). Root and
3
+ * branch cards carry what a branch shares; each leaf carries only its
4
+ * deltas and a summary that names the theory it encodes (backbeat
5
+ * placement, half-time feel, two-step kick, dembow, tresillo, royal-road
6
+ * progression, yonanuki minor, ppongjjak two-beat and so on).
7
+ * `breakbeat-family` sits under `electronic` in the tree but belongs to
8
+ * this family's file.
9
+ *
10
+ * References (theory, not quotation):
11
+ * - pop: Philip Tagg, Everyday Tonality (2009); Allan F. Moore, Song Means
12
+ * (2012), on loops, modal interchange and verse-chorus form.
13
+ * - hip hop: Kyle Adams, "On the Metrical Techniques of Flow in Rap Music"
14
+ * (Music Theory Online 15.5, 2009); Joseph Schloss, Making Beats (2004).
15
+ * - breakbeat and UK bass: Mark J. Butler, Unlocking the Groove (2006);
16
+ * Simon Reynolds, Energy Flash (1998), on the hardcore continuum.
17
+ *
18
+ * Every rhythm here is an abstract onset grid and every progression a
19
+ * functional numeral grammar; no melody, lyric or recording is quoted.
20
+ */
21
+
22
+ import { grid, intervals, kit, maybe, role } from "./parts.ts";
23
+ import {
24
+ card,
25
+ type RoleTexture,
26
+ type RoleVoice,
27
+ type StyleCard,
28
+ } from "./schema.ts";
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Shared grids (16 steps = one 4/4 bar of sixteenths unless noted)
32
+
33
+ const BACKBEAT = grid("....x.......x...");
34
+ const HALF_SNARE = grid("........x.......");
35
+ const FOUR_FLOOR = grid("x...x...x...x...");
36
+ const EIGHTH_HAT = grid("x.x.x.x.x.x.x.x.");
37
+ const SIXTEENTH_HAT = grid("xxxxxxxxxxxxxxxx");
38
+ const OFFBEAT_HAT = grid("..x...x...x...x.");
39
+ /** Trap hats: straight 16ths with probabilistic roll steps. */
40
+ const TRAP_HAT = grid("x.x.x.x.x.x.x5xx");
41
+ /** Two-step drum and bass: kick on 1 and the "and" of 3, snare on 2 and 4. */
42
+ const TWO_STEP_KICK = grid("x.........x.....");
43
+ /** Dembow: four-on-the-floor kick under snare on steps 3, 6, 11, 14. */
44
+ const DEMBOW_SNARE = grid("...x..x....x..x.");
45
+ /** Tresillo 3+3+2 sixteenths, once per half bar (the dembow bass cell). */
46
+ const TRESILLO = grid("x..x..x.x..x..x.");
47
+ /** Boom bap kick: 1, the "and" of 2-ish, the "a" of 3. */
48
+ const BOOM_BAP_KICK = grid("x......x..x.....");
49
+
50
+ /**
51
+ * Kit choices. The kit roles share one drum track, so every kit role of a
52
+ * card names the same choice (the generator takes the first kit role's).
53
+ */
54
+ const kitChoice = (...voices: RoleVoice[]): RoleTexture =>
55
+ Object.freeze({ required: true, voices: Object.freeze(voices) });
56
+ const MACHINE = kitChoice(kit("syn808"), kit("trap", 0.6));
57
+ const TRAP_KIT = kitChoice(kit("trap"), kit("syn808", 0.4));
58
+ const ACOUSTIC_KIT = kitChoice(kit("acoustic"));
59
+ const DUSTY_KIT = kitChoice(kit("lofi"), kit("acoustic", 0.4));
60
+ const ELECTRO_KIT = kitChoice(kit("electro"), kit("syn808", 0.5));
61
+ const CLUB_KIT = kitChoice(kit("syn909"), kit("electro", 0.4));
62
+ /** The same kit choice as an optional role. */
63
+ const opt = (choice: RoleTexture): RoleTexture =>
64
+ Object.freeze({ required: false, voices: choice.voices });
65
+
66
+ /** Every kit role on one kit choice (clap and open hat optional). */
67
+ function kitAll(choice: RoleTexture): Record<string, RoleTexture> {
68
+ return {
69
+ kick: choice,
70
+ snare: choice,
71
+ hat: choice,
72
+ clap: opt(choice),
73
+ openhat: opt(choice),
74
+ };
75
+ }
76
+
77
+ type LeafBody = Omit<StyleCard, "id" | "summary" | "seedSalt">;
78
+
79
+ /** A leaf card: id, a summary naming its theory, an origin-year salt. */
80
+ function leaf(
81
+ id: string,
82
+ summary: string,
83
+ seedSalt: number,
84
+ body: LeafBody,
85
+ ): StyleCard {
86
+ return card({ id, summary, seedSalt, ...body });
87
+ }
88
+
89
+ const PIANO_BALLAD = intervals(5, 3, 1, 1.2);
90
+ const RAP_FLOW = intervals(4, 2, 0.4, 3);
91
+ const HOOKY = intervals(5, 3, 0.8, 1.6);
92
+
93
+ // ---------------------------------------------------------------------------
94
+ // Root and branches
95
+
96
+ const ROOTS: readonly StyleCard[] = [
97
+ card({
98
+ id: "pop",
99
+ abstract: true,
100
+ summary:
101
+ "song-first: repeating hooks, backbeat on 2 and 4, I-V-vi-IV loops, verse-pre-chorus-chorus",
102
+ tempo: { bpm: [80, 130], typical: 112 },
103
+ rhythm: {
104
+ onsets: {
105
+ kick: grid("x.......x.x....."),
106
+ snare: BACKBEAT,
107
+ hat: EIGHTH_HAT,
108
+ },
109
+ },
110
+ harmony: {
111
+ presets: [
112
+ ["axis", 0.4],
113
+ ["sad-pop", 0.3],
114
+ ["fifties", 0.15],
115
+ ["canon", 0.15],
116
+ ],
117
+ },
118
+ melody: {
119
+ repetition: 0.75,
120
+ ambitus: [7, 12],
121
+ phraseBars: [
122
+ [2, 0.5],
123
+ [4, 0.5],
124
+ ],
125
+ intervals: HOOKY,
126
+ },
127
+ form: {
128
+ plans: [
129
+ [
130
+ [
131
+ "intro",
132
+ "verse",
133
+ "pre",
134
+ "chorus",
135
+ "verse",
136
+ "pre",
137
+ "chorus",
138
+ "bridge",
139
+ "chorus",
140
+ ],
141
+ 1,
142
+ ],
143
+ ],
144
+ },
145
+ texture: {
146
+ roles: {
147
+ chords: role("piano", "acoustic:0.5", "keys:0.5"),
148
+ lead: role("sing", "lead:0.5"),
149
+ pad: maybe("strings"),
150
+ },
151
+ },
152
+ mix: { loudness: "streaming" },
153
+ }),
154
+ card({
155
+ id: "traditional-pop",
156
+ abstract: true,
157
+ summary:
158
+ "crooner and standards pop: 32-bar AABA, ii-V turnarounds, two-beat bass, strings",
159
+ groove: { subdivision: 2, swingRatio: [1, 1.6] },
160
+ rhythm: {
161
+ onsets: {
162
+ kick: grid("x...x..."),
163
+ snare: grid("..x...x."),
164
+ hat: grid("x.x.x.x."),
165
+ },
166
+ },
167
+ harmony: {
168
+ presets: [
169
+ ["turnaround", 0.5],
170
+ ["ii-v-i", 0.5],
171
+ ],
172
+ sevenths: 0.6,
173
+ },
174
+ bass: { behaviour: [["root-fifth", 1]], onsets: grid("x...x...") },
175
+ form: {
176
+ plans: [[["verse", "verse", "bridge", "verse"], 1]],
177
+ archetype: "AABA",
178
+ },
179
+ texture: {
180
+ kind: "homophonic",
181
+ roles: {
182
+ kick: ACOUSTIC_KIT,
183
+ snare: ACOUSTIC_KIT,
184
+ hat: ACOUSTIC_KIT,
185
+ chords: role("strings", "piano:0.6"),
186
+ bass: role("contrabass", "upright:0.5"),
187
+ },
188
+ },
189
+ expression: { dynamics: [0.35, 0.85] },
190
+ mix: { space: 0.35 },
191
+ }),
192
+ card({
193
+ id: "sixties-pop",
194
+ abstract: true,
195
+ summary:
196
+ "1960s pop: fifties progressions, tambourine backbeat, eighth-note feel, vocal harmony",
197
+ groove: { subdivision: 2 },
198
+ rhythm: {
199
+ onsets: {
200
+ kick: grid("x...x.x."),
201
+ snare: grid("..x...x."),
202
+ hat: grid("xxxxxxxx"),
203
+ },
204
+ },
205
+ harmony: {
206
+ presets: [
207
+ ["fifties", 0.6],
208
+ ["axis", 0.4],
209
+ ],
210
+ },
211
+ bass: { onsets: grid("x...x.x.") },
212
+ texture: {
213
+ roles: {
214
+ kick: ACOUSTIC_KIT,
215
+ snare: ACOUSTIC_KIT,
216
+ hat: ACOUSTIC_KIT,
217
+ bass: role("fender", "bass:0.5"),
218
+ chords: role("jangle", "piano:0.5"),
219
+ counter: maybe("choir"),
220
+ },
221
+ },
222
+ }),
223
+ card({
224
+ id: "modern-pop",
225
+ abstract: true,
226
+ summary:
227
+ "modern pop: programmed drums, four-chord loops, sparse verses, big choruses",
228
+ rhythm: { onsets: { clap: BACKBEAT } },
229
+ texture: {
230
+ roles: { ...kitAll(MACHINE), chords: role("keys", "pluck:0.5") },
231
+ },
232
+ }),
233
+ card({
234
+ id: "hip-hop",
235
+ abstract: true,
236
+ summary:
237
+ "beat-first: boom-bap or trap grids, loops of one to four chords, rap-led flow on the 16th grid",
238
+ tempo: { bpm: [70, 100], typical: 90 },
239
+ groove: { swingRatio: [1, 1.3], humanize: { timingMs: 6, velocity: 0.08 } },
240
+ rhythm: {
241
+ onsets: {
242
+ kick: BOOM_BAP_KICK,
243
+ snare: BACKBEAT,
244
+ hat: EIGHTH_HAT,
245
+ },
246
+ },
247
+ pitch: {
248
+ scales: [
249
+ ["minor", 0.5],
250
+ ["dorian", 0.3],
251
+ ["minor-pentatonic", 0.2],
252
+ ],
253
+ },
254
+ harmony: {
255
+ model: "functional",
256
+ presets: [
257
+ ["aeolian", 0.4],
258
+ ["dorian-vamp", 0.3],
259
+ ["sad-pop", 0.3],
260
+ ],
261
+ rhythm: [
262
+ [1, 0.5],
263
+ [0.5, 0.5],
264
+ ],
265
+ sevenths: 0.5,
266
+ },
267
+ melody: {
268
+ density: [1, 2],
269
+ repetition: 0.85,
270
+ ambitus: [3, 8],
271
+ intervals: RAP_FLOW,
272
+ },
273
+ bass: {
274
+ behaviour: [
275
+ ["root", 0.6],
276
+ ["ostinato", 0.4],
277
+ ],
278
+ },
279
+ form: {
280
+ plans: [[["intro", "verse", "chorus", "verse", "chorus", "outro"], 1]],
281
+ },
282
+ texture: {
283
+ roles: {
284
+ kick: MACHINE,
285
+ snare: MACHINE,
286
+ hat: MACHINE,
287
+ chords: role("epiano", "keys:0.5", "strings:0.3"),
288
+ lead: role("vocal", "pluck:0.5"),
289
+ },
290
+ },
291
+ mix: { loudness: "loud" },
292
+ }),
293
+ card({
294
+ id: "old-school",
295
+ abstract: true,
296
+ summary:
297
+ "old-school hip hop: break loops, electro drum machines, one-chord funk vamps",
298
+ tempo: { bpm: [95, 115], typical: 104 },
299
+ harmony: { model: "modal" },
300
+ texture: { roles: kitAll(ELECTRO_KIT) },
301
+ }),
302
+ card({
303
+ id: "regional-rap",
304
+ abstract: true,
305
+ summary: "regional rap: boom-bap swing, bounce, crunk and g-funk grooves",
306
+ groove: { swingRatio: [1.1, 1.4] },
307
+ }),
308
+ card({
309
+ id: "modern-rap",
310
+ abstract: true,
311
+ summary:
312
+ "trap-era rap: half-time snare on 3, rolling 16th hats, 808 sub on the kick",
313
+ tempo: { bpm: [130, 160], typical: 140 },
314
+ groove: { swingRatio: [1, 1.1], humanize: { timingMs: 2, velocity: 0.06 } },
315
+ rhythm: {
316
+ onsets: {
317
+ kick: grid("x.....x.......x."),
318
+ snare: HALF_SNARE,
319
+ hat: TRAP_HAT,
320
+ },
321
+ },
322
+ bass: {
323
+ behaviour: [["root", 1]],
324
+ onsets: grid("x.....x.......x."),
325
+ kickLock: 0.6,
326
+ },
327
+ texture: { roles: kitAll(TRAP_KIT) },
328
+ }),
329
+ card({
330
+ id: "breakbeat-family",
331
+ abstract: true,
332
+ summary:
333
+ "breakbeat and bass: syncopated broken kits off the four-on-the-floor, sub bass, 130-175 bpm",
334
+ tempo: { bpm: [130, 175], typical: 170 },
335
+ meter: { hypermeter: [[8, 1]] },
336
+ groove: { humanize: { timingMs: 1, velocity: 0.05 } },
337
+ rhythm: {
338
+ onsets: {
339
+ kick: TWO_STEP_KICK,
340
+ snare: BACKBEAT,
341
+ hat: EIGHTH_HAT,
342
+ // The electronic root's clap on 2 and 4 would fight half-time
343
+ // snares; leaves that clap name their own grid.
344
+ clap: null,
345
+ },
346
+ fills: { every: 8, density: [0.3, 0.6] },
347
+ },
348
+ pitch: {
349
+ scales: [
350
+ ["minor", 0.7],
351
+ ["phrygian", 0.3],
352
+ ],
353
+ },
354
+ harmony: { presets: [["aeolian", 1]], rhythm: [[0.5, 1]] },
355
+ melody: { repetition: 0.85 },
356
+ bass: {
357
+ behaviour: [
358
+ ["root", 0.5],
359
+ ["octave", 0.5],
360
+ ],
361
+ range: [26, 45],
362
+ },
363
+ form: {
364
+ plans: [[["intro", "build", "drop", "breakdown", "drop", "outro"], 1]],
365
+ archetype: "build-drop",
366
+ },
367
+ texture: {
368
+ roles: {
369
+ ...kitAll(MACHINE),
370
+ bass: role("bass", "saw:0.5"),
371
+ chords: role("keys", "strings:0.5"),
372
+ lead: maybe("lead"),
373
+ },
374
+ },
375
+ mix: { loudness: "club" },
376
+ }),
377
+ ];
378
+
379
+ // ---------------------------------------------------------------------------
380
+ // Traditional pop (two-beat, swung eighths, standards harmony)
381
+
382
+ const WALTZ_KICK = grid("x.....");
383
+ const WALTZ_SNARE = grid("..x.x.");
384
+ const WALTZ_HAT = grid("x.x.x.");
385
+
386
+ const TRADITIONAL: readonly StyleCard[] = [
387
+ leaf(
388
+ "tin-pan-alley",
389
+ "32-bar AABA standard: I-vi-ii-V turnaround, ii-V-I bridge in the subdominant, swung two-beat",
390
+ 1920,
391
+ {
392
+ tempo: { bpm: [100, 150], typical: 126 },
393
+ groove: { swingRatio: [1.5, 2] },
394
+ harmony: {
395
+ presets: [
396
+ ["turnaround", 0.6],
397
+ ["ii-v-i", 0.4],
398
+ ],
399
+ cadences: [
400
+ ["V-I", 0.8],
401
+ ["half", 0.2],
402
+ ],
403
+ sevenths: 0.8,
404
+ },
405
+ melody: { ambitus: [9, 13], chordToneRate: 0.8 },
406
+ },
407
+ ),
408
+ leaf(
409
+ "crooner",
410
+ "crooner ballad: slow swung eighths, sevenths and sixths, rubato phrasing over strings and brushed kit",
411
+ 1940,
412
+ {
413
+ tempo: { bpm: [60, 96], typical: 76 },
414
+ groove: { swingRatio: [1.4, 1.8] },
415
+ harmony: { sevenths: 0.85 },
416
+ melody: { density: [0.5, 1.5], intervals: PIANO_BALLAD },
417
+ texture: {
418
+ roles: { chords: role("strings", "grand:0.6"), pad: maybe("violins") },
419
+ },
420
+ expression: { dynamics: [0.3, 0.75] },
421
+ },
422
+ ),
423
+ leaf(
424
+ "lounge",
425
+ "lounge and space-age pop: major sevenths and ninths, latin-tinged straight eights, vibes and organ",
426
+ 1958,
427
+ {
428
+ tempo: { bpm: [100, 135], typical: 116 },
429
+ groove: { swingRatio: [1, 1.2] },
430
+ rhythm: { onsets: { kick: grid("x..xx..."), rim: grid("..x..x.x") } },
431
+ harmony: { presets: [["ii-v-i", 1]], sevenths: 0.9 },
432
+ texture: {
433
+ roles: {
434
+ rim: opt(ACOUSTIC_KIT),
435
+ chords: role("vibes", "hammond:0.5", "piano:0.4"),
436
+ lead: role("flute", "vibes:0.5", "ooh:0.4"),
437
+ },
438
+ },
439
+ },
440
+ ),
441
+ leaf(
442
+ "exotica",
443
+ "exotica: phrygian-dominant and lydian color, vibes, bells and hand percussion over a mambo-like ostinato",
444
+ 1957,
445
+ {
446
+ tempo: { bpm: [90, 125], typical: 104 },
447
+ groove: { swingRatio: [1, 1] },
448
+ rhythm: {
449
+ onsets: {
450
+ kick: grid("x..x..x."),
451
+ perc: grid("x.xx.xx."),
452
+ bell: grid("..x...x."),
453
+ },
454
+ },
455
+ pitch: {
456
+ scales: [
457
+ ["phrygian-dominant", 0.4],
458
+ ["lydian", 0.3],
459
+ ["major-pentatonic", 0.3],
460
+ ],
461
+ },
462
+ harmony: { model: "modal", sevenths: 0.7 },
463
+ bass: { behaviour: [["ostinato", 1]] },
464
+ texture: {
465
+ roles: {
466
+ perc: role("drums"),
467
+ bell: maybe("bell", "chimes:0.5"),
468
+ chords: role("vibes", "marimba:0.6", "harp:0.4"),
469
+ lead: role("vibes", "flute:0.5"),
470
+ },
471
+ },
472
+ mix: { space: 0.5 },
473
+ },
474
+ ),
475
+ leaf(
476
+ "light-music",
477
+ "light orchestral music: diatonic major, string melody with woodwind countermelody, homophonic, no drums",
478
+ 1935,
479
+ {
480
+ groove: { swingRatio: [1, 1] },
481
+ meter: {
482
+ signatures: [
483
+ ["4/4", 0.7],
484
+ ["3/4", 0.3],
485
+ ],
486
+ },
487
+ harmony: {
488
+ presets: [
489
+ ["canon", 0.5],
490
+ ["fifties", 0.5],
491
+ ],
492
+ sevenths: 0.2,
493
+ voicing: { types: [["open", 1]], range: [48, 79], notes: [3, 5] },
494
+ },
495
+ texture: {
496
+ roles: {
497
+ kick: null,
498
+ snare: null,
499
+ hat: null,
500
+ chords: role("strings", "harp:0.4"),
501
+ lead: role("violins", "flute:0.5", "oboe:0.4"),
502
+ counter: maybe("clarinet", "horn:0.5"),
503
+ },
504
+ },
505
+ mix: { space: 0.45, loudness: "classical" },
506
+ },
507
+ ),
508
+ leaf(
509
+ "schlager",
510
+ "schlager: oom-pah two-beat (bass on 1 and 3, chord on 2 and 4), plain I-IV-V major, singalong chorus",
511
+ 1960,
512
+ {
513
+ tempo: { bpm: [110, 140], typical: 124 },
514
+ groove: { swingRatio: [1, 1] },
515
+ rhythm: {
516
+ onsets: {
517
+ kick: grid("x...x..."),
518
+ snare: grid("..x...x."),
519
+ hat: grid("x.x.x.x."),
520
+ },
521
+ },
522
+ pitch: { scales: [["major", 1]] },
523
+ harmony: {
524
+ sources: { forms: 1, presets: 0, chain: 0 },
525
+ forms: [
526
+ [["I", "I", "V7", "V7", "V7", "V7", "I", "I"], 0.4],
527
+ [["I", "IV", "V7", "I"], 0.4],
528
+ [["I", "I", "IV", "IV", "V7", "V7", "I", "I"], 0.2],
529
+ ],
530
+ sevenths: 0,
531
+ },
532
+ bass: { behaviour: [["root-fifth", 1]], onsets: grid("x...x...") },
533
+ melody: { ambitus: [7, 11], repetition: 0.85 },
534
+ texture: {
535
+ roles: { chords: role("reeds", "keys:0.5"), lead: role("sing") },
536
+ },
537
+ },
538
+ ),
539
+ leaf(
540
+ "chanson",
541
+ "chanson: text-led melody, valse-musette 3/4 or rubato 4/4, minor with harmonic-minor V",
542
+ 1930,
543
+ {
544
+ meter: {
545
+ signatures: [
546
+ ["3/4", 0.5],
547
+ ["4/4", 0.5],
548
+ ],
549
+ },
550
+ tempo: { bpm: [80, 160], typical: 120 },
551
+ rhythm: {
552
+ onsets: { kick: WALTZ_KICK, snare: WALTZ_SNARE, hat: WALTZ_HAT },
553
+ },
554
+ pitch: {
555
+ scales: [
556
+ ["harmonic-minor", 0.5],
557
+ ["minor", 0.3],
558
+ ["major", 0.2],
559
+ ],
560
+ },
561
+ harmony: {
562
+ presets: [
563
+ ["minor-ii-v", 0.5],
564
+ ["aeolian", 0.5],
565
+ ],
566
+ },
567
+ melody: { density: [1, 3], chordToneRate: 0.6 },
568
+ bass: { onsets: grid("x.....") },
569
+ texture: {
570
+ roles: {
571
+ chords: role("reeds", "piano:0.6", "nylon:0.4"),
572
+ bass: role("contrabass"),
573
+ },
574
+ },
575
+ },
576
+ ),
577
+ leaf(
578
+ "canzone",
579
+ "canzone italiana: bel-canto melody with wide climaxing leaps, I-vi-IV-V, strings and nylon guitar",
580
+ 1951,
581
+ {
582
+ groove: { swingRatio: [1, 1] },
583
+ tempo: { bpm: [70, 120], typical: 92 },
584
+ harmony: {
585
+ presets: [
586
+ ["fifties", 0.5],
587
+ ["canon", 0.3],
588
+ ["minor-ii-v", 0.2],
589
+ ],
590
+ },
591
+ melody: {
592
+ ambitus: [10, 15],
593
+ intervals: intervals(4, 3, 1.6, 1),
594
+ contour: [["arch", 1]],
595
+ },
596
+ texture: { roles: { chords: role("nylon", "strings:0.6", "piano:0.4") } },
597
+ },
598
+ ),
599
+ leaf(
600
+ "european-pop-ballad",
601
+ "Euro ballad: piano-led verse, I-V-vi-IV chorus, final chorus up a step (truck-driver modulation in the form)",
602
+ 1975,
603
+ {
604
+ groove: { subdivision: 4, swingRatio: [1, 1] },
605
+ tempo: { bpm: [66, 100], typical: 80 },
606
+ rhythm: {
607
+ onsets: {
608
+ kick: grid("x.......x......."),
609
+ snare: BACKBEAT,
610
+ hat: EIGHTH_HAT,
611
+ },
612
+ },
613
+ harmony: {
614
+ presets: [
615
+ ["axis", 0.5],
616
+ ["canon", 0.5],
617
+ ],
618
+ sevenths: 0.15,
619
+ },
620
+ bass: { behaviour: [["root", 1]], onsets: grid("x.......x.......") },
621
+ melody: { ambitus: [10, 14], intervals: PIANO_BALLAD },
622
+ texture: {
623
+ roles: { chords: role("grand", "strings:0.5"), bass: role("bass") },
624
+ },
625
+ },
626
+ ),
627
+ leaf(
628
+ "musette",
629
+ "bal musette: fast valse 3/4, chromatic passing tones, accordion lead, bass on 1 and chord on 2-3",
630
+ 1910,
631
+ {
632
+ meter: { signatures: [["3/4", 1]] },
633
+ tempo: { bpm: [140, 200], typical: 168 },
634
+ groove: { swingRatio: [1.2, 1.5] },
635
+ rhythm: { onsets: { kick: WALTZ_KICK, snare: WALTZ_SNARE, hat: null } },
636
+ pitch: {
637
+ scales: [
638
+ ["harmonic-minor", 0.5],
639
+ ["major", 0.5],
640
+ ],
641
+ },
642
+ harmony: {
643
+ presets: [
644
+ ["minor-ii-v", 0.5],
645
+ ["turnaround", 0.5],
646
+ ],
647
+ },
648
+ melody: { density: [2, 3], intervals: intervals(6, 2, 0.6, 0.6) },
649
+ bass: { onsets: grid("x.....") },
650
+ texture: {
651
+ roles: {
652
+ hat: null,
653
+ chords: role("reeds", "nylon:0.5"),
654
+ lead: role("reeds"),
655
+ },
656
+ },
657
+ },
658
+ ),
659
+ leaf(
660
+ "kayokyoku",
661
+ "kayokyoku: yonanuki minor melody (1 2 b3 5 b6, no 4th or 7th) over harmonic-minor i-iv-V7, strings and guitar, foxtrot or go-go beat",
662
+ 1965,
663
+ {
664
+ groove: { subdivision: 4, swingRatio: [1, 1.1] },
665
+ rhythm: {
666
+ onsets: {
667
+ kick: grid("x.......x......."),
668
+ snare: BACKBEAT,
669
+ hat: EIGHTH_HAT,
670
+ },
671
+ },
672
+ pitch: {
673
+ scales: [
674
+ ["yonanuki-minor", 0.8],
675
+ ["harmonic-minor", 0.2],
676
+ ],
677
+ },
678
+ harmony: {
679
+ sources: { forms: 1, presets: 0, chain: 0 },
680
+ forms: [
681
+ [["i", "iv", "V7", "i"], 0.5],
682
+ [["i", "VI", "iv", "V7"], 0.3],
683
+ [["iv", "V7", "i", "i"], 0.2],
684
+ ],
685
+ sevenths: 0.2,
686
+ },
687
+ bass: { onsets: grid("x.......x.......") },
688
+ texture: { roles: { chords: role("strings", "electric@clean:0.5") } },
689
+ },
690
+ ),
691
+ leaf(
692
+ "enka",
693
+ "enka: slow yonanuki minor melody (1 2 b3 5 b6) with kobushi ornament, i-iv-V7 harmonic-minor cadence, shakuhachi and strings",
694
+ 1960,
695
+ {
696
+ tempo: { bpm: [60, 90], typical: 72 },
697
+ groove: { swingRatio: [1.3, 1.6] },
698
+ pitch: { scales: [["yonanuki-minor", 1]] },
699
+ harmony: {
700
+ sources: { forms: 1, presets: 0, chain: 0 },
701
+ forms: [
702
+ [["i", "iv", "V7", "i"], 0.6],
703
+ [["i", "i", "iv", "V7"], 0.4],
704
+ ],
705
+ sevenths: 0.2,
706
+ rhythm: [[0.5, 1]],
707
+ },
708
+ melody: { density: [0.5, 1.5], ambitus: [7, 12], finals: [[0, 1]] },
709
+ texture: {
710
+ roles: {
711
+ chords: role("strings", "electric@clean:0.4"),
712
+ counter: maybe("shakuhachi", "koto:0.5"),
713
+ lead: role("sing"),
714
+ },
715
+ },
716
+ expression: { dynamics: [0.3, 0.8] },
717
+ },
718
+ ),
719
+ leaf(
720
+ "shidaiqu",
721
+ "shidaiqu: Chinese pentatonic melody over a jazz-band foxtrot two-beat, sixth chords, erhu and strings",
722
+ 1930,
723
+ {
724
+ tempo: { bpm: [90, 130], typical: 110 },
725
+ pitch: { scales: [["major-pentatonic", 1]] },
726
+ harmony: { presets: [["turnaround", 1]], sevenths: 0.3 },
727
+ melody: {
728
+ finals: [
729
+ [0, 0.6],
730
+ [4, 0.4],
731
+ ],
732
+ },
733
+ texture: {
734
+ roles: {
735
+ chords: role("piano", "strings:0.5"),
736
+ counter: maybe("erhu", "violin:0.5"),
737
+ lead: role("sing", "erhu:0.4"),
738
+ },
739
+ },
740
+ },
741
+ ),
742
+ leaf(
743
+ "trot",
744
+ "trot: ppongjjak two-beat (bass on the beat, snare on the off-beats), yonanuki minor melody (1 2 b3 5 b6), i-iv-V7, quick tempo",
745
+ 1930,
746
+ {
747
+ tempo: { bpm: [120, 150], typical: 132 },
748
+ groove: { swingRatio: [1, 1.2] },
749
+ rhythm: {
750
+ onsets: {
751
+ kick: grid("x...x..."),
752
+ snare: grid("..x...x."),
753
+ hat: grid("xxxxxxxx"),
754
+ },
755
+ },
756
+ pitch: { scales: [["yonanuki-minor", 1]] },
757
+ harmony: {
758
+ sources: { forms: 1, presets: 0, chain: 0 },
759
+ forms: [
760
+ [["i", "i", "iv", "iv", "V7", "V7", "i", "i"], 0.6],
761
+ [["i", "iv", "V7", "i"], 0.4],
762
+ ],
763
+ sevenths: 0.1,
764
+ },
765
+ bass: { behaviour: [["root-fifth", 1]], onsets: grid("x...x...") },
766
+ melody: { repetition: 0.8 },
767
+ texture: {
768
+ roles: {
769
+ chords: role("keys", "electric@clean:0.5"),
770
+ lead: role("sing", "sax:0.4"),
771
+ },
772
+ },
773
+ },
774
+ ),
775
+ ];
776
+
777
+ // ---------------------------------------------------------------------------
778
+ // Sixties pop
779
+
780
+ const SIXTIES: readonly StyleCard[] = [
781
+ leaf(
782
+ "brill-building",
783
+ "Brill Building and girl group: baion rhythm (tresillo kick), I-vi-IV-V, wall-of-sound reverb and castanets",
784
+ 1960,
785
+ {
786
+ tempo: { bpm: [100, 140], typical: 120 },
787
+ groove: { subdivision: 4 },
788
+ rhythm: {
789
+ onsets: {
790
+ kick: grid("x..x....x......."),
791
+ snare: BACKBEAT,
792
+ hat: EIGHTH_HAT,
793
+ perc: grid("x..x..x........."),
794
+ },
795
+ },
796
+ harmony: { presets: [["fifties", 1]] },
797
+ bass: { onsets: grid("x..x....x..x....") },
798
+ texture: {
799
+ roles: {
800
+ perc: maybe("drums"),
801
+ chords: role("piano", "strings:0.6"),
802
+ counter: role("choir", "ooh:0.5"),
803
+ },
804
+ },
805
+ mix: { space: 0.6 },
806
+ },
807
+ ),
808
+ leaf(
809
+ "sunshine-pop",
810
+ "sunshine and baroque pop: major sevenths, lydian color, harpsichord and strings, stacked vocal harmony",
811
+ 1966,
812
+ {
813
+ pitch: {
814
+ scales: [
815
+ ["major", 0.6],
816
+ ["lydian", 0.2],
817
+ ["mixolydian", 0.2],
818
+ ],
819
+ },
820
+ harmony: {
821
+ presets: [
822
+ ["canon", 0.5],
823
+ ["axis", 0.5],
824
+ ],
825
+ sevenths: 0.5,
826
+ },
827
+ texture: {
828
+ roles: {
829
+ chords: role("harpsichord", "jangle:0.6", "piano:0.4"),
830
+ pad: maybe("strings"),
831
+ counter: role("aah", "choir:0.5"),
832
+ },
833
+ },
834
+ },
835
+ ),
836
+ leaf(
837
+ "bubblegum",
838
+ "bubblegum: three-chord I-IV-V, major-pentatonic hook repeated verbatim, bright eighth-note bounce",
839
+ 1968,
840
+ {
841
+ tempo: { bpm: [118, 140], typical: 128 },
842
+ pitch: { scales: [["major", 1]] },
843
+ harmony: {
844
+ presets: [
845
+ ["fifties", 0.5],
846
+ ["axis", 0.5],
847
+ ],
848
+ sevenths: 0,
849
+ },
850
+ melody: { repetition: 0.95, ambitus: [5, 9] },
851
+ texture: {
852
+ roles: { chords: role("piano", "organ:0.5"), lead: role("sing") },
853
+ },
854
+ },
855
+ ),
856
+ leaf(
857
+ "ye-ye",
858
+ "ye-ye: twist backbeat with handclaps, minor-major mixture, Farfisa organ and twangy guitar",
859
+ 1963,
860
+ {
861
+ tempo: { bpm: [130, 165], typical: 148 },
862
+ rhythm: { onsets: { clap: grid("..x...x.") } },
863
+ pitch: {
864
+ scales: [
865
+ ["major", 0.5],
866
+ ["minor", 0.5],
867
+ ],
868
+ },
869
+ harmony: {
870
+ presets: [
871
+ ["fifties", 0.5],
872
+ ["aeolian", 0.5],
873
+ ],
874
+ },
875
+ texture: {
876
+ roles: {
877
+ clap: opt(ACOUSTIC_KIT),
878
+ chords: role("farfisa", "electric@spring:0.6"),
879
+ },
880
+ },
881
+ },
882
+ ),
883
+ leaf(
884
+ "power-pop",
885
+ "power pop: crunchy power chords, I-IV-V with bVII mixture, driving eighth-note bass, high harmonies",
886
+ 1972,
887
+ {
888
+ tempo: { bpm: [125, 160], typical: 140 },
889
+ pitch: {
890
+ scales: [
891
+ ["major", 0.7],
892
+ ["mixolydian", 0.3],
893
+ ],
894
+ },
895
+ harmony: {
896
+ presets: [
897
+ ["mixolydian-rock", 0.4],
898
+ ["axis", 0.6],
899
+ ],
900
+ voicing: {
901
+ types: [
902
+ ["power", 0.6],
903
+ ["close", 0.4],
904
+ ],
905
+ },
906
+ },
907
+ bass: { behaviour: [["root", 1]], onsets: grid("xxxxxxxx") },
908
+ texture: {
909
+ roles: {
910
+ chords: role("electric@crunch", "jangle:0.5"),
911
+ counter: maybe("aah"),
912
+ },
913
+ },
914
+ },
915
+ ),
916
+ ];
917
+
918
+ // ---------------------------------------------------------------------------
919
+ // Modern pop
920
+
921
+ const MODERN: readonly StyleCard[] = [
922
+ leaf(
923
+ "new-wave",
924
+ "new wave: motorik eighth-note hats and bass, mixolydian bVII, angular synth and chorus guitar",
925
+ 1979,
926
+ {
927
+ tempo: { bpm: [125, 160], typical: 140 },
928
+ rhythm: {
929
+ onsets: { kick: FOUR_FLOOR, hat: EIGHTH_HAT },
930
+ },
931
+ pitch: {
932
+ scales: [
933
+ ["mixolydian", 0.4],
934
+ ["minor", 0.3],
935
+ ["major", 0.3],
936
+ ],
937
+ },
938
+ harmony: {
939
+ presets: [
940
+ ["mixolydian-rock", 0.5],
941
+ ["aeolian", 0.5],
942
+ ],
943
+ },
944
+ bass: {
945
+ behaviour: [
946
+ ["octave", 0.5],
947
+ ["root", 0.5],
948
+ ],
949
+ onsets: grid("x.x.x.x.x.x.x.x."),
950
+ },
951
+ texture: {
952
+ roles: {
953
+ ...kitAll(ELECTRO_KIT),
954
+ chords: role("electric@clean", "saw:0.5"),
955
+ lead: role("sing", "square:0.4"),
956
+ },
957
+ },
958
+ },
959
+ ),
960
+ leaf(
961
+ "synth-pop",
962
+ "synth-pop: sequenced 16th arpeggios, minor loops with bVI-bVII, drum-machine backbeat",
963
+ 1981,
964
+ {
965
+ tempo: { bpm: [110, 132], typical: 120 },
966
+ rhythm: {
967
+ onsets: { kick: grid("x.......x.x....."), hat: SIXTEENTH_HAT },
968
+ },
969
+ pitch: {
970
+ scales: [
971
+ ["minor", 0.6],
972
+ ["major", 0.4],
973
+ ],
974
+ },
975
+ harmony: {
976
+ presets: [
977
+ ["aeolian", 0.5],
978
+ ["sad-pop", 0.5],
979
+ ],
980
+ },
981
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x.x.x.x.x.x.x.x.") },
982
+ texture: {
983
+ roles: {
984
+ ...kitAll(ELECTRO_KIT),
985
+ chords: role("saw", "keys:0.5"),
986
+ arp: role("pluck", "square:0.5"),
987
+ lead: role("sing", "lead:0.4"),
988
+ },
989
+ },
990
+ },
991
+ ),
992
+ leaf(
993
+ "dance-pop",
994
+ "dance-pop: four-on-the-floor kick, off-beat hats, clap backbeat, sidechain pump, I-V-vi-IV",
995
+ 1984,
996
+ {
997
+ tempo: { bpm: [115, 130], typical: 122 },
998
+ rhythm: {
999
+ onsets: { kick: FOUR_FLOOR, hat: OFFBEAT_HAT, clap: BACKBEAT },
1000
+ },
1001
+ bass: { behaviour: [["octave", 1]], onsets: grid("..x...x...x...x.") },
1002
+ texture: {
1003
+ roles: { ...kitAll(CLUB_KIT), chords: role("saw", "piano:0.5") },
1004
+ },
1005
+ mix: { fx: { chords: { duck: "pump" } }, loudness: "club" },
1006
+ },
1007
+ ),
1008
+ leaf(
1009
+ "teen-pop",
1010
+ "teen pop: R&B-swung 16ths, I-V-vi-IV and vi-IV-I-V, stacked harmony on the chorus hook",
1011
+ 1998,
1012
+ {
1013
+ tempo: { bpm: [90, 110], typical: 98 },
1014
+ groove: { swingRatio: [1.1, 1.3] },
1015
+ rhythm: {
1016
+ onsets: { kick: grid("x..x..x...x....."), hat: SIXTEENTH_HAT },
1017
+ },
1018
+ harmony: {
1019
+ presets: [
1020
+ ["axis", 0.5],
1021
+ ["sad-pop", 0.5],
1022
+ ],
1023
+ },
1024
+ texture: {
1025
+ roles: { ...kitAll(MACHINE), counter: maybe("aah", "choir:0.5") },
1026
+ },
1027
+ },
1028
+ ),
1029
+ leaf(
1030
+ "adult-contemporary",
1031
+ "adult contemporary and power ballad: piano ostinato, I-V-vi-IV and the canon's stepwise bass descent, half-note kick, slow 4/4",
1032
+ 1975,
1033
+ {
1034
+ tempo: { bpm: [60, 84], typical: 72 },
1035
+ rhythm: { onsets: { kick: grid("x.......x......."), hat: EIGHTH_HAT } },
1036
+ harmony: {
1037
+ presets: [
1038
+ ["canon", 0.5],
1039
+ ["axis", 0.5],
1040
+ ],
1041
+ sevenths: 0.3,
1042
+ rhythm: [
1043
+ [1, 0.6],
1044
+ [2, 0.4],
1045
+ ],
1046
+ },
1047
+ melody: {
1048
+ intervals: PIANO_BALLAD,
1049
+ ambitus: [9, 14],
1050
+ density: [0.5, 1.5],
1051
+ },
1052
+ texture: {
1053
+ roles: {
1054
+ ...kitAll(ACOUSTIC_KIT),
1055
+ chords: role("grand", "rhodes:0.4"),
1056
+ pad: maybe("strings"),
1057
+ },
1058
+ },
1059
+ expression: { dynamics: [0.3, 0.9] },
1060
+ },
1061
+ ),
1062
+ leaf(
1063
+ "electropop",
1064
+ "electropop: side-chained synth chords, minor loop, clap backbeat and 16th hats, vocoder hooks",
1065
+ 2008,
1066
+ {
1067
+ tempo: { bpm: [112, 130], typical: 124 },
1068
+ rhythm: {
1069
+ onsets: { kick: FOUR_FLOOR, hat: SIXTEENTH_HAT, clap: BACKBEAT },
1070
+ },
1071
+ pitch: {
1072
+ scales: [
1073
+ ["minor", 0.7],
1074
+ ["dorian", 0.3],
1075
+ ],
1076
+ },
1077
+ harmony: {
1078
+ presets: [
1079
+ ["aeolian", 0.5],
1080
+ ["sad-pop", 0.5],
1081
+ ],
1082
+ },
1083
+ texture: {
1084
+ roles: {
1085
+ ...kitAll(CLUB_KIT),
1086
+ chords: role("saw", "square:0.4"),
1087
+ lead: role("sing", "vocoder:0.4"),
1088
+ },
1089
+ },
1090
+ mix: { fx: { chords: { duck: "pump" } } },
1091
+ },
1092
+ ),
1093
+ leaf(
1094
+ "latin-pop",
1095
+ "latin pop: tresillo 3+3+2 in kick and bass, nylon guitar, minor i-VI-III-VII, Spanish-language phrasing",
1096
+ 1980,
1097
+ {
1098
+ tempo: { bpm: [88, 110], typical: 96 },
1099
+ rhythm: {
1100
+ onsets: {
1101
+ kick: TRESILLO,
1102
+ snare: grid("...x..x....x..x."),
1103
+ hat: EIGHTH_HAT,
1104
+ },
1105
+ },
1106
+ pitch: {
1107
+ scales: [
1108
+ ["minor", 0.6],
1109
+ ["major", 0.4],
1110
+ ],
1111
+ },
1112
+ harmony: {
1113
+ presets: [
1114
+ ["sad-pop", 0.5],
1115
+ ["andalusian", 0.3],
1116
+ ["axis", 0.2],
1117
+ ],
1118
+ },
1119
+ bass: { behaviour: [["root", 1]], onsets: TRESILLO },
1120
+ texture: {
1121
+ roles: { chords: role("nylon", "piano:0.5"), perc: maybe("drums") },
1122
+ },
1123
+ },
1124
+ ),
1125
+ leaf(
1126
+ "indie-pop",
1127
+ "indie pop and twee: jangly major-key strums, glockenspiel doubling, diary-confessional melody that leans on the sixth",
1128
+ 1986,
1129
+ {
1130
+ tempo: { bpm: [110, 150], typical: 128 },
1131
+ pitch: {
1132
+ scales: [
1133
+ ["major", 0.6],
1134
+ ["minor", 0.4],
1135
+ ],
1136
+ },
1137
+ harmony: {
1138
+ presets: [
1139
+ ["axis", 0.4],
1140
+ ["sad-pop", 0.3],
1141
+ ["canon", 0.3],
1142
+ ],
1143
+ voicing: { types: [["open", 1]], strokes: [["jangle", 1]] },
1144
+ },
1145
+ melody: {
1146
+ finals: [
1147
+ [0, 0.4],
1148
+ [5, 0.3],
1149
+ [2, 0.3],
1150
+ ],
1151
+ },
1152
+ texture: {
1153
+ roles: {
1154
+ ...kitAll(ACOUSTIC_KIT),
1155
+ chords: role("jangle", "acoustic:0.5"),
1156
+ counter: maybe("glock", "celesta:0.5"),
1157
+ },
1158
+ },
1159
+ },
1160
+ ),
1161
+ leaf(
1162
+ "art-pop",
1163
+ "art pop: lydian and dorian color, mixed meter with 5/4 and 7/8 (2+2+3), wide intervals, through-composed bridges",
1164
+ 1977,
1165
+ {
1166
+ meter: {
1167
+ signatures: [
1168
+ ["4/4", 0.5],
1169
+ ["5/4", 0.2],
1170
+ ["7/8", 0.3],
1171
+ ],
1172
+ grouping: [[[2, 2, 3], 1]],
1173
+ },
1174
+ pitch: {
1175
+ scales: [
1176
+ ["lydian", 0.4],
1177
+ ["dorian", 0.3],
1178
+ ["major", 0.3],
1179
+ ],
1180
+ },
1181
+ harmony: {
1182
+ model: "modal",
1183
+ sevenths: 0.6,
1184
+ voicing: {
1185
+ types: [
1186
+ ["open", 0.5],
1187
+ ["quartal", 0.5],
1188
+ ],
1189
+ },
1190
+ },
1191
+ melody: { intervals: intervals(3, 2.5, 1.6, 0.6), ambitus: [10, 17] },
1192
+ texture: {
1193
+ roles: { chords: role("piano", "strings:0.5", "granular:0.3") },
1194
+ },
1195
+ },
1196
+ ),
1197
+ leaf(
1198
+ "bedroom-pop",
1199
+ "bedroom pop: lo-fi kit, chorused guitar, major-seventh loops, close-miked vocal in a narrow range",
1200
+ 2016,
1201
+ {
1202
+ tempo: { bpm: [72, 100], typical: 86 },
1203
+ groove: {
1204
+ swingRatio: [1.1, 1.3],
1205
+ humanize: { timingMs: 10, velocity: 0.1 },
1206
+ },
1207
+ harmony: {
1208
+ presets: [
1209
+ ["canon", 0.5],
1210
+ ["axis", 0.5],
1211
+ ],
1212
+ sevenths: 0.8,
1213
+ },
1214
+ melody: { ambitus: [5, 9] },
1215
+ texture: {
1216
+ roles: {
1217
+ ...kitAll(DUSTY_KIT),
1218
+ chords: role("electric@dreampop", "lofi:0.5"),
1219
+ },
1220
+ },
1221
+ mix: { fx: { chords: { chorus: "seasick" } }, space: 0.45 },
1222
+ },
1223
+ ),
1224
+ leaf(
1225
+ "alt-pop",
1226
+ "alt-pop and dark pop: sparse 808 and half-time snare, minor with iv and bVI, whispered low-register melody",
1227
+ 2015,
1228
+ {
1229
+ tempo: { bpm: [80, 110], typical: 94 },
1230
+ rhythm: {
1231
+ onsets: {
1232
+ kick: grid("x.....x...x....."),
1233
+ snare: HALF_SNARE,
1234
+ clap: null,
1235
+ hat: TRAP_HAT,
1236
+ },
1237
+ },
1238
+ pitch: {
1239
+ scales: [
1240
+ ["minor", 0.7],
1241
+ ["phrygian", 0.3],
1242
+ ],
1243
+ },
1244
+ harmony: {
1245
+ presets: [
1246
+ ["aeolian", 0.6],
1247
+ ["sad-pop", 0.4],
1248
+ ],
1249
+ },
1250
+ bass: { behaviour: [["root", 1]], onsets: grid("x.....x...x.....") },
1251
+ melody: { range: [55, 76], ambitus: [5, 9] },
1252
+ texture: {
1253
+ roles: {
1254
+ ...kitAll(TRAP_KIT),
1255
+ clap: null,
1256
+ chords: role("felt", "keys:0.5"),
1257
+ },
1258
+ },
1259
+ },
1260
+ ),
1261
+ leaf(
1262
+ "chamber-pop-modern",
1263
+ "orchestral and chamber pop: string quartet voicings, piano, 3/4 or 4/4, secondary dominants and suspensions",
1264
+ 1997,
1265
+ {
1266
+ meter: {
1267
+ signatures: [
1268
+ ["4/4", 0.6],
1269
+ ["3/4", 0.4],
1270
+ ],
1271
+ },
1272
+ harmony: {
1273
+ presets: [
1274
+ ["canon", 0.4],
1275
+ ["turnaround", 0.3],
1276
+ ["axis", 0.3],
1277
+ ],
1278
+ sevenths: 0.4,
1279
+ voicing: { types: [["open", 1]], notes: [3, 5] },
1280
+ },
1281
+ texture: {
1282
+ roles: {
1283
+ ...kitAll(ACOUSTIC_KIT),
1284
+ chords: role("strings", "piano:0.6"),
1285
+ counter: role("cello", "violin:0.5", "horn:0.3"),
1286
+ },
1287
+ },
1288
+ mix: { space: 0.4 },
1289
+ },
1290
+ ),
1291
+ leaf(
1292
+ "hyperpop",
1293
+ "hyperpop: maximal bubblegum-I-V-vi-IV over distorted 808s and trap rolls, 150-180 bpm, pitched-up bright formant vocals",
1294
+ 2019,
1295
+ {
1296
+ tempo: { bpm: [140, 180], typical: 160 },
1297
+ rhythm: {
1298
+ onsets: {
1299
+ kick: grid("x.....x...x...x."),
1300
+ snare: HALF_SNARE,
1301
+ clap: HALF_SNARE,
1302
+ hat: SIXTEENTH_HAT,
1303
+ },
1304
+ },
1305
+ pitch: {
1306
+ scales: [
1307
+ ["major", 0.7],
1308
+ ["major-pentatonic", 0.3],
1309
+ ],
1310
+ },
1311
+ harmony: {
1312
+ presets: [
1313
+ ["axis", 0.6],
1314
+ ["canon", 0.4],
1315
+ ],
1316
+ },
1317
+ melody: { density: [2, 4], ambitus: [9, 15], range: [64, 88] },
1318
+ bass: { behaviour: [["root", 1]], onsets: grid("x.....x...x...x.") },
1319
+ texture: {
1320
+ roles: {
1321
+ ...kitAll(TRAP_KIT),
1322
+ chords: role("saw", "sparkle:0.5"),
1323
+ lead: role("vocal", "square:0.5"),
1324
+ },
1325
+ },
1326
+ mix: {
1327
+ fx: {
1328
+ bass: { distort: "fold" },
1329
+ lead: { formant: "bright" },
1330
+ chords: { crush: "8-bit" },
1331
+ },
1332
+ loudness: "loud",
1333
+ },
1334
+ },
1335
+ ),
1336
+ leaf(
1337
+ "pc-music",
1338
+ "PC Music bubblegum bass: glossy major I-IV-vi-V, metallic plucks and bell synths, pitched vocals, 128-140 bpm",
1339
+ 2014,
1340
+ {
1341
+ tempo: { bpm: [124, 142], typical: 132 },
1342
+ rhythm: {
1343
+ onsets: { kick: FOUR_FLOOR, snare: BACKBEAT, hat: OFFBEAT_HAT },
1344
+ },
1345
+ pitch: { scales: [["major", 1]] },
1346
+ harmony: {
1347
+ sources: { forms: 1, presets: 0, chain: 0 },
1348
+ forms: [
1349
+ [["I", "IV", "vi", "V"], 0.6],
1350
+ [["IV", "I", "V", "vi"], 0.4],
1351
+ ],
1352
+ sevenths: 0.2,
1353
+ },
1354
+ texture: {
1355
+ roles: {
1356
+ ...kitAll(CLUB_KIT),
1357
+ chords: role("pluck", "bell:0.5", "sparkle:0.4"),
1358
+ lead: role("vocal"),
1359
+ },
1360
+ },
1361
+ mix: { fx: { lead: { formant: "tiny" } } },
1362
+ },
1363
+ ),
1364
+ leaf(
1365
+ "shibuya-kei",
1366
+ "Shibuya-kei: bossa-nova and lounge collage, ii-V-I with major sevenths and ninths, brisk 16ths, vibes and flute",
1367
+ 1993,
1368
+ {
1369
+ tempo: { bpm: [110, 140], typical: 124 },
1370
+ rhythm: {
1371
+ onsets: {
1372
+ kick: grid("x..x..x...x....."),
1373
+ rim: grid("x..x..x...x..x.."),
1374
+ },
1375
+ },
1376
+ harmony: {
1377
+ presets: [
1378
+ ["ii-v-i", 0.6],
1379
+ ["turnaround", 0.4],
1380
+ ],
1381
+ sevenths: 0.9,
1382
+ },
1383
+ bass: { behaviour: [["root-fifth", 1]] },
1384
+ texture: {
1385
+ roles: {
1386
+ ...kitAll(ACOUSTIC_KIT),
1387
+ rim: opt(ACOUSTIC_KIT),
1388
+ chords: role("nylon", "rhodes:0.5", "vibes:0.4"),
1389
+ counter: maybe("flute", "trumpet:0.4"),
1390
+ },
1391
+ },
1392
+ },
1393
+ ),
1394
+ leaf(
1395
+ "city-pop",
1396
+ "city pop: IVmaj7-III7-vi7 and ii-V chains, slap bass and Rhodes, 16th funk guitar, extended sevenths and ninths",
1397
+ 1980,
1398
+ {
1399
+ tempo: { bpm: [96, 124], typical: 108 },
1400
+ groove: { swingRatio: [1, 1.1] },
1401
+ rhythm: { onsets: { hat: SIXTEENTH_HAT } },
1402
+ harmony: {
1403
+ presets: [
1404
+ ["ii-v-i", 0.4],
1405
+ ["turnaround", 0.3],
1406
+ ["axis", 0.3],
1407
+ ],
1408
+ forms: [[["IVmaj7", "III7", "vi7", "vi7"], 1]],
1409
+ sources: { presets: 1, forms: 1 },
1410
+ sevenths: 0.9,
1411
+ },
1412
+ bass: {
1413
+ behaviour: [
1414
+ ["octave", 0.6],
1415
+ ["root", 0.4],
1416
+ ],
1417
+ onsets: grid("x..x..x.x.x..x.."),
1418
+ },
1419
+ texture: {
1420
+ roles: {
1421
+ ...kitAll(ACOUSTIC_KIT),
1422
+ bass: role("slap", "fender:0.5"),
1423
+ chords: role("rhodes", "funk:0.5"),
1424
+ },
1425
+ },
1426
+ },
1427
+ ),
1428
+ leaf(
1429
+ "j-pop",
1430
+ "J-pop: royal-road progression IVmaj7-V7-iii7-vi, dense syllabic melody across a wide range, 120-170 bpm",
1431
+ 1995,
1432
+ {
1433
+ tempo: { bpm: [120, 175], typical: 144 },
1434
+ harmony: {
1435
+ forms: [[["IVmaj7", "V7", "iii7", "vi"], 1]],
1436
+ presets: [["canon", 1]],
1437
+ sources: { presets: 1, forms: 2 },
1438
+ sevenths: 0.5,
1439
+ },
1440
+ melody: { density: [2, 4], ambitus: [10, 15] },
1441
+ texture: {
1442
+ roles: {
1443
+ ...kitAll(ACOUSTIC_KIT),
1444
+ chords: role("electric@clean", "piano:0.6", "strings:0.4"),
1445
+ },
1446
+ },
1447
+ },
1448
+ ),
1449
+ leaf(
1450
+ "k-pop",
1451
+ "K-pop: section-by-section style switches over a minor trap-EDM hybrid, half-time pre-chorus, dance-break drop",
1452
+ 2010,
1453
+ {
1454
+ tempo: { bpm: [96, 130], typical: 116 },
1455
+ rhythm: { onsets: { kick: grid("x.....x...x....."), hat: TRAP_HAT } },
1456
+ pitch: {
1457
+ scales: [
1458
+ ["minor", 0.6],
1459
+ ["dorian", 0.4],
1460
+ ],
1461
+ },
1462
+ harmony: {
1463
+ presets: [
1464
+ ["aeolian", 0.5],
1465
+ ["sad-pop", 0.5],
1466
+ ],
1467
+ },
1468
+ form: {
1469
+ plans: [
1470
+ [
1471
+ [
1472
+ "intro",
1473
+ "verse",
1474
+ "pre",
1475
+ "chorus",
1476
+ "verse",
1477
+ "pre",
1478
+ "chorus",
1479
+ "drop",
1480
+ "chorus",
1481
+ ],
1482
+ 1,
1483
+ ],
1484
+ ],
1485
+ },
1486
+ texture: {
1487
+ roles: { ...kitAll(TRAP_KIT), chords: role("saw", "pluck:0.5") },
1488
+ },
1489
+ },
1490
+ ),
1491
+ leaf(
1492
+ "c-pop",
1493
+ "C-pop and Mandopop: pentatonic-leaning ballad melody over the canon bass line (I-V-vi-iii-IV-I-IV-V), piano and strings",
1494
+ 1980,
1495
+ {
1496
+ tempo: { bpm: [64, 96], typical: 76 },
1497
+ pitch: {
1498
+ scales: [
1499
+ ["major", 0.6],
1500
+ ["major-pentatonic", 0.4],
1501
+ ],
1502
+ },
1503
+ harmony: {
1504
+ presets: [
1505
+ ["canon", 0.7],
1506
+ ["axis", 0.3],
1507
+ ],
1508
+ sevenths: 0.3,
1509
+ },
1510
+ melody: { intervals: PIANO_BALLAD },
1511
+ texture: {
1512
+ roles: {
1513
+ ...kitAll(ACOUSTIC_KIT),
1514
+ chords: role("grand", "strings:0.6"),
1515
+ counter: maybe("erhu", "strings:0.4"),
1516
+ },
1517
+ },
1518
+ },
1519
+ ),
1520
+ leaf(
1521
+ "vocaloid",
1522
+ "Vocaloid: synthesized-voice melody too fast and wide for a singer, royal-road and canon loops, 150-200 bpm rock band",
1523
+ 2008,
1524
+ {
1525
+ tempo: { bpm: [150, 200], typical: 172 },
1526
+ harmony: {
1527
+ forms: [[["IVmaj7", "V7", "iii7", "vi"], 1]],
1528
+ presets: [["canon", 1]],
1529
+ sources: { presets: 1, forms: 2 },
1530
+ },
1531
+ melody: {
1532
+ density: [3, 4],
1533
+ ambitus: [12, 19],
1534
+ intervals: intervals(4, 3, 1.6, 0.8),
1535
+ },
1536
+ texture: {
1537
+ roles: {
1538
+ ...kitAll(ACOUSTIC_KIT),
1539
+ chords: role("electric@crunch", "piano:0.5"),
1540
+ lead: role("vocoder", "square:0.5"),
1541
+ },
1542
+ },
1543
+ },
1544
+ ),
1545
+ leaf(
1546
+ "v-pop",
1547
+ "Southeast Asian pop ballad: minor-key verses on harmonic-minor i-iv-V7 (the bolero and nhac tre ballad), melismatic chorus peak, acoustic guitar and soft kit",
1548
+ 1985,
1549
+ {
1550
+ tempo: { bpm: [66, 104], typical: 82 },
1551
+ pitch: {
1552
+ scales: [
1553
+ ["harmonic-minor", 0.6],
1554
+ ["minor", 0.4],
1555
+ ],
1556
+ },
1557
+ harmony: {
1558
+ sources: { forms: 1, presets: 0, chain: 0 },
1559
+ forms: [
1560
+ [["i", "iv", "V7", "i"], 0.4],
1561
+ [["i", "VI", "iv", "V7"], 0.3],
1562
+ [["i", "iv", "VII", "III"], 0.3],
1563
+ ],
1564
+ sevenths: 0.3,
1565
+ },
1566
+ melody: { intervals: PIANO_BALLAD },
1567
+ texture: {
1568
+ roles: {
1569
+ ...kitAll(ACOUSTIC_KIT),
1570
+ chords: role("acoustic", "piano:0.6"),
1571
+ },
1572
+ },
1573
+ },
1574
+ ),
1575
+ leaf(
1576
+ "russian-pop",
1577
+ "Russian estrada pop: minor i-iv-VII-III loop with harmonic-minor V, four-on-the-floor dance verse, singalong chorus",
1578
+ 1975,
1579
+ {
1580
+ tempo: { bpm: [110, 132], typical: 124 },
1581
+ rhythm: { onsets: { kick: FOUR_FLOOR, hat: OFFBEAT_HAT } },
1582
+ pitch: {
1583
+ scales: [
1584
+ ["harmonic-minor", 0.5],
1585
+ ["minor", 0.5],
1586
+ ],
1587
+ },
1588
+ harmony: {
1589
+ forms: [[["i", "iv", "bVII", "bIII"], 1]],
1590
+ presets: [["aeolian", 1]],
1591
+ sources: { presets: 1, forms: 2 },
1592
+ cadences: [
1593
+ ["V-I", 0.6],
1594
+ ["half", 0.4],
1595
+ ],
1596
+ },
1597
+ texture: {
1598
+ roles: { ...kitAll(CLUB_KIT), chords: role("keys", "strings:0.5") },
1599
+ },
1600
+ },
1601
+ ),
1602
+ leaf(
1603
+ "turkish-pop",
1604
+ "Turkish pop: hicaz and kurdi makam color in 12-tone pop, darbuka on the duyek-like syncopation, 9/8 roman option (2+2+2+3)",
1605
+ 1990,
1606
+ {
1607
+ meter: {
1608
+ signatures: [
1609
+ ["4/4", 0.7],
1610
+ ["9/8", 0.3],
1611
+ ],
1612
+ grouping: [[[2, 2, 2, 3], 1]],
1613
+ },
1614
+ rhythm: { onsets: { perc: grid("x..x..x.x.x.....") } },
1615
+ pitch: {
1616
+ scales: [
1617
+ ["hijaz", 0.5],
1618
+ ["kurd", 0.3],
1619
+ ["nahawand", 0.2],
1620
+ ],
1621
+ },
1622
+ harmony: { model: "modal", sevenths: 0.1 },
1623
+ melody: { intervals: intervals(6, 2, 0.6, 0.8) },
1624
+ texture: {
1625
+ roles: {
1626
+ perc: role("daf", "tabla:0.4"),
1627
+ chords: role("strings", "keys:0.5"),
1628
+ counter: maybe("oud", "kamancheh:0.5"),
1629
+ },
1630
+ },
1631
+ },
1632
+ ),
1633
+ leaf(
1634
+ "arabic-pop",
1635
+ "Arabic pop: maqsum iqa' (dum-tak-tak-dum-tak) on darbuka, maqam hijaz or nahawand in 12-tone pop, string-section unisons",
1636
+ 1990,
1637
+ {
1638
+ tempo: { bpm: [90, 120], typical: 104 },
1639
+ rhythm: {
1640
+ onsets: {
1641
+ perc: grid("x.x...x.x...x..."),
1642
+ kick: grid("x.......x......."),
1643
+ hat: null,
1644
+ },
1645
+ },
1646
+ pitch: {
1647
+ scales: [
1648
+ ["hijaz", 0.5],
1649
+ ["nahawand", 0.3],
1650
+ ["kurd", 0.2],
1651
+ ],
1652
+ },
1653
+ harmony: { model: "modal", sevenths: 0 },
1654
+ melody: { intervals: intervals(6, 2, 0.5, 0.8) },
1655
+ texture: {
1656
+ kind: "heterophonic",
1657
+ roles: {
1658
+ hat: null,
1659
+ perc: role("daf", "framedrum:0.5"),
1660
+ chords: role("strings"),
1661
+ counter: maybe("violins", "oud:0.6"),
1662
+ },
1663
+ },
1664
+ },
1665
+ ),
1666
+ leaf(
1667
+ "persian-pop",
1668
+ "Persian pop: 6/8 dance rhythm (shesh-o-hasht), dastgah-flavoured harmonic minor, santur and tar fills over synths",
1669
+ 1970,
1670
+ {
1671
+ meter: { signatures: [["6/8", 1]] },
1672
+ groove: { subdivision: 2 },
1673
+ tempo: { bpm: [90, 130], typical: 110 },
1674
+ rhythm: {
1675
+ onsets: {
1676
+ kick: grid("x..x.."),
1677
+ snare: grid("...x.."),
1678
+ hat: grid("xxxxxx"),
1679
+ perc: grid("x.xx.x"),
1680
+ clap: null,
1681
+ },
1682
+ },
1683
+ pitch: {
1684
+ scales: [
1685
+ ["harmonic-minor", 0.5],
1686
+ ["nahawand", 0.3],
1687
+ ["hijaz", 0.2],
1688
+ ],
1689
+ },
1690
+ harmony: {
1691
+ presets: [
1692
+ ["aeolian", 0.5],
1693
+ ["minor-ii-v", 0.5],
1694
+ ],
1695
+ },
1696
+ bass: { onsets: grid("x..x..") },
1697
+ texture: {
1698
+ roles: {
1699
+ perc: role("daf", "tabla:0.5"),
1700
+ chords: role("keys", "strings:0.5"),
1701
+ counter: maybe("santur", "tar:0.6"),
1702
+ },
1703
+ },
1704
+ },
1705
+ ),
1706
+ leaf(
1707
+ "indian-pop",
1708
+ "Indipop: raga-flavoured kafi or khamaj melody, dholak-tabla kaharwa groove (8 beats), synth strings and bansuri",
1709
+ 1990,
1710
+ {
1711
+ tempo: { bpm: [90, 120], typical: 100 },
1712
+ rhythm: { onsets: { perc: grid("x..x..x.x..x..x.") } },
1713
+ pitch: {
1714
+ scales: [
1715
+ ["kafi", 0.4],
1716
+ ["khamaj", 0.4],
1717
+ ["major", 0.2],
1718
+ ],
1719
+ },
1720
+ harmony: { model: "modal", sevenths: 0 },
1721
+ melody: { intervals: intervals(6, 2, 0.6, 0.8) },
1722
+ texture: {
1723
+ roles: {
1724
+ perc: role("tabla"),
1725
+ chords: role("strings", "keys:0.5"),
1726
+ counter: maybe("bansuri", "sitar:0.5"),
1727
+ },
1728
+ },
1729
+ },
1730
+ ),
1731
+ leaf(
1732
+ "nordic-pop",
1733
+ "Nordic and dansband pop: foxtrot two-beat bass, bright major I-IV-V-vi, melodic sustained chorus, clean guitar",
1734
+ 1975,
1735
+ {
1736
+ tempo: { bpm: [112, 136], typical: 124 },
1737
+ groove: { swingRatio: [1, 1] },
1738
+ rhythm: {
1739
+ onsets: {
1740
+ kick: grid("x.......x......."),
1741
+ snare: BACKBEAT,
1742
+ hat: EIGHTH_HAT,
1743
+ },
1744
+ },
1745
+ harmony: {
1746
+ presets: [
1747
+ ["axis", 0.4],
1748
+ ["fifties", 0.3],
1749
+ ["canon", 0.3],
1750
+ ],
1751
+ },
1752
+ bass: {
1753
+ behaviour: [["root-fifth", 1]],
1754
+ onsets: grid("x.......x......."),
1755
+ },
1756
+ texture: {
1757
+ roles: {
1758
+ ...kitAll(ACOUSTIC_KIT),
1759
+ chords: role("electric@clean", "keys:0.5"),
1760
+ },
1761
+ },
1762
+ },
1763
+ ),
1764
+ ];
1765
+
1766
+ // ---------------------------------------------------------------------------
1767
+ // Old school
1768
+
1769
+ const OLD_SCHOOL: readonly StyleCard[] = [
1770
+ leaf(
1771
+ "old-school-hip-hop",
1772
+ "old school hip hop: one-chord funk vamp from a looped break, electro drum-machine backbeat, call-and-response MC",
1773
+ 1979,
1774
+ {
1775
+ rhythm: { onsets: { kick: grid("x.....x...x....."), hat: EIGHTH_HAT } },
1776
+ pitch: {
1777
+ scales: [
1778
+ ["dorian", 0.5],
1779
+ ["mixolydian", 0.5],
1780
+ ],
1781
+ },
1782
+ harmony: { sevenths: 0.7 },
1783
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x..x..x...x.x...") },
1784
+ texture: { roles: { chords: role("funk", "clav:0.5", "keys:0.4") } },
1785
+ },
1786
+ ),
1787
+ leaf(
1788
+ "golden-age",
1789
+ "golden-age boom bap: swung 16ths (MPC swing), kick-snare backbeat, chopped jazz-soul loop of one or two chords",
1790
+ 1988,
1791
+ {
1792
+ tempo: { bpm: [84, 100], typical: 92 },
1793
+ groove: { swingRatio: [1.35, 1.7] },
1794
+ rhythm: { onsets: { kick: BOOM_BAP_KICK, hat: EIGHTH_HAT } },
1795
+ pitch: {
1796
+ scales: [
1797
+ ["minor", 0.5],
1798
+ ["dorian", 0.5],
1799
+ ],
1800
+ },
1801
+ harmony: {
1802
+ model: "functional",
1803
+ presets: [
1804
+ ["dorian-vamp", 0.6],
1805
+ ["minor-ii-v", 0.4],
1806
+ ],
1807
+ sevenths: 0.8,
1808
+ },
1809
+ texture: {
1810
+ roles: {
1811
+ ...kitAll(DUSTY_KIT),
1812
+ chords: role("rhodes", "upright:0.4", "piano:0.4"),
1813
+ },
1814
+ },
1815
+ },
1816
+ ),
1817
+ leaf(
1818
+ "miami-bass",
1819
+ "Miami bass: TR-808 boom with long decaying sub, syncopated kick, 16th hats and claps, 125-140 bpm",
1820
+ 1986,
1821
+ {
1822
+ tempo: { bpm: [124, 140], typical: 130 },
1823
+ rhythm: {
1824
+ onsets: {
1825
+ kick: grid("x..x..x...x....."),
1826
+ clap: BACKBEAT,
1827
+ hat: SIXTEENTH_HAT,
1828
+ },
1829
+ },
1830
+ bass: {
1831
+ behaviour: [["root", 1]],
1832
+ onsets: grid("x..x..x...x....."),
1833
+ kickLock: 0.8,
1834
+ range: [24, 40],
1835
+ },
1836
+ texture: { roles: { ...kitAll(MACHINE), bass: role("bass") } },
1837
+ },
1838
+ ),
1839
+ leaf(
1840
+ "toasting",
1841
+ "toasting: MC chant over a reggae riddim, one-drop kick and rim on beat 3, off-beat skank chords",
1842
+ 1970,
1843
+ {
1844
+ tempo: { bpm: [66, 84], typical: 76 },
1845
+ rhythm: {
1846
+ onsets: {
1847
+ kick: HALF_SNARE,
1848
+ rim: HALF_SNARE,
1849
+ snare: null,
1850
+ hat: EIGHTH_HAT,
1851
+ },
1852
+ },
1853
+ pitch: {
1854
+ scales: [
1855
+ ["minor", 0.5],
1856
+ ["major", 0.5],
1857
+ ],
1858
+ },
1859
+ harmony: {
1860
+ model: "functional",
1861
+ presets: [
1862
+ ["aeolian", 0.5],
1863
+ ["axis", 0.5],
1864
+ ],
1865
+ voicing: { types: [["close", 1]], strokes: [["reggae", 1]] },
1866
+ },
1867
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x..x..x.x....x..") },
1868
+ texture: {
1869
+ roles: {
1870
+ ...kitAll(ACOUSTIC_KIT),
1871
+ rim: ACOUSTIC_KIT,
1872
+ snare: null,
1873
+ chords: role("electric@clean", "organ:0.5"),
1874
+ },
1875
+ },
1876
+ },
1877
+ ),
1878
+ ];
1879
+
1880
+ // ---------------------------------------------------------------------------
1881
+ // Regional rap
1882
+
1883
+ const REGIONAL: readonly StyleCard[] = [
1884
+ leaf(
1885
+ "g-funk",
1886
+ "G-funk: laid-back 90s funk tempo, minor ninths and dorian sevenths, portamento sine lead, live bass on the one",
1887
+ 1992,
1888
+ {
1889
+ tempo: { bpm: [86, 100], typical: 94 },
1890
+ rhythm: {
1891
+ onsets: {
1892
+ kick: grid("x......xx.x....."),
1893
+ hat: SIXTEENTH_HAT,
1894
+ clap: BACKBEAT,
1895
+ },
1896
+ },
1897
+ pitch: {
1898
+ scales: [
1899
+ ["dorian", 0.5],
1900
+ ["minor", 0.5],
1901
+ ],
1902
+ },
1903
+ harmony: {
1904
+ presets: [
1905
+ ["dorian-vamp", 0.6],
1906
+ ["minor-ii-v", 0.4],
1907
+ ],
1908
+ sevenths: 0.9,
1909
+ },
1910
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x..x..x.x.......") },
1911
+ texture: {
1912
+ roles: {
1913
+ ...kitAll(MACHINE),
1914
+ chords: role("rhodes", "keys:0.5"),
1915
+ lead: role("triangle", "vocal:0.5"),
1916
+ },
1917
+ },
1918
+ },
1919
+ ),
1920
+ leaf(
1921
+ "east-coast-hardcore",
1922
+ "East Coast hardcore: dark minor piano loop with a dissonant b2, hard boom-bap kick, dusty swing",
1923
+ 1994,
1924
+ {
1925
+ tempo: { bpm: [84, 98], typical: 90 },
1926
+ groove: { swingRatio: [1.2, 1.5] },
1927
+ pitch: {
1928
+ scales: [
1929
+ ["minor", 0.6],
1930
+ ["phrygian", 0.4],
1931
+ ],
1932
+ },
1933
+ harmony: { presets: [["aeolian", 1]], sevenths: 0.2 },
1934
+ texture: {
1935
+ roles: { ...kitAll(DUSTY_KIT), chords: role("piano", "strings:0.4") },
1936
+ },
1937
+ },
1938
+ ),
1939
+ leaf(
1940
+ "horrorcore",
1941
+ "horrorcore: harmonic-minor and phrygian dread, tritone-laden bass, music-box and church-organ samples over boom bap",
1942
+ 1994,
1943
+ {
1944
+ tempo: { bpm: [76, 96], typical: 86 },
1945
+ pitch: {
1946
+ scales: [
1947
+ ["harmonic-minor", 0.5],
1948
+ ["phrygian", 0.5],
1949
+ ],
1950
+ },
1951
+ harmony: {
1952
+ presets: [["aeolian", 1]],
1953
+ cadences: [
1954
+ ["V-I", 0.5],
1955
+ ["bII-I", 0.5],
1956
+ ],
1957
+ },
1958
+ texture: {
1959
+ roles: { ...kitAll(DUSTY_KIT), chords: role("organ", "musicbox:0.5") },
1960
+ },
1961
+ },
1962
+ ),
1963
+ leaf(
1964
+ "southern-rap",
1965
+ "Southern rap: slow 808 groove with triplet hats, chopped-and-screwed slowdown, organ and minor blues",
1966
+ 1996,
1967
+ {
1968
+ tempo: { bpm: [64, 84], typical: 72 },
1969
+ groove: { subdivision: 3, swingRatio: [1, 1] },
1970
+ rhythm: {
1971
+ onsets: {
1972
+ kick: grid("x.....x..x.."),
1973
+ snare: grid("...x.....x.."),
1974
+ hat: grid("x.xx.xx.xx.x"),
1975
+ },
1976
+ },
1977
+ pitch: {
1978
+ scales: [
1979
+ ["minor-pentatonic", 0.5],
1980
+ ["blues", 0.2],
1981
+ ["minor", 0.3],
1982
+ ],
1983
+ },
1984
+ bass: { behaviour: [["root", 1]], onsets: grid("x.....x..x..") },
1985
+ texture: {
1986
+ roles: { ...kitAll(MACHINE), chords: role("organ", "epiano:0.5") },
1987
+ },
1988
+ },
1989
+ ),
1990
+ leaf(
1991
+ "bounce",
1992
+ "New Orleans bounce: Triggerman-style syncopated break at 95-105 bpm, call-and-response chant, sparse harmony",
1993
+ 1991,
1994
+ {
1995
+ tempo: { bpm: [94, 108], typical: 100 },
1996
+ rhythm: {
1997
+ onsets: {
1998
+ kick: grid("x..x..x.x.....x."),
1999
+ snare: grid("....x..x....x..."),
2000
+ hat: SIXTEENTH_HAT,
2001
+ },
2002
+ },
2003
+ harmony: { model: "modal", sevenths: 0 },
2004
+ bass: { behaviour: [["root", 1]], onsets: grid("x..x..x.x.....x.") },
2005
+ texture: { roles: kitAll(MACHINE) },
2006
+ },
2007
+ ),
2008
+ leaf(
2009
+ "crunk",
2010
+ "crunk and snap: slow 808 half-time with the snap on 3, chant hooks, minor synth stabs",
2011
+ 2002,
2012
+ {
2013
+ tempo: { bpm: [70, 84], typical: 76 },
2014
+ rhythm: {
2015
+ onsets: {
2016
+ kick: grid("x.........x....."),
2017
+ snare: null,
2018
+ clap: HALF_SNARE,
2019
+ hat: EIGHTH_HAT,
2020
+ },
2021
+ },
2022
+ pitch: { scales: [["minor", 1]] },
2023
+ bass: { behaviour: [["root", 1]], onsets: grid("x.........x.....") },
2024
+ texture: {
2025
+ roles: {
2026
+ ...kitAll(MACHINE),
2027
+ snare: null,
2028
+ clap: MACHINE,
2029
+ chords: role("square", "saw:0.5"),
2030
+ },
2031
+ },
2032
+ },
2033
+ ),
2034
+ leaf(
2035
+ "hyphy",
2036
+ "hyphy: Bay Area bounce at 95-110 bpm, knocking 808, handclaps on 2 and 4, minimal synth riffs",
2037
+ 2004,
2038
+ {
2039
+ tempo: { bpm: [94, 110], typical: 102 },
2040
+ rhythm: { onsets: { kick: grid("x...x.x...x..x.."), clap: BACKBEAT } },
2041
+ harmony: { model: "modal" },
2042
+ bass: { behaviour: [["root", 1]], onsets: grid("x...x.x...x..x..") },
2043
+ texture: {
2044
+ roles: {
2045
+ ...kitAll(MACHINE),
2046
+ clap: MACHINE,
2047
+ chords: role("square", "pluck:0.5"),
2048
+ },
2049
+ },
2050
+ },
2051
+ ),
2052
+ leaf(
2053
+ "jerk",
2054
+ "jerk and ratchet: minimal 808 and finger-snaps, sparse kick, synth-whistle hook on one note, 100-120 bpm",
2055
+ 2009,
2056
+ {
2057
+ tempo: { bpm: [96, 120], typical: 104 },
2058
+ rhythm: {
2059
+ onsets: {
2060
+ kick: grid("x.....x.x......."),
2061
+ clap: BACKBEAT,
2062
+ hat: EIGHTH_HAT,
2063
+ },
2064
+ },
2065
+ harmony: { model: "modal" },
2066
+ melody: { ambitus: [3, 6], repetition: 0.95 },
2067
+ texture: {
2068
+ roles: {
2069
+ ...kitAll(MACHINE),
2070
+ clap: MACHINE,
2071
+ chords: role("square"),
2072
+ lead: role("vocal", "triangle:0.5"),
2073
+ },
2074
+ },
2075
+ },
2076
+ ),
2077
+ leaf(
2078
+ "memphis-rap",
2079
+ "Memphis rap: lo-fi tape 808, cowbell ostinato, triplet hats, phrygian horror-movie keys",
2080
+ 1992,
2081
+ {
2082
+ tempo: { bpm: [130, 150], typical: 140 },
2083
+ rhythm: {
2084
+ onsets: {
2085
+ kick: grid("x.....x...x....."),
2086
+ snare: HALF_SNARE,
2087
+ hat: EIGHTH_HAT,
2088
+ bell: grid("x..x..x...x..x.."),
2089
+ },
2090
+ },
2091
+ pitch: {
2092
+ scales: [
2093
+ ["phrygian", 0.6],
2094
+ ["minor", 0.4],
2095
+ ],
2096
+ },
2097
+ harmony: { model: "modal" },
2098
+ texture: {
2099
+ roles: {
2100
+ ...kitAll(DUSTY_KIT),
2101
+ bell: role("bell"),
2102
+ chords: role("keys", "organ:0.5"),
2103
+ },
2104
+ },
2105
+ mix: { fx: { chords: { crush: "lofi" } } },
2106
+ },
2107
+ ),
2108
+ leaf(
2109
+ "phonk",
2110
+ "phonk: cowbell melody (drift phonk) over distorted 808, half-time snare, Memphis-sampled phrygian loops, 130-160 bpm",
2111
+ 2018,
2112
+ {
2113
+ tempo: { bpm: [130, 160], typical: 144 },
2114
+ rhythm: {
2115
+ onsets: {
2116
+ kick: grid("x.....x.x.....x."),
2117
+ snare: HALF_SNARE,
2118
+ hat: SIXTEENTH_HAT,
2119
+ bell: grid("x..x..x...x.x..."),
2120
+ },
2121
+ },
2122
+ pitch: {
2123
+ scales: [
2124
+ ["phrygian", 0.7],
2125
+ ["minor", 0.3],
2126
+ ],
2127
+ },
2128
+ harmony: { model: "modal" },
2129
+ bass: { behaviour: [["root", 1]], onsets: grid("x.....x.x.....x.") },
2130
+ texture: {
2131
+ roles: {
2132
+ ...kitAll(TRAP_KIT),
2133
+ bell: role("bell", "steelpan:0.3"),
2134
+ chords: role("keys"),
2135
+ },
2136
+ },
2137
+ mix: { fx: { bass: { distort: "crunch" } } },
2138
+ },
2139
+ ),
2140
+ ];
2141
+
2142
+ // ---------------------------------------------------------------------------
2143
+ // Modern rap
2144
+
2145
+ const MODERN_RAP: readonly StyleCard[] = [
2146
+ leaf(
2147
+ "trap",
2148
+ "trap: half-time snare on beat 3 at 130-160 bpm, rolling hat triplets, gliding 808 sub, minor bell or piano loop",
2149
+ 2005,
2150
+ {
2151
+ pitch: {
2152
+ scales: [
2153
+ ["minor", 0.6],
2154
+ ["harmonic-minor", 0.4],
2155
+ ],
2156
+ },
2157
+ harmony: { presets: [["aeolian", 1]] },
2158
+ texture: { roles: { chords: role("bell", "piano:0.5", "strings:0.3") } },
2159
+ },
2160
+ ),
2161
+ leaf(
2162
+ "drill",
2163
+ "drill: sliding 808 bass melodies, half-time snare with a late off-beat snare, triplet-skipping hats, 138-145 bpm, phrygian",
2164
+ 2013,
2165
+ {
2166
+ tempo: { bpm: [136, 146], typical: 142 },
2167
+ rhythm: {
2168
+ onsets: {
2169
+ kick: grid("x.....x...x....."),
2170
+ snare: grid("........x..x...."),
2171
+ hat: grid("x..x..x.x..x.x.."),
2172
+ },
2173
+ },
2174
+ pitch: {
2175
+ scales: [
2176
+ ["phrygian", 0.5],
2177
+ ["harmonic-minor", 0.5],
2178
+ ],
2179
+ },
2180
+ harmony: { model: "modal" },
2181
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x.....x...x..x..") },
2182
+ texture: { roles: { chords: role("strings", "piano:0.5", "choir:0.3") } },
2183
+ },
2184
+ ),
2185
+ leaf(
2186
+ "cloud-rap",
2187
+ "cloud rap: hazy reverb pads, slow half-time, major-seventh loops, ethereal sampled vocals",
2188
+ 2011,
2189
+ {
2190
+ tempo: { bpm: [60, 80], typical: 70 },
2191
+ rhythm: {
2192
+ onsets: {
2193
+ kick: grid("x.........x....."),
2194
+ snare: grid("........x......."),
2195
+ hat: EIGHTH_HAT,
2196
+ },
2197
+ },
2198
+ pitch: {
2199
+ scales: [
2200
+ ["major", 0.5],
2201
+ ["dorian", 0.5],
2202
+ ],
2203
+ },
2204
+ harmony: {
2205
+ presets: [
2206
+ ["canon", 0.5],
2207
+ ["dorian-vamp", 0.5],
2208
+ ],
2209
+ sevenths: 0.8,
2210
+ },
2211
+ texture: {
2212
+ roles: {
2213
+ pad: role("granular", "strings:0.5"),
2214
+ chords: role("keys", "sparkle:0.5"),
2215
+ },
2216
+ },
2217
+ mix: { space: 0.6 },
2218
+ },
2219
+ ),
2220
+ leaf(
2221
+ "rage",
2222
+ "rage and plugg: detuned distorted saw lead hook, 150-165 bpm half-time, 808 locked to kick; plugg leans major and bouncy",
2223
+ 2020,
2224
+ {
2225
+ tempo: { bpm: [148, 168], typical: 156 },
2226
+ pitch: {
2227
+ scales: [
2228
+ ["minor", 0.5],
2229
+ ["major", 0.3],
2230
+ ["dorian", 0.2],
2231
+ ],
2232
+ },
2233
+ harmony: {
2234
+ presets: [
2235
+ ["aeolian", 0.5],
2236
+ ["axis", 0.5],
2237
+ ],
2238
+ },
2239
+ melody: { repetition: 0.95, ambitus: [5, 9] },
2240
+ texture: {
2241
+ roles: {
2242
+ chords: role("saw", "square:0.5"),
2243
+ lead: role("saw", "vocal:0.5"),
2244
+ },
2245
+ },
2246
+ mix: { fx: { chords: { distort: "warm" } } },
2247
+ },
2248
+ ),
2249
+ leaf(
2250
+ "abstract-hip-hop",
2251
+ "abstract and instrumental hip hop: unquantised 'drunk' feel (snare late, kick early), jazz extensions, sample collage",
2252
+ 1996,
2253
+ {
2254
+ tempo: { bpm: [78, 96], typical: 88 },
2255
+ groove: {
2256
+ swingRatio: [1.3, 1.6],
2257
+ roleOffset: { snare: 0.15, kick: -0.08 },
2258
+ humanize: { timingMs: 12, velocity: 0.1 },
2259
+ },
2260
+ rhythm: {
2261
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2262
+ },
2263
+ harmony: {
2264
+ presets: [
2265
+ ["minor-ii-v", 0.5],
2266
+ ["dorian-vamp", 0.5],
2267
+ ],
2268
+ sevenths: 0.9,
2269
+ },
2270
+ bass: { behaviour: [["root", 1]], onsets: BOOM_BAP_KICK, kickLock: 0.5 },
2271
+ texture: {
2272
+ roles: { ...kitAll(DUSTY_KIT), chords: role("rhodes", "vibes:0.5") },
2273
+ },
2274
+ },
2275
+ ),
2276
+ leaf(
2277
+ "jazz-rap",
2278
+ "jazz rap: ii-V-I and minor-ii-V loops, upright bass, muted trumpet and Rhodes over swung boom bap",
2279
+ 1990,
2280
+ {
2281
+ tempo: { bpm: [84, 100], typical: 92 },
2282
+ groove: { swingRatio: [1.4, 1.8] },
2283
+ rhythm: {
2284
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2285
+ },
2286
+ harmony: {
2287
+ presets: [
2288
+ ["ii-v-i", 0.5],
2289
+ ["minor-ii-v", 0.5],
2290
+ ],
2291
+ sevenths: 0.9,
2292
+ },
2293
+ bass: {
2294
+ behaviour: [["root-fifth", 1]],
2295
+ onsets: grid("x.....x.x......."),
2296
+ },
2297
+ texture: {
2298
+ roles: {
2299
+ ...kitAll(DUSTY_KIT),
2300
+ bass: role("upright"),
2301
+ chords: role("rhodes", "piano:0.5"),
2302
+ counter: maybe("mutedtrumpet", "sax:0.5"),
2303
+ },
2304
+ },
2305
+ },
2306
+ ),
2307
+ leaf(
2308
+ "lofi-hip-hop",
2309
+ "lo-fi hip hop: lazy MPC swing, major-seventh and minor-ninth ii-V loops, tape-crushed Rhodes, vinyl dust",
2310
+ 2015,
2311
+ {
2312
+ tempo: { bpm: [70, 90], typical: 80 },
2313
+ groove: {
2314
+ swingRatio: [1.5, 1.9],
2315
+ humanize: { timingMs: 8, velocity: 0.08 },
2316
+ },
2317
+ rhythm: {
2318
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2319
+ },
2320
+ pitch: {
2321
+ scales: [
2322
+ ["major", 0.4],
2323
+ ["dorian", 0.6],
2324
+ ],
2325
+ },
2326
+ harmony: {
2327
+ presets: [
2328
+ ["ii-v-i", 0.5],
2329
+ ["dorian-vamp", 0.5],
2330
+ ],
2331
+ sevenths: 1,
2332
+ },
2333
+ melody: { density: [0.5, 1.5] },
2334
+ texture: {
2335
+ roles: {
2336
+ ...kitAll(DUSTY_KIT),
2337
+ chords: role("rhodes", "lofi:0.6"),
2338
+ lead: maybe("lofi", "vibes:0.5"),
2339
+ },
2340
+ },
2341
+ mix: { fx: { chords: { crush: "lofi" } }, loudness: "streaming" },
2342
+ },
2343
+ ),
2344
+ leaf(
2345
+ "experimental-hip-hop",
2346
+ "experimental and industrial hip hop: distorted kits, atonal noise layers, locrian and phrygian, abrupt form cuts",
2347
+ 2005,
2348
+ {
2349
+ tempo: { bpm: [80, 150], typical: 110 },
2350
+ rhythm: {
2351
+ onsets: {
2352
+ kick: grid("x..x.....x..x..."),
2353
+ snare: grid("....x..x....x..."),
2354
+ hat: grid("x.3.x.3.x.3.x.3."),
2355
+ },
2356
+ },
2357
+ pitch: {
2358
+ scales: [
2359
+ ["phrygian", 0.5],
2360
+ ["locrian", 0.5],
2361
+ ],
2362
+ },
2363
+ harmony: { model: "modal" },
2364
+ texture: {
2365
+ roles: { ...kitAll(ELECTRO_KIT), chords: role("saw", "granular:0.5") },
2366
+ },
2367
+ mix: { fx: { chords: { distort: "fold" } } },
2368
+ },
2369
+ ),
2370
+ leaf(
2371
+ "grime",
2372
+ "grime: 140 bpm eskibeat, square-wave stabs, sparse kick and snare on 3, staccato 16th MC flow",
2373
+ 2003,
2374
+ {
2375
+ tempo: { bpm: [138, 142], typical: 140 },
2376
+ rhythm: {
2377
+ onsets: {
2378
+ kick: grid("x.....x......x.."),
2379
+ snare: HALF_SNARE,
2380
+ hat: EIGHTH_HAT,
2381
+ },
2382
+ },
2383
+ pitch: {
2384
+ scales: [
2385
+ ["minor", 0.5],
2386
+ ["phrygian", 0.5],
2387
+ ],
2388
+ },
2389
+ harmony: { model: "modal" },
2390
+ bass: { behaviour: [["root", 1]], onsets: grid("x..x..x...x..x..") },
2391
+ texture: {
2392
+ roles: {
2393
+ ...kitAll(ELECTRO_KIT),
2394
+ chords: role("square", "pluck:0.5"),
2395
+ bass: role("square", "bass:0.5"),
2396
+ },
2397
+ },
2398
+ },
2399
+ ),
2400
+ leaf(
2401
+ "uk-hip-hop",
2402
+ "UK hip hop: boom bap with a straighter swing, dusty minor loops, conversational flow",
2403
+ 1990,
2404
+ {
2405
+ tempo: { bpm: [86, 98], typical: 92 },
2406
+ groove: { swingRatio: [1.1, 1.3] },
2407
+ rhythm: {
2408
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2409
+ },
2410
+ harmony: { presets: [["aeolian", 1]] },
2411
+ texture: {
2412
+ roles: { ...kitAll(DUSTY_KIT), chords: role("piano", "strings:0.5") },
2413
+ },
2414
+ },
2415
+ ),
2416
+ leaf(
2417
+ "french-rap",
2418
+ "French rap: melancholic minor piano and strings, harmonic-minor i-iv-V, boom bap or trap grid",
2419
+ 1991,
2420
+ {
2421
+ tempo: { bpm: [84, 145], typical: 92 },
2422
+ rhythm: {
2423
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2424
+ },
2425
+ pitch: {
2426
+ scales: [
2427
+ ["harmonic-minor", 0.5],
2428
+ ["minor", 0.5],
2429
+ ],
2430
+ },
2431
+ harmony: {
2432
+ presets: [
2433
+ ["minor-ii-v", 0.5],
2434
+ ["aeolian", 0.5],
2435
+ ],
2436
+ },
2437
+ texture: { roles: { chords: role("piano", "strings:0.6") } },
2438
+ },
2439
+ ),
2440
+ leaf(
2441
+ "latin-trap",
2442
+ "Latin trap: trap half-time with dembow-tinged rim, minor i-VI-III-VII, nylon or bell loop",
2443
+ 2016,
2444
+ {
2445
+ tempo: { bpm: [130, 150], typical: 140 },
2446
+ rhythm: { onsets: { rim: DEMBOW_SNARE } },
2447
+ pitch: {
2448
+ scales: [
2449
+ ["minor", 0.7],
2450
+ ["harmonic-minor", 0.3],
2451
+ ],
2452
+ },
2453
+ harmony: {
2454
+ presets: [
2455
+ ["sad-pop", 0.5],
2456
+ ["aeolian", 0.5],
2457
+ ],
2458
+ },
2459
+ texture: {
2460
+ roles: { rim: opt(TRAP_KIT), chords: role("nylon", "bell:0.5") },
2461
+ },
2462
+ },
2463
+ ),
2464
+ leaf(
2465
+ "afro-trap",
2466
+ "Afrotrap: afrobeats 3+3+2 hat and percussion over trap 808, 100-112 bpm, major-pentatonic hooks",
2467
+ 2015,
2468
+ {
2469
+ tempo: { bpm: [100, 114], typical: 106 },
2470
+ rhythm: {
2471
+ onsets: {
2472
+ kick: grid("x.....x...x....."),
2473
+ snare: BACKBEAT,
2474
+ hat: TRESILLO,
2475
+ perc: grid("..x..x..x..x..x."),
2476
+ },
2477
+ },
2478
+ pitch: {
2479
+ scales: [
2480
+ ["major-pentatonic", 0.4],
2481
+ ["minor", 0.6],
2482
+ ],
2483
+ },
2484
+ harmony: {
2485
+ presets: [
2486
+ ["axis", 0.5],
2487
+ ["aeolian", 0.5],
2488
+ ],
2489
+ },
2490
+ texture: {
2491
+ roles: { perc: role("drums"), chords: role("pluck", "marimba:0.5") },
2492
+ },
2493
+ },
2494
+ ),
2495
+ leaf(
2496
+ "rap-rock",
2497
+ "rap rock and rapcore: live kit backbeat, drop-tuned power-chord riffs on i and bII, rapped verses, sung chorus",
2498
+ 1990,
2499
+ {
2500
+ tempo: { bpm: [86, 110], typical: 96 },
2501
+ rhythm: {
2502
+ onsets: {
2503
+ kick: grid("x.x....x..x....."),
2504
+ snare: BACKBEAT,
2505
+ hat: EIGHTH_HAT,
2506
+ },
2507
+ },
2508
+ pitch: {
2509
+ scales: [
2510
+ ["phrygian", 0.5],
2511
+ ["minor", 0.5],
2512
+ ],
2513
+ },
2514
+ harmony: {
2515
+ presets: [["aeolian", 1]],
2516
+ voicing: { types: [["power", 1]] },
2517
+ rhythm: [[1, 1]],
2518
+ },
2519
+ bass: { behaviour: [["root", 1]], onsets: grid("x.x....x..x.....") },
2520
+ texture: {
2521
+ roles: {
2522
+ ...kitAll(ACOUSTIC_KIT),
2523
+ chords: role("electric@metal", "electric@crunch:0.5"),
2524
+ bass: role("bass@bassdrive"),
2525
+ },
2526
+ },
2527
+ },
2528
+ ),
2529
+ leaf(
2530
+ "turntablism",
2531
+ "turntablism: scratch-led break, cut-up stabs on the 16th grid, chirps and transforms as rhythm, one-chord bed",
2532
+ 1988,
2533
+ {
2534
+ tempo: { bpm: [88, 104], typical: 96 },
2535
+ rhythm: {
2536
+ onsets: {
2537
+ kick: BOOM_BAP_KICK,
2538
+ snare: BACKBEAT,
2539
+ hat: grid("x.x.x.xxx.x.x.xx"),
2540
+ perc: grid("..xx.x...x.xx.x."),
2541
+ },
2542
+ },
2543
+ harmony: { model: "modal" },
2544
+ melody: { density: [2, 4], intervals: intervals(2, 1, 1.2, 2) },
2545
+ texture: {
2546
+ roles: {
2547
+ ...kitAll(DUSTY_KIT),
2548
+ perc: role("drums"),
2549
+ lead: role("vocal", "square:0.5"),
2550
+ },
2551
+ },
2552
+ },
2553
+ ),
2554
+ leaf(
2555
+ "religious-rap",
2556
+ "Christian hip hop: gospel organ and choir over boom bap or trap, major IV-I plagal cadences",
2557
+ 1990,
2558
+ {
2559
+ tempo: { bpm: [80, 145], typical: 92 },
2560
+ rhythm: {
2561
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2562
+ },
2563
+ pitch: {
2564
+ scales: [
2565
+ ["major", 0.6],
2566
+ ["mixolydian", 0.4],
2567
+ ],
2568
+ },
2569
+ harmony: {
2570
+ presets: [
2571
+ ["axis", 0.5],
2572
+ ["canon", 0.5],
2573
+ ],
2574
+ cadences: [
2575
+ ["IV-I", 0.6],
2576
+ ["V-I", 0.4],
2577
+ ],
2578
+ },
2579
+ texture: {
2580
+ roles: { chords: role("gospel", "piano:0.5"), counter: maybe("choir") },
2581
+ },
2582
+ },
2583
+ ),
2584
+ ];
2585
+
2586
+ // ---------------------------------------------------------------------------
2587
+ // Breakbeat, drum and bass, UK bass
2588
+
2589
+ const BREAKS: readonly StyleCard[] = [
2590
+ leaf(
2591
+ "breakbeat",
2592
+ "breakbeat: syncopated funk-break kick (1, and-of-2, and-of-3), snare 2 and 4 with ghosts, acid stabs, 125-140 bpm",
2593
+ 1991,
2594
+ {
2595
+ tempo: { bpm: [125, 140], typical: 132 },
2596
+ rhythm: {
2597
+ onsets: {
2598
+ kick: grid("x.x.......x....."),
2599
+ snare: grid("....x..3.3..x..3"),
2600
+ hat: EIGHTH_HAT,
2601
+ },
2602
+ },
2603
+ texture: { roles: { chords: role("saw", "keys:0.5") } },
2604
+ mix: { fx: { chords: { autofilter: "env-follow" } } },
2605
+ },
2606
+ ),
2607
+ leaf(
2608
+ "big-beat",
2609
+ "big beat: distorted mid-tempo breaks, one-chord rock riff, build-drop arrangement, 100-130 bpm",
2610
+ 1995,
2611
+ {
2612
+ tempo: { bpm: [100, 135], typical: 120 },
2613
+ rhythm: {
2614
+ onsets: {
2615
+ kick: grid("x.x.......x.x..."),
2616
+ snare: BACKBEAT,
2617
+ hat: EIGHTH_HAT,
2618
+ },
2619
+ },
2620
+ pitch: {
2621
+ scales: [
2622
+ ["mixolydian", 0.5],
2623
+ ["minor", 0.5],
2624
+ ],
2625
+ },
2626
+ harmony: {
2627
+ presets: [["mixolydian-rock", 1]],
2628
+ voicing: { types: [["power", 1]] },
2629
+ },
2630
+ texture: { roles: { chords: role("electric@fuzz", "saw:0.5") } },
2631
+ mix: { fx: { snare: { distort: "crunch" } } },
2632
+ },
2633
+ ),
2634
+ leaf(
2635
+ "jungle",
2636
+ "jungle: chopped breakbeat with ghosted snare re-edits at 160-175 bpm, half-speed reggae sub-bass, ragga MC",
2637
+ 1993,
2638
+ {
2639
+ tempo: { bpm: [158, 176], typical: 166 },
2640
+ rhythm: {
2641
+ onsets: {
2642
+ kick: grid("x.x.......x....."),
2643
+ snare: grid("....x..4.4..x.4."),
2644
+ hat: grid("x.x.x.x.x.x.x.x."),
2645
+ },
2646
+ },
2647
+ harmony: { model: "modal" },
2648
+ bass: {
2649
+ behaviour: [["ostinato", 1]],
2650
+ onsets: grid("x.......x.x....."),
2651
+ range: [26, 40],
2652
+ },
2653
+ texture: {
2654
+ roles: {
2655
+ bass: role("bass", "triangle:0.5"),
2656
+ chords: role("strings", "keys:0.5"),
2657
+ },
2658
+ },
2659
+ },
2660
+ ),
2661
+ leaf(
2662
+ "drum-and-bass",
2663
+ "drum and bass: two-step kick on 1 and the and-of-3, snare on 2 and 4 at 170-176 bpm, reese bass, minor pads",
2664
+ 1995,
2665
+ {
2666
+ tempo: { bpm: [168, 178], typical: 174 },
2667
+ rhythm: {
2668
+ onsets: { kick: TWO_STEP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2669
+ },
2670
+ bass: {
2671
+ behaviour: [
2672
+ ["ostinato", 0.6],
2673
+ ["root", 0.4],
2674
+ ],
2675
+ onsets: grid("x.......x.x....."),
2676
+ },
2677
+ texture: {
2678
+ roles: { bass: role("bass@reese", "saw:0.4"), pad: maybe("strings") },
2679
+ },
2680
+ },
2681
+ ),
2682
+ leaf(
2683
+ "halftime",
2684
+ "halftime: drum-and-bass tempo (160-175) with the snare only on beat 3, heavy sub, sparse minimal stabs",
2685
+ 2012,
2686
+ {
2687
+ tempo: { bpm: [160, 176], typical: 170 },
2688
+ rhythm: {
2689
+ onsets: {
2690
+ kick: grid("x.........x....."),
2691
+ snare: HALF_SNARE,
2692
+ hat: grid("x...x...x...x..."),
2693
+ },
2694
+ },
2695
+ harmony: { model: "modal" },
2696
+ bass: { behaviour: [["root", 1]], onsets: grid("x.........x.....") },
2697
+ texture: { roles: { bass: role("bass@reese", "bass:0.5") } },
2698
+ },
2699
+ ),
2700
+ leaf(
2701
+ "breakcore",
2702
+ "breakcore: hyper-chopped amen re-edits at 180-260 bpm, 32nd-note snare rolls, distorted kicks, abrupt collage",
2703
+ 1997,
2704
+ {
2705
+ tempo: { bpm: [180, 260], typical: 200 },
2706
+ rhythm: {
2707
+ onsets: {
2708
+ kick: grid("x.x...x...x.x..."),
2709
+ snare: grid("....x.5x..5.x5xx"),
2710
+ hat: SIXTEENTH_HAT,
2711
+ },
2712
+ },
2713
+ pitch: {
2714
+ scales: [
2715
+ ["phrygian", 0.5],
2716
+ ["minor", 0.5],
2717
+ ],
2718
+ },
2719
+ harmony: { model: "modal" },
2720
+ texture: { roles: { chords: role("saw", "granular:0.5") } },
2721
+ mix: { fx: { kick: { distort: "fold" } }, loudness: "loud" },
2722
+ },
2723
+ ),
2724
+ leaf(
2725
+ "uk-garage",
2726
+ "UK garage 2-step: skipping kick that skips beats 2 and 4, snare on 2 and 4, shuffled 16ths, minor-seventh organ stabs",
2727
+ 1997,
2728
+ {
2729
+ tempo: { bpm: [130, 138], typical: 134 },
2730
+ groove: { swingRatio: [1.25, 1.5] },
2731
+ rhythm: {
2732
+ onsets: {
2733
+ kick: grid("x.........x..5.."),
2734
+ snare: BACKBEAT,
2735
+ hat: grid("..x...x...x...x."),
2736
+ },
2737
+ },
2738
+ pitch: {
2739
+ scales: [
2740
+ ["minor", 0.5],
2741
+ ["dorian", 0.5],
2742
+ ],
2743
+ },
2744
+ harmony: {
2745
+ presets: [
2746
+ ["dorian-vamp", 0.5],
2747
+ ["minor-ii-v", 0.5],
2748
+ ],
2749
+ sevenths: 0.9,
2750
+ rhythm: [[1, 1]],
2751
+ },
2752
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x..x......x..x..") },
2753
+ texture: {
2754
+ roles: {
2755
+ chords: role("organ", "rhodes:0.5"),
2756
+ lead: role("vocal", "sing:0.5"),
2757
+ },
2758
+ },
2759
+ },
2760
+ ),
2761
+ leaf(
2762
+ "bassline",
2763
+ "bassline (niche): four-on-the-floor at 135-142, wobbling detuned bass riff, organ stabs, garage shuffle",
2764
+ 2004,
2765
+ {
2766
+ tempo: { bpm: [134, 142], typical: 138 },
2767
+ groove: { swingRatio: [1.15, 1.35] },
2768
+ rhythm: {
2769
+ onsets: { kick: FOUR_FLOOR, snare: BACKBEAT, hat: OFFBEAT_HAT },
2770
+ },
2771
+ bass: { behaviour: [["ostinato", 1]], onsets: grid("x.xx..x.x.xx..x.") },
2772
+ texture: {
2773
+ roles: { bass: role("saw", "square:0.5"), chords: role("organ") },
2774
+ },
2775
+ mix: { fx: { bass: { autofilter: "wobble" } } },
2776
+ },
2777
+ ),
2778
+ leaf(
2779
+ "dubstep",
2780
+ "dubstep: 138-142 bpm with half-time snare on beat 3, sub-bass wobbles, phrygian b2, dark space",
2781
+ 2004,
2782
+ {
2783
+ tempo: { bpm: [138, 142], typical: 140 },
2784
+ rhythm: {
2785
+ onsets: {
2786
+ kick: grid("x.........x....."),
2787
+ snare: HALF_SNARE,
2788
+ hat: grid("..x...x...x...x."),
2789
+ },
2790
+ },
2791
+ pitch: {
2792
+ scales: [
2793
+ ["phrygian", 0.5],
2794
+ ["minor", 0.5],
2795
+ ],
2796
+ },
2797
+ harmony: { model: "modal" },
2798
+ bass: { behaviour: [["root", 1]], onsets: grid("x.....x...x.....") },
2799
+ mix: { fx: { bass: { autofilter: "wobble" } }, space: 0.5 },
2800
+ },
2801
+ ),
2802
+ leaf(
2803
+ "brostep",
2804
+ "brostep and riddim: 140-150 half-time, formant-growl bass in repeating triplet riddim cells, festival drops",
2805
+ 2010,
2806
+ {
2807
+ tempo: { bpm: [140, 150], typical: 145 },
2808
+ rhythm: {
2809
+ onsets: {
2810
+ kick: grid("x.........x....."),
2811
+ snare: HALF_SNARE,
2812
+ hat: EIGHTH_HAT,
2813
+ },
2814
+ },
2815
+ pitch: {
2816
+ scales: [
2817
+ ["phrygian", 0.6],
2818
+ ["minor", 0.4],
2819
+ ],
2820
+ },
2821
+ harmony: { model: "modal" },
2822
+ bass: {
2823
+ behaviour: [["ostinato", 1]],
2824
+ onsets: grid("x..x..x..x..x..."),
2825
+ range: [28, 45],
2826
+ },
2827
+ texture: { roles: { bass: role("saw", "square:0.5") } },
2828
+ mix: {
2829
+ fx: { bass: { formant: "giant", distort: "fold" } },
2830
+ loudness: "loud",
2831
+ },
2832
+ },
2833
+ ),
2834
+ leaf(
2835
+ "future-bass",
2836
+ "future bass: side-chain-pumped supersaw chords on IV-V-iii-vi, half-time snare, pitched vocal chops, 130-160 bpm",
2837
+ 2014,
2838
+ {
2839
+ tempo: { bpm: [130, 160], typical: 150 },
2840
+ rhythm: {
2841
+ onsets: {
2842
+ kick: grid("x.....x...x....."),
2843
+ snare: HALF_SNARE,
2844
+ hat: TRAP_HAT,
2845
+ },
2846
+ },
2847
+ pitch: { scales: [["major", 1]] },
2848
+ harmony: {
2849
+ presets: [
2850
+ ["canon", 0.4],
2851
+ ["axis", 0.6],
2852
+ ],
2853
+ forms: [[["IVmaj7", "V", "iii7", "vi7"], 1]],
2854
+ sources: { presets: 1, forms: 2 },
2855
+ sevenths: 0.7,
2856
+ rhythm: [[1, 1]],
2857
+ },
2858
+ texture: {
2859
+ roles: {
2860
+ chords: role("saw", "sparkle:0.5"),
2861
+ lead: role("vocal", "pluck:0.5"),
2862
+ },
2863
+ },
2864
+ mix: { fx: { chords: { duck: "pump" } } },
2865
+ },
2866
+ ),
2867
+ leaf(
2868
+ "future-garage",
2869
+ "future garage: 2-step skip at 130-140 with heavy reverb, minor-ninth pads, pitched vocal fragments",
2870
+ 2008,
2871
+ {
2872
+ tempo: { bpm: [128, 140], typical: 134 },
2873
+ groove: { swingRatio: [1.2, 1.4] },
2874
+ rhythm: {
2875
+ onsets: {
2876
+ kick: grid("x.........x....."),
2877
+ snare: BACKBEAT,
2878
+ hat: grid("..x..x....x..x.."),
2879
+ },
2880
+ },
2881
+ harmony: {
2882
+ presets: [
2883
+ ["dorian-vamp", 0.5],
2884
+ ["aeolian", 0.5],
2885
+ ],
2886
+ sevenths: 0.9,
2887
+ },
2888
+ texture: {
2889
+ roles: {
2890
+ pad: role("granular", "strings:0.5"),
2891
+ lead: role("vocal", "pluck:0.5"),
2892
+ },
2893
+ },
2894
+ mix: { space: 0.65 },
2895
+ },
2896
+ ),
2897
+ leaf(
2898
+ "uk-funky",
2899
+ "UK funky: 128-132 bpm tribal-house syncopation, tresillo kick bias over the floor, soca-derived percussion, minor chords",
2900
+ 2007,
2901
+ {
2902
+ tempo: { bpm: [126, 132], typical: 130 },
2903
+ rhythm: {
2904
+ onsets: {
2905
+ kick: grid("x..x..x.x..x..x."),
2906
+ snare: BACKBEAT,
2907
+ hat: OFFBEAT_HAT,
2908
+ perc: grid("x.xx.x.xx.x.x.x."),
2909
+ },
2910
+ },
2911
+ pitch: {
2912
+ scales: [
2913
+ ["minor", 0.5],
2914
+ ["dorian", 0.5],
2915
+ ],
2916
+ },
2917
+ harmony: { presets: [["dorian-vamp", 1]], sevenths: 0.8 },
2918
+ texture: {
2919
+ roles: { perc: role("drums"), chords: role("keys", "organ:0.5") },
2920
+ },
2921
+ },
2922
+ ),
2923
+ leaf(
2924
+ "wonky",
2925
+ "wonky and glitch hop: off-grid lurching microtiming, crunchy detuned synths, slow 85-110 half-time",
2926
+ 2007,
2927
+ {
2928
+ tempo: { bpm: [84, 110], typical: 95 },
2929
+ groove: {
2930
+ microtiming: [0, 0.2, -0.1, 0.3],
2931
+ roleOffset: { snare: 0.12 },
2932
+ humanize: { timingMs: 14, velocity: 0.1 },
2933
+ },
2934
+ rhythm: {
2935
+ onsets: { kick: BOOM_BAP_KICK, snare: BACKBEAT, hat: EIGHTH_HAT },
2936
+ },
2937
+ pitch: {
2938
+ scales: [
2939
+ ["dorian", 0.5],
2940
+ ["minor", 0.5],
2941
+ ],
2942
+ },
2943
+ harmony: { presets: [["dorian-vamp", 1]], sevenths: 0.8 },
2944
+ texture: { roles: { chords: role("saw", "square:0.5") } },
2945
+ mix: { fx: { chords: { crush: "lofi" } } },
2946
+ },
2947
+ ),
2948
+ leaf(
2949
+ "broken-beat",
2950
+ "broken beat: jazz-funk chords over a displaced 120-130 kick, snare on 2 and the and-of-3, swung 16ths",
2951
+ 1999,
2952
+ {
2953
+ tempo: { bpm: [118, 130], typical: 124 },
2954
+ groove: { swingRatio: [1.2, 1.4] },
2955
+ rhythm: {
2956
+ onsets: {
2957
+ kick: grid("x.....x....x...."),
2958
+ snare: grid("....x.....x....."),
2959
+ hat: SIXTEENTH_HAT,
2960
+ },
2961
+ },
2962
+ pitch: {
2963
+ scales: [
2964
+ ["dorian", 0.6],
2965
+ ["minor", 0.4],
2966
+ ],
2967
+ },
2968
+ harmony: {
2969
+ presets: [
2970
+ ["minor-ii-v", 0.5],
2971
+ ["dorian-vamp", 0.5],
2972
+ ],
2973
+ sevenths: 0.9,
2974
+ },
2975
+ texture: { roles: { chords: role("rhodes", "keys:0.5") } },
2976
+ },
2977
+ ),
2978
+ leaf(
2979
+ "footwork",
2980
+ "footwork and juke: 155-165 bpm, triplet-dotted kick polyrhythm (3 over 4), sparse snare, chopped vocal loop",
2981
+ 2008,
2982
+ {
2983
+ tempo: { bpm: [155, 165], typical: 160 },
2984
+ groove: { subdivision: 3 },
2985
+ rhythm: {
2986
+ onsets: {
2987
+ kick: grid("x..x..x..x.."),
2988
+ snare: grid("......x....."),
2989
+ hat: grid("x.x.x.x.x.x."),
2990
+ },
2991
+ },
2992
+ harmony: { model: "modal" },
2993
+ bass: { behaviour: [["root", 1]], onsets: grid("x..x..x..x..") },
2994
+ texture: { roles: { lead: role("vocal", "pluck:0.5") } },
2995
+ },
2996
+ ),
2997
+ leaf(
2998
+ "baltimore-club",
2999
+ "Baltimore club: break-derived kick with triplet pick-ups on beat 4, 125-135 bpm, chopped vocal stabs",
3000
+ 1992,
3001
+ {
3002
+ tempo: { bpm: [125, 135], typical: 130 },
3003
+ rhythm: {
3004
+ onsets: {
3005
+ kick: grid("x...x...x.x.x..."),
3006
+ snare: BACKBEAT,
3007
+ hat: OFFBEAT_HAT,
3008
+ },
3009
+ },
3010
+ harmony: { model: "modal" },
3011
+ bass: { behaviour: [["root", 1]], onsets: grid("x...x...x.x.x...") },
3012
+ texture: { roles: { lead: role("vocal", "pluck:0.5") } },
3013
+ },
3014
+ ),
3015
+ leaf(
3016
+ "jersey-club",
3017
+ "Jersey club: triplet kick rolls (the five-hit run), 130-145 bpm, sampled vocal chops and bedspring percussion",
3018
+ 2008,
3019
+ {
3020
+ tempo: { bpm: [130, 145], typical: 140 },
3021
+ groove: { subdivision: 3 },
3022
+ rhythm: {
3023
+ onsets: {
3024
+ kick: grid("x..x..x.xx.x"),
3025
+ snare: grid("...x.....x.."),
3026
+ hat: grid("..x..x..x..x"),
3027
+ },
3028
+ },
3029
+ harmony: { model: "modal" },
3030
+ bass: { behaviour: [["root", 1]], onsets: grid("x..x..x.....") },
3031
+ texture: { roles: { lead: role("vocal", "pluck:0.5") } },
3032
+ },
3033
+ ),
3034
+ leaf(
3035
+ "moombahton",
3036
+ "moombahton: dembow (kick on every beat, snare on 3, 6, 11 and 14 of 16) at 108-112 bpm, minor synth stabs",
3037
+ 2009,
3038
+ {
3039
+ tempo: { bpm: [106, 114], typical: 110 },
3040
+ rhythm: {
3041
+ onsets: { kick: FOUR_FLOOR, snare: DEMBOW_SNARE, hat: EIGHTH_HAT },
3042
+ },
3043
+ harmony: { presets: [["aeolian", 1]] },
3044
+ bass: { behaviour: [["root", 1]], onsets: TRESILLO },
3045
+ texture: { roles: { chords: role("saw", "pluck:0.5") } },
3046
+ },
3047
+ ),
3048
+ leaf(
3049
+ "deconstructed-club",
3050
+ "deconstructed club: fractured grids with no steady downbeat, metallic hits, atonal locrian textures, abrupt silences",
3051
+ 2015,
3052
+ {
3053
+ tempo: { bpm: [100, 145], typical: 125 },
3054
+ rhythm: {
3055
+ onsets: {
3056
+ kick: grid("x....4..3..x...."),
3057
+ snare: grid("...4.......x..3."),
3058
+ hat: grid("..3..4....3...4."),
3059
+ },
3060
+ },
3061
+ pitch: {
3062
+ scales: [
3063
+ ["locrian", 0.5],
3064
+ ["phrygian", 0.5],
3065
+ ],
3066
+ },
3067
+ harmony: { model: "modal" },
3068
+ texture: {
3069
+ roles: { ...kitAll(ELECTRO_KIT), chords: role("granular", "bell:0.5") },
3070
+ },
3071
+ mix: { fx: { kick: { distort: "fold" } }, space: 0.55 },
3072
+ },
3073
+ ),
3074
+ leaf(
3075
+ "bass-music",
3076
+ "festival trap and bass music: half-time trap drums at 140-150, harmonic-minor build-drop, 808 and saw drops",
3077
+ 2012,
3078
+ {
3079
+ tempo: { bpm: [140, 152], typical: 146 },
3080
+ rhythm: {
3081
+ onsets: {
3082
+ kick: grid("x.....x...x....."),
3083
+ snare: HALF_SNARE,
3084
+ hat: TRAP_HAT,
3085
+ },
3086
+ },
3087
+ pitch: {
3088
+ scales: [
3089
+ ["harmonic-minor", 0.6],
3090
+ ["minor", 0.4],
3091
+ ],
3092
+ },
3093
+ texture: {
3094
+ roles: { ...kitAll(TRAP_KIT), chords: role("saw", "bell:0.5") },
3095
+ },
3096
+ },
3097
+ ),
3098
+ leaf(
3099
+ "beatdown",
3100
+ "beatdown: slow 90-110 half-time weight, sparse heavy kick, low phrygian riffs, maximal sub",
3101
+ 2008,
3102
+ {
3103
+ tempo: { bpm: [88, 110], typical: 100 },
3104
+ rhythm: {
3105
+ onsets: {
3106
+ kick: grid("x.......x..x...."),
3107
+ snare: HALF_SNARE,
3108
+ hat: grid("x...x...x...x..."),
3109
+ },
3110
+ },
3111
+ pitch: { scales: [["phrygian", 1]] },
3112
+ harmony: { model: "modal" },
3113
+ bass: { behaviour: [["root", 1]], onsets: grid("x.......x..x....") },
3114
+ mix: { fx: { bass: { distort: "warm" } } },
3115
+ },
3116
+ ),
3117
+ leaf(
3118
+ "funkot",
3119
+ "funkot: Indonesian house at 160-200 bpm, four-on-the-floor with kendang-like off-beat percussion, dangdut phrygian-dominant melody",
3120
+ 2000,
3121
+ {
3122
+ tempo: { bpm: [160, 200], typical: 180 },
3123
+ rhythm: {
3124
+ onsets: {
3125
+ kick: FOUR_FLOOR,
3126
+ snare: BACKBEAT,
3127
+ hat: OFFBEAT_HAT,
3128
+ perc: grid("..xx..x...xx..x."),
3129
+ },
3130
+ },
3131
+ pitch: {
3132
+ scales: [
3133
+ ["phrygian-dominant", 0.6],
3134
+ ["harmonic-minor", 0.4],
3135
+ ],
3136
+ },
3137
+ harmony: { model: "modal" },
3138
+ texture: {
3139
+ roles: {
3140
+ perc: role("tabla", "drums:0.5"),
3141
+ lead: role("sing", "flute:0.5"),
3142
+ chords: role("keys"),
3143
+ },
3144
+ },
3145
+ },
3146
+ ),
3147
+ leaf(
3148
+ "singeli",
3149
+ "singeli: Tanzanian street music at 200-300 bpm, frantic sampled hand-drum loops, keyboard ostinatos, rapid MC chant",
3150
+ 2010,
3151
+ {
3152
+ tempo: { bpm: [200, 300], typical: 230 },
3153
+ rhythm: {
3154
+ onsets: {
3155
+ kick: FOUR_FLOOR,
3156
+ snare: grid("..x...x...x...x."),
3157
+ hat: SIXTEENTH_HAT,
3158
+ perc: TRESILLO,
3159
+ },
3160
+ },
3161
+ pitch: {
3162
+ scales: [
3163
+ ["major", 0.5],
3164
+ ["mixolydian", 0.5],
3165
+ ],
3166
+ },
3167
+ harmony: { model: "modal" },
3168
+ melody: { density: [2, 4] },
3169
+ texture: {
3170
+ roles: {
3171
+ perc: role("drums"),
3172
+ chords: role("keys", "marimba:0.5"),
3173
+ lead: role("vocal"),
3174
+ },
3175
+ },
3176
+ },
3177
+ ),
3178
+ ];
3179
+
3180
+ export const POP_CARDS: readonly StyleCard[] = Object.freeze([
3181
+ ...ROOTS,
3182
+ ...TRADITIONAL,
3183
+ ...SIXTIES,
3184
+ ...MODERN,
3185
+ ...OLD_SCHOOL,
3186
+ ...REGIONAL,
3187
+ ...MODERN_RAP,
3188
+ ...BREAKS,
3189
+ ]);