@devaloop/devalang 0.0.1-beta.3 → 0.1.2

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 (346) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +251 -221
  3. package/out-tsc/api.d.ts +180 -0
  4. package/out-tsc/api.d.ts.map +1 -0
  5. package/out-tsc/api.js +286 -0
  6. package/out-tsc/api.js.map +1 -0
  7. package/out-tsc/bin/index.d.ts +12 -0
  8. package/out-tsc/bin/index.d.ts.map +1 -0
  9. package/out-tsc/bin/index.js +20 -54
  10. package/out-tsc/bin/index.js.map +1 -0
  11. package/out-tsc/examples/basic-usage.d.ts +8 -0
  12. package/out-tsc/examples/basic-usage.d.ts.map +1 -0
  13. package/out-tsc/examples/basic-usage.js +113 -0
  14. package/out-tsc/examples/basic-usage.js.map +1 -0
  15. package/out-tsc/index.d.ts +19 -5
  16. package/out-tsc/index.d.ts.map +1 -0
  17. package/out-tsc/index.js +24 -6
  18. package/out-tsc/index.js.map +1 -0
  19. package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
  20. package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
  21. package/out-tsc/scripts/copy-wasm-dts.js +36 -32
  22. package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
  23. package/out-tsc/scripts/postinstall.d.ts +1 -0
  24. package/out-tsc/scripts/postinstall.d.ts.map +1 -0
  25. package/out-tsc/scripts/postinstall.js +4 -1
  26. package/out-tsc/scripts/postinstall.js.map +1 -0
  27. package/out-tsc/scripts/version/bump.d.ts +5 -1
  28. package/out-tsc/scripts/version/bump.d.ts.map +1 -0
  29. package/out-tsc/scripts/version/bump.js +122 -44
  30. package/out-tsc/scripts/version/bump.js.map +1 -0
  31. package/out-tsc/scripts/version/fetch.d.ts +12 -1
  32. package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
  33. package/out-tsc/scripts/version/fetch.js +68 -24
  34. package/out-tsc/scripts/version/fetch.js.map +1 -0
  35. package/out-tsc/scripts/version/index.d.ts +6 -0
  36. package/out-tsc/scripts/version/index.d.ts.map +1 -0
  37. package/out-tsc/scripts/version/index.js +44 -22
  38. package/out-tsc/scripts/version/index.js.map +1 -0
  39. package/out-tsc/scripts/version/sync.d.ts +5 -1
  40. package/out-tsc/scripts/version/sync.d.ts.map +1 -0
  41. package/out-tsc/scripts/version/sync.js +95 -29
  42. package/out-tsc/scripts/version/sync.js.map +1 -0
  43. package/out-tsc/types.d.ts +68 -0
  44. package/out-tsc/types.d.ts.map +1 -0
  45. package/out-tsc/{core/types/value.js → types.js} +4 -0
  46. package/out-tsc/types.js.map +1 -0
  47. package/out-tsc/wasm.d.ts +8 -0
  48. package/out-tsc/wasm.d.ts.map +1 -0
  49. package/out-tsc/{core/index.js → wasm.js} +9 -6
  50. package/out-tsc/wasm.js.map +1 -0
  51. package/package.json +42 -42
  52. package/.cargo/config.toml +0 -2
  53. package/.devalang +0 -9
  54. package/.github/workflows/ci.yml +0 -103
  55. package/Cargo.toml +0 -84
  56. package/docs/CHANGELOG.md +0 -622
  57. package/docs/CONTRIBUTING.md +0 -101
  58. package/docs/ROADMAP.md +0 -38
  59. package/docs/TODO.md +0 -71
  60. package/examples/automation.deva +0 -42
  61. package/examples/bank.deva +0 -7
  62. package/examples/bus.deva +0 -10
  63. package/examples/chain.deva +0 -19
  64. package/examples/condition.deva +0 -20
  65. package/examples/duration.deva +0 -9
  66. package/examples/effect.deva +0 -2
  67. package/examples/events.deva +0 -12
  68. package/examples/filter.deva +0 -11
  69. package/examples/function.deva +0 -15
  70. package/examples/group.deva +0 -12
  71. package/examples/index.deva +0 -63
  72. package/examples/lfo.deva +0 -9
  73. package/examples/loop.deva +0 -10
  74. package/examples/pattern.deva +0 -8
  75. package/examples/plugin.deva +0 -16
  76. package/examples/routing.deva +0 -23
  77. package/examples/samples/hat-808.wav +0 -0
  78. package/examples/samples/kick-808.wav +0 -0
  79. package/examples/synth.deva +0 -24
  80. package/examples/synth_types.deva +0 -17
  81. package/examples/variables.deva +0 -9
  82. package/out-tsc/bin/project-version.json +0 -6
  83. package/out-tsc/core/functions/index.d.ts +0 -42
  84. package/out-tsc/core/functions/index.js +0 -87
  85. package/out-tsc/core/index.d.ts +0 -6
  86. package/out-tsc/core/types/index.d.ts +0 -4
  87. package/out-tsc/core/types/index.js +0 -20
  88. package/out-tsc/core/types/plugin.d.ts +0 -18
  89. package/out-tsc/core/types/plugin.js +0 -2
  90. package/out-tsc/core/types/result.d.ts +0 -27
  91. package/out-tsc/core/types/result.js +0 -2
  92. package/out-tsc/core/types/statement.d.ts +0 -106
  93. package/out-tsc/core/types/statement.js +0 -2
  94. package/out-tsc/core/types/value.d.ts +0 -43
  95. package/out-tsc/pkg/devalang_core.d.ts +0 -15
  96. package/out-tsc/pkg/devalang_core.js +0 -65
  97. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
  98. package/out-tsc/scripts/version/copy-to-binary.d.ts +0 -1
  99. package/out-tsc/scripts/version/copy-to-binary.js +0 -79
  100. package/project-version.json +0 -6
  101. package/rust/bindings/Cargo.toml +0 -9
  102. package/rust/bindings/src/lib.rs +0 -86
  103. package/rust/cli/addon/commands.rs +0 -35
  104. package/rust/cli/addon/download.rs +0 -234
  105. package/rust/cli/addon/install.rs +0 -33
  106. package/rust/cli/addon/list.rs +0 -224
  107. package/rust/cli/addon/metadata.rs +0 -124
  108. package/rust/cli/addon/mod.rs +0 -8
  109. package/rust/cli/addon/remove.rs +0 -271
  110. package/rust/cli/addon/update.rs +0 -305
  111. package/rust/cli/addon/utils.rs +0 -109
  112. package/rust/cli/build/commands.rs +0 -153
  113. package/rust/cli/build/mod.rs +0 -2
  114. package/rust/cli/build/process.rs +0 -165
  115. package/rust/cli/check/mod.rs +0 -208
  116. package/rust/cli/discover/commands.rs +0 -275
  117. package/rust/cli/discover/config.rs +0 -109
  118. package/rust/cli/discover/fs.rs +0 -19
  119. package/rust/cli/discover/install.rs +0 -214
  120. package/rust/cli/discover/metadata.rs +0 -48
  121. package/rust/cli/discover/mod.rs +0 -5
  122. package/rust/cli/init/commands.rs +0 -88
  123. package/rust/cli/init/mod.rs +0 -1
  124. package/rust/cli/login/commands.rs +0 -124
  125. package/rust/cli/login/mod.rs +0 -1
  126. package/rust/cli/me/commands.rs +0 -52
  127. package/rust/cli/me/mod.rs +0 -1
  128. package/rust/cli/mod.rs +0 -12
  129. package/rust/cli/parser.rs +0 -320
  130. package/rust/cli/play/commands.rs +0 -375
  131. package/rust/cli/play/io.rs +0 -17
  132. package/rust/cli/play/mod.rs +0 -5
  133. package/rust/cli/play/process.rs +0 -159
  134. package/rust/cli/play/realtime.rs +0 -91
  135. package/rust/cli/play/utils.rs +0 -23
  136. package/rust/cli/telemetry/commands.rs +0 -22
  137. package/rust/cli/telemetry/event_creator.rs +0 -80
  138. package/rust/cli/telemetry/mod.rs +0 -3
  139. package/rust/cli/telemetry/send.rs +0 -51
  140. package/rust/cli/template/commands.rs +0 -69
  141. package/rust/cli/template/mod.rs +0 -1
  142. package/rust/cli/update/commands.rs +0 -6
  143. package/rust/cli/update/mod.rs +0 -1
  144. package/rust/config/driver.rs +0 -112
  145. package/rust/config/mod.rs +0 -3
  146. package/rust/config/ops.rs +0 -26
  147. package/rust/config/settings.rs +0 -101
  148. package/rust/core/audio/engine/driver.rs +0 -237
  149. package/rust/core/audio/engine/export.rs +0 -169
  150. package/rust/core/audio/engine/helpers.rs +0 -178
  151. package/rust/core/audio/engine/mod.rs +0 -56
  152. package/rust/core/audio/engine/notes/dsp.rs +0 -88
  153. package/rust/core/audio/engine/notes/mod.rs +0 -53
  154. package/rust/core/audio/engine/notes/params.rs +0 -294
  155. package/rust/core/audio/engine/sample/insert.rs +0 -300
  156. package/rust/core/audio/engine/sample/mod.rs +0 -40
  157. package/rust/core/audio/engine/sample/padding.rs +0 -170
  158. package/rust/core/audio/evaluator/condition.rs +0 -61
  159. package/rust/core/audio/evaluator/mod.rs +0 -9
  160. package/rust/core/audio/evaluator/numeric.rs +0 -152
  161. package/rust/core/audio/evaluator/rhs.rs +0 -16
  162. package/rust/core/audio/evaluator/string_expr.rs +0 -94
  163. package/rust/core/audio/interpreter/driver.rs +0 -574
  164. package/rust/core/audio/interpreter/mod.rs +0 -2
  165. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -179
  166. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -398
  167. package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +0 -323
  168. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -3
  169. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -371
  170. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
  171. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
  172. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
  173. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
  174. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
  175. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
  176. package/rust/core/audio/interpreter/statements/automate.rs +0 -16
  177. package/rust/core/audio/interpreter/statements/call.rs +0 -325
  178. package/rust/core/audio/interpreter/statements/condition.rs +0 -72
  179. package/rust/core/audio/interpreter/statements/function.rs +0 -24
  180. package/rust/core/audio/interpreter/statements/let_.rs +0 -36
  181. package/rust/core/audio/interpreter/statements/load.rs +0 -17
  182. package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
  183. package/rust/core/audio/interpreter/statements/mod.rs +0 -12
  184. package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
  185. package/rust/core/audio/interpreter/statements/spawn.rs +0 -302
  186. package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
  187. package/rust/core/audio/interpreter/statements/trigger.rs +0 -242
  188. package/rust/core/audio/loader/mod.rs +0 -1
  189. package/rust/core/audio/loader/trigger.rs +0 -98
  190. package/rust/core/audio/mod.rs +0 -6
  191. package/rust/core/audio/player.rs +0 -70
  192. package/rust/core/audio/special/easing.rs +0 -189
  193. package/rust/core/audio/special/env.rs +0 -45
  194. package/rust/core/audio/special/math.rs +0 -134
  195. package/rust/core/audio/special/mod.rs +0 -9
  196. package/rust/core/audio/special/modulator.rs +0 -143
  197. package/rust/core/builder/mod.rs +0 -129
  198. package/rust/core/debugger/lexer.rs +0 -27
  199. package/rust/core/debugger/logs.rs +0 -52
  200. package/rust/core/debugger/mod.rs +0 -30
  201. package/rust/core/debugger/preprocessor.rs +0 -27
  202. package/rust/core/debugger/store.rs +0 -38
  203. package/rust/core/error/mod.rs +0 -269
  204. package/rust/core/lexer/driver.rs +0 -59
  205. package/rust/core/lexer/handler/arrow.rs +0 -82
  206. package/rust/core/lexer/handler/at.rs +0 -21
  207. package/rust/core/lexer/handler/brace.rs +0 -41
  208. package/rust/core/lexer/handler/colon.rs +0 -21
  209. package/rust/core/lexer/handler/comment.rs +0 -30
  210. package/rust/core/lexer/handler/dot.rs +0 -21
  211. package/rust/core/lexer/handler/driver.rs +0 -337
  212. package/rust/core/lexer/handler/identifier.rs +0 -47
  213. package/rust/core/lexer/handler/indent.rs +0 -66
  214. package/rust/core/lexer/handler/mod.rs +0 -15
  215. package/rust/core/lexer/handler/newline.rs +0 -23
  216. package/rust/core/lexer/handler/number.rs +0 -31
  217. package/rust/core/lexer/handler/operator.rs +0 -46
  218. package/rust/core/lexer/handler/parenthesis.rs +0 -41
  219. package/rust/core/lexer/handler/slash.rs +0 -21
  220. package/rust/core/lexer/handler/string.rs +0 -63
  221. package/rust/core/lexer/mod.rs +0 -3
  222. package/rust/core/lexer/token.rs +0 -91
  223. package/rust/core/mod.rs +0 -9
  224. package/rust/core/parser/driver/block.rs +0 -111
  225. package/rust/core/parser/driver/cursor.rs +0 -82
  226. package/rust/core/parser/driver/driver_impl.rs +0 -159
  227. package/rust/core/parser/driver/mod.rs +0 -6
  228. package/rust/core/parser/driver/parse_array.rs +0 -120
  229. package/rust/core/parser/driver/parse_map.rs +0 -247
  230. package/rust/core/parser/driver/parser.rs +0 -160
  231. package/rust/core/parser/handler/arrow_call.rs +0 -328
  232. package/rust/core/parser/handler/at.rs +0 -279
  233. package/rust/core/parser/handler/bank.rs +0 -104
  234. package/rust/core/parser/handler/condition.rs +0 -83
  235. package/rust/core/parser/handler/dot.rs +0 -148
  236. package/rust/core/parser/handler/identifier/automate.rs +0 -254
  237. package/rust/core/parser/handler/identifier/call.rs +0 -91
  238. package/rust/core/parser/handler/identifier/emit.rs +0 -70
  239. package/rust/core/parser/handler/identifier/function.rs +0 -113
  240. package/rust/core/parser/handler/identifier/group.rs +0 -89
  241. package/rust/core/parser/handler/identifier/let_.rs +0 -173
  242. package/rust/core/parser/handler/identifier/mod.rs +0 -55
  243. package/rust/core/parser/handler/identifier/on.rs +0 -107
  244. package/rust/core/parser/handler/identifier/print.rs +0 -49
  245. package/rust/core/parser/handler/identifier/sleep.rs +0 -96
  246. package/rust/core/parser/handler/identifier/spawn.rs +0 -91
  247. package/rust/core/parser/handler/identifier/synth.rs +0 -171
  248. package/rust/core/parser/handler/loop_.rs +0 -194
  249. package/rust/core/parser/handler/mod.rs +0 -9
  250. package/rust/core/parser/handler/pattern.rs +0 -97
  251. package/rust/core/parser/handler/tempo.rs +0 -105
  252. package/rust/core/parser/mod.rs +0 -3
  253. package/rust/core/parser/statement.rs +0 -10
  254. package/rust/core/plugin/loader.rs +0 -137
  255. package/rust/core/plugin/mod.rs +0 -2
  256. package/rust/core/plugin/runner/mod.rs +0 -11
  257. package/rust/core/plugin/runner/non_wasm.rs +0 -481
  258. package/rust/core/plugin/runner/wasm32.rs +0 -44
  259. package/rust/core/preprocessor/loader/inject.rs +0 -313
  260. package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
  261. package/rust/core/preprocessor/loader/mod.rs +0 -235
  262. package/rust/core/preprocessor/mod.rs +0 -4
  263. package/rust/core/preprocessor/module.rs +0 -55
  264. package/rust/core/preprocessor/processor/handlers.rs +0 -107
  265. package/rust/core/preprocessor/processor/mod.rs +0 -1
  266. package/rust/core/preprocessor/resolver/bank.rs +0 -49
  267. package/rust/core/preprocessor/resolver/call.rs +0 -124
  268. package/rust/core/preprocessor/resolver/condition.rs +0 -95
  269. package/rust/core/preprocessor/resolver/driver.rs +0 -324
  270. package/rust/core/preprocessor/resolver/function.rs +0 -69
  271. package/rust/core/preprocessor/resolver/group.rs +0 -122
  272. package/rust/core/preprocessor/resolver/let_.rs +0 -32
  273. package/rust/core/preprocessor/resolver/loop_.rs +0 -318
  274. package/rust/core/preprocessor/resolver/mod.rs +0 -16
  275. package/rust/core/preprocessor/resolver/pattern.rs +0 -95
  276. package/rust/core/preprocessor/resolver/spawn.rs +0 -99
  277. package/rust/core/preprocessor/resolver/synth.rs +0 -54
  278. package/rust/core/preprocessor/resolver/tempo.rs +0 -48
  279. package/rust/core/preprocessor/resolver/trigger.rs +0 -116
  280. package/rust/core/preprocessor/resolver/value.rs +0 -176
  281. package/rust/core/store/global.rs +0 -57
  282. package/rust/core/store/mod.rs +0 -1
  283. package/rust/lib.rs +0 -323
  284. package/rust/macros/Cargo.toml +0 -14
  285. package/rust/macros/src/lib.rs +0 -52
  286. package/rust/main.rs +0 -557
  287. package/rust/types/Cargo.toml +0 -11
  288. package/rust/types/src/addons.rs +0 -57
  289. package/rust/types/src/ast.rs +0 -202
  290. package/rust/types/src/config.rs +0 -82
  291. package/rust/types/src/lib.rs +0 -15
  292. package/rust/types/src/plugin.rs +0 -20
  293. package/rust/types/src/store.rs +0 -139
  294. package/rust/types/src/telemetry.rs +0 -85
  295. package/rust/utils/Cargo.toml +0 -29
  296. package/rust/utils/src/error.rs +0 -186
  297. package/rust/utils/src/file.rs +0 -477
  298. package/rust/utils/src/first_usage.rs +0 -97
  299. package/rust/utils/src/lib.rs +0 -9
  300. package/rust/utils/src/logger.rs +0 -200
  301. package/rust/utils/src/path.rs +0 -158
  302. package/rust/utils/src/signature.rs +0 -41
  303. package/rust/utils/src/spinner.rs +0 -20
  304. package/rust/utils/src/version.rs +0 -58
  305. package/rust/utils/src/watcher.rs +0 -46
  306. package/rust/web/api.rs +0 -5
  307. package/rust/web/auth.rs +0 -5
  308. package/rust/web/cdn.rs +0 -34
  309. package/rust/web/forge.rs +0 -5
  310. package/rust/web/mod.rs +0 -5
  311. package/rust/web/sso.rs +0 -5
  312. package/templates/minimal/.devalang +0 -5
  313. package/templates/minimal/README.md +0 -218
  314. package/templates/minimal/src/index.deva +0 -2
  315. package/templates/welcome/.devalang +0 -5
  316. package/templates/welcome/README.md +0 -218
  317. package/templates/welcome/samples/kick-808.wav +0 -0
  318. package/templates/welcome/src/index.deva +0 -61
  319. package/templates/welcome/src/variables.deva +0 -3
  320. package/tests/integration.rs +0 -21
  321. package/tests/rust/cli_check_build.rs +0 -21
  322. package/tests/rust/cli_help.rs +0 -12
  323. package/tests/rust/cli_template_list.rs +0 -10
  324. package/tests/rust/cli_version.rs +0 -11
  325. package/tests/typescript/index.spec.ts +0 -136
  326. package/tests/typescript/playhead.spec.ts +0 -36
  327. package/tests/typescript/render_e2e.spec.ts +0 -77
  328. package/tsconfig.json +0 -115
  329. package/typescript/bin/index.ts +0 -28
  330. package/typescript/core/functions/index.ts +0 -94
  331. package/typescript/core/index.ts +0 -6
  332. package/typescript/core/types/index.ts +0 -4
  333. package/typescript/core/types/plugin.ts +0 -19
  334. package/typescript/core/types/result.ts +0 -29
  335. package/typescript/core/types/statement.ts +0 -47
  336. package/typescript/core/types/value.ts +0 -29
  337. package/typescript/index.ts +0 -8
  338. package/typescript/pkg/devalang_core.d.ts +0 -4
  339. package/typescript/pkg/devalang_core.ts +0 -65
  340. package/typescript/scripts/copy-wasm-dts.ts +0 -41
  341. package/typescript/scripts/postinstall.ts +0 -85
  342. package/typescript/scripts/version/bump.ts +0 -44
  343. package/typescript/scripts/version/copy-to-binary.ts +0 -82
  344. package/typescript/scripts/version/fetch.ts +0 -18
  345. package/typescript/scripts/version/index.ts +0 -25
  346. package/typescript/scripts/version/sync.ts +0 -24
@@ -1,169 +0,0 @@
1
- use crate::core::audio::engine::driver::MidiNoteEvent;
2
- use std::fs::File;
3
-
4
- pub fn generate_midi_file_impl(
5
- midi_events: &Vec<MidiNoteEvent>,
6
- output_path: &String,
7
- bpm: Option<f32>,
8
- tpqn: Option<u16>,
9
- ) -> Result<(), String> {
10
- use midly::num::{u7, u15, u24};
11
- use midly::{
12
- Format, Header, MetaMessage, MidiMessage, Smf, Timing, TrackEvent, TrackEventKind,
13
- };
14
-
15
- if midi_events.is_empty() {
16
- return Ok(());
17
- }
18
-
19
- let bpm = bpm.unwrap_or(120.0_f32);
20
- let tpqn: u16 = tpqn.unwrap_or(480u16);
21
- let header = Header {
22
- format: Format::SingleTrack,
23
- timing: Timing::Metrical(u15::from(tpqn)),
24
- };
25
-
26
- #[derive(Clone)]
27
- struct AbsEvent {
28
- tick: u64,
29
- kind: TrackEventKind<'static>,
30
- }
31
-
32
- let mut abs_events: Vec<AbsEvent> = Vec::new();
33
- let microsecs_per_quarter = (60_000_000.0 / bpm) as u32;
34
- abs_events.push(AbsEvent {
35
- tick: 0,
36
- kind: TrackEventKind::Meta(MetaMessage::Tempo(u24::from(microsecs_per_quarter))),
37
- });
38
-
39
- for ev in midi_events {
40
- let start_secs = (ev.start_ms as f32) / 1000.0;
41
- let dur_secs = (ev.duration_ms as f32) / 1000.0;
42
- let start_ticks_f = start_secs * (bpm / 60.0) * (tpqn as f32);
43
- let dur_ticks_f = dur_secs * (bpm / 60.0) * (tpqn as f32);
44
- let start_tick = start_ticks_f.max(0.0).round() as u64;
45
- let off_tick = (start_ticks_f + dur_ticks_f).max(start_tick as f32).round() as u64;
46
-
47
- let key = u7::from(ev.key.min(127));
48
- let vel = u7::from(ev.vel.min(127));
49
-
50
- abs_events.push(AbsEvent {
51
- tick: start_tick,
52
- kind: TrackEventKind::Midi {
53
- channel: (ev.channel as u8).into(),
54
- message: MidiMessage::NoteOn { key, vel },
55
- },
56
- });
57
-
58
- abs_events.push(AbsEvent {
59
- tick: off_tick,
60
- kind: TrackEventKind::Midi {
61
- channel: (ev.channel as u8).into(),
62
- message: MidiMessage::NoteOff {
63
- key,
64
- vel: u7::from(0),
65
- },
66
- },
67
- });
68
- }
69
-
70
- let max_tick = abs_events.iter().map(|e| e.tick).max().unwrap_or(0);
71
- abs_events.push(AbsEvent {
72
- tick: max_tick + 0,
73
- kind: TrackEventKind::Meta(MetaMessage::EndOfTrack),
74
- });
75
- abs_events.sort_by_key(|e| e.tick);
76
-
77
- let mut track: Vec<TrackEvent> = Vec::new();
78
- let mut last_tick: u64 = 0;
79
- for e in abs_events {
80
- let delta = (e.tick - last_tick) as u32;
81
- track.push(TrackEvent {
82
- delta: delta.into(),
83
- kind: e.kind,
84
- });
85
- last_tick = e.tick;
86
- }
87
-
88
- let smf = Smf {
89
- header,
90
- tracks: vec![track],
91
- };
92
-
93
- if let Ok(mut file) = File::create(output_path) {
94
- if let Err(e) = smf.write_std(&mut file) {
95
- return Err(format!("Error writing MIDI file: {}", e));
96
- }
97
- } else {
98
- return Err(format!("Cannot create MIDI file at {}", output_path));
99
- }
100
-
101
- Ok(())
102
- }
103
-
104
- pub fn generate_wav_file_impl(
105
- buffer: &mut Vec<i16>,
106
- output_dir: &String,
107
- audio_format: Option<String>,
108
- sample_rate: Option<u32>,
109
- ) -> Result<(), String> {
110
- if buffer.len() % (crate::core::audio::engine::CHANNELS as usize) != 0 {
111
- buffer.push(0);
112
- }
113
-
114
- let sr = sample_rate.unwrap_or(crate::core::audio::engine::SAMPLE_RATE);
115
- let format_str = audio_format.unwrap_or_else(|| "Wav16".to_string());
116
- let fmt_low = format_str.to_lowercase();
117
-
118
- match fmt_low.as_str() {
119
- "wav16" => {
120
- let spec = hound::WavSpec {
121
- channels: crate::core::audio::engine::CHANNELS,
122
- sample_rate: sr,
123
- bits_per_sample: 16,
124
- sample_format: hound::SampleFormat::Int,
125
- };
126
-
127
- let mut writer = hound::WavWriter::create(output_dir, spec)
128
- .map_err(|e| format!("Error creating WAV file: {}", e))?;
129
-
130
- for sample in buffer.iter() {
131
- writer
132
- .write_sample(*sample)
133
- .map_err(|e| format!("Error writing sample: {:?}", e))?;
134
- }
135
-
136
- writer
137
- .finalize()
138
- .map_err(|e| format!("Error finalizing WAV: {:?}", e))?;
139
- }
140
- "wav24" | "wav32" => {
141
- let bits = if fmt_low.contains("24") { 24 } else { 32 };
142
- let spec = hound::WavSpec {
143
- channels: crate::core::audio::engine::CHANNELS,
144
- sample_rate: sr,
145
- bits_per_sample: bits,
146
- sample_format: hound::SampleFormat::Int,
147
- };
148
-
149
- let mut writer = hound::WavWriter::create(output_dir, spec)
150
- .map_err(|e| format!("Error creating WAV file: {}", e))?;
151
-
152
- for &s in buffer.iter() {
153
- let v32 = (s as i32) << (bits - 16);
154
- writer
155
- .write_sample(v32)
156
- .map_err(|e| format!("Error writing sample: {:?}", e))?;
157
- }
158
-
159
- writer
160
- .finalize()
161
- .map_err(|e| format!("Error finalizing WAV: {:?}", e))?;
162
- }
163
- _ => {
164
- return Err(format!("Unsupported audio format: {}", format_str));
165
- }
166
- }
167
-
168
- Ok(())
169
- }
@@ -1,178 +0,0 @@
1
- use devalang_types::Value;
2
- use std::collections::HashMap;
3
-
4
- type OptMap = Option<HashMap<String, Value>>;
5
-
6
- pub fn env_maps_from_automation(
7
- automation: &Option<HashMap<String, Value>>,
8
- ) -> (OptMap, OptMap, OptMap) {
9
- if let Some(auto) = automation {
10
- let vol = match auto.get("volume") {
11
- Some(Value::Map(m)) => Some(m.clone()),
12
- _ => None,
13
- };
14
- let pan = match auto.get("pan") {
15
- Some(Value::Map(m)) => Some(m.clone()),
16
- _ => None,
17
- };
18
- let pit = match auto.get("pitch") {
19
- Some(Value::Map(m)) => Some(m.clone()),
20
- _ => None,
21
- };
22
- (vol, pan, pit)
23
- } else {
24
- (None, None, None)
25
- }
26
- }
27
-
28
- /// Convert an Option<HashMap<..>> into a HashMap (empty if None).
29
- pub fn env_map_to_hash(opt: &Option<HashMap<String, Value>>) -> HashMap<String, Value> {
30
- match opt {
31
- Some(m) => m.clone(),
32
- None => HashMap::new(),
33
- }
34
- }
35
-
36
- pub fn eval_env_map(
37
- env_opt: &Option<HashMap<String, Value>>,
38
- progress: f32,
39
- default_val: f32,
40
- ) -> f32 {
41
- let env = match env_opt {
42
- Some(m) => m,
43
- None => {
44
- return default_val;
45
- }
46
- };
47
- let mut points: Vec<(f32, f32)> = Vec::with_capacity(env.len());
48
- for (k, v) in env.iter() {
49
- let key = if k.ends_with('%') {
50
- &k[..k.len() - 1]
51
- } else {
52
- &k[..]
53
- };
54
- if let Ok(mut p) = key.parse::<f32>() {
55
- p = (p / 100.0).clamp(0.0, 1.0);
56
- let val = match v {
57
- Value::Number(n) => *n,
58
- Value::String(s) => s.parse::<f32>().unwrap_or(default_val),
59
- Value::Identifier(s) => s.parse::<f32>().unwrap_or(default_val),
60
- _ => default_val,
61
- };
62
- points.push((p, val));
63
- }
64
- }
65
- if points.is_empty() {
66
- return default_val;
67
- }
68
- points.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
69
- let t = progress.clamp(0.0, 1.0);
70
- if t <= points[0].0 {
71
- return points[0].1;
72
- }
73
- if t >= points[points.len() - 1].0 {
74
- return points[points.len() - 1].1;
75
- }
76
- for w in points.windows(2) {
77
- let (p0, v0) = w[0];
78
- let (p1, v1) = w[1];
79
- if t >= p0 && t <= p1 {
80
- let ratio = if (p1 - p0).abs() < f32::EPSILON {
81
- 0.0
82
- } else {
83
- (t - p0) / (p1 - p0)
84
- };
85
- return v0 + (v1 - v0) * ratio;
86
- }
87
- }
88
- default_val
89
- }
90
-
91
- pub fn oscillator_sample(waveform: &str, current_freq: f32, t: f32) -> f32 {
92
- let phase = 2.0 * std::f32::consts::PI * current_freq * t;
93
- match waveform {
94
- "sine" => phase.sin(),
95
- "square" => {
96
- if phase.sin() >= 0.0 {
97
- 1.0
98
- } else {
99
- -1.0
100
- }
101
- }
102
- "saw" => 2.0 * (current_freq * t - (current_freq * t + 0.5).floor()),
103
- "triangle" => (2.0 * (2.0 * (current_freq * t).fract() - 1.0)).abs() * 2.0 - 1.0,
104
- _ => 0.0,
105
- }
106
- }
107
-
108
- pub fn adsr_envelope_value(
109
- i: usize,
110
- attack_samples: usize,
111
- decay_samples: usize,
112
- sustain_samples: usize,
113
- release_samples: usize,
114
- sustain_level: f32,
115
- ) -> f32 {
116
- let attack_start = 0usize;
117
- let decay_start = attack_samples;
118
- let sustain_start = attack_samples + decay_samples;
119
- let release_start = attack_samples + decay_samples + sustain_samples;
120
-
121
- if i < attack_start + attack_samples && attack_samples > 0 {
122
- let k = i - attack_start;
123
- let denom = if attack_samples > 1 {
124
- (attack_samples - 1) as f32
125
- } else {
126
- 1.0
127
- };
128
- (k as f32) / denom
129
- } else if i < decay_start + decay_samples && decay_samples > 0 {
130
- let k = i - decay_start;
131
- let denom = if decay_samples > 1 {
132
- (decay_samples - 1) as f32
133
- } else {
134
- 1.0
135
- };
136
- let ratio = (k as f32) / denom;
137
- 1.0 - (1.0 - sustain_level) * ratio
138
- } else if i < sustain_start + sustain_samples {
139
- sustain_level
140
- } else if release_samples > 0 {
141
- // release: interpolate from sustain_level down to 0 inclusive
142
- let k = i.saturating_sub(release_start);
143
- let denom = if release_samples > 1 {
144
- (release_samples - 1) as f32
145
- } else {
146
- 1.0
147
- };
148
- let ratio = (k as f32) / denom;
149
- let val = sustain_level * (1.0 - ratio);
150
- if val < 0.0 { 0.0 } else { val }
151
- } else {
152
- 0.0
153
- }
154
- }
155
-
156
- pub fn pan_gains(pan_val: f32) -> (f32, f32) {
157
- let left_gain = 1.0 - pan_val.max(0.0);
158
- let right_gain = 1.0 + pan_val.min(0.0);
159
- (left_gain, right_gain)
160
- }
161
-
162
- pub fn mix_stereo_samples_into_buffer(
163
- engine: &mut super::driver::AudioEngine,
164
- start_sample: usize,
165
- channels: usize,
166
- stereo_samples: &[i16],
167
- ) {
168
- let offset = start_sample * channels;
169
- let required_len = offset + stereo_samples.len();
170
-
171
- if engine.buffer.len() < required_len {
172
- engine.buffer.resize(required_len, 0);
173
- }
174
-
175
- for (i, sample) in stereo_samples.iter().enumerate() {
176
- engine.buffer[offset + i] = engine.buffer[offset + i].saturating_add(*sample);
177
- }
178
- }
@@ -1,56 +0,0 @@
1
- pub mod driver;
2
- pub mod export;
3
- pub mod helpers;
4
- pub mod notes;
5
- pub mod sample;
6
-
7
- pub use driver::AudioEngine;
8
-
9
- pub use driver::CHANNELS;
10
- pub use driver::MidiNoteEvent;
11
- pub use driver::SAMPLE_RATE;
12
- pub use helpers::*;
13
-
14
- use crate::core::audio::interpreter::driver::run_audio_program;
15
- use crate::core::parser::statement::Statement;
16
- use crate::core::store::global::GlobalStore;
17
- use devalang_types::{FunctionTable, VariableTable};
18
- use std::collections::HashMap;
19
-
20
- /// Render audio for a set of parsed modules.
21
- ///
22
- /// For each entry in `modules` (module path -> statements), create an
23
- /// AudioEngine, setup empty module-local VariableTable and FunctionTable,
24
- /// invoke the interpreter driver to schedule audio into the engine, and
25
- /// return a map of module name -> AudioEngine.
26
- pub fn render_audio_with_modules(
27
- modules: HashMap<String, Vec<Statement>>,
28
- _output_dir: &str,
29
- global_store: &mut GlobalStore,
30
- ) -> HashMap<String, AudioEngine> {
31
- let mut result: HashMap<String, AudioEngine> = HashMap::new();
32
-
33
- for (module_name, statements) in modules.into_iter() {
34
- // Create engine named after module (used for diagnostics)
35
- let mut engine = AudioEngine::new(module_name.clone());
36
-
37
- // Create empty module-local tables; interpreter expects these as starting context
38
- let module_vars = VariableTable::new();
39
- let module_funcs = FunctionTable::new();
40
-
41
- // Run interpreter which will populate the engine.buffer and midi events
42
- let (_max_end_time, _cursor_time) = run_audio_program(
43
- &statements,
44
- &mut engine,
45
- module_name.clone(),
46
- module_name.clone(),
47
- module_vars,
48
- module_funcs,
49
- global_store,
50
- );
51
-
52
- result.insert(module_name, engine);
53
- }
54
-
55
- result
56
- }
@@ -1,88 +0,0 @@
1
- use crate::core::audio::engine::notes::params::NoteSetup;
2
- use devalang_types::Value;
3
- use std::collections::HashMap;
4
-
5
- pub fn render_notes_into_buffer(
6
- engine: &mut crate::core::audio::engine::AudioEngine,
7
- _waveform: &str,
8
- _freq: f32,
9
- _amp: f32,
10
- _start_time_ms: f32,
11
- _duration_ms: f32,
12
- _synth_params: HashMap<String, Value>,
13
- _note_params: HashMap<String, Value>,
14
- _automation: Option<HashMap<String, Value>>,
15
- setup: NoteSetup,
16
- ) -> Vec<(usize, usize)> {
17
- use crate::core::audio::engine::helpers;
18
-
19
- let sample_rate = setup.sample_rate;
20
- let channels = setup.channels;
21
- let total_samples = setup.total_samples;
22
- let start_sample = setup.start_sample;
23
-
24
- let mut stereo_samples: Vec<i16> = Vec::with_capacity(total_samples * channels);
25
- let fade_len = (sample_rate * 0.01) as usize; // 10ms fade
26
-
27
- for i in 0..total_samples {
28
- let t = ((start_sample + i) as f32) / sample_rate;
29
-
30
- // simplified voice/unison and oscillator sampling
31
- let mut value = helpers::oscillator_sample(_waveform, _freq, t);
32
-
33
- // apply ADSR envelope
34
- let envelope = helpers::adsr_envelope_value(
35
- i,
36
- setup.attack_samples,
37
- setup.decay_samples,
38
- if total_samples > setup.attack_samples + setup.decay_samples + setup.release_samples {
39
- total_samples - setup.attack_samples - setup.decay_samples - setup.release_samples
40
- } else {
41
- 0
42
- },
43
- setup.release_samples,
44
- setup.sustain_level,
45
- );
46
-
47
- value *= envelope * (i16::MAX as f32) * _amp;
48
-
49
- if fade_len > 0 && i < fade_len {
50
- if fade_len == 1 {
51
- value *= 0.0;
52
- } else {
53
- value *= (i as f32) / (fade_len as f32);
54
- }
55
- } else if fade_len > 0 && i >= total_samples.saturating_sub(fade_len) {
56
- if fade_len == 1 {
57
- value *= 0.0;
58
- } else {
59
- value *= ((total_samples - 1 - i) as f32) / ((fade_len - 1) as f32);
60
- }
61
- }
62
-
63
- let (left_gain, right_gain) = helpers::pan_gains(0.0);
64
- let left = (value * left_gain)
65
- .round()
66
- .clamp(i16::MIN as f32, i16::MAX as f32) as i16;
67
- let right = (value * right_gain)
68
- .round()
69
- .clamp(i16::MIN as f32, i16::MAX as f32) as i16;
70
-
71
- // push samples interleaved for channels=2, fallback zeros for other channel counts
72
- if channels >= 2 {
73
- stereo_samples.push(left);
74
- stereo_samples.push(right);
75
- } else if channels == 1 {
76
- stereo_samples.push(((left as i32 + right as i32) / 2) as i16);
77
- } else {
78
- stereo_samples.push(left);
79
- stereo_samples.push(right);
80
- }
81
- }
82
-
83
- engine.note_count = engine.note_count.saturating_add(1);
84
- helpers::mix_stereo_samples_into_buffer(engine, start_sample, channels, &stereo_samples);
85
-
86
- // Return the inserted sample range for this note (start_sample, total_samples)
87
- vec![(start_sample, stereo_samples.len())]
88
- }
@@ -1,53 +0,0 @@
1
- use devalang_types::Value;
2
- use std::collections::HashMap;
3
-
4
- pub mod dsp;
5
- pub mod params;
6
-
7
- // Minimal safe facade: parse the setup then call DSP renderer.
8
-
9
- pub fn insert_note_impl(
10
- engine: &mut crate::core::audio::engine::AudioEngine,
11
- owner: Option<String>,
12
- waveform: String,
13
- freq: f32,
14
- amp: f32,
15
- start_time_ms: f32,
16
- duration_ms: f32,
17
- synth_params: HashMap<String, Value>,
18
- note_params: HashMap<String, Value>,
19
- automation: Option<HashMap<String, Value>>,
20
- ) -> Vec<(usize, usize)> {
21
- let setup = params::build_note_setup(
22
- engine,
23
- &waveform,
24
- freq,
25
- amp,
26
- start_time_ms,
27
- duration_ms,
28
- &synth_params,
29
- &note_params,
30
- &automation,
31
- );
32
-
33
- let ranges = dsp::render_notes_into_buffer(
34
- engine,
35
- &waveform,
36
- freq,
37
- amp,
38
- start_time_ms,
39
- duration_ms,
40
- synth_params,
41
- note_params,
42
- automation,
43
- setup,
44
- );
45
-
46
- if let Some(owner_name) = owner {
47
- for (start, len) in ranges.iter() {
48
- engine.record_last_note_range(&owner_name, *start, *len);
49
- }
50
- }
51
-
52
- ranges
53
- }