takomusic 1.2.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.
- package/LICENSE +661 -0
- package/README.md +230 -0
- package/dist/__tests__/checker.test.d.ts +2 -0
- package/dist/__tests__/checker.test.d.ts.map +1 -0
- package/dist/__tests__/checker.test.js +316 -0
- package/dist/__tests__/checker.test.js.map +1 -0
- package/dist/__tests__/compiler.test.d.ts +2 -0
- package/dist/__tests__/compiler.test.d.ts.map +1 -0
- package/dist/__tests__/compiler.test.js +260 -0
- package/dist/__tests__/compiler.test.js.map +1 -0
- package/dist/__tests__/generators.test.d.ts +2 -0
- package/dist/__tests__/generators.test.d.ts.map +1 -0
- package/dist/__tests__/generators.test.js +283 -0
- package/dist/__tests__/generators.test.js.map +1 -0
- package/dist/__tests__/interpreter.test.d.ts +2 -0
- package/dist/__tests__/interpreter.test.d.ts.map +1 -0
- package/dist/__tests__/interpreter.test.js +298 -0
- package/dist/__tests__/interpreter.test.js.map +1 -0
- package/dist/__tests__/lexer.test.d.ts +2 -0
- package/dist/__tests__/lexer.test.d.ts.map +1 -0
- package/dist/__tests__/lexer.test.js +89 -0
- package/dist/__tests__/lexer.test.js.map +1 -0
- package/dist/__tests__/parser.test.d.ts +2 -0
- package/dist/__tests__/parser.test.d.ts.map +1 -0
- package/dist/__tests__/parser.test.js +116 -0
- package/dist/__tests__/parser.test.js.map +1 -0
- package/dist/checker/checker.d.ts +37 -0
- package/dist/checker/checker.d.ts.map +1 -0
- package/dist/checker/checker.js +428 -0
- package/dist/checker/checker.js.map +1 -0
- package/dist/checker/index.d.ts +3 -0
- package/dist/checker/index.d.ts.map +1 -0
- package/dist/checker/index.js +2 -0
- package/dist/checker/index.js.map +1 -0
- package/dist/cli/commands/build.d.ts +2 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +173 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/check.d.ts +2 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +79 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +187 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/fmt.d.ts +2 -0
- package/dist/cli/commands/fmt.d.ts.map +1 -0
- package/dist/cli/commands/fmt.js +73 -0
- package/dist/cli/commands/fmt.js.map +1 -0
- package/dist/cli/commands/import.d.ts +2 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +99 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +514 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/play.d.ts +2 -0
- package/dist/cli/commands/play.d.ts.map +1 -0
- package/dist/cli/commands/play.js +216 -0
- package/dist/cli/commands/play.js.map +1 -0
- package/dist/cli/commands/record.d.ts +2 -0
- package/dist/cli/commands/record.d.ts.map +1 -0
- package/dist/cli/commands/record.js +393 -0
- package/dist/cli/commands/record.js.map +1 -0
- package/dist/cli/commands/render.d.ts +2 -0
- package/dist/cli/commands/render.d.ts.map +1 -0
- package/dist/cli/commands/render.js +278 -0
- package/dist/cli/commands/render.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +93 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compiler/compiler.d.ts +12 -0
- package/dist/compiler/compiler.d.ts.map +1 -0
- package/dist/compiler/compiler.js +146 -0
- package/dist/compiler/compiler.js.map +1 -0
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +2 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/config/config.d.ts +43 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +200 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/errors.d.ts +49 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +168 -0
- package/dist/errors.js.map +1 -0
- package/dist/formatter/formatter.d.ts +13 -0
- package/dist/formatter/formatter.d.ts.map +1 -0
- package/dist/formatter/formatter.js +242 -0
- package/dist/formatter/formatter.js.map +1 -0
- package/dist/formatter/index.d.ts +2 -0
- package/dist/formatter/index.d.ts.map +1 -0
- package/dist/formatter/index.js +2 -0
- package/dist/formatter/index.js.map +1 -0
- package/dist/generators/index.d.ts +5 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +5 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/midi.d.ts +3 -0
- package/dist/generators/midi.d.ts.map +1 -0
- package/dist/generators/midi.js +360 -0
- package/dist/generators/midi.js.map +1 -0
- package/dist/generators/musicxml.d.ts +3 -0
- package/dist/generators/musicxml.d.ts.map +1 -0
- package/dist/generators/musicxml.js +332 -0
- package/dist/generators/musicxml.js.map +1 -0
- package/dist/generators/tempo-midi.d.ts +3 -0
- package/dist/generators/tempo-midi.d.ts.map +1 -0
- package/dist/generators/tempo-midi.js +123 -0
- package/dist/generators/tempo-midi.js.map +1 -0
- package/dist/generators/vsqx.d.ts +3 -0
- package/dist/generators/vsqx.d.ts.map +1 -0
- package/dist/generators/vsqx.js +354 -0
- package/dist/generators/vsqx.js.map +1 -0
- package/dist/importers/index.d.ts +2 -0
- package/dist/importers/index.d.ts.map +1 -0
- package/dist/importers/index.js +3 -0
- package/dist/importers/index.js.map +1 -0
- package/dist/importers/musicxml.d.ts +4 -0
- package/dist/importers/musicxml.d.ts.map +1 -0
- package/dist/importers/musicxml.js +392 -0
- package/dist/importers/musicxml.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter/builtins/algorithmic.d.ts +12 -0
- package/dist/interpreter/builtins/algorithmic.d.ts.map +1 -0
- package/dist/interpreter/builtins/algorithmic.js +244 -0
- package/dist/interpreter/builtins/algorithmic.js.map +1 -0
- package/dist/interpreter/builtins/audio.d.ts +10 -0
- package/dist/interpreter/builtins/audio.d.ts.map +1 -0
- package/dist/interpreter/builtins/audio.js +169 -0
- package/dist/interpreter/builtins/audio.js.map +1 -0
- package/dist/interpreter/builtins/core.d.ts +15 -0
- package/dist/interpreter/builtins/core.d.ts.map +1 -0
- package/dist/interpreter/builtins/core.js +265 -0
- package/dist/interpreter/builtins/core.js.map +1 -0
- package/dist/interpreter/builtins/dynamics.d.ts +8 -0
- package/dist/interpreter/builtins/dynamics.d.ts.map +1 -0
- package/dist/interpreter/builtins/dynamics.js +86 -0
- package/dist/interpreter/builtins/dynamics.js.map +1 -0
- package/dist/interpreter/builtins/effects.d.ts +16 -0
- package/dist/interpreter/builtins/effects.d.ts.map +1 -0
- package/dist/interpreter/builtins/effects.js +220 -0
- package/dist/interpreter/builtins/effects.js.map +1 -0
- package/dist/interpreter/builtins/index.d.ts +16 -0
- package/dist/interpreter/builtins/index.d.ts.map +1 -0
- package/dist/interpreter/builtins/index.js +17 -0
- package/dist/interpreter/builtins/index.js.map +1 -0
- package/dist/interpreter/builtins/layout.d.ts +12 -0
- package/dist/interpreter/builtins/layout.d.ts.map +1 -0
- package/dist/interpreter/builtins/layout.js +175 -0
- package/dist/interpreter/builtins/layout.js.map +1 -0
- package/dist/interpreter/builtins/live.d.ts +11 -0
- package/dist/interpreter/builtins/live.d.ts.map +1 -0
- package/dist/interpreter/builtins/live.js +125 -0
- package/dist/interpreter/builtins/live.js.map +1 -0
- package/dist/interpreter/builtins/midi.d.ts +16 -0
- package/dist/interpreter/builtins/midi.d.ts.map +1 -0
- package/dist/interpreter/builtins/midi.js +320 -0
- package/dist/interpreter/builtins/midi.js.map +1 -0
- package/dist/interpreter/builtins/mixing.d.ts +6 -0
- package/dist/interpreter/builtins/mixing.d.ts.map +1 -0
- package/dist/interpreter/builtins/mixing.js +62 -0
- package/dist/interpreter/builtins/mixing.js.map +1 -0
- package/dist/interpreter/builtins/notation.d.ts +24 -0
- package/dist/interpreter/builtins/notation.d.ts.map +1 -0
- package/dist/interpreter/builtins/notation.js +251 -0
- package/dist/interpreter/builtins/notation.js.map +1 -0
- package/dist/interpreter/builtins/ornaments.d.ts +8 -0
- package/dist/interpreter/builtins/ornaments.d.ts.map +1 -0
- package/dist/interpreter/builtins/ornaments.js +155 -0
- package/dist/interpreter/builtins/ornaments.js.map +1 -0
- package/dist/interpreter/builtins/techniques.d.ts +11 -0
- package/dist/interpreter/builtins/techniques.d.ts.map +1 -0
- package/dist/interpreter/builtins/techniques.js +234 -0
- package/dist/interpreter/builtins/techniques.js.map +1 -0
- package/dist/interpreter/builtins/tuning.d.ts +7 -0
- package/dist/interpreter/builtins/tuning.d.ts.map +1 -0
- package/dist/interpreter/builtins/tuning.js +52 -0
- package/dist/interpreter/builtins/tuning.js.map +1 -0
- package/dist/interpreter/builtins/types.d.ts +27 -0
- package/dist/interpreter/builtins/types.d.ts.map +1 -0
- package/dist/interpreter/builtins/types.js +3 -0
- package/dist/interpreter/builtins/types.js.map +1 -0
- package/dist/interpreter/builtins/vocaloid.d.ts +10 -0
- package/dist/interpreter/builtins/vocaloid.d.ts.map +1 -0
- package/dist/interpreter/builtins/vocaloid.js +165 -0
- package/dist/interpreter/builtins/vocaloid.js.map +1 -0
- package/dist/interpreter/index.d.ts +4 -0
- package/dist/interpreter/index.d.ts.map +1 -0
- package/dist/interpreter/index.js +4 -0
- package/dist/interpreter/index.js.map +1 -0
- package/dist/interpreter/interpreter.d.ts +305 -0
- package/dist/interpreter/interpreter.d.ts.map +1 -0
- package/dist/interpreter/interpreter.js +8463 -0
- package/dist/interpreter/interpreter.js.map +1 -0
- package/dist/interpreter/runtime.d.ts +67 -0
- package/dist/interpreter/runtime.d.ts.map +1 -0
- package/dist/interpreter/runtime.js +88 -0
- package/dist/interpreter/runtime.js.map +1 -0
- package/dist/interpreter/scope.d.ts +21 -0
- package/dist/interpreter/scope.d.ts.map +1 -0
- package/dist/interpreter/scope.js +60 -0
- package/dist/interpreter/scope.js.map +1 -0
- package/dist/interpreter/trackState.d.ts +205 -0
- package/dist/interpreter/trackState.d.ts.map +1 -0
- package/dist/interpreter/trackState.js +12 -0
- package/dist/interpreter/trackState.js.map +1 -0
- package/dist/lexer/index.d.ts +2 -0
- package/dist/lexer/index.d.ts.map +1 -0
- package/dist/lexer/index.js +2 -0
- package/dist/lexer/index.js.map +1 -0
- package/dist/lexer/lexer.d.ts +30 -0
- package/dist/lexer/lexer.d.ts.map +1 -0
- package/dist/lexer/lexer.js +385 -0
- package/dist/lexer/lexer.js.map +1 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +2 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parser.d.ts +55 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +896 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/types/ast.d.ts +220 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +3 -0
- package/dist/types/ast.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ir/advanced.d.ts +491 -0
- package/dist/types/ir/advanced.d.ts.map +1 -0
- package/dist/types/ir/advanced.js +3 -0
- package/dist/types/ir/advanced.js.map +1 -0
- package/dist/types/ir/algorithmic.d.ts +48 -0
- package/dist/types/ir/algorithmic.d.ts.map +1 -0
- package/dist/types/ir/algorithmic.js +3 -0
- package/dist/types/ir/algorithmic.js.map +1 -0
- package/dist/types/ir/analysis.d.ts +34 -0
- package/dist/types/ir/analysis.d.ts.map +1 -0
- package/dist/types/ir/analysis.js +3 -0
- package/dist/types/ir/analysis.js.map +1 -0
- package/dist/types/ir/audio.d.ts +249 -0
- package/dist/types/ir/audio.d.ts.map +1 -0
- package/dist/types/ir/audio.js +3 -0
- package/dist/types/ir/audio.js.map +1 -0
- package/dist/types/ir/automation.d.ts +46 -0
- package/dist/types/ir/automation.d.ts.map +1 -0
- package/dist/types/ir/automation.js +3 -0
- package/dist/types/ir/automation.js.map +1 -0
- package/dist/types/ir/collaboration.d.ts +20 -0
- package/dist/types/ir/collaboration.d.ts.map +1 -0
- package/dist/types/ir/collaboration.js +3 -0
- package/dist/types/ir/collaboration.js.map +1 -0
- package/dist/types/ir/core.d.ts +153 -0
- package/dist/types/ir/core.d.ts.map +1 -0
- package/dist/types/ir/core.js +3 -0
- package/dist/types/ir/core.js.map +1 -0
- package/dist/types/ir/effects.d.ts +169 -0
- package/dist/types/ir/effects.d.ts.map +1 -0
- package/dist/types/ir/effects.js +3 -0
- package/dist/types/ir/effects.js.map +1 -0
- package/dist/types/ir/extended.d.ts +104 -0
- package/dist/types/ir/extended.d.ts.map +1 -0
- package/dist/types/ir/extended.js +3 -0
- package/dist/types/ir/extended.js.map +1 -0
- package/dist/types/ir/index.d.ts +16 -0
- package/dist/types/ir/index.d.ts.map +1 -0
- package/dist/types/ir/index.js +17 -0
- package/dist/types/ir/index.js.map +1 -0
- package/dist/types/ir/mastering.d.ts +86 -0
- package/dist/types/ir/mastering.d.ts.map +1 -0
- package/dist/types/ir/mastering.js +3 -0
- package/dist/types/ir/mastering.js.map +1 -0
- package/dist/types/ir/midi.d.ts +79 -0
- package/dist/types/ir/midi.d.ts.map +1 -0
- package/dist/types/ir/midi.js +3 -0
- package/dist/types/ir/midi.js.map +1 -0
- package/dist/types/ir/notation.d.ts +963 -0
- package/dist/types/ir/notation.d.ts.map +1 -0
- package/dist/types/ir/notation.js +3 -0
- package/dist/types/ir/notation.js.map +1 -0
- package/dist/types/ir/recording.d.ts +48 -0
- package/dist/types/ir/recording.d.ts.map +1 -0
- package/dist/types/ir/recording.js +3 -0
- package/dist/types/ir/recording.js.map +1 -0
- package/dist/types/ir/sampling.d.ts +59 -0
- package/dist/types/ir/sampling.d.ts.map +1 -0
- package/dist/types/ir/sampling.js +3 -0
- package/dist/types/ir/sampling.js.map +1 -0
- package/dist/types/ir/sequencing.d.ts +118 -0
- package/dist/types/ir/sequencing.d.ts.map +1 -0
- package/dist/types/ir/sequencing.js +3 -0
- package/dist/types/ir/sequencing.js.map +1 -0
- package/dist/types/ir/sync.d.ts +39 -0
- package/dist/types/ir/sync.d.ts.map +1 -0
- package/dist/types/ir/sync.js +3 -0
- package/dist/types/ir/sync.js.map +1 -0
- package/dist/types/ir.d.ts +2 -0
- package/dist/types/ir.d.ts.map +1 -0
- package/dist/types/ir.js +3 -0
- package/dist/types/ir.js.map +1 -0
- package/dist/types/token.d.ts +72 -0
- package/dist/types/token.d.ts.map +1 -0
- package/dist/types/token.js +90 -0
- package/dist/types/token.js.map +1 -0
- package/dist/utils/stdlib.d.ts +18 -0
- package/dist/utils/stdlib.d.ts.map +1 -0
- package/dist/utils/stdlib.js +51 -0
- package/dist/utils/stdlib.js.map +1 -0
- package/lib/articulation.mf +46 -0
- package/lib/composition.mf +299 -0
- package/lib/curves.mf +183 -0
- package/lib/dynamics.mf +141 -0
- package/lib/expression.mf +221 -0
- package/lib/genres.mf +348 -0
- package/lib/notation.mf +224 -0
- package/lib/ornaments.mf +98 -0
- package/lib/patterns.mf +170 -0
- package/lib/rhythm.mf +269 -0
- package/lib/theory.mf +257 -0
- package/lib/utils.mf +140 -0
- package/package.json +49 -0
package/lib/dynamics.mf
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Dynamics functions for TakoMusic
|
|
2
|
+
// Volume and velocity control over time
|
|
3
|
+
|
|
4
|
+
import { clip, lerp } from "./utils.mf";
|
|
5
|
+
|
|
6
|
+
// Crescendo - gradually increase velocity
|
|
7
|
+
export proc crescendo(notes, durs, startVel, endVel) {
|
|
8
|
+
const count = len(notes);
|
|
9
|
+
for (i in 0..count) {
|
|
10
|
+
const t = i / (count - 1);
|
|
11
|
+
const vel = floor(lerp(startVel, endVel, t));
|
|
12
|
+
note(notes[i], durs[i], clip(vel, 1, 127));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Decrescendo (diminuendo) - gradually decrease velocity
|
|
17
|
+
export proc decrescendo(notes, durs, startVel, endVel) {
|
|
18
|
+
crescendo(notes, durs, startVel, endVel);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Crescendo with uniform duration
|
|
22
|
+
export proc crescendoUniform(notes, dur, startVel, endVel) {
|
|
23
|
+
const count = len(notes);
|
|
24
|
+
for (i in 0..count) {
|
|
25
|
+
const t = i / (count - 1);
|
|
26
|
+
const vel = floor(lerp(startVel, endVel, t));
|
|
27
|
+
note(notes[i], dur, clip(vel, 1, 127));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Decrescendo with uniform duration
|
|
32
|
+
export proc decrescendoUniform(notes, dur, startVel, endVel) {
|
|
33
|
+
crescendoUniform(notes, dur, startVel, endVel);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Apply accent pattern to notes
|
|
37
|
+
// pattern: array of booleans, true = accented
|
|
38
|
+
export proc accentPattern(notes, pattern, dur, baseVel, accentVel) {
|
|
39
|
+
for (i in 0..len(notes)) {
|
|
40
|
+
const patIdx = i % len(pattern);
|
|
41
|
+
let vel = baseVel;
|
|
42
|
+
if (pattern[patIdx]) {
|
|
43
|
+
vel = accentVel;
|
|
44
|
+
}
|
|
45
|
+
note(notes[i], dur, clip(vel, 1, 127));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Sforzando - sudden strong accent then immediate drop
|
|
50
|
+
export proc sforzando(pitch, dur, peakVel, sustainVel) {
|
|
51
|
+
const attackDur = dur / 8;
|
|
52
|
+
const sustainDur = dur * 7/8;
|
|
53
|
+
note(pitch, attackDur, clip(peakVel, 1, 127));
|
|
54
|
+
note(pitch, sustainDur, clip(sustainVel, 1, 127));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Forte-piano - loud attack immediately soft
|
|
58
|
+
export proc fortePiano(pitch, dur, forteVel, pianoVel) {
|
|
59
|
+
const attackDur = dur / 16;
|
|
60
|
+
const sustainDur = dur * 15/16;
|
|
61
|
+
note(pitch, attackDur, clip(forteVel, 1, 127));
|
|
62
|
+
note(pitch, sustainDur, clip(pianoVel, 1, 127));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Rinforzando - reinforced accent
|
|
66
|
+
export proc rinforzando(pitch, dur, vel) {
|
|
67
|
+
const accentedVel = clip(vel + 25, 1, 127);
|
|
68
|
+
note(pitch, dur, accentedVel);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Swell - crescendo then decrescendo (messa di voce)
|
|
72
|
+
export proc swell(pitch, dur, minVel, maxVel, steps) {
|
|
73
|
+
const halfSteps = floor(steps / 2);
|
|
74
|
+
const stepDur = dur / steps;
|
|
75
|
+
|
|
76
|
+
// Crescendo half
|
|
77
|
+
for (i in 0..halfSteps) {
|
|
78
|
+
const t = i / halfSteps;
|
|
79
|
+
const vel = floor(lerp(minVel, maxVel, t));
|
|
80
|
+
note(pitch, stepDur, clip(vel, 1, 127));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Decrescendo half
|
|
84
|
+
for (i in 0..steps - halfSteps) {
|
|
85
|
+
const t = i / (steps - halfSteps);
|
|
86
|
+
const vel = floor(lerp(maxVel, minVel, t));
|
|
87
|
+
note(pitch, stepDur, clip(vel, 1, 127));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Hairpin crescendo using CC expression
|
|
92
|
+
export proc hairpinCresc(startVal, endVal, dur) {
|
|
93
|
+
const ticks = durToTicks(dur);
|
|
94
|
+
const steps = 16;
|
|
95
|
+
|
|
96
|
+
for (i in 0..=steps) {
|
|
97
|
+
const t = i / steps;
|
|
98
|
+
const val = floor(lerp(startVal, endVal, t));
|
|
99
|
+
const tick = floor(ticks * t);
|
|
100
|
+
atTick(tick);
|
|
101
|
+
expression(clip(val, 0, 127));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Hairpin decrescendo using CC expression
|
|
106
|
+
export proc hairpinDecresc(startVal, endVal, dur) {
|
|
107
|
+
hairpinCresc(startVal, endVal, dur);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Subito forte - suddenly loud
|
|
111
|
+
export proc subitoForte(pitch, dur) {
|
|
112
|
+
note(pitch, dur, 112);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Subito piano - suddenly soft
|
|
116
|
+
export proc subitoPiano(pitch, dur) {
|
|
117
|
+
note(pitch, dur, 50);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Morendo - dying away (decreasing velocity and slowing)
|
|
121
|
+
export proc morendo(notes, baseDur, startVel) {
|
|
122
|
+
const count = len(notes);
|
|
123
|
+
for (i in 0..count) {
|
|
124
|
+
const t = i / count;
|
|
125
|
+
const vel = floor(startVel * (1 - t * 0.8));
|
|
126
|
+
const dur = baseDur * (1 + t * 0.5);
|
|
127
|
+
note(notes[i], dur, clip(vel, 1, 127));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Perdendosi - fading away to nothing
|
|
132
|
+
export proc perdendosi(notes, baseDur, startVel) {
|
|
133
|
+
const count = len(notes);
|
|
134
|
+
for (i in 0..count) {
|
|
135
|
+
const t = i / count;
|
|
136
|
+
const vel = floor(startVel * (1 - t));
|
|
137
|
+
if (vel > 0) {
|
|
138
|
+
note(notes[i], baseDur, clip(vel, 1, 127));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// Expression functions for TakoMusic
|
|
2
|
+
// Pitch bend, modulation, and expressive techniques
|
|
3
|
+
|
|
4
|
+
import { clip, lerp } from "./utils.mf";
|
|
5
|
+
|
|
6
|
+
// Vibrato using pitch bend
|
|
7
|
+
// depth: semitones (e.g., 0.5 for half semitone)
|
|
8
|
+
// rate: oscillations per beat
|
|
9
|
+
export proc vibrato(pitch, dur, depth, rate) {
|
|
10
|
+
const ticks = durToTicks(dur);
|
|
11
|
+
const cycles = floor(rate * 4);
|
|
12
|
+
const steps = cycles * 8;
|
|
13
|
+
const stepTicks = floor(ticks / steps);
|
|
14
|
+
|
|
15
|
+
// Play the note
|
|
16
|
+
note(pitch, dur);
|
|
17
|
+
|
|
18
|
+
// Apply pitch bend oscillation
|
|
19
|
+
at(cursor());
|
|
20
|
+
advanceTick(-ticks);
|
|
21
|
+
|
|
22
|
+
for (i in 0..steps) {
|
|
23
|
+
const phase = (i % 8) / 8;
|
|
24
|
+
let bend = 0;
|
|
25
|
+
|
|
26
|
+
// Sine-like approximation
|
|
27
|
+
if (phase < 0.25) {
|
|
28
|
+
bend = phase * 4;
|
|
29
|
+
} else {
|
|
30
|
+
if (phase < 0.75) {
|
|
31
|
+
bend = 1 - (phase - 0.25) * 4;
|
|
32
|
+
} else {
|
|
33
|
+
bend = -1 + (phase - 0.75) * 4;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const bendVal = floor(8192 + bend * depth * 4096);
|
|
38
|
+
pitchBend(clip(bendVal, 0, 16383));
|
|
39
|
+
advanceTick(stepTicks);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Reset pitch bend
|
|
43
|
+
pitchBend(8192);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Simple vibrato (fewer parameters)
|
|
47
|
+
export proc vibratoSimple(pitch, dur) {
|
|
48
|
+
vibrato(pitch, dur, 0.3, 5);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Portamento / glide between two pitches
|
|
52
|
+
export proc portamento(fromPitch, toPitch, dur) {
|
|
53
|
+
const fromMidi = pitchMidi(fromPitch);
|
|
54
|
+
const toMidi = pitchMidi(toPitch);
|
|
55
|
+
const semitones = toMidi - fromMidi;
|
|
56
|
+
const ticks = durToTicks(dur);
|
|
57
|
+
const steps = 16;
|
|
58
|
+
const stepTicks = floor(ticks / steps);
|
|
59
|
+
|
|
60
|
+
// Start from the first pitch
|
|
61
|
+
note(fromPitch, dur);
|
|
62
|
+
|
|
63
|
+
// Glide using pitch bend
|
|
64
|
+
at(cursor());
|
|
65
|
+
advanceTick(-ticks);
|
|
66
|
+
|
|
67
|
+
for (i in 0..=steps) {
|
|
68
|
+
const t = i / steps;
|
|
69
|
+
const bendSemitones = semitones * t;
|
|
70
|
+
const bendVal = floor(8192 + bendSemitones * 4096 / 2);
|
|
71
|
+
pitchBend(clip(bendVal, 0, 16383));
|
|
72
|
+
advanceTick(stepTicks);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Reset
|
|
76
|
+
pitchBend(8192);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Bend up to pitch
|
|
80
|
+
export proc bendUp(pitch, dur, semitones) {
|
|
81
|
+
const ticks = durToTicks(dur);
|
|
82
|
+
const steps = 8;
|
|
83
|
+
const stepTicks = floor(ticks / steps);
|
|
84
|
+
|
|
85
|
+
// Start with bend down
|
|
86
|
+
pitchBend(floor(8192 - semitones * 4096 / 2));
|
|
87
|
+
note(pitch, dur);
|
|
88
|
+
|
|
89
|
+
// Bend up to normal
|
|
90
|
+
at(cursor());
|
|
91
|
+
advanceTick(-ticks);
|
|
92
|
+
|
|
93
|
+
for (i in 0..=steps) {
|
|
94
|
+
const t = i / steps;
|
|
95
|
+
const bendVal = floor(8192 - semitones * (1 - t) * 4096 / 2);
|
|
96
|
+
pitchBend(clip(bendVal, 0, 16383));
|
|
97
|
+
advanceTick(stepTicks);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
pitchBend(8192);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Bend down from pitch
|
|
104
|
+
export proc bendDown(pitch, dur, semitones) {
|
|
105
|
+
const ticks = durToTicks(dur);
|
|
106
|
+
const steps = 8;
|
|
107
|
+
const stepTicks = floor(ticks / steps);
|
|
108
|
+
|
|
109
|
+
note(pitch, dur);
|
|
110
|
+
|
|
111
|
+
at(cursor());
|
|
112
|
+
advanceTick(-ticks);
|
|
113
|
+
|
|
114
|
+
for (i in 0..=steps) {
|
|
115
|
+
const t = i / steps;
|
|
116
|
+
const bendVal = floor(8192 - semitones * t * 4096 / 2);
|
|
117
|
+
pitchBend(clip(bendVal, 0, 16383));
|
|
118
|
+
advanceTick(stepTicks);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
pitchBend(8192);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Scoop - quick bend up into note
|
|
125
|
+
export proc scoop(pitch, dur, semitones) {
|
|
126
|
+
bendUp(pitch, dur, semitones);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Fall - bend down at end of note
|
|
130
|
+
export proc fall(pitch, dur, semitones) {
|
|
131
|
+
const mainDur = dur * 3/4;
|
|
132
|
+
const fallDur = dur * 1/4;
|
|
133
|
+
|
|
134
|
+
note(pitch, mainDur);
|
|
135
|
+
|
|
136
|
+
const ticks = durToTicks(fallDur);
|
|
137
|
+
const steps = 4;
|
|
138
|
+
const stepTicks = floor(ticks / steps);
|
|
139
|
+
|
|
140
|
+
for (i in 0..=steps) {
|
|
141
|
+
const t = i / steps;
|
|
142
|
+
const bendVal = floor(8192 - semitones * t * 4096 / 2);
|
|
143
|
+
pitchBend(clip(bendVal, 0, 16383));
|
|
144
|
+
advanceTick(stepTicks);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
pitchBend(8192);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Modulation wheel automation
|
|
151
|
+
export proc modulationSwell(startVal, peakVal, dur) {
|
|
152
|
+
const ticks = durToTicks(dur);
|
|
153
|
+
const halfTicks = floor(ticks / 2);
|
|
154
|
+
const steps = 8;
|
|
155
|
+
|
|
156
|
+
// Increase
|
|
157
|
+
for (i in 0..=steps) {
|
|
158
|
+
const t = i / steps;
|
|
159
|
+
const val = floor(lerp(startVal, peakVal, t));
|
|
160
|
+
atTick(floor(halfTicks * t));
|
|
161
|
+
modulation(clip(val, 0, 127));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Decrease
|
|
165
|
+
for (i in 0..=steps) {
|
|
166
|
+
const t = i / steps;
|
|
167
|
+
const val = floor(lerp(peakVal, startVal, t));
|
|
168
|
+
atTick(halfTicks + floor(halfTicks * t));
|
|
169
|
+
modulation(clip(val, 0, 127));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Breath controller (CC2)
|
|
174
|
+
export proc breathController(startVal, endVal, dur) {
|
|
175
|
+
const ticks = durToTicks(dur);
|
|
176
|
+
const steps = 16;
|
|
177
|
+
|
|
178
|
+
for (i in 0..=steps) {
|
|
179
|
+
const t = i / steps;
|
|
180
|
+
const val = floor(lerp(startVal, endVal, t));
|
|
181
|
+
atTick(floor(ticks * t));
|
|
182
|
+
cc(2, clip(val, 0, 127));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Tremolo using modulation
|
|
187
|
+
export proc tremoloMod(pitch, dur, depth, rate) {
|
|
188
|
+
const ticks = durToTicks(dur);
|
|
189
|
+
const cycles = floor(rate * 4);
|
|
190
|
+
const steps = cycles * 4;
|
|
191
|
+
const stepTicks = floor(ticks / steps);
|
|
192
|
+
|
|
193
|
+
note(pitch, dur);
|
|
194
|
+
|
|
195
|
+
at(cursor());
|
|
196
|
+
advanceTick(-ticks);
|
|
197
|
+
|
|
198
|
+
for (i in 0..steps) {
|
|
199
|
+
const phase = (i % 4) / 4;
|
|
200
|
+
let val = 0;
|
|
201
|
+
|
|
202
|
+
if (phase < 0.5) {
|
|
203
|
+
val = floor(depth * phase * 2);
|
|
204
|
+
} else {
|
|
205
|
+
val = floor(depth * (1 - (phase - 0.5) * 2));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
modulation(clip(val, 0, 127));
|
|
209
|
+
advanceTick(stepTicks);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
modulation(0);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Legato transition between notes
|
|
216
|
+
export proc legatoSlide(fromPitch, toPitch, dur, slideDur) {
|
|
217
|
+
const mainDur = dur - slideDur;
|
|
218
|
+
|
|
219
|
+
note(fromPitch, mainDur);
|
|
220
|
+
portamento(fromPitch, toPitch, slideDur);
|
|
221
|
+
}
|
package/lib/genres.mf
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// Genre-specific patterns for TakoMusic
|
|
2
|
+
// Common rhythm and accompaniment patterns by genre
|
|
3
|
+
|
|
4
|
+
// Bossa Nova guitar pattern
|
|
5
|
+
export proc bossaNovaGuitar(chordNotes, dur) {
|
|
6
|
+
const eighth = dur / 2;
|
|
7
|
+
|
|
8
|
+
// Classic bossa pattern: bass on 1, chord on 'and' of 1, etc.
|
|
9
|
+
note(chordNotes[0], eighth); // bass
|
|
10
|
+
chord(slice(chordNotes, 1, len(chordNotes)), eighth); // chord
|
|
11
|
+
rest(eighth);
|
|
12
|
+
chord(chordNotes, eighth);
|
|
13
|
+
rest(eighth);
|
|
14
|
+
chord(chordNotes, eighth);
|
|
15
|
+
note(chordNotes[0], eighth);
|
|
16
|
+
chord(slice(chordNotes, 1, len(chordNotes)), eighth);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Bossa Nova drum pattern
|
|
20
|
+
export proc bossaNovaDrums(dur, bars) {
|
|
21
|
+
const eighth = dur / 2;
|
|
22
|
+
|
|
23
|
+
for (bar in 0..bars) {
|
|
24
|
+
// Rim click pattern
|
|
25
|
+
for (beat in 0..8) {
|
|
26
|
+
if (beat == 2 || beat == 5) {
|
|
27
|
+
drum(snare, eighth);
|
|
28
|
+
} else {
|
|
29
|
+
drum(hhc, eighth);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Funk guitar/keyboard stab
|
|
36
|
+
export proc funkStab(chordNotes, dur) {
|
|
37
|
+
const sixteenth = dur / 4;
|
|
38
|
+
|
|
39
|
+
// Classic funk pattern with ghost notes
|
|
40
|
+
chord(chordNotes, sixteenth, 100);
|
|
41
|
+
rest(sixteenth);
|
|
42
|
+
chord(chordNotes, sixteenth, 60);
|
|
43
|
+
rest(sixteenth);
|
|
44
|
+
rest(sixteenth);
|
|
45
|
+
chord(chordNotes, sixteenth, 100);
|
|
46
|
+
rest(sixteenth);
|
|
47
|
+
chord(chordNotes, sixteenth, 70);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Funk drum pattern
|
|
51
|
+
export proc funkDrums(dur, bars) {
|
|
52
|
+
const sixteenth = dur / 4;
|
|
53
|
+
|
|
54
|
+
for (bar in 0..bars) {
|
|
55
|
+
for (beat in 0..16) {
|
|
56
|
+
// Kick pattern
|
|
57
|
+
if (beat == 0 || beat == 6 || beat == 10) {
|
|
58
|
+
drum(kick, sixteenth);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Snare on 2 and 4 with ghost notes
|
|
62
|
+
if (beat == 4 || beat == 12) {
|
|
63
|
+
drum(snare, sixteenth, 100);
|
|
64
|
+
}
|
|
65
|
+
if (beat == 3 || beat == 7 || beat == 11 || beat == 15) {
|
|
66
|
+
drum(snare, sixteenth, 40);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Hi-hat
|
|
70
|
+
if (beat % 2 == 0) {
|
|
71
|
+
drum(hhc, sixteenth);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Fill gaps with rest
|
|
75
|
+
if (beat == 1 || beat == 2 || beat == 5 || beat == 8 || beat == 9 || beat == 13 || beat == 14) {
|
|
76
|
+
rest(sixteenth);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Reggae skank (offbeat chords)
|
|
83
|
+
export proc reggaeSkank(chordNotes, dur, bars) {
|
|
84
|
+
const eighth = dur / 2;
|
|
85
|
+
|
|
86
|
+
for (bar in 0..bars) {
|
|
87
|
+
for (beat in 0..8) {
|
|
88
|
+
if (beat % 2 == 1) {
|
|
89
|
+
chord(chordNotes, eighth, 90);
|
|
90
|
+
} else {
|
|
91
|
+
rest(eighth);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Reggae one drop drum pattern
|
|
98
|
+
export proc reggaeOneDrop(dur, bars) {
|
|
99
|
+
const eighth = dur / 2;
|
|
100
|
+
|
|
101
|
+
for (bar in 0..bars) {
|
|
102
|
+
for (beat in 0..8) {
|
|
103
|
+
// Kick and snare together on 3
|
|
104
|
+
if (beat == 4) {
|
|
105
|
+
drum(kick, eighth);
|
|
106
|
+
drum(snare, eighth);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Hi-hat on every eighth
|
|
110
|
+
drum(hhc, eighth);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// EDM four-on-the-floor kick
|
|
116
|
+
export proc fourOnFloor(dur, bars) {
|
|
117
|
+
for (bar in 0..bars) {
|
|
118
|
+
for (beat in 0..4) {
|
|
119
|
+
drum(kick, dur);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// EDM offbeat hi-hat
|
|
125
|
+
export proc offbeatHiHat(dur, bars) {
|
|
126
|
+
const eighth = dur / 2;
|
|
127
|
+
|
|
128
|
+
for (bar in 0..bars) {
|
|
129
|
+
for (beat in 0..8) {
|
|
130
|
+
if (beat % 2 == 1) {
|
|
131
|
+
drum(hho, eighth);
|
|
132
|
+
} else {
|
|
133
|
+
rest(eighth);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// EDM buildup (increasing hi-hat density)
|
|
140
|
+
export proc edmBuildup(bars) {
|
|
141
|
+
const sixteenth = 1/16;
|
|
142
|
+
|
|
143
|
+
for (bar in 0..bars) {
|
|
144
|
+
const density = floor(4 + bar * 4);
|
|
145
|
+
for (i in 0..16) {
|
|
146
|
+
if (i % floor(16 / density) == 0) {
|
|
147
|
+
drum(hhc, sixteenth);
|
|
148
|
+
} else {
|
|
149
|
+
rest(sixteenth);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Rock drum beat
|
|
156
|
+
export proc rockBeat(dur, bars) {
|
|
157
|
+
const eighth = dur / 2;
|
|
158
|
+
|
|
159
|
+
for (bar in 0..bars) {
|
|
160
|
+
for (beat in 0..8) {
|
|
161
|
+
// Kick on 1 and 3
|
|
162
|
+
if (beat == 0 || beat == 4) {
|
|
163
|
+
drum(kick, eighth);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Snare on 2 and 4
|
|
167
|
+
if (beat == 2 || beat == 6) {
|
|
168
|
+
drum(snare, eighth);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Constant hi-hat
|
|
172
|
+
drum(hhc, eighth);
|
|
173
|
+
|
|
174
|
+
if (beat == 1 || beat == 3 || beat == 5 || beat == 7) {
|
|
175
|
+
rest(eighth);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Rock power chord riff pattern
|
|
182
|
+
export proc powerChordRiff(root, dur) {
|
|
183
|
+
const eighth = dur / 2;
|
|
184
|
+
const pwr = [root, transpose(root, 7)];
|
|
185
|
+
|
|
186
|
+
chord(pwr, eighth, 100);
|
|
187
|
+
chord(pwr, eighth, 100);
|
|
188
|
+
rest(eighth);
|
|
189
|
+
chord(pwr, eighth, 80);
|
|
190
|
+
rest(dur);
|
|
191
|
+
chord(pwr, dur, 100);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Shuffle/blues pattern
|
|
195
|
+
export proc shuffleBeat(dur, bars) {
|
|
196
|
+
const triplet = dur / 3;
|
|
197
|
+
|
|
198
|
+
for (bar in 0..bars) {
|
|
199
|
+
for (beat in 0..4) {
|
|
200
|
+
// Kick on 1 and 3
|
|
201
|
+
if (beat == 0 || beat == 2) {
|
|
202
|
+
drum(kick, triplet * 2);
|
|
203
|
+
drum(hhc, triplet);
|
|
204
|
+
} else {
|
|
205
|
+
// Snare on 2 and 4
|
|
206
|
+
drum(snare, triplet * 2);
|
|
207
|
+
drum(hhc, triplet);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Jazz ride pattern
|
|
214
|
+
export proc jazzRide(dur, bars) {
|
|
215
|
+
const triplet = dur / 3;
|
|
216
|
+
|
|
217
|
+
for (bar in 0..bars) {
|
|
218
|
+
for (beat in 0..4) {
|
|
219
|
+
drum(ride, triplet * 2);
|
|
220
|
+
drum(ride, triplet);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Jazz walking bass style
|
|
226
|
+
export proc jazzWalk(scale, dur, bars) {
|
|
227
|
+
for (bar in 0..bars) {
|
|
228
|
+
for (beat in 0..4) {
|
|
229
|
+
const idx = (bar * 4 + beat) % len(scale);
|
|
230
|
+
note(transpose(scale[idx], -12), dur);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Latin tumbao bass pattern
|
|
236
|
+
export proc tumbaoBass(root, fifth, dur) {
|
|
237
|
+
const eighth = dur / 2;
|
|
238
|
+
|
|
239
|
+
rest(eighth);
|
|
240
|
+
note(transpose(root, -12), eighth);
|
|
241
|
+
rest(eighth);
|
|
242
|
+
note(transpose(fifth, -12), eighth);
|
|
243
|
+
note(transpose(root, -12), eighth);
|
|
244
|
+
rest(eighth);
|
|
245
|
+
rest(eighth);
|
|
246
|
+
note(transpose(fifth, -12), eighth);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Salsa clave (son clave 3-2)
|
|
250
|
+
export proc salsaClave(dur, bars) {
|
|
251
|
+
const eighth = dur / 2;
|
|
252
|
+
|
|
253
|
+
for (bar in 0..floor(bars / 2)) {
|
|
254
|
+
// 3 side
|
|
255
|
+
drum(hhc, eighth);
|
|
256
|
+
rest(eighth);
|
|
257
|
+
rest(eighth);
|
|
258
|
+
drum(hhc, eighth);
|
|
259
|
+
rest(eighth);
|
|
260
|
+
rest(eighth);
|
|
261
|
+
drum(hhc, eighth);
|
|
262
|
+
rest(eighth);
|
|
263
|
+
|
|
264
|
+
// 2 side
|
|
265
|
+
rest(eighth);
|
|
266
|
+
rest(eighth);
|
|
267
|
+
drum(hhc, eighth);
|
|
268
|
+
rest(eighth);
|
|
269
|
+
drum(hhc, eighth);
|
|
270
|
+
rest(eighth);
|
|
271
|
+
rest(eighth);
|
|
272
|
+
rest(eighth);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Disco beat
|
|
277
|
+
export proc discoBeat(dur, bars) {
|
|
278
|
+
const eighth = dur / 2;
|
|
279
|
+
|
|
280
|
+
for (bar in 0..bars) {
|
|
281
|
+
for (beat in 0..8) {
|
|
282
|
+
// Four on the floor
|
|
283
|
+
if (beat % 2 == 0) {
|
|
284
|
+
drum(kick, eighth);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Open hi-hat on offbeats
|
|
288
|
+
if (beat % 2 == 1) {
|
|
289
|
+
drum(hho, eighth);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Snare on 2 and 4
|
|
293
|
+
if (beat == 2 || beat == 6) {
|
|
294
|
+
drum(snare, eighth);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Hip-hop boom bap beat
|
|
301
|
+
export proc boomBap(dur, bars) {
|
|
302
|
+
const sixteenth = dur / 4;
|
|
303
|
+
|
|
304
|
+
for (bar in 0..bars) {
|
|
305
|
+
for (beat in 0..16) {
|
|
306
|
+
// Kick pattern
|
|
307
|
+
if (beat == 0 || beat == 5 || beat == 10) {
|
|
308
|
+
drum(kick, sixteenth);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Snare on 2 and 4
|
|
312
|
+
if (beat == 4 || beat == 12) {
|
|
313
|
+
drum(snare, sixteenth);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Hi-hat
|
|
317
|
+
if (beat % 2 == 0) {
|
|
318
|
+
drum(hhc, sixteenth);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Rest for gaps
|
|
322
|
+
if (beat == 1 || beat == 2 || beat == 3 || beat == 6 || beat == 7 || beat == 8 || beat == 9 || beat == 11 || beat == 13 || beat == 14 || beat == 15) {
|
|
323
|
+
rest(sixteenth);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Trap hi-hat rolls
|
|
330
|
+
export proc trapHiHats(dur, bars) {
|
|
331
|
+
const thirtysecond = dur / 8;
|
|
332
|
+
|
|
333
|
+
for (bar in 0..bars) {
|
|
334
|
+
for (beat in 0..4) {
|
|
335
|
+
// Regular hits with occasional rolls
|
|
336
|
+
if (beat == 2) {
|
|
337
|
+
// Roll on beat 3
|
|
338
|
+
for (i in 0..8) {
|
|
339
|
+
drum(hhc, thirtysecond);
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
for (i in 0..4) {
|
|
343
|
+
drum(hhc, dur / 4);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|