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.
Files changed (335) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +230 -0
  3. package/dist/__tests__/checker.test.d.ts +2 -0
  4. package/dist/__tests__/checker.test.d.ts.map +1 -0
  5. package/dist/__tests__/checker.test.js +316 -0
  6. package/dist/__tests__/checker.test.js.map +1 -0
  7. package/dist/__tests__/compiler.test.d.ts +2 -0
  8. package/dist/__tests__/compiler.test.d.ts.map +1 -0
  9. package/dist/__tests__/compiler.test.js +260 -0
  10. package/dist/__tests__/compiler.test.js.map +1 -0
  11. package/dist/__tests__/generators.test.d.ts +2 -0
  12. package/dist/__tests__/generators.test.d.ts.map +1 -0
  13. package/dist/__tests__/generators.test.js +283 -0
  14. package/dist/__tests__/generators.test.js.map +1 -0
  15. package/dist/__tests__/interpreter.test.d.ts +2 -0
  16. package/dist/__tests__/interpreter.test.d.ts.map +1 -0
  17. package/dist/__tests__/interpreter.test.js +298 -0
  18. package/dist/__tests__/interpreter.test.js.map +1 -0
  19. package/dist/__tests__/lexer.test.d.ts +2 -0
  20. package/dist/__tests__/lexer.test.d.ts.map +1 -0
  21. package/dist/__tests__/lexer.test.js +89 -0
  22. package/dist/__tests__/lexer.test.js.map +1 -0
  23. package/dist/__tests__/parser.test.d.ts +2 -0
  24. package/dist/__tests__/parser.test.d.ts.map +1 -0
  25. package/dist/__tests__/parser.test.js +116 -0
  26. package/dist/__tests__/parser.test.js.map +1 -0
  27. package/dist/checker/checker.d.ts +37 -0
  28. package/dist/checker/checker.d.ts.map +1 -0
  29. package/dist/checker/checker.js +428 -0
  30. package/dist/checker/checker.js.map +1 -0
  31. package/dist/checker/index.d.ts +3 -0
  32. package/dist/checker/index.d.ts.map +1 -0
  33. package/dist/checker/index.js +2 -0
  34. package/dist/checker/index.js.map +1 -0
  35. package/dist/cli/commands/build.d.ts +2 -0
  36. package/dist/cli/commands/build.d.ts.map +1 -0
  37. package/dist/cli/commands/build.js +173 -0
  38. package/dist/cli/commands/build.js.map +1 -0
  39. package/dist/cli/commands/check.d.ts +2 -0
  40. package/dist/cli/commands/check.d.ts.map +1 -0
  41. package/dist/cli/commands/check.js +79 -0
  42. package/dist/cli/commands/check.js.map +1 -0
  43. package/dist/cli/commands/doctor.d.ts +2 -0
  44. package/dist/cli/commands/doctor.d.ts.map +1 -0
  45. package/dist/cli/commands/doctor.js +187 -0
  46. package/dist/cli/commands/doctor.js.map +1 -0
  47. package/dist/cli/commands/fmt.d.ts +2 -0
  48. package/dist/cli/commands/fmt.d.ts.map +1 -0
  49. package/dist/cli/commands/fmt.js +73 -0
  50. package/dist/cli/commands/fmt.js.map +1 -0
  51. package/dist/cli/commands/import.d.ts +2 -0
  52. package/dist/cli/commands/import.d.ts.map +1 -0
  53. package/dist/cli/commands/import.js +99 -0
  54. package/dist/cli/commands/import.js.map +1 -0
  55. package/dist/cli/commands/init.d.ts +2 -0
  56. package/dist/cli/commands/init.d.ts.map +1 -0
  57. package/dist/cli/commands/init.js +514 -0
  58. package/dist/cli/commands/init.js.map +1 -0
  59. package/dist/cli/commands/play.d.ts +2 -0
  60. package/dist/cli/commands/play.d.ts.map +1 -0
  61. package/dist/cli/commands/play.js +216 -0
  62. package/dist/cli/commands/play.js.map +1 -0
  63. package/dist/cli/commands/record.d.ts +2 -0
  64. package/dist/cli/commands/record.d.ts.map +1 -0
  65. package/dist/cli/commands/record.js +393 -0
  66. package/dist/cli/commands/record.js.map +1 -0
  67. package/dist/cli/commands/render.d.ts +2 -0
  68. package/dist/cli/commands/render.d.ts.map +1 -0
  69. package/dist/cli/commands/render.js +278 -0
  70. package/dist/cli/commands/render.js.map +1 -0
  71. package/dist/cli/index.d.ts +3 -0
  72. package/dist/cli/index.d.ts.map +1 -0
  73. package/dist/cli/index.js +93 -0
  74. package/dist/cli/index.js.map +1 -0
  75. package/dist/compiler/compiler.d.ts +12 -0
  76. package/dist/compiler/compiler.d.ts.map +1 -0
  77. package/dist/compiler/compiler.js +146 -0
  78. package/dist/compiler/compiler.js.map +1 -0
  79. package/dist/compiler/index.d.ts +2 -0
  80. package/dist/compiler/index.d.ts.map +1 -0
  81. package/dist/compiler/index.js +2 -0
  82. package/dist/compiler/index.js.map +1 -0
  83. package/dist/config/config.d.ts +43 -0
  84. package/dist/config/config.d.ts.map +1 -0
  85. package/dist/config/config.js +200 -0
  86. package/dist/config/config.js.map +1 -0
  87. package/dist/config/index.d.ts +2 -0
  88. package/dist/config/index.d.ts.map +1 -0
  89. package/dist/config/index.js +2 -0
  90. package/dist/config/index.js.map +1 -0
  91. package/dist/errors.d.ts +49 -0
  92. package/dist/errors.d.ts.map +1 -0
  93. package/dist/errors.js +168 -0
  94. package/dist/errors.js.map +1 -0
  95. package/dist/formatter/formatter.d.ts +13 -0
  96. package/dist/formatter/formatter.d.ts.map +1 -0
  97. package/dist/formatter/formatter.js +242 -0
  98. package/dist/formatter/formatter.js.map +1 -0
  99. package/dist/formatter/index.d.ts +2 -0
  100. package/dist/formatter/index.d.ts.map +1 -0
  101. package/dist/formatter/index.js +2 -0
  102. package/dist/formatter/index.js.map +1 -0
  103. package/dist/generators/index.d.ts +5 -0
  104. package/dist/generators/index.d.ts.map +1 -0
  105. package/dist/generators/index.js +5 -0
  106. package/dist/generators/index.js.map +1 -0
  107. package/dist/generators/midi.d.ts +3 -0
  108. package/dist/generators/midi.d.ts.map +1 -0
  109. package/dist/generators/midi.js +360 -0
  110. package/dist/generators/midi.js.map +1 -0
  111. package/dist/generators/musicxml.d.ts +3 -0
  112. package/dist/generators/musicxml.d.ts.map +1 -0
  113. package/dist/generators/musicxml.js +332 -0
  114. package/dist/generators/musicxml.js.map +1 -0
  115. package/dist/generators/tempo-midi.d.ts +3 -0
  116. package/dist/generators/tempo-midi.d.ts.map +1 -0
  117. package/dist/generators/tempo-midi.js +123 -0
  118. package/dist/generators/tempo-midi.js.map +1 -0
  119. package/dist/generators/vsqx.d.ts +3 -0
  120. package/dist/generators/vsqx.d.ts.map +1 -0
  121. package/dist/generators/vsqx.js +354 -0
  122. package/dist/generators/vsqx.js.map +1 -0
  123. package/dist/importers/index.d.ts +2 -0
  124. package/dist/importers/index.d.ts.map +1 -0
  125. package/dist/importers/index.js +3 -0
  126. package/dist/importers/index.js.map +1 -0
  127. package/dist/importers/musicxml.d.ts +4 -0
  128. package/dist/importers/musicxml.d.ts.map +1 -0
  129. package/dist/importers/musicxml.js +392 -0
  130. package/dist/importers/musicxml.js.map +1 -0
  131. package/dist/index.d.ts +11 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +12 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/interpreter/builtins/algorithmic.d.ts +12 -0
  136. package/dist/interpreter/builtins/algorithmic.d.ts.map +1 -0
  137. package/dist/interpreter/builtins/algorithmic.js +244 -0
  138. package/dist/interpreter/builtins/algorithmic.js.map +1 -0
  139. package/dist/interpreter/builtins/audio.d.ts +10 -0
  140. package/dist/interpreter/builtins/audio.d.ts.map +1 -0
  141. package/dist/interpreter/builtins/audio.js +169 -0
  142. package/dist/interpreter/builtins/audio.js.map +1 -0
  143. package/dist/interpreter/builtins/core.d.ts +15 -0
  144. package/dist/interpreter/builtins/core.d.ts.map +1 -0
  145. package/dist/interpreter/builtins/core.js +265 -0
  146. package/dist/interpreter/builtins/core.js.map +1 -0
  147. package/dist/interpreter/builtins/dynamics.d.ts +8 -0
  148. package/dist/interpreter/builtins/dynamics.d.ts.map +1 -0
  149. package/dist/interpreter/builtins/dynamics.js +86 -0
  150. package/dist/interpreter/builtins/dynamics.js.map +1 -0
  151. package/dist/interpreter/builtins/effects.d.ts +16 -0
  152. package/dist/interpreter/builtins/effects.d.ts.map +1 -0
  153. package/dist/interpreter/builtins/effects.js +220 -0
  154. package/dist/interpreter/builtins/effects.js.map +1 -0
  155. package/dist/interpreter/builtins/index.d.ts +16 -0
  156. package/dist/interpreter/builtins/index.d.ts.map +1 -0
  157. package/dist/interpreter/builtins/index.js +17 -0
  158. package/dist/interpreter/builtins/index.js.map +1 -0
  159. package/dist/interpreter/builtins/layout.d.ts +12 -0
  160. package/dist/interpreter/builtins/layout.d.ts.map +1 -0
  161. package/dist/interpreter/builtins/layout.js +175 -0
  162. package/dist/interpreter/builtins/layout.js.map +1 -0
  163. package/dist/interpreter/builtins/live.d.ts +11 -0
  164. package/dist/interpreter/builtins/live.d.ts.map +1 -0
  165. package/dist/interpreter/builtins/live.js +125 -0
  166. package/dist/interpreter/builtins/live.js.map +1 -0
  167. package/dist/interpreter/builtins/midi.d.ts +16 -0
  168. package/dist/interpreter/builtins/midi.d.ts.map +1 -0
  169. package/dist/interpreter/builtins/midi.js +320 -0
  170. package/dist/interpreter/builtins/midi.js.map +1 -0
  171. package/dist/interpreter/builtins/mixing.d.ts +6 -0
  172. package/dist/interpreter/builtins/mixing.d.ts.map +1 -0
  173. package/dist/interpreter/builtins/mixing.js +62 -0
  174. package/dist/interpreter/builtins/mixing.js.map +1 -0
  175. package/dist/interpreter/builtins/notation.d.ts +24 -0
  176. package/dist/interpreter/builtins/notation.d.ts.map +1 -0
  177. package/dist/interpreter/builtins/notation.js +251 -0
  178. package/dist/interpreter/builtins/notation.js.map +1 -0
  179. package/dist/interpreter/builtins/ornaments.d.ts +8 -0
  180. package/dist/interpreter/builtins/ornaments.d.ts.map +1 -0
  181. package/dist/interpreter/builtins/ornaments.js +155 -0
  182. package/dist/interpreter/builtins/ornaments.js.map +1 -0
  183. package/dist/interpreter/builtins/techniques.d.ts +11 -0
  184. package/dist/interpreter/builtins/techniques.d.ts.map +1 -0
  185. package/dist/interpreter/builtins/techniques.js +234 -0
  186. package/dist/interpreter/builtins/techniques.js.map +1 -0
  187. package/dist/interpreter/builtins/tuning.d.ts +7 -0
  188. package/dist/interpreter/builtins/tuning.d.ts.map +1 -0
  189. package/dist/interpreter/builtins/tuning.js +52 -0
  190. package/dist/interpreter/builtins/tuning.js.map +1 -0
  191. package/dist/interpreter/builtins/types.d.ts +27 -0
  192. package/dist/interpreter/builtins/types.d.ts.map +1 -0
  193. package/dist/interpreter/builtins/types.js +3 -0
  194. package/dist/interpreter/builtins/types.js.map +1 -0
  195. package/dist/interpreter/builtins/vocaloid.d.ts +10 -0
  196. package/dist/interpreter/builtins/vocaloid.d.ts.map +1 -0
  197. package/dist/interpreter/builtins/vocaloid.js +165 -0
  198. package/dist/interpreter/builtins/vocaloid.js.map +1 -0
  199. package/dist/interpreter/index.d.ts +4 -0
  200. package/dist/interpreter/index.d.ts.map +1 -0
  201. package/dist/interpreter/index.js +4 -0
  202. package/dist/interpreter/index.js.map +1 -0
  203. package/dist/interpreter/interpreter.d.ts +305 -0
  204. package/dist/interpreter/interpreter.d.ts.map +1 -0
  205. package/dist/interpreter/interpreter.js +8463 -0
  206. package/dist/interpreter/interpreter.js.map +1 -0
  207. package/dist/interpreter/runtime.d.ts +67 -0
  208. package/dist/interpreter/runtime.d.ts.map +1 -0
  209. package/dist/interpreter/runtime.js +88 -0
  210. package/dist/interpreter/runtime.js.map +1 -0
  211. package/dist/interpreter/scope.d.ts +21 -0
  212. package/dist/interpreter/scope.d.ts.map +1 -0
  213. package/dist/interpreter/scope.js +60 -0
  214. package/dist/interpreter/scope.js.map +1 -0
  215. package/dist/interpreter/trackState.d.ts +205 -0
  216. package/dist/interpreter/trackState.d.ts.map +1 -0
  217. package/dist/interpreter/trackState.js +12 -0
  218. package/dist/interpreter/trackState.js.map +1 -0
  219. package/dist/lexer/index.d.ts +2 -0
  220. package/dist/lexer/index.d.ts.map +1 -0
  221. package/dist/lexer/index.js +2 -0
  222. package/dist/lexer/index.js.map +1 -0
  223. package/dist/lexer/lexer.d.ts +30 -0
  224. package/dist/lexer/lexer.d.ts.map +1 -0
  225. package/dist/lexer/lexer.js +385 -0
  226. package/dist/lexer/lexer.js.map +1 -0
  227. package/dist/parser/index.d.ts +2 -0
  228. package/dist/parser/index.d.ts.map +1 -0
  229. package/dist/parser/index.js +2 -0
  230. package/dist/parser/index.js.map +1 -0
  231. package/dist/parser/parser.d.ts +55 -0
  232. package/dist/parser/parser.d.ts.map +1 -0
  233. package/dist/parser/parser.js +896 -0
  234. package/dist/parser/parser.js.map +1 -0
  235. package/dist/types/ast.d.ts +220 -0
  236. package/dist/types/ast.d.ts.map +1 -0
  237. package/dist/types/ast.js +3 -0
  238. package/dist/types/ast.js.map +1 -0
  239. package/dist/types/index.d.ts +4 -0
  240. package/dist/types/index.d.ts.map +1 -0
  241. package/dist/types/index.js +4 -0
  242. package/dist/types/index.js.map +1 -0
  243. package/dist/types/ir/advanced.d.ts +491 -0
  244. package/dist/types/ir/advanced.d.ts.map +1 -0
  245. package/dist/types/ir/advanced.js +3 -0
  246. package/dist/types/ir/advanced.js.map +1 -0
  247. package/dist/types/ir/algorithmic.d.ts +48 -0
  248. package/dist/types/ir/algorithmic.d.ts.map +1 -0
  249. package/dist/types/ir/algorithmic.js +3 -0
  250. package/dist/types/ir/algorithmic.js.map +1 -0
  251. package/dist/types/ir/analysis.d.ts +34 -0
  252. package/dist/types/ir/analysis.d.ts.map +1 -0
  253. package/dist/types/ir/analysis.js +3 -0
  254. package/dist/types/ir/analysis.js.map +1 -0
  255. package/dist/types/ir/audio.d.ts +249 -0
  256. package/dist/types/ir/audio.d.ts.map +1 -0
  257. package/dist/types/ir/audio.js +3 -0
  258. package/dist/types/ir/audio.js.map +1 -0
  259. package/dist/types/ir/automation.d.ts +46 -0
  260. package/dist/types/ir/automation.d.ts.map +1 -0
  261. package/dist/types/ir/automation.js +3 -0
  262. package/dist/types/ir/automation.js.map +1 -0
  263. package/dist/types/ir/collaboration.d.ts +20 -0
  264. package/dist/types/ir/collaboration.d.ts.map +1 -0
  265. package/dist/types/ir/collaboration.js +3 -0
  266. package/dist/types/ir/collaboration.js.map +1 -0
  267. package/dist/types/ir/core.d.ts +153 -0
  268. package/dist/types/ir/core.d.ts.map +1 -0
  269. package/dist/types/ir/core.js +3 -0
  270. package/dist/types/ir/core.js.map +1 -0
  271. package/dist/types/ir/effects.d.ts +169 -0
  272. package/dist/types/ir/effects.d.ts.map +1 -0
  273. package/dist/types/ir/effects.js +3 -0
  274. package/dist/types/ir/effects.js.map +1 -0
  275. package/dist/types/ir/extended.d.ts +104 -0
  276. package/dist/types/ir/extended.d.ts.map +1 -0
  277. package/dist/types/ir/extended.js +3 -0
  278. package/dist/types/ir/extended.js.map +1 -0
  279. package/dist/types/ir/index.d.ts +16 -0
  280. package/dist/types/ir/index.d.ts.map +1 -0
  281. package/dist/types/ir/index.js +17 -0
  282. package/dist/types/ir/index.js.map +1 -0
  283. package/dist/types/ir/mastering.d.ts +86 -0
  284. package/dist/types/ir/mastering.d.ts.map +1 -0
  285. package/dist/types/ir/mastering.js +3 -0
  286. package/dist/types/ir/mastering.js.map +1 -0
  287. package/dist/types/ir/midi.d.ts +79 -0
  288. package/dist/types/ir/midi.d.ts.map +1 -0
  289. package/dist/types/ir/midi.js +3 -0
  290. package/dist/types/ir/midi.js.map +1 -0
  291. package/dist/types/ir/notation.d.ts +963 -0
  292. package/dist/types/ir/notation.d.ts.map +1 -0
  293. package/dist/types/ir/notation.js +3 -0
  294. package/dist/types/ir/notation.js.map +1 -0
  295. package/dist/types/ir/recording.d.ts +48 -0
  296. package/dist/types/ir/recording.d.ts.map +1 -0
  297. package/dist/types/ir/recording.js +3 -0
  298. package/dist/types/ir/recording.js.map +1 -0
  299. package/dist/types/ir/sampling.d.ts +59 -0
  300. package/dist/types/ir/sampling.d.ts.map +1 -0
  301. package/dist/types/ir/sampling.js +3 -0
  302. package/dist/types/ir/sampling.js.map +1 -0
  303. package/dist/types/ir/sequencing.d.ts +118 -0
  304. package/dist/types/ir/sequencing.d.ts.map +1 -0
  305. package/dist/types/ir/sequencing.js +3 -0
  306. package/dist/types/ir/sequencing.js.map +1 -0
  307. package/dist/types/ir/sync.d.ts +39 -0
  308. package/dist/types/ir/sync.d.ts.map +1 -0
  309. package/dist/types/ir/sync.js +3 -0
  310. package/dist/types/ir/sync.js.map +1 -0
  311. package/dist/types/ir.d.ts +2 -0
  312. package/dist/types/ir.d.ts.map +1 -0
  313. package/dist/types/ir.js +3 -0
  314. package/dist/types/ir.js.map +1 -0
  315. package/dist/types/token.d.ts +72 -0
  316. package/dist/types/token.d.ts.map +1 -0
  317. package/dist/types/token.js +90 -0
  318. package/dist/types/token.js.map +1 -0
  319. package/dist/utils/stdlib.d.ts +18 -0
  320. package/dist/utils/stdlib.d.ts.map +1 -0
  321. package/dist/utils/stdlib.js +51 -0
  322. package/dist/utils/stdlib.js.map +1 -0
  323. package/lib/articulation.mf +46 -0
  324. package/lib/composition.mf +299 -0
  325. package/lib/curves.mf +183 -0
  326. package/lib/dynamics.mf +141 -0
  327. package/lib/expression.mf +221 -0
  328. package/lib/genres.mf +348 -0
  329. package/lib/notation.mf +224 -0
  330. package/lib/ornaments.mf +98 -0
  331. package/lib/patterns.mf +170 -0
  332. package/lib/rhythm.mf +269 -0
  333. package/lib/theory.mf +257 -0
  334. package/lib/utils.mf +140 -0
  335. package/package.json +49 -0
@@ -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
+ }