@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,316 +0,0 @@
1
- use crate::core::{audio::engine::AudioEngine, plugin::runner::WasmPluginRunner};
2
- use devalang_types::Value;
3
- use devalang_utils::logger::{LogLevel, Logger};
4
- use std::collections::HashMap;
5
-
6
- pub fn interprete_note_method(
7
- args: &Vec<devalang_types::Value>,
8
- target: &str,
9
- audio_engine: &mut AudioEngine,
10
- variable_table: &devalang_types::VariableTable,
11
- global_store: &crate::core::store::global::GlobalStore,
12
- waveform_str: &str,
13
- synth_params: &HashMap<String, devalang_types::Value>,
14
- amp: f32,
15
- base_bpm: f32,
16
- base_duration: f32,
17
- max_end_time: &mut f32,
18
- mut cursor_time: Option<&mut f32>,
19
- cursor_copy: f32,
20
- update_cursor: bool,
21
- ) -> (f32, f32) {
22
- let filtered_args: Vec<_> = args
23
- .iter()
24
- .filter(|arg| !matches!(arg, Value::Unknown))
25
- .collect();
26
-
27
- let Some(Value::Identifier(note_name)) = filtered_args.first().map(|v| (*v).clone()) else {
28
- println!(
29
- "❌ Invalid or missing argument for 'note' method on '{}'.",
30
- target
31
- );
32
- return (*max_end_time, cursor_copy);
33
- };
34
-
35
- let mut note_params = HashMap::new();
36
- if let Some(arg1) = filtered_args.get(1) {
37
- if let Value::Map(map) = (*arg1).clone() {
38
- for (key, value) in map {
39
- note_params.insert(key, value);
40
- }
41
- }
42
- }
43
-
44
- // Note parameters and calculations
45
- let amp_note = extract_f32(&note_params, "amp", base_bpm).unwrap_or(amp);
46
- let duration_ms =
47
- extract_f32(&note_params, "duration", base_bpm).unwrap_or(base_duration * 1000.0);
48
-
49
- let duration_secs = duration_ms / 1000.0;
50
- let final_freq = note_to_freq(&note_name);
51
- let start_time = cursor_copy;
52
- let end_time = start_time + duration_secs;
53
-
54
- // Fetch automation map if present:
55
- // - Global (per-synth): key "<target>__automation" => map with key "params"
56
- // - Per-note: note parameter "automate" => map
57
- let auto_key = format!("{}__automation", target);
58
- let synth_automation = match variable_table.get(&auto_key) {
59
- Some(Value::Map(map)) => match map.get("params") {
60
- Some(Value::Map(p)) => Some(p.clone()),
61
- _ => None,
62
- },
63
- _ => None,
64
- };
65
-
66
- let note_automation = match note_params.get("automate") {
67
- Some(Value::Map(m)) => Some(m.clone()),
68
- _ => None,
69
- };
70
-
71
- // Merge: per-note overrides synth automation per key (volume/pan/pitch)
72
- let automation = match (synth_automation, note_automation) {
73
- (Some(mut a), Some(n)) => {
74
- for (k, v) in n {
75
- a.insert(k, v);
76
- }
77
- Some(a)
78
- }
79
- (None, Some(n)) => Some(n),
80
- (Some(a), None) => Some(a),
81
- _ => None,
82
- };
83
-
84
- // If waveform references a plugin alias (e.g., alias.synth), use the WASM plugin runner
85
- if waveform_str.contains('.') && waveform_str.ends_with(".synth") {
86
- let alias = waveform_str.split('.').next().unwrap_or("");
87
- if let Some(Value::String(uri)) = variable_table.get(alias) {
88
- if let Some(id) = uri.strip_prefix("devalang://plugin/") {
89
- let mut parts = id.split('.');
90
- let author = parts.next().unwrap_or("");
91
- let name = parts.next().unwrap_or("");
92
- let key = format!("{}:{}", author, name);
93
- if let Some((_info, wasm_bytes)) = global_store.plugins.get(&key) {
94
- // Prepare buffer (stereo f32)
95
- let sample_rate = 44100.0_f32;
96
- let total_samples = ((duration_ms / 1000.0) * sample_rate) as usize;
97
- let channels = 2usize;
98
- let start_index = ((start_time * sample_rate) as usize) * channels;
99
- let required_len = start_index + total_samples * channels;
100
- if audio_engine.buffer.len() < required_len {
101
- audio_engine.buffer.resize(required_len, 0);
102
- }
103
- let mut fbuf = vec![0.0f32; total_samples * channels];
104
- let runner = WasmPluginRunner::new();
105
- let mut params_num: std::collections::HashMap<String, f32> =
106
- std::collections::HashMap::new();
107
- let mut params_str: std::collections::HashMap<String, String> =
108
- std::collections::HashMap::new();
109
- for (k, v) in synth_params.iter() {
110
- match v {
111
- Value::Number(n) => {
112
- params_num.insert(k.clone(), *n);
113
- }
114
- Value::String(s) => {
115
- params_str.insert(k.clone(), s.clone());
116
- }
117
- Value::Identifier(s) => {
118
- params_str.insert(k.clone(), s.clone());
119
- }
120
- _ => {}
121
- }
122
- }
123
- let _ = runner.render_note_with_params_in_place(
124
- wasm_bytes,
125
- &mut fbuf,
126
- None,
127
- final_freq,
128
- amp_note,
129
- duration_ms as i32,
130
- 44100,
131
- 2,
132
- &params_num,
133
- Some(&params_str),
134
- );
135
- for (i, sample) in fbuf.iter().enumerate().take(total_samples * channels) {
136
- let s = (sample.clamp(-1.0, 1.0) * (i16::MAX as f32)) as i16;
137
- let idx = start_index + i;
138
- audio_engine.buffer[idx] = audio_engine.buffer[idx].saturating_add(s);
139
- }
140
- } else {
141
- let logger = Logger::new();
142
- logger.log_message(
143
- LogLevel::Warning,
144
- &format!(
145
- "Plugin bytes not found for key '{}' (alias '{}').",
146
- key, alias
147
- ),
148
- );
149
- }
150
- } else {
151
- let logger = Logger::new();
152
- logger.log_message(
153
- LogLevel::Warning,
154
- &format!("Invalid plugin URI in alias '{}': {}", alias, uri),
155
- );
156
- }
157
- } else {
158
- let logger = Logger::new();
159
- logger.log_message(
160
- LogLevel::Warning,
161
- &format!("Plugin alias '{}' not found in variable table.", alias),
162
- );
163
- }
164
- } else {
165
- // Allow types to adjust per-note scheduling/params
166
- let start_ms = start_time * 1000.0;
167
- let mut final_amp = amp_note;
168
- let mut final_note_params = note_params.clone();
169
-
170
- let mut handled = false;
171
- if let Some(tval) = synth_params.get("type") {
172
- let tname = match tval {
173
- Value::String(s) => s.as_str(),
174
- Value::Identifier(s) => s.as_str(),
175
- _ => "",
176
- };
177
- match tname {
178
- "arp" => {
179
- // compute a step (ms) from synth params (rate/step). compute_arp_step
180
- // will interpret `rate` as number of notes across the provided duration
181
- let step_ms = crate::core::audio::interpreter::statements::arrow_call::types::arp::
182
- compute_arp_step(duration_ms, 1, &synth_params);
183
- let steps = if step_ms > 0.0 {
184
- ((duration_ms / step_ms).ceil() as usize).max(1)
185
- } else {
186
- 1usize
187
- };
188
-
189
- // For each arp step, call prepare_note to get per-step params and schedule it
190
- for idx in 0..steps {
191
- let (start_abs_ms, freq_step, amp_out, params_out) =
192
- crate::core::audio::interpreter::statements::arrow_call::types::arp::prepare_note(
193
- &note_name,
194
- idx,
195
- steps,
196
- start_ms,
197
- duration_ms,
198
- amp_note,
199
- &synth_params,
200
- &final_note_params,
201
- &automation,
202
- );
203
-
204
- // sub-note duration: default to step_ms so arp steps are audible and sequenced
205
- let sub_duration_ms = if step_ms > 0.0 { step_ms } else { duration_ms };
206
-
207
- audio_engine.insert_note(
208
- waveform_str.to_string(),
209
- freq_step,
210
- amp_out,
211
- start_abs_ms,
212
- sub_duration_ms,
213
- synth_params.clone(),
214
- params_out.clone(),
215
- automation.clone(),
216
- );
217
- }
218
-
219
- // mark handled to avoid the unconditional insert below
220
- handled = true;
221
- }
222
- "pluck" => {
223
- let (_s, _f, amp_out, params_out) =
224
- crate::core::audio::interpreter::statements::arrow_call::types::pluck::prepare_note(
225
- &note_name,
226
- 0,
227
- 1,
228
- start_ms,
229
- duration_ms,
230
- amp_note,
231
- &synth_params,
232
- &final_note_params,
233
- &automation,
234
- );
235
- final_amp = amp_out;
236
- final_note_params = params_out;
237
- }
238
- "pad" => {
239
- let (_s, _f, amp_out, params_out) =
240
- crate::core::audio::interpreter::statements::arrow_call::types::pad::prepare_note(
241
- &note_name,
242
- 0,
243
- 1,
244
- start_ms,
245
- duration_ms,
246
- amp_note,
247
- &synth_params,
248
- &final_note_params,
249
- &automation,
250
- );
251
- final_amp = amp_out;
252
- final_note_params = params_out;
253
- }
254
- _ => {}
255
- }
256
- }
257
-
258
- if !handled {
259
- audio_engine.insert_note(
260
- waveform_str.to_string(),
261
- final_freq,
262
- final_amp,
263
- start_ms,
264
- duration_ms,
265
- synth_params.clone(),
266
- final_note_params,
267
- automation,
268
- );
269
- }
270
- }
271
-
272
- *max_end_time = (*max_end_time).max(end_time);
273
-
274
- if update_cursor {
275
- if let Some(c) = cursor_time.as_mut() {
276
- **c = end_time;
277
- }
278
- }
279
-
280
- return (*max_end_time, end_time);
281
- }
282
-
283
- fn extract_f32(map: &HashMap<String, Value>, key: &str, base_bpm: f32) -> Option<f32> {
284
- map.get(key).and_then(|v| match v {
285
- Value::Number(n) => Some(*n),
286
- Value::Beat(beat_str) => {
287
- let parts: Vec<&str> = beat_str.split('/').collect();
288
- if parts.len() == 2 {
289
- let numerator = parts[0].parse::<f32>().ok()?;
290
- let denominator = parts[1].parse::<f32>().ok()?;
291
-
292
- Some((numerator / denominator) * ((60.0 / base_bpm) * 1000.0))
293
- } else {
294
- None
295
- }
296
- }
297
- _ => None,
298
- })
299
- }
300
-
301
- fn note_to_freq(note: &str) -> f32 {
302
- let notes = [
303
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
304
- ];
305
-
306
- if note.len() < 2 || note.len() > 3 {
307
- return 440.0;
308
- }
309
-
310
- let (name, octave_str) = note.split_at(note.len() - 1);
311
- let semitone = notes.iter().position(|&n| n == name).unwrap_or(9) as i32;
312
- let octave = octave_str.parse::<i32>().unwrap_or(4);
313
- let midi_note = (octave + 1) * 12 + semitone;
314
-
315
- 440.0 * (2.0_f32).powf(((midi_note as f32) - 69.0) / 12.0)
316
- }
@@ -1,3 +0,0 @@
1
- pub mod interprete;
2
- pub mod methods;
3
- pub mod types;
@@ -1,192 +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
- synth_params
7
- .entry("attack".to_string())
8
- .or_insert(DV::Number(1.0));
9
- synth_params
10
- .entry("decay".to_string())
11
- .or_insert(DV::Number(50.0));
12
- synth_params
13
- .entry("sustain".to_string())
14
- .or_insert(DV::Number(0.0));
15
- synth_params
16
- .entry("release".to_string())
17
- .or_insert(DV::Number(120.0));
18
- synth_params
19
- .entry("glide".to_string())
20
- .or_insert(DV::Boolean(false));
21
- synth_params
22
- .entry("slide".to_string())
23
- .or_insert(DV::Boolean(false));
24
- // arp defaults
25
- synth_params
26
- .entry("gate".to_string())
27
- .or_insert(DV::Number(80.0));
28
- synth_params
29
- .entry("pattern".to_string())
30
- .or_insert(DV::String("up".to_string()));
31
- // per-step velocity shaping
32
- synth_params
33
- .entry("velocity_scale".to_string())
34
- .or_insert(DV::Number(0.25));
35
- }
36
-
37
- // Helper to compute an arp step and schedule notes; this is small and returns the computed step
38
- pub fn compute_arp_step(
39
- duration_ms: f32,
40
- note_count: usize,
41
- synth_params: &HashMap<String, Value>,
42
- ) -> f32 {
43
- // New API: synth_params may contain "rate" (beats/duration string or number),
44
- // "pattern" (up, down, updown), and "step" (ms or number)
45
- use devalang_types::Duration as D;
46
-
47
- // If rate is provided as number (notes across duration), use it
48
- if let Some(Value::Number(rate)) = synth_params.get("rate") {
49
- if *rate > 0.0 {
50
- return duration_ms / *rate;
51
- }
52
- }
53
-
54
- // If rate provided as Duration/Beat/String parse as musical fraction -> seconds
55
- if let Some(v) = synth_params.get("rate") {
56
- match v {
57
- Value::Duration(d) => match d {
58
- D::Number(sec) => {
59
- if *sec > 0.0 {
60
- return sec * 1000.0;
61
- }
62
- }
63
- D::Beat(_) | D::Identifier(_) => {
64
- // need bpm; fallback 120
65
- let bpm = synth_params
66
- .get("bpm")
67
- .and_then(|bv| {
68
- if let Value::Number(n) = bv {
69
- Some(*n)
70
- } else {
71
- None
72
- }
73
- })
74
- .unwrap_or(120.0);
75
- if let Some(sec) =
76
- crate::core::audio::engine::driver::duration_to_seconds(d, bpm)
77
- {
78
- if sec > 0.0 {
79
- return sec * 1000.0;
80
- }
81
- }
82
- }
83
- _ => {}
84
- },
85
- Value::String(s) | Value::Identifier(s) => {
86
- let bpm = synth_params
87
- .get("bpm")
88
- .and_then(|bv| {
89
- if let Value::Number(n) = bv {
90
- Some(*n)
91
- } else {
92
- None
93
- }
94
- })
95
- .unwrap_or(120.0);
96
- if let Some(sec) =
97
- crate::core::audio::engine::driver::parse_fraction_to_seconds(s, bpm)
98
- {
99
- if sec > 0.0 {
100
- return sec * 1000.0;
101
- }
102
- }
103
- if let Ok(n) = s.parse::<f32>() {
104
- if n > 0.0 {
105
- return duration_ms / n;
106
- }
107
- }
108
- }
109
- _ => {}
110
- }
111
- }
112
-
113
- // fallback to explicit step param
114
- let default_step = (duration_ms / (note_count as f32)) * 0.5;
115
- match synth_params.get("step") {
116
- Some(Value::Number(n)) => *n,
117
- Some(Value::String(s)) => s.parse::<f32>().unwrap_or(default_step),
118
- Some(Value::Identifier(s)) => s.parse::<f32>().unwrap_or(default_step),
119
- _ => default_step,
120
- }
121
- }
122
-
123
- // Ensure arp defaults include an arp_step if provided as beats / number string
124
- pub fn ensure_arp_step(synth_params: &mut HashMap<String, Value>, default_step: f32) {
125
- use devalang_types::Value as DV;
126
- if !synth_params.contains_key("arp_step") {
127
- synth_params.insert("arp_step".to_string(), DV::Number(default_step));
128
- }
129
- }
130
-
131
- // Prepare per-note scheduling & params for arp
132
- pub fn prepare_note(
133
- note_name: &str,
134
- index: usize,
135
- total: usize,
136
- start_time_ms: f32,
137
- duration_ms: f32,
138
- amp: f32,
139
- synth_params: &HashMap<String, Value>,
140
- note_params: &HashMap<String, Value>,
141
- _automation: &Option<HashMap<String, Value>>,
142
- ) -> (f32, f32, f32, HashMap<String, Value>) {
143
- // compute a slightly syncopated step: half-step + small swing
144
- let mut step = compute_arp_step(duration_ms, total, synth_params);
145
- // introduce simple swing based on index
146
- let swing = match synth_params.get("swing") {
147
- Some(Value::Number(n)) => *n,
148
- _ => 0.05,
149
- };
150
- if index % 2 == 1 {
151
- step *= 1.0 + swing;
152
- }
153
- let start = start_time_ms + (index as f32) * step;
154
- // For now, arp doesn't alter amp or params beyond start offset
155
- let amp_out = amp;
156
- let mut params_out = note_params.clone();
157
- // optionally expose arp-specific params into note params
158
- if let Some(Value::Number(n)) = synth_params.get("gate") {
159
- // normalize gate to 0.0-1.0 if >1 (percent)
160
- let gate_val = if *n > 1.0 { (*n) / 100.0 } else { *n };
161
- params_out
162
- .entry("gate".to_string())
163
- .or_insert(Value::Number(gate_val));
164
- }
165
- // simple velocity curve across arp steps (so later steps can be quieter/louder)
166
- if let Some(Value::Number(vscale)) = synth_params.get("velocity_scale") {
167
- let mult = 1.0 - ((index as f32) / (total as f32)) * (*vscale);
168
- params_out.insert("velocity".to_string(), Value::Number(mult.max(0.0)));
169
- }
170
- // propagate pattern if present (engine or higher layer may use it)
171
- if let Some(Value::String(p)) = synth_params.get("pattern") {
172
- params_out.insert("pattern".to_string(), Value::String(p.clone()));
173
- }
174
- (start, note_to_freq(note_name), amp_out, params_out)
175
- }
176
-
177
- fn note_to_freq(note: &str) -> f32 {
178
- let notes = [
179
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
180
- ];
181
-
182
- if note.len() < 2 || note.len() > 3 {
183
- return 440.0;
184
- }
185
-
186
- let (name, octave_str) = note.split_at(note.len() - 1);
187
- let semitone = notes.iter().position(|&n| n == name).unwrap_or(9) as i32;
188
- let octave = octave_str.parse::<i32>().unwrap_or(4);
189
- let midi_note = (octave + 1) * 12 + semitone;
190
-
191
- 440.0 * (2.0_f32).powf(((midi_note as f32) - 69.0) / 12.0)
192
- }
@@ -1,24 +0,0 @@
1
- pub mod arp;
2
- pub mod pad;
3
- pub mod pluck;
4
- pub mod sub;
5
-
6
- use devalang_types::Value;
7
- use std::collections::HashMap;
8
-
9
- pub fn apply_type(synth_params: &mut HashMap<String, Value>) {
10
- if let Some(tval) = synth_params.get("type") {
11
- let tname = match tval {
12
- Value::String(s) => s.as_str(),
13
- Value::Identifier(s) => s.as_str(),
14
- _ => "",
15
- };
16
- match tname {
17
- "pad" => pad::apply_defaults(synth_params),
18
- "pluck" => pluck::apply_defaults(synth_params),
19
- "arp" => arp::apply_defaults(synth_params),
20
- "sub" => sub::apply_defaults(synth_params),
21
- _ => {}
22
- }
23
- }
24
- }
@@ -1,116 +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
- // pad: long attack/release, high sustain (0.0-1.0)
7
- synth_params
8
- .entry("attack".to_string())
9
- .or_insert(DV::Number(600.0));
10
- synth_params
11
- .entry("decay".to_string())
12
- .or_insert(DV::Number(300.0));
13
- synth_params
14
- .entry("sustain".to_string())
15
- .or_insert(DV::Number(0.8));
16
- synth_params
17
- .entry("release".to_string())
18
- .or_insert(DV::Number(900.0));
19
- // optional unison/voices parameters
20
- synth_params
21
- .entry("voices".to_string())
22
- .or_insert(DV::Number(3.0));
23
- synth_params
24
- .entry("unison_detune".to_string())
25
- .or_insert(DV::Number(15.0));
26
- // slightly wider default chorus/depth for pads
27
- if !synth_params.contains_key("effects") {
28
- let mut ch: std::collections::HashMap<String, Value> = std::collections::HashMap::new();
29
- ch.insert("type".to_string(), Value::String("chorus".to_string()));
30
- ch.insert("depth".to_string(), Value::Number(0.12));
31
- ch.insert("rate".to_string(), Value::Number(0.25));
32
- synth_params.insert("effects".to_string(), DV::Array(vec![DV::Map(ch)]));
33
- }
34
- }
35
-
36
- // Prepare per-note modifications for pad: longer release/attack, gentle detune per-voice
37
- pub fn prepare_note(
38
- _note_name: &str,
39
- index: usize,
40
- total: usize,
41
- _start_time_ms: f32,
42
- _duration_ms: f32,
43
- amp: f32,
44
- synth_params: &HashMap<String, Value>,
45
- note_params: &HashMap<String, Value>,
46
- _automation: &Option<HashMap<String, Value>>,
47
- ) -> (f32, f32, f32, HashMap<String, Value>) {
48
- let mut params_out = note_params.clone();
49
- // inject pad envelope defaults if missing
50
- params_out
51
- .entry("attack".to_string())
52
- .or_insert(Value::Number(600.0));
53
- params_out
54
- .entry("release".to_string())
55
- .or_insert(Value::Number(900.0));
56
- params_out
57
- .entry("sustain".to_string())
58
- .or_insert(Value::Number(0.8));
59
-
60
- // propagate unison/voices into per-note params if synth provided
61
- if let Some(Value::Number(v)) = synth_params.get("voices") {
62
- params_out.insert("voices".to_string(), Value::Number(*v));
63
- }
64
- if let Some(Value::Number(d)) = synth_params.get("unison_detune") {
65
- params_out.insert("unison_detune".to_string(), Value::Number(*d));
66
- }
67
-
68
- // gentle detune based on index and synth param "detune" if present
69
- // gentle detune based on synth detune or unison settings
70
- let detune_base = match synth_params.get("detune") {
71
- Some(Value::Number(n)) => *n,
72
- _ => 0.0,
73
- };
74
- let mut detune = detune_base * ((index as f32) / (total as f32));
75
- // if unison used, spread voices around center
76
- if let Some(Value::Number(_voices)) = synth_params.get("voices") {
77
- if let Some(Value::Number(ud)) = synth_params.get("unison_detune") {
78
- // spread by a fraction based on voice index
79
- detune += (*ud) * (((index as f32) - (total as f32 - 1.0) / 2.0) / (total as f32));
80
- }
81
- }
82
-
83
- params_out.insert("detune".to_string(), Value::Number(detune));
84
-
85
- // compute frequency with detune in cents
86
- let freq = note_to_freq(_note_name) * (2.0_f32).powf(detune / 1200.0);
87
-
88
- // add a subtle chorus placeholder effect if none present (engine may ignore unknown effects)
89
- use devalang_types::Value as DV;
90
- if !params_out.contains_key("effects") {
91
- let mut ch: std::collections::HashMap<String, Value> = std::collections::HashMap::new();
92
- ch.insert("type".to_string(), Value::String("chorus".to_string()));
93
- ch.insert("depth".to_string(), Value::Number(0.15));
94
- ch.insert("rate".to_string(), Value::Number(0.25));
95
- params_out.insert("effects".to_string(), DV::Array(vec![DV::Map(ch)]));
96
- }
97
-
98
- (0.0, freq, amp, params_out)
99
- }
100
-
101
- fn note_to_freq(note: &str) -> f32 {
102
- let notes = [
103
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
104
- ];
105
-
106
- if note.len() < 2 || note.len() > 3 {
107
- return 440.0;
108
- }
109
-
110
- let (name, octave_str) = note.split_at(note.len() - 1);
111
- let semitone = notes.iter().position(|&n| n == name).unwrap_or(9) as i32;
112
- let octave = octave_str.parse::<i32>().unwrap_or(4);
113
- let midi_note = (octave + 1) * 12 + semitone;
114
-
115
- 440.0 * (2.0_f32).powf(((midi_note as f32) - 69.0) / 12.0)
116
- }