@devaloop/devalang 0.0.1-beta.2 → 0.1.1

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 (329) hide show
  1. package/README.md +177 -146
  2. package/out-tsc/api.d.ts +180 -0
  3. package/out-tsc/api.d.ts.map +1 -0
  4. package/out-tsc/api.js +286 -0
  5. package/out-tsc/api.js.map +1 -0
  6. package/out-tsc/bin/index.d.ts +12 -0
  7. package/out-tsc/bin/index.d.ts.map +1 -0
  8. package/out-tsc/bin/index.js +20 -54
  9. package/out-tsc/bin/index.js.map +1 -0
  10. package/out-tsc/examples/basic-usage.d.ts +8 -0
  11. package/out-tsc/examples/basic-usage.d.ts.map +1 -0
  12. package/out-tsc/examples/basic-usage.js +113 -0
  13. package/out-tsc/examples/basic-usage.js.map +1 -0
  14. package/out-tsc/index.d.ts +19 -5
  15. package/out-tsc/index.d.ts.map +1 -0
  16. package/out-tsc/index.js +24 -6
  17. package/out-tsc/index.js.map +1 -0
  18. package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
  19. package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
  20. package/out-tsc/scripts/copy-wasm-dts.js +36 -32
  21. package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
  22. package/out-tsc/scripts/postinstall.d.ts +1 -0
  23. package/out-tsc/scripts/postinstall.d.ts.map +1 -0
  24. package/out-tsc/scripts/postinstall.js +4 -1
  25. package/out-tsc/scripts/postinstall.js.map +1 -0
  26. package/out-tsc/scripts/version/bump.d.ts +5 -1
  27. package/out-tsc/scripts/version/bump.d.ts.map +1 -0
  28. package/out-tsc/scripts/version/bump.js +114 -44
  29. package/out-tsc/scripts/version/bump.js.map +1 -0
  30. package/out-tsc/scripts/version/fetch.d.ts +12 -1
  31. package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
  32. package/out-tsc/scripts/version/fetch.js +68 -24
  33. package/out-tsc/scripts/version/fetch.js.map +1 -0
  34. package/out-tsc/scripts/version/index.d.ts +6 -0
  35. package/out-tsc/scripts/version/index.d.ts.map +1 -0
  36. package/out-tsc/scripts/version/index.js +44 -22
  37. package/out-tsc/scripts/version/index.js.map +1 -0
  38. package/out-tsc/scripts/version/sync.d.ts +5 -1
  39. package/out-tsc/scripts/version/sync.d.ts.map +1 -0
  40. package/out-tsc/scripts/version/sync.js +78 -29
  41. package/out-tsc/scripts/version/sync.js.map +1 -0
  42. package/out-tsc/types.d.ts +68 -0
  43. package/out-tsc/types.d.ts.map +1 -0
  44. package/out-tsc/{core/types/value.js → types.js} +4 -0
  45. package/out-tsc/types.js.map +1 -0
  46. package/out-tsc/wasm.d.ts +8 -0
  47. package/out-tsc/wasm.d.ts.map +1 -0
  48. package/out-tsc/{core/index.js → wasm.js} +9 -6
  49. package/out-tsc/wasm.js.map +1 -0
  50. package/package.json +50 -37
  51. package/.cargo/config.toml +0 -2
  52. package/.devalang +0 -9
  53. package/.github/workflows/ci.yml +0 -103
  54. package/Cargo.toml +0 -81
  55. package/docs/CHANGELOG.md +0 -581
  56. package/docs/CONTRIBUTING.md +0 -101
  57. package/docs/ROADMAP.md +0 -38
  58. package/docs/TODO.md +0 -71
  59. package/examples/automation.deva +0 -42
  60. package/examples/bank.deva +0 -7
  61. package/examples/bus.deva +0 -10
  62. package/examples/condition.deva +0 -20
  63. package/examples/duration.deva +0 -9
  64. package/examples/effect.deva +0 -2
  65. package/examples/events.deva +0 -12
  66. package/examples/filter.deva +0 -11
  67. package/examples/function.deva +0 -15
  68. package/examples/group.deva +0 -12
  69. package/examples/index.deva +0 -63
  70. package/examples/lfo.deva +0 -9
  71. package/examples/loop.deva +0 -10
  72. package/examples/pattern.deva +0 -8
  73. package/examples/plugin.deva +0 -16
  74. package/examples/samples/hat-808.wav +0 -0
  75. package/examples/samples/kick-808.wav +0 -0
  76. package/examples/synth.deva +0 -24
  77. package/examples/synth_types.deva +0 -17
  78. package/examples/variables.deva +0 -9
  79. package/out-tsc/core/functions/index.d.ts +0 -42
  80. package/out-tsc/core/functions/index.js +0 -87
  81. package/out-tsc/core/index.d.ts +0 -6
  82. package/out-tsc/core/types/index.d.ts +0 -4
  83. package/out-tsc/core/types/index.js +0 -20
  84. package/out-tsc/core/types/plugin.d.ts +0 -18
  85. package/out-tsc/core/types/plugin.js +0 -2
  86. package/out-tsc/core/types/result.d.ts +0 -27
  87. package/out-tsc/core/types/result.js +0 -2
  88. package/out-tsc/core/types/statement.d.ts +0 -106
  89. package/out-tsc/core/types/statement.js +0 -2
  90. package/out-tsc/core/types/value.d.ts +0 -43
  91. package/out-tsc/pkg/devalang_core.d.ts +0 -15
  92. package/out-tsc/pkg/devalang_core.js +0 -65
  93. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
  94. package/project-version.json +0 -6
  95. package/rust/cli/bank/api.rs +0 -122
  96. package/rust/cli/bank/commands.rs +0 -306
  97. package/rust/cli/bank/mod.rs +0 -29
  98. package/rust/cli/build/commands.rs +0 -153
  99. package/rust/cli/build/mod.rs +0 -2
  100. package/rust/cli/build/process.rs +0 -165
  101. package/rust/cli/check/mod.rs +0 -208
  102. package/rust/cli/discover/commands.rs +0 -253
  103. package/rust/cli/discover/config.rs +0 -111
  104. package/rust/cli/discover/fs.rs +0 -19
  105. package/rust/cli/discover/install.rs +0 -103
  106. package/rust/cli/discover/metadata.rs +0 -48
  107. package/rust/cli/discover/mod.rs +0 -5
  108. package/rust/cli/init/commands.rs +0 -88
  109. package/rust/cli/init/mod.rs +0 -1
  110. package/rust/cli/install/addon.rs +0 -118
  111. package/rust/cli/install/bank.rs +0 -72
  112. package/rust/cli/install/commands.rs +0 -35
  113. package/rust/cli/install/mod.rs +0 -4
  114. package/rust/cli/install/plugin.rs +0 -80
  115. package/rust/cli/login/commands.rs +0 -124
  116. package/rust/cli/login/mod.rs +0 -1
  117. package/rust/cli/mod.rs +0 -12
  118. package/rust/cli/parser.rs +0 -359
  119. package/rust/cli/play/commands.rs +0 -375
  120. package/rust/cli/play/io.rs +0 -17
  121. package/rust/cli/play/mod.rs +0 -5
  122. package/rust/cli/play/process.rs +0 -159
  123. package/rust/cli/play/realtime.rs +0 -91
  124. package/rust/cli/play/utils.rs +0 -23
  125. package/rust/cli/telemetry/commands.rs +0 -22
  126. package/rust/cli/telemetry/event_creator.rs +0 -80
  127. package/rust/cli/telemetry/mod.rs +0 -3
  128. package/rust/cli/telemetry/send.rs +0 -51
  129. package/rust/cli/template/commands.rs +0 -69
  130. package/rust/cli/template/mod.rs +0 -1
  131. package/rust/cli/update/commands.rs +0 -6
  132. package/rust/cli/update/mod.rs +0 -1
  133. package/rust/config/driver.rs +0 -112
  134. package/rust/config/mod.rs +0 -3
  135. package/rust/config/ops.rs +0 -26
  136. package/rust/config/settings.rs +0 -101
  137. package/rust/core/audio/engine/driver.rs +0 -220
  138. package/rust/core/audio/engine/export.rs +0 -169
  139. package/rust/core/audio/engine/helpers.rs +0 -178
  140. package/rust/core/audio/engine/mod.rs +0 -56
  141. package/rust/core/audio/engine/notes/dsp.rs +0 -85
  142. package/rust/core/audio/engine/notes/mod.rs +0 -44
  143. package/rust/core/audio/engine/notes/params.rs +0 -294
  144. package/rust/core/audio/engine/sample/insert.rs +0 -199
  145. package/rust/core/audio/engine/sample/mod.rs +0 -40
  146. package/rust/core/audio/engine/sample/padding.rs +0 -170
  147. package/rust/core/audio/evaluator/condition.rs +0 -61
  148. package/rust/core/audio/evaluator/mod.rs +0 -9
  149. package/rust/core/audio/evaluator/numeric.rs +0 -152
  150. package/rust/core/audio/evaluator/rhs.rs +0 -16
  151. package/rust/core/audio/evaluator/string_expr.rs +0 -94
  152. package/rust/core/audio/interpreter/driver.rs +0 -574
  153. package/rust/core/audio/interpreter/mod.rs +0 -2
  154. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -175
  155. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -384
  156. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -2
  157. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -316
  158. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
  159. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
  160. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
  161. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
  162. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
  163. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
  164. package/rust/core/audio/interpreter/statements/automate.rs +0 -16
  165. package/rust/core/audio/interpreter/statements/call.rs +0 -295
  166. package/rust/core/audio/interpreter/statements/condition.rs +0 -72
  167. package/rust/core/audio/interpreter/statements/function.rs +0 -24
  168. package/rust/core/audio/interpreter/statements/let_.rs +0 -36
  169. package/rust/core/audio/interpreter/statements/load.rs +0 -17
  170. package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
  171. package/rust/core/audio/interpreter/statements/mod.rs +0 -12
  172. package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
  173. package/rust/core/audio/interpreter/statements/spawn.rs +0 -253
  174. package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
  175. package/rust/core/audio/interpreter/statements/trigger.rs +0 -239
  176. package/rust/core/audio/loader/mod.rs +0 -1
  177. package/rust/core/audio/loader/trigger.rs +0 -98
  178. package/rust/core/audio/mod.rs +0 -6
  179. package/rust/core/audio/player.rs +0 -70
  180. package/rust/core/audio/special/easing.rs +0 -189
  181. package/rust/core/audio/special/env.rs +0 -45
  182. package/rust/core/audio/special/math.rs +0 -134
  183. package/rust/core/audio/special/mod.rs +0 -9
  184. package/rust/core/audio/special/modulator.rs +0 -143
  185. package/rust/core/builder/mod.rs +0 -129
  186. package/rust/core/debugger/lexer.rs +0 -27
  187. package/rust/core/debugger/logs.rs +0 -52
  188. package/rust/core/debugger/mod.rs +0 -30
  189. package/rust/core/debugger/preprocessor.rs +0 -27
  190. package/rust/core/debugger/store.rs +0 -38
  191. package/rust/core/error/mod.rs +0 -269
  192. package/rust/core/lexer/driver.rs +0 -59
  193. package/rust/core/lexer/handler/arrow.rs +0 -82
  194. package/rust/core/lexer/handler/at.rs +0 -21
  195. package/rust/core/lexer/handler/brace.rs +0 -41
  196. package/rust/core/lexer/handler/colon.rs +0 -21
  197. package/rust/core/lexer/handler/comment.rs +0 -30
  198. package/rust/core/lexer/handler/dot.rs +0 -21
  199. package/rust/core/lexer/handler/driver.rs +0 -337
  200. package/rust/core/lexer/handler/identifier.rs +0 -47
  201. package/rust/core/lexer/handler/indent.rs +0 -66
  202. package/rust/core/lexer/handler/mod.rs +0 -15
  203. package/rust/core/lexer/handler/newline.rs +0 -23
  204. package/rust/core/lexer/handler/number.rs +0 -31
  205. package/rust/core/lexer/handler/operator.rs +0 -46
  206. package/rust/core/lexer/handler/parenthesis.rs +0 -41
  207. package/rust/core/lexer/handler/slash.rs +0 -21
  208. package/rust/core/lexer/handler/string.rs +0 -63
  209. package/rust/core/lexer/mod.rs +0 -3
  210. package/rust/core/lexer/token.rs +0 -91
  211. package/rust/core/mod.rs +0 -9
  212. package/rust/core/parser/driver/block.rs +0 -111
  213. package/rust/core/parser/driver/cursor.rs +0 -82
  214. package/rust/core/parser/driver/driver_impl.rs +0 -139
  215. package/rust/core/parser/driver/mod.rs +0 -6
  216. package/rust/core/parser/driver/parse_array.rs +0 -120
  217. package/rust/core/parser/driver/parse_map.rs +0 -223
  218. package/rust/core/parser/driver/parser.rs +0 -160
  219. package/rust/core/parser/handler/arrow_call.rs +0 -277
  220. package/rust/core/parser/handler/at.rs +0 -279
  221. package/rust/core/parser/handler/bank.rs +0 -104
  222. package/rust/core/parser/handler/condition.rs +0 -83
  223. package/rust/core/parser/handler/dot.rs +0 -148
  224. package/rust/core/parser/handler/identifier/automate.rs +0 -254
  225. package/rust/core/parser/handler/identifier/call.rs +0 -91
  226. package/rust/core/parser/handler/identifier/emit.rs +0 -70
  227. package/rust/core/parser/handler/identifier/function.rs +0 -113
  228. package/rust/core/parser/handler/identifier/group.rs +0 -89
  229. package/rust/core/parser/handler/identifier/let_.rs +0 -173
  230. package/rust/core/parser/handler/identifier/mod.rs +0 -55
  231. package/rust/core/parser/handler/identifier/on.rs +0 -107
  232. package/rust/core/parser/handler/identifier/print.rs +0 -49
  233. package/rust/core/parser/handler/identifier/sleep.rs +0 -96
  234. package/rust/core/parser/handler/identifier/spawn.rs +0 -91
  235. package/rust/core/parser/handler/identifier/synth.rs +0 -135
  236. package/rust/core/parser/handler/loop_.rs +0 -194
  237. package/rust/core/parser/handler/mod.rs +0 -9
  238. package/rust/core/parser/handler/pattern.rs +0 -74
  239. package/rust/core/parser/handler/tempo.rs +0 -105
  240. package/rust/core/parser/mod.rs +0 -3
  241. package/rust/core/parser/statement.rs +0 -10
  242. package/rust/core/plugin/loader.rs +0 -137
  243. package/rust/core/plugin/mod.rs +0 -2
  244. package/rust/core/plugin/runner/mod.rs +0 -11
  245. package/rust/core/plugin/runner/non_wasm.rs +0 -297
  246. package/rust/core/plugin/runner/wasm32.rs +0 -43
  247. package/rust/core/preprocessor/loader/inject.rs +0 -278
  248. package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
  249. package/rust/core/preprocessor/loader/mod.rs +0 -235
  250. package/rust/core/preprocessor/mod.rs +0 -4
  251. package/rust/core/preprocessor/module.rs +0 -55
  252. package/rust/core/preprocessor/processor/handlers.rs +0 -107
  253. package/rust/core/preprocessor/processor/mod.rs +0 -1
  254. package/rust/core/preprocessor/resolver/bank.rs +0 -49
  255. package/rust/core/preprocessor/resolver/call.rs +0 -124
  256. package/rust/core/preprocessor/resolver/condition.rs +0 -95
  257. package/rust/core/preprocessor/resolver/driver.rs +0 -324
  258. package/rust/core/preprocessor/resolver/function.rs +0 -69
  259. package/rust/core/preprocessor/resolver/group.rs +0 -122
  260. package/rust/core/preprocessor/resolver/let_.rs +0 -32
  261. package/rust/core/preprocessor/resolver/loop_.rs +0 -318
  262. package/rust/core/preprocessor/resolver/mod.rs +0 -16
  263. package/rust/core/preprocessor/resolver/pattern.rs +0 -83
  264. package/rust/core/preprocessor/resolver/spawn.rs +0 -99
  265. package/rust/core/preprocessor/resolver/synth.rs +0 -54
  266. package/rust/core/preprocessor/resolver/tempo.rs +0 -48
  267. package/rust/core/preprocessor/resolver/trigger.rs +0 -116
  268. package/rust/core/preprocessor/resolver/value.rs +0 -176
  269. package/rust/core/store/global.rs +0 -57
  270. package/rust/core/store/mod.rs +0 -1
  271. package/rust/lib.rs +0 -323
  272. package/rust/main.rs +0 -388
  273. package/rust/types/Cargo.toml +0 -11
  274. package/rust/types/src/addons.rs +0 -55
  275. package/rust/types/src/ast.rs +0 -202
  276. package/rust/types/src/config.rs +0 -84
  277. package/rust/types/src/lib.rs +0 -15
  278. package/rust/types/src/plugin.rs +0 -20
  279. package/rust/types/src/store.rs +0 -139
  280. package/rust/types/src/telemetry.rs +0 -85
  281. package/rust/utils/Cargo.toml +0 -26
  282. package/rust/utils/src/error.rs +0 -186
  283. package/rust/utils/src/file.rs +0 -94
  284. package/rust/utils/src/first_usage.rs +0 -97
  285. package/rust/utils/src/lib.rs +0 -9
  286. package/rust/utils/src/logger.rs +0 -200
  287. package/rust/utils/src/path.rs +0 -129
  288. package/rust/utils/src/signature.rs +0 -41
  289. package/rust/utils/src/spinner.rs +0 -20
  290. package/rust/utils/src/version.rs +0 -27
  291. package/rust/utils/src/watcher.rs +0 -46
  292. package/rust/web/api.rs +0 -5
  293. package/rust/web/cdn.rs +0 -34
  294. package/rust/web/mod.rs +0 -3
  295. package/rust/web/sso.rs +0 -5
  296. package/templates/minimal/.devalang +0 -5
  297. package/templates/minimal/README.md +0 -218
  298. package/templates/minimal/src/index.deva +0 -2
  299. package/templates/welcome/.devalang +0 -5
  300. package/templates/welcome/README.md +0 -218
  301. package/templates/welcome/samples/kick-808.wav +0 -0
  302. package/templates/welcome/src/index.deva +0 -61
  303. package/templates/welcome/src/variables.deva +0 -3
  304. package/tests/integration.rs +0 -21
  305. package/tests/rust/cli_check_build.rs +0 -21
  306. package/tests/rust/cli_help.rs +0 -12
  307. package/tests/rust/cli_template_list.rs +0 -10
  308. package/tests/rust/cli_version.rs +0 -11
  309. package/tests/typescript/index.spec.ts +0 -136
  310. package/tests/typescript/playhead.spec.ts +0 -36
  311. package/tests/typescript/render_e2e.spec.ts +0 -77
  312. package/tsconfig.json +0 -115
  313. package/typescript/bin/index.ts +0 -28
  314. package/typescript/core/functions/index.ts +0 -94
  315. package/typescript/core/index.ts +0 -6
  316. package/typescript/core/types/index.ts +0 -4
  317. package/typescript/core/types/plugin.ts +0 -19
  318. package/typescript/core/types/result.ts +0 -29
  319. package/typescript/core/types/statement.ts +0 -47
  320. package/typescript/core/types/value.ts +0 -29
  321. package/typescript/index.ts +0 -8
  322. package/typescript/pkg/devalang_core.d.ts +0 -4
  323. package/typescript/pkg/devalang_core.ts +0 -65
  324. package/typescript/scripts/copy-wasm-dts.ts +0 -41
  325. package/typescript/scripts/postinstall.ts +0 -85
  326. package/typescript/scripts/version/bump.ts +0 -44
  327. package/typescript/scripts/version/fetch.ts +0 -18
  328. package/typescript/scripts/version/index.ts +0 -25
  329. package/typescript/scripts/version/sync.ts +0 -24
@@ -1,97 +0,0 @@
1
- use devalang_types::Value;
2
- use std::collections::HashMap;
3
-
4
- pub fn apply_defaults(synth_params: &mut HashMap<String, Value>) {
5
- use devalang_types::Value as DV;
6
- // pluck: very short attack, short decay, very low sustain, short release
7
- synth_params
8
- .entry("attack".to_string())
9
- .or_insert(DV::Number(2.0));
10
- synth_params
11
- .entry("decay".to_string())
12
- .or_insert(DV::Number(80.0));
13
- synth_params
14
- .entry("sustain".to_string())
15
- .or_insert(DV::Number(0.0));
16
- synth_params
17
- .entry("release".to_string())
18
- .or_insert(DV::Number(120.0));
19
- synth_params
20
- .entry("glide".to_string())
21
- .or_insert(DV::Boolean(false));
22
- synth_params
23
- .entry("slide".to_string())
24
- .or_insert(DV::Boolean(false));
25
- // small transient helper for plucks
26
- synth_params
27
- .entry("pluck_click".to_string())
28
- .or_insert(DV::Number(0.08));
29
- synth_params
30
- .entry("pluck_click_ms".to_string())
31
- .or_insert(DV::Number(8.0));
32
- }
33
-
34
- // Prepare per-note modifications for pluck: short attack/release, optional amp curve per-index
35
- pub fn prepare_note(
36
- _note_name: &str,
37
- index: usize,
38
- _total: usize,
39
- _start_time_ms: f32,
40
- _duration_ms: f32,
41
- amp: f32,
42
- _synth_params: &HashMap<String, Value>,
43
- note_params: &HashMap<String, Value>,
44
- _automation: &Option<HashMap<String, Value>>,
45
- ) -> (f32, f32, f32, HashMap<String, Value>) {
46
- // pluck slightly reduces amp for later notes by a tiny fraction
47
- let decay = 0.02 * (index as f32);
48
- let amp_out = (amp * (1.0 - decay)).max(0.0);
49
- let mut params_out = note_params.clone();
50
- // ensure short attack & short release to sound plucky
51
- params_out
52
- .entry("attack".to_string())
53
- .or_insert(Value::Number(1.0));
54
- params_out
55
- .entry("release".to_string())
56
- .or_insert(Value::Number(100.0));
57
- params_out
58
- .entry("sustain".to_string())
59
- .or_insert(Value::Number(0.0));
60
- // add a small "click" transient and a light resonant filter to emphasize the pluck
61
- use devalang_types::Value as DV;
62
- let freq = note_to_freq(_note_name);
63
- let mut filt: std::collections::HashMap<String, Value> = std::collections::HashMap::new();
64
- filt.insert("type".to_string(), Value::String("bandpass".to_string()));
65
- // center filter a bit above the note to give a bright pluck transient
66
- // use more explicit filter parameter names requested by user
67
- filt.insert(
68
- "cutoff".to_string(),
69
- Value::Number((freq * 2.0).min(10000.0)),
70
- );
71
- filt.insert("resonance".to_string(), Value::Number(6.0));
72
- // only insert filters if not already present
73
- if !params_out.contains_key("filters") {
74
- params_out.insert("filters".to_string(), DV::Array(vec![DV::Map(filt)]));
75
- }
76
- // frequency unchanged here; caller computes freq
77
- // stronger pitch drop for a plucky character
78
- let freq_end = freq * 0.98;
79
- (0.0, freq_end, amp_out, params_out)
80
- }
81
-
82
- fn note_to_freq(note: &str) -> f32 {
83
- let notes = [
84
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
85
- ];
86
-
87
- if note.len() < 2 || note.len() > 3 {
88
- return 440.0;
89
- }
90
-
91
- let (name, octave_str) = note.split_at(note.len() - 1);
92
- let semitone = notes.iter().position(|&n| n == name).unwrap_or(9) as i32;
93
- let octave = octave_str.parse::<i32>().unwrap_or(4);
94
- let midi_note = (octave + 1) * 12 + semitone;
95
-
96
- 440.0 * (2.0_f32).powf(((midi_note as f32) - 69.0) / 12.0)
97
- }
@@ -1,100 +0,0 @@
1
- use devalang_types::Value;
2
- use std::collections::HashMap;
3
-
4
- pub fn apply_defaults(synth_params: &mut HashMap<String, Value>) {
5
- use devalang_types::Value as DV;
6
- // sub bass: strong sustain, lowpass emphasis
7
- synth_params
8
- .entry("attack".to_string())
9
- .or_insert(DV::Number(10.0));
10
- synth_params
11
- .entry("decay".to_string())
12
- .or_insert(DV::Number(80.0));
13
- // sustain stored as 0.0-1.0 for consistency
14
- synth_params
15
- .entry("sustain".to_string())
16
- .or_insert(DV::Number(1.0));
17
- synth_params
18
- .entry("release".to_string())
19
- .or_insert(DV::Number(300.0));
20
- synth_params
21
- .entry("detune".to_string())
22
- .or_insert(DV::Number(0.0));
23
- synth_params
24
- .entry("lowpass".to_string())
25
- .or_insert(DV::Number(150.0));
26
- // octave stacking and drive for extra body
27
- synth_params
28
- .entry("octaves".to_string())
29
- .or_insert(DV::Number(1.0));
30
- synth_params
31
- .entry("drive".to_string())
32
- .or_insert(DV::Number(0.0));
33
- // encourage a lowpass default if none provided
34
- synth_params
35
- .entry("lowpass".to_string())
36
- .or_insert(DV::Number(120.0));
37
- }
38
-
39
- // prepare_note for sub: shift note one or two octaves down and set stronger amp
40
- pub fn prepare_note(
41
- note_name: &str,
42
- _index: usize,
43
- _total: usize,
44
- _start_time_ms: f32,
45
- _duration_ms: f32,
46
- amp: f32,
47
- _synth_params: &HashMap<String, Value>,
48
- note_params: &HashMap<String, Value>,
49
- _automation: &Option<HashMap<String, Value>>,
50
- ) -> (f32, f32, f32, HashMap<String, Value>) {
51
- let mut params_out = note_params.clone();
52
- params_out
53
- .entry("attack".to_string())
54
- .or_insert(Value::Number(5.0));
55
- params_out
56
- .entry("release".to_string())
57
- .or_insert(Value::Number(200.0));
58
- params_out
59
- .entry("sustain".to_string())
60
- .or_insert(Value::Number(1.0));
61
-
62
- // compute deep-frequency one octave down by default
63
- let freq = note_to_freq(note_name) * 0.5;
64
- // allow stacking additional octaves for extra body
65
- if let Some(Value::Number(o)) = _synth_params.get("octaves") {
66
- let oct = (*o as i32).max(1);
67
- if oct >= 2 {
68
- // add lower harmonic by halving frequency again (engine may layer if octaves param is observed)
69
- // we still return the primary frequency but advertise octaves in params
70
- params_out.insert("octaves".to_string(), Value::Number(*o));
71
- }
72
- }
73
-
74
- // boost amplitude a little for sub
75
- let amp_out = (amp * 1.5).min(1.0);
76
-
77
- // advertise drive if present so engine/effects can apply soft clipping
78
- if let Some(Value::Number(d)) = _synth_params.get("drive") {
79
- params_out.insert("drive".to_string(), Value::Number(*d));
80
- }
81
-
82
- (0.0, freq, amp_out, params_out)
83
- }
84
-
85
- fn note_to_freq(note: &str) -> f32 {
86
- let notes = [
87
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
88
- ];
89
-
90
- if note.len() < 2 || note.len() > 3 {
91
- return 440.0;
92
- }
93
-
94
- let (name, octave_str) = note.split_at(note.len() - 1);
95
- let semitone = notes.iter().position(|&n| n == name).unwrap_or(9) as i32;
96
- let octave = octave_str.parse::<i32>().unwrap_or(4);
97
- let midi_note = (octave + 1) * 12 + semitone;
98
-
99
- 440.0 * (2.0_f32).powf(((midi_note as f32) - 69.0) / 12.0)
100
- }
@@ -1,16 +0,0 @@
1
- use crate::core::parser::statement::{Statement, StatementKind};
2
- use devalang_types::VariableTable;
3
-
4
- // Store automation configuration into the variable table under a namespaced key
5
- // Key: "<target>__automation" => Value::Map({ target, params })
6
- pub fn interprete_automate_statement(
7
- stmt: &Statement,
8
- variable_table: &mut VariableTable,
9
- ) -> Option<VariableTable> {
10
- if let StatementKind::Automate { target } = &stmt.kind {
11
- let key = format!("{}__automation", target);
12
- variable_table.set(key, stmt.value.clone());
13
- return Some(variable_table.clone());
14
- }
15
- None
16
- }
@@ -1,295 +0,0 @@
1
- use devalang_types::{Duration, Value};
2
-
3
- use crate::core::{
4
- audio::{engine::AudioEngine, interpreter::driver::execute_audio_block},
5
- parser::statement::{Statement, StatementKind},
6
- store::global::GlobalStore,
7
- };
8
- use devalang_types::store::{FunctionTable, VariableTable};
9
-
10
- pub fn interprete_call_statement(
11
- stmt: &Statement,
12
- audio_engine: &mut AudioEngine,
13
- variable_table: &VariableTable,
14
- functions: &FunctionTable,
15
- global_store: &GlobalStore,
16
- base_bpm: f32,
17
- base_duration: f32,
18
- max_end_time: f32,
19
- cursor_time: f32,
20
- ) -> (f32, f32) {
21
- if let StatementKind::Call { name, args } = &stmt.kind {
22
- // Classic function call case
23
- if let Some(func) = functions.functions.get(name) {
24
- // function found
25
- if func.parameters.len() != args.len() {
26
- eprintln!(
27
- "❌ Function '{}' expects {} args, got {}",
28
- name,
29
- func.parameters.len(),
30
- args.len()
31
- );
32
- return (max_end_time, cursor_time);
33
- }
34
-
35
- let mut local_vars = VariableTable::with_parent(variable_table.clone());
36
- for (param, arg) in func.parameters.iter().zip(args) {
37
- local_vars.set(param.clone(), arg.clone());
38
- }
39
-
40
- return execute_audio_block(
41
- audio_engine,
42
- global_store,
43
- local_vars,
44
- functions.clone(),
45
- &func.body,
46
- base_bpm,
47
- base_duration,
48
- max_end_time,
49
- cursor_time,
50
- );
51
- }
52
-
53
- // Group case
54
- if let Some(group_stmt) = find_group(name, variable_table, global_store) {
55
- // group found
56
- if let Value::Map(map) = &group_stmt.value {
57
- if let Some(Value::Block(body)) = map.get("body") {
58
- return execute_audio_block(
59
- audio_engine,
60
- global_store,
61
- variable_table.clone(),
62
- functions.clone(),
63
- body,
64
- base_bpm,
65
- base_duration,
66
- max_end_time,
67
- cursor_time,
68
- );
69
- }
70
- }
71
- }
72
-
73
- // Pattern case
74
- if let Some(pattern_stmt) = find_pattern(name, variable_table, global_store) {
75
- // Extract pattern string from statement value
76
- if let Value::String(pat) = &pattern_stmt.value {
77
- // Determine target entity (explicit or inferred)
78
- let mut target_entity = name.clone();
79
- if let StatementKind::Pattern { name: _n, target } = &pattern_stmt.kind {
80
- if let Some(t) = target {
81
- target_entity = t.clone();
82
- }
83
- }
84
-
85
- // Build a variable table snapshot for resolution like triggers do
86
- // Preserve the full parent chain so lookups behave the same as runtime
87
- fn clone_with_parents(
88
- orig: &devalang_types::VariableTable,
89
- ) -> devalang_types::VariableTable {
90
- devalang_types::VariableTable {
91
- variables: orig.variables.clone(),
92
- parent: orig
93
- .parent
94
- .as_ref()
95
- .map(|p| Box::new(clone_with_parents(p))),
96
- }
97
- }
98
-
99
- let final_variable_table = clone_with_parents(variable_table);
100
-
101
- // Normalize pattern: remove spaces and line breaks
102
- let pattern_str: String = pat.chars().filter(|c| !c.is_whitespace()).collect();
103
- if pattern_str.is_empty() {
104
- return (max_end_time, cursor_time);
105
- }
106
-
107
- let step_count = pattern_str.len() as f32;
108
- // Assume pattern spans one bar (4 beats)
109
- let total_bar = 4.0 * base_duration;
110
- let step_duration = total_bar / step_count; // seconds per step
111
-
112
- let mut updated_max = max_end_time;
113
-
114
- for (i, ch) in pattern_str.chars().enumerate() {
115
- if ch == '-' {
116
- continue; // rest
117
- }
118
-
119
- // Schedule a trigger at cursor_time + offset
120
- let event_time = cursor_time + (i as f32) * step_duration;
121
-
122
- // Resolve trigger value similarly to interprete_trigger_statement
123
- let mut trigger_val = Value::String(target_entity.clone());
124
- if let Some(val) = variable_table.variables.get(&target_entity) {
125
- match val {
126
- Value::Identifier(id) => {
127
- // resolve from parent if available
128
- if let Some(parent) = &variable_table.parent {
129
- if let Some(v) = parent.get(id) {
130
- trigger_val = v.clone();
131
- }
132
- } else if let Some(v) = variable_table.get(id) {
133
- trigger_val = v.clone();
134
- }
135
- }
136
- Value::Map(map) => {
137
- if let Some(Value::String(src)) = map.get("entity") {
138
- trigger_val = Value::String(src.clone());
139
- } else if let Some(Value::Identifier(src)) = map.get("entity") {
140
- trigger_val = Value::Identifier(src.clone());
141
- }
142
- }
143
- Value::Sample(sample_src) => {
144
- trigger_val = Value::Sample(sample_src.clone());
145
- }
146
- _ => {
147
- // leave as string
148
- }
149
- }
150
- }
151
-
152
- // Use loader to get sample path and sample length
153
- let (src, sample_length) = crate::core::audio::loader::trigger::load_trigger(
154
- &trigger_val,
155
- &Duration::Number(step_duration),
156
- &None,
157
- base_duration,
158
- final_variable_table.clone(),
159
- );
160
-
161
- let play_length = step_duration.min(sample_length);
162
-
163
- let trigger_src = match trigger_val.get("entity") {
164
- Some(Value::String(s)) => s.clone(),
165
- Some(Value::Identifier(id)) => id.clone(),
166
- Some(Value::Statement(stmt)) => {
167
- if let StatementKind::Trigger { entity, .. } = &stmt.kind {
168
- entity.clone()
169
- } else {
170
- src.clone()
171
- }
172
- }
173
- _ => src.clone(),
174
- };
175
-
176
- audio_engine.insert_sample(
177
- &trigger_src,
178
- event_time,
179
- play_length,
180
- None,
181
- &final_variable_table,
182
- );
183
-
184
- let end_time = event_time + play_length;
185
- if end_time > updated_max {
186
- updated_max = end_time;
187
- }
188
- }
189
-
190
- return (updated_max, cursor_time);
191
- }
192
- }
193
-
194
- // Function or group not found; keep as debug-free fail path
195
- }
196
-
197
- (max_end_time, cursor_time)
198
- }
199
-
200
- fn find_group(
201
- name: &str,
202
- variable_table: &VariableTable,
203
- global_store: &GlobalStore,
204
- ) -> Option<Statement> {
205
- use crate::core::parser::statement::Statement;
206
- use crate::core::parser::statement::StatementKind;
207
-
208
- if let Some(Value::Statement(stmt_box)) = variable_table.get(name) {
209
- if let StatementKind::Group = stmt_box.kind {
210
- return Some(*stmt_box.clone());
211
- }
212
- }
213
-
214
- if let Some(val) = global_store.variables.variables.get(name) {
215
- match val {
216
- Value::Statement(stmt_box) => {
217
- if let StatementKind::Group = stmt_box.kind {
218
- return Some(*stmt_box.clone());
219
- }
220
- }
221
- Value::Map(map) => {
222
- // Try to rebuild a Group statement from the stored map
223
- if let (Some(Value::String(_id)), Some(Value::Block(_body))) =
224
- (map.get("identifier"), map.get("body"))
225
- {
226
- let stmt = Statement {
227
- kind: StatementKind::Group,
228
- value: Value::Map(map.clone()),
229
- indent: 0,
230
- line: 0,
231
- column: 0,
232
- };
233
- return Some(stmt);
234
- }
235
- }
236
- _ => {}
237
- }
238
- }
239
-
240
- None
241
- }
242
-
243
- fn find_pattern(
244
- name: &str,
245
- variable_table: &VariableTable,
246
- global_store: &GlobalStore,
247
- ) -> Option<Statement> {
248
- use crate::core::parser::statement::Statement;
249
- use crate::core::parser::statement::StatementKind;
250
-
251
- if let Some(Value::Statement(stmt_box)) = variable_table.get(name) {
252
- if let StatementKind::Pattern { .. } = stmt_box.kind {
253
- return Some(*stmt_box.clone());
254
- }
255
- }
256
-
257
- if let Some(val) = global_store.variables.variables.get(name) {
258
- match val {
259
- Value::Statement(stmt_box) => {
260
- if let StatementKind::Pattern { .. } = stmt_box.kind {
261
- return Some(*stmt_box.clone());
262
- }
263
- }
264
- Value::Map(map) => {
265
- if let Some(Value::String(_pat)) = map.get("pattern") {
266
- // Rebuild a Pattern statement from stored map if possible
267
- let stmt = Statement {
268
- kind: StatementKind::Pattern {
269
- name: name.to_string(),
270
- target: map.get("target").and_then(|v| match v {
271
- Value::String(s) => Some(s.clone()),
272
- _ => None,
273
- }),
274
- },
275
- value: Value::String(
276
- map.get("pattern")
277
- .and_then(|v| match v {
278
- Value::String(s) => Some(s.clone()),
279
- _ => None,
280
- })
281
- .unwrap_or_default(),
282
- ),
283
- indent: 0,
284
- line: 0,
285
- column: 0,
286
- };
287
- return Some(stmt);
288
- }
289
- }
290
- _ => {}
291
- }
292
- }
293
-
294
- None
295
- }
@@ -1,72 +0,0 @@
1
- use devalang_types::Value;
2
-
3
- use crate::core::{
4
- audio::{
5
- engine::AudioEngine, evaluator::evaluate_condition_string,
6
- interpreter::driver::execute_audio_block,
7
- },
8
- parser::statement::Statement,
9
- store::global::GlobalStore,
10
- };
11
- use devalang_types::store::{FunctionTable, VariableTable};
12
-
13
- pub fn interprete_condition_statement(
14
- stmt: &Statement,
15
- audio_engine: &mut AudioEngine,
16
- global_store: &GlobalStore,
17
- variable_table: &VariableTable,
18
- functions_table: &FunctionTable,
19
- base_bpm: f32,
20
- base_duration: f32,
21
- max_end_time: f32,
22
- cursor_time: f32,
23
- ) -> (f32, f32) {
24
- let cur_time = cursor_time;
25
- let max_time = max_end_time;
26
-
27
- let mut current = stmt.value.clone();
28
-
29
- loop {
30
- let Value::Map(map) = current else {
31
- break;
32
- };
33
-
34
- let should_execute = match map.get("condition") {
35
- Some(Value::Boolean(b)) => *b,
36
- Some(Value::String(expr)) => evaluate_condition_string(expr, &variable_table.clone()),
37
- Some(_) => false,
38
- None => true,
39
- };
40
-
41
- if should_execute {
42
- if let Some(Value::Block(block)) = map.get("body") {
43
- let (new_max, cursor_time) = execute_audio_block(
44
- audio_engine,
45
- global_store,
46
- variable_table.clone(),
47
- functions_table.clone(),
48
- block,
49
- base_bpm,
50
- base_duration,
51
- max_time,
52
- cur_time,
53
- );
54
- return (new_max, cursor_time);
55
- } else {
56
- break;
57
- }
58
- }
59
-
60
- // Advance to the next condition
61
- match map.get("next") {
62
- Some(Value::Map(next_map)) => {
63
- current = Value::Map(next_map.clone());
64
- }
65
- _ => {
66
- break;
67
- }
68
- }
69
- }
70
-
71
- (max_end_time, cursor_time)
72
- }
@@ -1,24 +0,0 @@
1
- use crate::core::parser::statement::{Statement, StatementKind};
2
- use devalang_types::store::{FunctionDef, FunctionTable};
3
-
4
- pub fn interprete_function_statement(
5
- stmt: &Statement,
6
- functions_table: &mut FunctionTable,
7
- ) -> Option<FunctionTable> {
8
- if let StatementKind::Function {
9
- name,
10
- parameters,
11
- body,
12
- } = &stmt.kind
13
- {
14
- functions_table.add_function(FunctionDef {
15
- name: name.clone(),
16
- parameters: parameters.clone(),
17
- body: body.clone(),
18
- });
19
-
20
- return Some(functions_table.clone());
21
- }
22
-
23
- None
24
- }
@@ -1,36 +0,0 @@
1
- use crate::core::parser::statement::{Statement, StatementKind};
2
- use devalang_types::Value;
3
- use devalang_types::store::VariableTable;
4
-
5
- pub fn interprete_let_statement(
6
- stmt: &Statement,
7
- variable_table: &mut VariableTable,
8
- ) -> Option<VariableTable> {
9
- if let StatementKind::Let { name } = &stmt.kind {
10
- // If RHS is a string and looks like an expression, evaluate it
11
- let evaluated = match &stmt.value {
12
- Value::String(s) if s.contains("$env") || s.contains("$math") => {
13
- // We don't have direct env here; use defaults or infer from table
14
- let bpm = if let Some(Value::Number(n)) = variable_table.get("bpm") {
15
- *n
16
- } else {
17
- 120.0
18
- };
19
- // Try to infer beat from time-based variables if any, else 0.0
20
- let beat = if let Some(Value::Number(n)) = variable_table.get("beat") {
21
- *n
22
- } else {
23
- 0.0
24
- };
25
- crate::core::audio::evaluator::evaluate_rhs_into_value(s, variable_table, bpm, beat)
26
- }
27
- other => other.clone(),
28
- };
29
-
30
- variable_table.set(name.to_string(), evaluated);
31
-
32
- return Some(variable_table.clone());
33
- }
34
-
35
- None
36
- }
@@ -1,17 +0,0 @@
1
- use devalang_types::Value;
2
-
3
- use crate::core::parser::statement::{Statement, StatementKind};
4
- use devalang_types::store::VariableTable;
5
-
6
- pub fn interprete_load_statement(
7
- stmt: &Statement,
8
- variable_table: &mut VariableTable,
9
- ) -> Option<VariableTable> {
10
- if let StatementKind::Load { source, alias } = &stmt.kind {
11
- variable_table.set(alias.to_string(), Value::Sample(source.clone()));
12
-
13
- return Some(variable_table.clone());
14
- }
15
-
16
- None
17
- }