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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Standard library path resolution
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = path.dirname(__filename);
|
|
6
|
+
// Package root (where lib/ is located)
|
|
7
|
+
const packageRoot = path.resolve(__dirname, '..', '..');
|
|
8
|
+
// Available standard library modules
|
|
9
|
+
export const STDLIB_MODULES = [
|
|
10
|
+
'theory',
|
|
11
|
+
'patterns',
|
|
12
|
+
'rhythm',
|
|
13
|
+
'dynamics',
|
|
14
|
+
'expression',
|
|
15
|
+
'articulation',
|
|
16
|
+
'ornaments',
|
|
17
|
+
'notation',
|
|
18
|
+
'genres',
|
|
19
|
+
'composition',
|
|
20
|
+
'curves',
|
|
21
|
+
'utils',
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Check if an import path is a standard library import
|
|
25
|
+
* @param importPath The import path (e.g., "std:theory" or "./local.mf")
|
|
26
|
+
*/
|
|
27
|
+
export function isStdlibImport(importPath) {
|
|
28
|
+
return importPath.startsWith('std:');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a standard library import to its file path
|
|
32
|
+
* @param importPath The import path (e.g., "std:theory")
|
|
33
|
+
* @returns The absolute path to the stdlib module file
|
|
34
|
+
*/
|
|
35
|
+
export function resolveStdlibPath(importPath) {
|
|
36
|
+
if (!isStdlibImport(importPath)) {
|
|
37
|
+
throw new Error(`Not a stdlib import: ${importPath}`);
|
|
38
|
+
}
|
|
39
|
+
const moduleName = importPath.slice(4); // Remove "std:" prefix
|
|
40
|
+
if (!STDLIB_MODULES.includes(moduleName)) {
|
|
41
|
+
throw new Error(`Unknown stdlib module: ${moduleName}. Available: ${STDLIB_MODULES.join(', ')}`);
|
|
42
|
+
}
|
|
43
|
+
return path.join(packageRoot, 'lib', `${moduleName}.mf`);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the standard library directory path
|
|
47
|
+
*/
|
|
48
|
+
export function getStdlibDir() {
|
|
49
|
+
return path.join(packageRoot, 'lib');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stdlib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdlib.js","sourceRoot":"","sources":["../../src/utils/stdlib.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,uCAAuC;AACvC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAExD,qCAAqC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,cAAc;IACd,WAAW;IACX,UAAU;IACV,QAAQ;IACR,aAAa;IACb,QAAQ;IACR,OAAO;CACC,CAAC;AAIX;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,OAAO,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;IAE/D,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,UAA0B,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,gBAAgB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,UAAU,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Articulation functions for TakoMusic
|
|
2
|
+
// These can be imported and used instead of built-in articulation functions
|
|
3
|
+
|
|
4
|
+
// staccato - play note shorter and slightly accented
|
|
5
|
+
export proc staccato(pitch, dur, vel) {
|
|
6
|
+
const actualVel = vel + 10;
|
|
7
|
+
const actualDur = dur / 2;
|
|
8
|
+
note(pitch, actualDur, actualVel);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// legato - play note with full duration, slightly softer
|
|
12
|
+
export proc legato(pitch, dur, vel) {
|
|
13
|
+
const actualVel = vel - 5;
|
|
14
|
+
note(pitch, dur, actualVel);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// accent - play note with increased velocity
|
|
18
|
+
export proc accent(pitch, dur, vel) {
|
|
19
|
+
const actualVel = vel + 20;
|
|
20
|
+
note(pitch, dur, actualVel);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// tenuto - play note with full duration and slight emphasis
|
|
24
|
+
export proc tenuto(pitch, dur, vel) {
|
|
25
|
+
const actualVel = vel + 8;
|
|
26
|
+
note(pitch, dur, actualVel);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// marcato - play note with strong accent
|
|
30
|
+
export proc marcato(pitch, dur, vel) {
|
|
31
|
+
const actualVel = vel + 30;
|
|
32
|
+
const actualDur = dur * 3/4;
|
|
33
|
+
note(pitch, actualDur, actualVel);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// portato - detached but with some weight (between staccato and legato)
|
|
37
|
+
export proc portato(pitch, dur, vel) {
|
|
38
|
+
const actualDur = dur * 3/4;
|
|
39
|
+
note(pitch, actualDur, vel);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// sforzando - sudden strong accent
|
|
43
|
+
export proc sforzando(pitch, dur, vel) {
|
|
44
|
+
const actualVel = min(127, vel + 40);
|
|
45
|
+
note(pitch, dur, actualVel);
|
|
46
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// Composition techniques for TakoMusic
|
|
2
|
+
// Melodic and structural transformations
|
|
3
|
+
|
|
4
|
+
import { clip } from "./utils.mf";
|
|
5
|
+
|
|
6
|
+
// Melodic sequence - transpose pattern by intervals
|
|
7
|
+
export proc sequence(melody, intervals, dur) {
|
|
8
|
+
// Play original
|
|
9
|
+
for (i in 0..len(melody)) {
|
|
10
|
+
note(melody[i], dur);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Play transposed versions
|
|
14
|
+
for (j in 0..len(intervals)) {
|
|
15
|
+
for (i in 0..len(melody)) {
|
|
16
|
+
note(transpose(melody[i], intervals[j]), dur);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Sequence with individual durations
|
|
22
|
+
export proc sequenceWithDurs(melody, durs, intervals) {
|
|
23
|
+
// Play original
|
|
24
|
+
for (i in 0..len(melody)) {
|
|
25
|
+
note(melody[i], durs[i]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Play transposed versions
|
|
29
|
+
for (j in 0..len(intervals)) {
|
|
30
|
+
for (i in 0..len(melody)) {
|
|
31
|
+
note(transpose(melody[i], intervals[j]), durs[i]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Call and response pattern
|
|
37
|
+
export proc callResponse(call, response, callDur, responseDur, gap) {
|
|
38
|
+
// Call
|
|
39
|
+
for (i in 0..len(call)) {
|
|
40
|
+
note(call[i], callDur);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Gap
|
|
44
|
+
rest(gap);
|
|
45
|
+
|
|
46
|
+
// Response
|
|
47
|
+
for (i in 0..len(response)) {
|
|
48
|
+
note(response[i], responseDur);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Call and response with automatic response generation (echo)
|
|
53
|
+
export proc callEcho(call, callDur, interval, gap) {
|
|
54
|
+
// Call
|
|
55
|
+
for (i in 0..len(call)) {
|
|
56
|
+
note(call[i], callDur);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Gap
|
|
60
|
+
rest(gap);
|
|
61
|
+
|
|
62
|
+
// Echo (transposed and softer)
|
|
63
|
+
for (i in 0..len(call)) {
|
|
64
|
+
note(transpose(call[i], interval), callDur, 70);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Ostinato - repeating pattern
|
|
69
|
+
export proc ostinato(pattern, dur, repetitions) {
|
|
70
|
+
for (rep in 0..repetitions) {
|
|
71
|
+
for (i in 0..len(pattern)) {
|
|
72
|
+
note(pattern[i], dur);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Ostinato with individual durations
|
|
78
|
+
export proc ostinatoWithDurs(pattern, durs, repetitions) {
|
|
79
|
+
for (rep in 0..repetitions) {
|
|
80
|
+
for (i in 0..len(pattern)) {
|
|
81
|
+
note(pattern[i], durs[i]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Canon - same melody with delayed entries
|
|
87
|
+
// Returns the total duration for synchronization
|
|
88
|
+
export proc canonMelody(melody, dur, delayBeats) {
|
|
89
|
+
for (i in 0..len(melody)) {
|
|
90
|
+
note(melody[i], dur);
|
|
91
|
+
}
|
|
92
|
+
return len(melody) * dur;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Helper to create canon entry point
|
|
96
|
+
export proc canonEntry(melody, dur, entryNumber, delayBeats) {
|
|
97
|
+
// Wait for entry
|
|
98
|
+
rest(delayBeats * entryNumber);
|
|
99
|
+
|
|
100
|
+
// Play melody
|
|
101
|
+
for (i in 0..len(melody)) {
|
|
102
|
+
note(melody[i], dur);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Imitation - similar to canon but with transformation
|
|
107
|
+
export proc imitation(melody, dur, interval, invert) {
|
|
108
|
+
for (i in 0..len(melody)) {
|
|
109
|
+
let pitch = melody[i];
|
|
110
|
+
|
|
111
|
+
if (invert) {
|
|
112
|
+
// Invert around first note
|
|
113
|
+
const axis = melody[0];
|
|
114
|
+
const axisMidi = pitchMidi(axis);
|
|
115
|
+
const noteMidi = pitchMidi(pitch);
|
|
116
|
+
const inverted = axisMidi - (noteMidi - axisMidi);
|
|
117
|
+
pitch = midiPitch(clip(inverted, 0, 127));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
note(transpose(pitch, interval), dur);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Theme and variation - apply transformation to theme
|
|
125
|
+
export proc variation(theme, dur, variationType) {
|
|
126
|
+
if (variationType == "original") {
|
|
127
|
+
for (i in 0..len(theme)) {
|
|
128
|
+
note(theme[i], dur);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (variationType == "octave") {
|
|
133
|
+
for (i in 0..len(theme)) {
|
|
134
|
+
note(transpose(theme[i], 12), dur);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (variationType == "retrograde") {
|
|
139
|
+
for (i in 0..len(theme)) {
|
|
140
|
+
const idx = len(theme) - 1 - i;
|
|
141
|
+
note(theme[idx], dur);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (variationType == "augment") {
|
|
146
|
+
for (i in 0..len(theme)) {
|
|
147
|
+
note(theme[i], dur * 2);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (variationType == "diminish") {
|
|
152
|
+
for (i in 0..len(theme)) {
|
|
153
|
+
note(theme[i], dur / 2);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (variationType == "invert") {
|
|
158
|
+
const axis = theme[0];
|
|
159
|
+
const axisMidi = pitchMidi(axis);
|
|
160
|
+
|
|
161
|
+
for (i in 0..len(theme)) {
|
|
162
|
+
const noteMidi = pitchMidi(theme[i]);
|
|
163
|
+
const inverted = axisMidi - (noteMidi - axisMidi);
|
|
164
|
+
note(midiPitch(clip(inverted, 0, 127)), dur);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Hocket - alternating notes between voices (returns patterns)
|
|
170
|
+
export proc hocket(melody) {
|
|
171
|
+
let voice1 = [];
|
|
172
|
+
let voice2 = [];
|
|
173
|
+
|
|
174
|
+
for (i in 0..len(melody)) {
|
|
175
|
+
if (i % 2 == 0) {
|
|
176
|
+
push(voice1, melody[i]);
|
|
177
|
+
push(voice2, 0); // 0 = rest
|
|
178
|
+
} else {
|
|
179
|
+
push(voice1, 0);
|
|
180
|
+
push(voice2, melody[i]);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return [voice1, voice2];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Play hocket pattern (0 = rest)
|
|
188
|
+
export proc playHocket(pattern, dur) {
|
|
189
|
+
for (i in 0..len(pattern)) {
|
|
190
|
+
if (pattern[i] == 0) {
|
|
191
|
+
rest(dur);
|
|
192
|
+
} else {
|
|
193
|
+
note(pattern[i], dur);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Stretto - overlapping entries
|
|
199
|
+
export proc strettoEntry(melody, dur, entryOffset) {
|
|
200
|
+
rest(entryOffset);
|
|
201
|
+
for (i in 0..len(melody)) {
|
|
202
|
+
note(melody[i], dur);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Pedal point - sustained bass note under changing harmony
|
|
207
|
+
export proc pedalPoint(pitch, dur, repetitions) {
|
|
208
|
+
for (i in 0..repetitions) {
|
|
209
|
+
note(pitch, dur);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Drone - continuous sustained notes
|
|
214
|
+
export proc drone(pitches, dur) {
|
|
215
|
+
chord(pitches, dur);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Arpeggio patterns for accompaniment
|
|
219
|
+
export proc albertiPattern(chordPitches, dur, repetitions) {
|
|
220
|
+
const pattern = [0, 2, 1, 2]; // Alberti bass pattern
|
|
221
|
+
|
|
222
|
+
for (rep in 0..repetitions) {
|
|
223
|
+
for (i in 0..len(pattern)) {
|
|
224
|
+
const idx = pattern[i];
|
|
225
|
+
if (idx < len(chordPitches)) {
|
|
226
|
+
note(chordPitches[idx], dur);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Broken chord ascending
|
|
233
|
+
export proc brokenChordUp(chordPitches, dur) {
|
|
234
|
+
for (i in 0..len(chordPitches)) {
|
|
235
|
+
note(chordPitches[i], dur);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Broken chord descending
|
|
240
|
+
export proc brokenChordDown(chordPitches, dur) {
|
|
241
|
+
for (i in 0..len(chordPitches)) {
|
|
242
|
+
const idx = len(chordPitches) - 1 - i;
|
|
243
|
+
note(chordPitches[idx], dur);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Antiphonal - alternating between two groups
|
|
248
|
+
export proc antiphonal(group1, group2, dur, exchanges) {
|
|
249
|
+
for (ex in 0..exchanges) {
|
|
250
|
+
// Group 1
|
|
251
|
+
for (i in 0..len(group1)) {
|
|
252
|
+
note(group1[i], dur);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Group 2
|
|
256
|
+
for (i in 0..len(group2)) {
|
|
257
|
+
note(group2[i], dur);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Motivic development - fragment and develop
|
|
263
|
+
export proc motifFragment(melody, startIdx, endIdx, dur) {
|
|
264
|
+
for (i in startIdx..endIdx) {
|
|
265
|
+
if (i < len(melody)) {
|
|
266
|
+
note(melody[i], dur);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Extend motif by repetition with variation
|
|
272
|
+
export proc motifExtend(motif, dur, extensions) {
|
|
273
|
+
// Original
|
|
274
|
+
for (i in 0..len(motif)) {
|
|
275
|
+
note(motif[i], dur);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Extended with last note repeated
|
|
279
|
+
for (ext in 0..extensions) {
|
|
280
|
+
note(motif[len(motif) - 1], dur);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Rhythmic displacement - shift pattern by offset
|
|
285
|
+
export proc displace(melody, dur, offsetDur) {
|
|
286
|
+
rest(offsetDur);
|
|
287
|
+
for (i in 0..len(melody)) {
|
|
288
|
+
note(melody[i], dur);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Polymelody helper - returns starting position
|
|
293
|
+
export proc layerMelody(melody, dur, startOffset) {
|
|
294
|
+
rest(startOffset);
|
|
295
|
+
for (i in 0..len(melody)) {
|
|
296
|
+
note(melody[i], dur);
|
|
297
|
+
}
|
|
298
|
+
return startOffset + len(melody) * dur;
|
|
299
|
+
}
|
package/lib/curves.mf
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Curve and interpolation functions for TakoMusic
|
|
2
|
+
// Generate smooth transitions and automation curves
|
|
3
|
+
|
|
4
|
+
import { lerp, clip } from "./utils.mf";
|
|
5
|
+
|
|
6
|
+
// Linear curve from start to end
|
|
7
|
+
export proc linearCurve(startVal, endVal, steps) {
|
|
8
|
+
let curve = [];
|
|
9
|
+
for (i in 0..=steps) {
|
|
10
|
+
const t = i / steps;
|
|
11
|
+
push(curve, lerp(startVal, endVal, t));
|
|
12
|
+
}
|
|
13
|
+
return curve;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Quadratic ease-in curve (starts slow, ends fast)
|
|
17
|
+
export proc easeInQuad(startVal, endVal, steps) {
|
|
18
|
+
let curve = [];
|
|
19
|
+
for (i in 0..=steps) {
|
|
20
|
+
const t = i / steps;
|
|
21
|
+
const eased = t * t;
|
|
22
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
23
|
+
}
|
|
24
|
+
return curve;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Quadratic ease-out curve (starts fast, ends slow)
|
|
28
|
+
export proc easeOutQuad(startVal, endVal, steps) {
|
|
29
|
+
let curve = [];
|
|
30
|
+
for (i in 0..=steps) {
|
|
31
|
+
const t = i / steps;
|
|
32
|
+
const eased = t * (2 - t);
|
|
33
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
34
|
+
}
|
|
35
|
+
return curve;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Quadratic ease-in-out curve (slow-fast-slow)
|
|
39
|
+
export proc easeInOutQuad(startVal, endVal, steps) {
|
|
40
|
+
let curve = [];
|
|
41
|
+
for (i in 0..=steps) {
|
|
42
|
+
const t = i / steps;
|
|
43
|
+
let eased = 0.0;
|
|
44
|
+
if (t < 0.5) {
|
|
45
|
+
eased = 2 * t * t;
|
|
46
|
+
} else {
|
|
47
|
+
eased = 1 - 2 * (1 - t) * (1 - t);
|
|
48
|
+
}
|
|
49
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
50
|
+
}
|
|
51
|
+
return curve;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Cubic ease-in curve
|
|
55
|
+
export proc easeInCubic(startVal, endVal, steps) {
|
|
56
|
+
let curve = [];
|
|
57
|
+
for (i in 0..=steps) {
|
|
58
|
+
const t = i / steps;
|
|
59
|
+
const eased = t * t * t;
|
|
60
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
61
|
+
}
|
|
62
|
+
return curve;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Cubic ease-out curve
|
|
66
|
+
export proc easeOutCubic(startVal, endVal, steps) {
|
|
67
|
+
let curve = [];
|
|
68
|
+
for (i in 0..=steps) {
|
|
69
|
+
const t = i / steps;
|
|
70
|
+
const t1 = t - 1;
|
|
71
|
+
const eased = t1 * t1 * t1 + 1;
|
|
72
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
73
|
+
}
|
|
74
|
+
return curve;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// S-curve (smooth step)
|
|
78
|
+
export proc smoothstep(startVal, endVal, steps) {
|
|
79
|
+
let curve = [];
|
|
80
|
+
for (i in 0..=steps) {
|
|
81
|
+
const t = i / steps;
|
|
82
|
+
const eased = t * t * (3 - 2 * t);
|
|
83
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
84
|
+
}
|
|
85
|
+
return curve;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Exponential curve approximation (for positive exponents)
|
|
89
|
+
export proc exponentialCurve(startVal, endVal, steps, exponent) {
|
|
90
|
+
let curve = [];
|
|
91
|
+
for (i in 0..=steps) {
|
|
92
|
+
const t = i / steps;
|
|
93
|
+
let eased = t;
|
|
94
|
+
|
|
95
|
+
// Approximate power function for common exponents
|
|
96
|
+
if (exponent == 2) {
|
|
97
|
+
eased = t * t;
|
|
98
|
+
} else {
|
|
99
|
+
if (exponent == 3) {
|
|
100
|
+
eased = t * t * t;
|
|
101
|
+
} else {
|
|
102
|
+
if (exponent == 4) {
|
|
103
|
+
eased = t * t * t * t;
|
|
104
|
+
} else {
|
|
105
|
+
// For other exponents, use repeated multiplication
|
|
106
|
+
eased = 1.0;
|
|
107
|
+
for (j in 0..floor(exponent)) {
|
|
108
|
+
eased = eased * t;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
push(curve, lerp(startVal, endVal, eased));
|
|
115
|
+
}
|
|
116
|
+
return curve;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Apply curve to MIDI CC automation
|
|
120
|
+
export proc applyCurveToCC(ccNum, curve, startTick, endTick) {
|
|
121
|
+
const steps = len(curve);
|
|
122
|
+
const tickRange = endTick - startTick;
|
|
123
|
+
|
|
124
|
+
for (i in 0..steps) {
|
|
125
|
+
const tick = startTick + floor(tickRange * i / (steps - 1));
|
|
126
|
+
const value = clip(floor(curve[i]), 0, 127);
|
|
127
|
+
atTick(tick);
|
|
128
|
+
cc(ccNum, value);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Tempo curve automation
|
|
133
|
+
export proc tempoCurveLinear(startTempo, endTempo, dur) {
|
|
134
|
+
const ticks = durToTicks(dur);
|
|
135
|
+
const steps = 32;
|
|
136
|
+
const curve = linearCurve(startTempo, endTempo, steps);
|
|
137
|
+
|
|
138
|
+
for (i in 0..len(curve)) {
|
|
139
|
+
const tick = floor(ticks * i / (len(curve) - 1));
|
|
140
|
+
atTick(tick);
|
|
141
|
+
tempo(floor(curve[i]));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Expression (dynamics) curve
|
|
146
|
+
export proc expressionCurveSmooth(startVal, endVal, dur) {
|
|
147
|
+
const ticks = durToTicks(dur);
|
|
148
|
+
const steps = 16;
|
|
149
|
+
const curve = smoothstep(startVal, endVal, steps);
|
|
150
|
+
|
|
151
|
+
applyCurveToCC(11, curve, 0, ticks);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Volume fade
|
|
155
|
+
export proc volumeFade(startVol, endVol, dur) {
|
|
156
|
+
const ticks = durToTicks(dur);
|
|
157
|
+
const steps = 16;
|
|
158
|
+
const curve = linearCurve(startVol, endVol, steps);
|
|
159
|
+
|
|
160
|
+
applyCurveToCC(7, curve, 0, ticks);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Pan sweep
|
|
164
|
+
export proc panSweep(startPan, endPan, dur) {
|
|
165
|
+
const ticks = durToTicks(dur);
|
|
166
|
+
const steps = 16;
|
|
167
|
+
const curve = linearCurve(startPan, endPan, steps);
|
|
168
|
+
|
|
169
|
+
applyCurveToCC(10, curve, 0, ticks);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Pitch bend curve (smooth glissando)
|
|
173
|
+
export proc pitchBendCurveSmooth(startBend, endBend, dur) {
|
|
174
|
+
const ticks = durToTicks(dur);
|
|
175
|
+
const steps = 32;
|
|
176
|
+
const curve = smoothstep(startBend, endBend, steps);
|
|
177
|
+
|
|
178
|
+
for (i in 0..len(curve)) {
|
|
179
|
+
const tick = floor(ticks * i / (len(curve) - 1));
|
|
180
|
+
atTick(tick);
|
|
181
|
+
pitchBend(floor(curve[i]));
|
|
182
|
+
}
|
|
183
|
+
}
|