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,224 @@
1
+ // Notation helpers for TakoMusic
2
+ // Musical notation utilities and conversions
3
+
4
+ import { clip } from "./utils.mf";
5
+
6
+ // Convert dynamic marking to velocity
7
+ export proc dynamicToVel(marking) {
8
+ if (marking == "pppp") { return 16; }
9
+ if (marking == "ppp") { return 33; }
10
+ if (marking == "pp") { return 49; }
11
+ if (marking == "p") { return 64; }
12
+ if (marking == "mp") { return 80; }
13
+ if (marking == "mf") { return 96; }
14
+ if (marking == "f") { return 112; }
15
+ if (marking == "ff") { return 120; }
16
+ if (marking == "fff") { return 124; }
17
+ if (marking == "ffff") { return 127; }
18
+ return 96; // default mf
19
+ }
20
+
21
+ // Convert tempo marking to BPM
22
+ export proc tempoToBpm(marking) {
23
+ if (marking == "grave") { return 40; }
24
+ if (marking == "largo") { return 50; }
25
+ if (marking == "lento") { return 60; }
26
+ if (marking == "adagio") { return 70; }
27
+ if (marking == "andante") { return 90; }
28
+ if (marking == "moderato") { return 110; }
29
+ if (marking == "allegretto") { return 115; }
30
+ if (marking == "allegro") { return 130; }
31
+ if (marking == "vivace") { return 150; }
32
+ if (marking == "presto") { return 180; }
33
+ if (marking == "prestissimo") { return 200; }
34
+ return 120; // default
35
+ }
36
+
37
+ // Play triplet feel
38
+ export proc tripletFeel(notes, baseDur) {
39
+ const longDur = baseDur * 2/3;
40
+ const shortDur = baseDur * 1/3;
41
+
42
+ for (i in 0..len(notes)) {
43
+ if (i % 2 == 0) {
44
+ note(notes[i], longDur);
45
+ } else {
46
+ note(notes[i], shortDur);
47
+ }
48
+ }
49
+ }
50
+
51
+ // Play dotted rhythm
52
+ export proc dottedRhythm(notes, baseDur) {
53
+ const longDur = baseDur * 3/4;
54
+ const shortDur = baseDur * 1/4;
55
+
56
+ for (i in 0..len(notes)) {
57
+ if (i % 2 == 0) {
58
+ note(notes[i], longDur);
59
+ } else {
60
+ note(notes[i], shortDur);
61
+ }
62
+ }
63
+ }
64
+
65
+ // Generate scale in specific octave range
66
+ export proc scaleInRange(scaleFunc, root, octaves) {
67
+ let result = [];
68
+ for (oct in 0..octaves) {
69
+ const octaveRoot = transpose(root, oct * 12);
70
+ const scale = scaleFunc(octaveRoot);
71
+ for (i in 0..len(scale) - 1) {
72
+ push(result, scale[i]);
73
+ }
74
+ }
75
+ return result;
76
+ }
77
+
78
+ // Create melody from scale degrees
79
+ export proc melodyFromDegrees(scale, degrees, dur) {
80
+ for (i in 0..len(degrees)) {
81
+ const degree = degrees[i];
82
+ if (degree == 0) {
83
+ rest(dur);
84
+ } else {
85
+ const idx = (degree - 1) % len(scale);
86
+ const octave = floor((degree - 1) / len(scale));
87
+ const pitch = transpose(scale[idx], octave * 12);
88
+ note(pitch, dur);
89
+ }
90
+ }
91
+ }
92
+
93
+ // Harmonize melody with interval
94
+ export proc harmonize(melody, interval, dur) {
95
+ for (i in 0..len(melody)) {
96
+ const pitches = [melody[i], transpose(melody[i], interval)];
97
+ chord(pitches, dur);
98
+ }
99
+ }
100
+
101
+ // Create countermelody (simple inversion)
102
+ export proc invertMelody(melody, axis) {
103
+ let result = [];
104
+ const axisMidi = pitchMidi(axis);
105
+
106
+ for (i in 0..len(melody)) {
107
+ const pitchMidi = pitchMidi(melody[i]);
108
+ const distance = pitchMidi - axisMidi;
109
+ const inverted = axisMidi - distance;
110
+ push(result, midiPitch(clip(inverted, 0, 127)));
111
+ }
112
+
113
+ return result;
114
+ }
115
+
116
+ // Retrograde (reverse) melody
117
+ export proc retrograde(melody) {
118
+ let result = [];
119
+ for (i in 0..len(melody)) {
120
+ const idx = len(melody) - 1 - i;
121
+ push(result, melody[idx]);
122
+ }
123
+ return result;
124
+ }
125
+
126
+ // Rhythmic augmentation (make durations longer)
127
+ export proc augment(rhythms, factor) {
128
+ let result = [];
129
+ for (i in 0..len(rhythms)) {
130
+ push(result, rhythms[i] * factor);
131
+ }
132
+ return result;
133
+ }
134
+
135
+ // Rhythmic diminution (make durations shorter)
136
+ export proc diminish(rhythms, factor) {
137
+ return augment(rhythms, 1 / factor);
138
+ }
139
+
140
+ // Generate pickup notes (anacrusis)
141
+ export proc pickupNotes(notes, totalDur, noteDur) {
142
+ const pickupDur = len(notes) * noteDur;
143
+ const waitDur = totalDur - pickupDur;
144
+
145
+ if (waitDur > 0) {
146
+ rest(waitDur);
147
+ }
148
+
149
+ for (i in 0..len(notes)) {
150
+ note(notes[i], noteDur);
151
+ }
152
+ }
153
+
154
+ // Bass line from chord progression
155
+ export proc bassLine(chords, dur) {
156
+ for (i in 0..len(chords)) {
157
+ const root = chords[i][0];
158
+ const bassNote = transpose(root, -12);
159
+ note(bassNote, dur);
160
+ }
161
+ }
162
+
163
+ // Walking bass pattern
164
+ export proc walkingBass(chord, nextChord, dur) {
165
+ const root = chord[0];
166
+ const third = chord[1];
167
+ const fifth = chord[2];
168
+ const nextRoot = nextChord[0];
169
+
170
+ // Basic walking pattern: root, third, fifth, approach
171
+ note(transpose(root, -12), dur);
172
+ note(transpose(third, -12), dur);
173
+ note(transpose(fifth, -12), dur);
174
+
175
+ // Approach note (half step below next root)
176
+ const approach = transpose(nextRoot, -13);
177
+ note(approach, dur);
178
+ }
179
+
180
+ // Alberti bass pattern
181
+ export proc albertiBass(chord, repetitions, dur) {
182
+ const pattern = [0, 2, 1, 2]; // root, fifth, third, fifth
183
+
184
+ for (rep in 0..repetitions) {
185
+ for (i in 0..len(pattern)) {
186
+ const idx = pattern[i];
187
+ if (idx < len(chord)) {
188
+ note(transpose(chord[idx], -12), dur);
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ // Convert note name to pitch
195
+ export proc noteNameToPitch(name, octave) {
196
+ let semitone = 0;
197
+
198
+ const noteLetter = charAt(name, 0);
199
+ if (noteLetter == "C") { semitone = 0; }
200
+ if (noteLetter == "D") { semitone = 2; }
201
+ if (noteLetter == "E") { semitone = 4; }
202
+ if (noteLetter == "F") { semitone = 5; }
203
+ if (noteLetter == "G") { semitone = 7; }
204
+ if (noteLetter == "A") { semitone = 9; }
205
+ if (noteLetter == "B") { semitone = 11; }
206
+
207
+ // Check for accidental
208
+ if (len(name) > 1) {
209
+ const accidental = charAt(name, 1);
210
+ if (accidental == "#") { semitone = semitone + 1; }
211
+ if (accidental == "b") { semitone = semitone - 1; }
212
+ }
213
+
214
+ const midiNum = 12 + octave * 12 + semitone;
215
+ return midiPitch(clip(midiNum, 0, 127));
216
+ }
217
+
218
+ // Tuplet helper (generic n-tuplet)
219
+ export proc playTuplet(notes, totalDur, ratio) {
220
+ const noteDur = totalDur / len(notes) * ratio;
221
+ for (i in 0..len(notes)) {
222
+ note(notes[i], noteDur);
223
+ }
224
+ }
@@ -0,0 +1,98 @@
1
+ // Ornament functions for TakoMusic
2
+ // Musical decorations and embellishments
3
+
4
+ // trill - rapid alternation between two adjacent notes
5
+ export proc trill(pitch, dur, interval) {
6
+ const count = 8;
7
+ const subDur = dur / count;
8
+
9
+ for (i in 0..count) {
10
+ if (i % 2 == 0) {
11
+ note(pitch, subDur);
12
+ } else {
13
+ note(transpose(pitch, interval), subDur);
14
+ }
15
+ }
16
+ }
17
+
18
+ // mordent - single alternation with adjacent note
19
+ export proc mordent(pitch, dur, interval) {
20
+ const mainDur = dur * 3/4;
21
+ const ornDur = dur * 1/4;
22
+
23
+ note(transpose(pitch, interval), ornDur);
24
+ note(pitch, mainDur);
25
+ }
26
+
27
+ // arpeggio - play chord notes in sequence
28
+ export proc arpeggio(pitches, dur) {
29
+ const subDur = dur / len(pitches);
30
+ forEach(pitches, (p) => note(p, subDur));
31
+ }
32
+
33
+ // tremolo - rapid repetition of single note
34
+ export proc tremolo(pitch, dur, rate) {
35
+ const count = floor(rate);
36
+ const subDur = dur / count;
37
+
38
+ for (i in 0..count) {
39
+ note(pitch, subDur);
40
+ }
41
+ }
42
+
43
+ // turn - ornamental figure going above and below the main note
44
+ export proc turn(pitch, dur) {
45
+ const subDur = dur / 4;
46
+
47
+ note(transpose(pitch, 2), subDur); // upper neighbor
48
+ note(pitch, subDur); // main note
49
+ note(transpose(pitch, -2), subDur); // lower neighbor
50
+ note(pitch, subDur); // main note
51
+ }
52
+
53
+ // gruppetto - Italian turn
54
+ export proc gruppetto(pitch, dur) {
55
+ const subDur = dur / 5;
56
+
57
+ note(pitch, subDur);
58
+ note(transpose(pitch, 2), subDur);
59
+ note(pitch, subDur);
60
+ note(transpose(pitch, -2), subDur);
61
+ note(pitch, subDur);
62
+ }
63
+
64
+ // appoggiatura - grace note that takes time from main note
65
+ export proc appoggiatura(gracePitch, mainPitch, totalDur) {
66
+ const graceDur = totalDur / 4;
67
+ const mainDur = totalDur * 3/4;
68
+
69
+ note(gracePitch, graceDur);
70
+ note(mainPitch, mainDur);
71
+ }
72
+
73
+ // acciaccatura - very short grace note (crushed note)
74
+ export proc acciaccatura(gracePitch, mainPitch, totalDur) {
75
+ const graceDur = totalDur / 8;
76
+ const mainDur = totalDur * 7/8;
77
+
78
+ note(gracePitch, graceDur);
79
+ note(mainPitch, mainDur);
80
+ }
81
+
82
+ // glissando - slide between two pitches
83
+ export proc glissando(startPitch, endPitch, dur) {
84
+ const startMidi = pitchMidi(startPitch);
85
+ const endMidi = pitchMidi(endPitch);
86
+ const steps = abs(endMidi - startMidi);
87
+ const subDur = dur / (steps + 1);
88
+
89
+ if (startMidi < endMidi) {
90
+ for (i in 0..=steps) {
91
+ note(midiPitch(startMidi + i), subDur);
92
+ }
93
+ } else {
94
+ for (i in 0..=steps) {
95
+ note(midiPitch(startMidi - i), subDur);
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,170 @@
1
+ // Advanced pattern generation for TakoMusic
2
+ // Algorithmic composition and generative music
3
+
4
+ import { choice, shuffle, clip, wrap, rotate } from "./utils.mf";
5
+
6
+ // Random walk melody generator
7
+ export proc randomWalk(startPitch, steps, maxStep) {
8
+ let melody = [];
9
+ let current = startPitch;
10
+
11
+ for (i in 0..steps) {
12
+ push(melody, current);
13
+ const step = random(-maxStep, maxStep + 1);
14
+ current = transpose(current, step);
15
+ current = transpose(C0, clip(pitchMidi(current), 0, 127));
16
+ }
17
+
18
+ return melody;
19
+ }
20
+
21
+ // Pentatonic random walk
22
+ export proc pentatonicWalk(root, steps) {
23
+ const scale = [0, 2, 4, 7, 9, 12];
24
+ let melody = [];
25
+ let idx = 0;
26
+
27
+ for (i in 0..steps) {
28
+ const offset = scale[idx % len(scale)];
29
+ const octave = floor(idx / len(scale));
30
+ push(melody, transpose(root, offset + octave * 12));
31
+
32
+ const step = random(-2, 3);
33
+ idx = clip(idx + step, 0, len(scale) * 3 - 1);
34
+ }
35
+
36
+ return melody;
37
+ }
38
+
39
+ // Fractal melody generator (simple self-similarity)
40
+ export proc fractalMelody(pattern, depth) {
41
+ if (depth == 0) {
42
+ return pattern;
43
+ }
44
+
45
+ let result = [];
46
+ for (i in 0..len(pattern)) {
47
+ const pitch = pattern[i];
48
+ push(result, pitch);
49
+
50
+ // Insert transposed version of pattern at smaller scale
51
+ const subPattern = fractalMelody(pattern, depth - 1);
52
+ for (j in 0..len(subPattern)) {
53
+ push(result, transpose(subPattern[j], 7));
54
+ }
55
+ }
56
+
57
+ return result;
58
+ }
59
+
60
+ // Probability-based rhythm pattern
61
+ export proc probabilityRhythm(steps, probability) {
62
+ let pattern = [];
63
+ for (i in 0..steps) {
64
+ push(pattern, random() < probability);
65
+ }
66
+ return pattern;
67
+ }
68
+
69
+ // Density-based rhythm (gradually increase/decrease density)
70
+ export proc densityRhythm(steps, startProb, endProb) {
71
+ let pattern = [];
72
+ for (i in 0..steps) {
73
+ const t = i / (steps - 1);
74
+ const prob = startProb + (endProb - startProb) * t;
75
+ push(pattern, random() < prob);
76
+ }
77
+ return pattern;
78
+ }
79
+
80
+ // Polyrhythmic pattern generator
81
+ export proc polyrhythm(ratio1, ratio2, cycles) {
82
+ const totalSteps = ratio1 * ratio2;
83
+ let pattern1 = [];
84
+ let pattern2 = [];
85
+
86
+ for (i in 0..totalSteps * cycles) {
87
+ push(pattern1, i % ratio1 == 0);
88
+ push(pattern2, i % ratio2 == 0);
89
+ }
90
+
91
+ return [pattern1, pattern2];
92
+ }
93
+
94
+ // Phasing pattern (Steve Reich style)
95
+ export proc phasePattern(pattern, phaseShift, repetitions) {
96
+ let result = [];
97
+
98
+ for (rep in 0..repetitions) {
99
+ const shift = floor(rep * phaseShift) % len(pattern);
100
+ const rotated = rotate(pattern, shift);
101
+ for (i in 0..len(rotated)) {
102
+ push(result, rotated[i]);
103
+ }
104
+ }
105
+
106
+ return result;
107
+ }
108
+
109
+ // Markov chain melody (simple 2-state)
110
+ export proc markovMelody(notes, transitionProb, length, startIdx) {
111
+ let melody = [];
112
+ let currentIdx = startIdx;
113
+
114
+ for (i in 0..length) {
115
+ push(melody, notes[currentIdx]);
116
+
117
+ // Simple transition: stay or move
118
+ if (random() < transitionProb) {
119
+ currentIdx = (currentIdx + 1) % len(notes);
120
+ }
121
+ }
122
+
123
+ return melody;
124
+ }
125
+
126
+ // Arpeggiate chord with pattern
127
+ export proc arpeggiate(chord, pattern, dur) {
128
+ for (i in 0..len(pattern)) {
129
+ const idx = pattern[i];
130
+ if (idx >= 0 && idx < len(chord)) {
131
+ note(chord[idx], dur);
132
+ } else {
133
+ rest(dur);
134
+ }
135
+ }
136
+ }
137
+
138
+ // Generate arpeggio pattern (up, down, up-down, random)
139
+ export proc arpeggioPattern(chordSize, style, length) {
140
+ let pattern = [];
141
+
142
+ for (i in 0..length) {
143
+ let idx = 0;
144
+
145
+ if (style == "up") {
146
+ idx = i % chordSize;
147
+ } else {
148
+ if (style == "down") {
149
+ idx = chordSize - 1 - (i % chordSize);
150
+ } else {
151
+ if (style == "updown") {
152
+ const cycle = chordSize * 2 - 2;
153
+ const pos = i % cycle;
154
+ if (pos < chordSize) {
155
+ idx = pos;
156
+ } else {
157
+ idx = chordSize - 2 - (pos - chordSize);
158
+ }
159
+ } else {
160
+ // random
161
+ idx = random(chordSize);
162
+ }
163
+ }
164
+ }
165
+
166
+ push(pattern, idx);
167
+ }
168
+
169
+ return pattern;
170
+ }