@devaloop/devalang 0.0.1-beta.1 → 0.0.1-beta.3

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 (207) hide show
  1. package/.devalang +9 -10
  2. package/Cargo.toml +84 -80
  3. package/README.md +10 -7
  4. package/docs/CHANGELOG.md +83 -0
  5. package/docs/ROADMAP.md +6 -2
  6. package/docs/TODO.md +3 -14
  7. package/examples/bus.deva +10 -0
  8. package/examples/chain.deva +19 -0
  9. package/examples/effect.deva +2 -0
  10. package/examples/filter.deva +11 -0
  11. package/examples/lfo.deva +9 -0
  12. package/examples/plugin.deva +10 -10
  13. package/examples/routing.deva +23 -0
  14. package/examples/synth.deva +11 -1
  15. package/examples/synth_types.deva +17 -0
  16. package/out-tsc/bin/project-version.json +6 -0
  17. package/out-tsc/core/functions/index.d.ts +5 -0
  18. package/out-tsc/core/functions/index.js +11 -0
  19. package/out-tsc/pkg/devalang_core.d.ts +2 -0
  20. package/out-tsc/pkg/devalang_core.js +17 -2
  21. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +1 -0
  22. package/out-tsc/scripts/version/copy-to-binary.d.ts +1 -0
  23. package/out-tsc/scripts/version/copy-to-binary.js +79 -0
  24. package/package.json +23 -10
  25. package/project-version.json +3 -3
  26. package/rust/bindings/Cargo.toml +9 -0
  27. package/rust/bindings/src/lib.rs +86 -0
  28. package/rust/cli/addon/commands.rs +35 -0
  29. package/rust/cli/addon/download.rs +234 -0
  30. package/rust/cli/addon/install.rs +33 -0
  31. package/rust/cli/addon/list.rs +224 -0
  32. package/rust/cli/addon/metadata.rs +124 -0
  33. package/rust/cli/addon/mod.rs +8 -0
  34. package/rust/cli/addon/remove.rs +271 -0
  35. package/rust/cli/addon/update.rs +305 -0
  36. package/rust/cli/{install/addon.rs → addon/utils.rs} +34 -43
  37. package/rust/cli/build/commands.rs +153 -103
  38. package/rust/cli/build/mod.rs +2 -2
  39. package/rust/cli/build/process.rs +165 -146
  40. package/rust/cli/check/mod.rs +208 -208
  41. package/rust/cli/discover/commands.rs +53 -31
  42. package/rust/cli/discover/config.rs +2 -4
  43. package/rust/cli/discover/install.rs +139 -28
  44. package/rust/cli/discover/metadata.rs +3 -3
  45. package/rust/cli/login/commands.rs +124 -124
  46. package/rust/cli/me/commands.rs +52 -0
  47. package/rust/cli/me/mod.rs +1 -0
  48. package/rust/cli/mod.rs +2 -2
  49. package/rust/cli/parser.rs +76 -70
  50. package/rust/cli/play/commands.rs +375 -324
  51. package/rust/cli/play/mod.rs +5 -5
  52. package/rust/cli/play/process.rs +159 -150
  53. package/rust/cli/play/realtime.rs +91 -91
  54. package/rust/cli/telemetry/commands.rs +22 -22
  55. package/rust/cli/telemetry/event_creator.rs +80 -80
  56. package/rust/cli/telemetry/mod.rs +3 -3
  57. package/rust/cli/telemetry/send.rs +51 -51
  58. package/rust/cli/template/commands.rs +69 -69
  59. package/rust/config/driver.rs +112 -103
  60. package/rust/config/mod.rs +3 -3
  61. package/rust/config/ops.rs +26 -26
  62. package/rust/config/settings.rs +101 -101
  63. package/rust/core/audio/engine/driver.rs +237 -0
  64. package/rust/core/audio/engine/export.rs +169 -0
  65. package/rust/core/audio/engine/helpers.rs +178 -170
  66. package/rust/core/audio/engine/mod.rs +56 -7
  67. package/rust/core/audio/engine/notes/dsp.rs +88 -0
  68. package/rust/core/audio/engine/notes/mod.rs +53 -0
  69. package/rust/core/audio/engine/notes/params.rs +294 -0
  70. package/rust/core/audio/engine/sample/insert.rs +300 -0
  71. package/rust/core/audio/engine/sample/mod.rs +40 -0
  72. package/rust/core/audio/engine/sample/padding.rs +170 -0
  73. package/rust/core/audio/evaluator/condition.rs +61 -0
  74. package/rust/core/audio/evaluator/mod.rs +9 -0
  75. package/rust/core/audio/{evaluator.rs → evaluator/numeric.rs} +152 -310
  76. package/rust/core/audio/evaluator/rhs.rs +16 -0
  77. package/rust/core/audio/evaluator/string_expr.rs +94 -0
  78. package/rust/core/audio/interpreter/driver.rs +574 -542
  79. package/rust/core/audio/interpreter/mod.rs +2 -14
  80. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +179 -0
  81. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +398 -0
  82. package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +323 -0
  83. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +3 -0
  84. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +371 -0
  85. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +3 -0
  86. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +192 -0
  87. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +24 -0
  88. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +116 -0
  89. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +97 -0
  90. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +100 -0
  91. package/rust/core/audio/interpreter/{automate.rs → statements/automate.rs} +2 -4
  92. package/rust/core/audio/interpreter/{call.rs → statements/call.rs} +36 -5
  93. package/rust/core/audio/interpreter/{condition.rs → statements/condition.rs} +72 -71
  94. package/rust/core/audio/interpreter/{function.rs → statements/function.rs} +24 -26
  95. package/rust/core/audio/interpreter/{let_.rs → statements/let_.rs} +36 -38
  96. package/rust/core/audio/interpreter/{load.rs → statements/load.rs} +17 -19
  97. package/rust/core/audio/interpreter/{loop_.rs → statements/loop_.rs} +115 -114
  98. package/rust/core/audio/interpreter/statements/mod.rs +12 -0
  99. package/rust/core/audio/interpreter/{sleep.rs → statements/sleep.rs} +28 -28
  100. package/rust/core/audio/interpreter/{spawn.rs → statements/spawn.rs} +54 -4
  101. package/rust/core/audio/interpreter/{tempo.rs → statements/tempo.rs} +40 -40
  102. package/rust/core/audio/interpreter/{trigger.rs → statements/trigger.rs} +242 -239
  103. package/rust/core/audio/loader/trigger.rs +98 -97
  104. package/rust/core/audio/mod.rs +6 -7
  105. package/rust/core/audio/special/easing.rs +189 -189
  106. package/rust/core/audio/special/env.rs +45 -45
  107. package/rust/core/audio/special/math.rs +134 -134
  108. package/rust/core/audio/special/modulator.rs +143 -143
  109. package/rust/core/builder/mod.rs +129 -86
  110. package/rust/core/debugger/{module.rs → logs.rs} +52 -55
  111. package/rust/core/debugger/mod.rs +30 -30
  112. package/rust/core/debugger/store.rs +38 -40
  113. package/rust/core/error/mod.rs +269 -269
  114. package/rust/core/lexer/driver.rs +2 -4
  115. package/rust/core/mod.rs +9 -10
  116. package/rust/core/parser/driver/block.rs +111 -0
  117. package/rust/core/parser/driver/cursor.rs +82 -0
  118. package/rust/core/parser/driver/driver_impl.rs +159 -0
  119. package/rust/core/parser/driver/mod.rs +6 -0
  120. package/rust/core/parser/driver/parse_array.rs +120 -0
  121. package/rust/core/parser/driver/parse_map.rs +247 -0
  122. package/rust/core/parser/driver/parser.rs +160 -0
  123. package/rust/core/parser/handler/arrow_call.rs +90 -15
  124. package/rust/core/parser/handler/at.rs +279 -279
  125. package/rust/core/parser/handler/bank.rs +104 -104
  126. package/rust/core/parser/handler/condition.rs +83 -83
  127. package/rust/core/parser/handler/dot.rs +148 -148
  128. package/rust/core/parser/handler/identifier/automate.rs +254 -254
  129. package/rust/core/parser/handler/identifier/call.rs +91 -91
  130. package/rust/core/parser/handler/identifier/emit.rs +70 -70
  131. package/rust/core/parser/handler/identifier/function.rs +113 -113
  132. package/rust/core/parser/handler/identifier/group.rs +89 -89
  133. package/rust/core/parser/handler/identifier/let_.rs +173 -173
  134. package/rust/core/parser/handler/identifier/mod.rs +55 -55
  135. package/rust/core/parser/handler/identifier/on.rs +107 -107
  136. package/rust/core/parser/handler/identifier/print.rs +49 -49
  137. package/rust/core/parser/handler/identifier/sleep.rs +96 -43
  138. package/rust/core/parser/handler/identifier/spawn.rs +91 -91
  139. package/rust/core/parser/handler/identifier/synth.rs +39 -3
  140. package/rust/core/parser/handler/loop_.rs +194 -194
  141. package/rust/core/parser/handler/pattern.rs +25 -2
  142. package/rust/core/parser/handler/tempo.rs +105 -57
  143. package/rust/core/parser/statement.rs +10 -11
  144. package/rust/core/plugin/loader.rs +137 -137
  145. package/rust/core/plugin/runner/mod.rs +11 -0
  146. package/rust/core/plugin/{runner.rs → runner/non_wasm.rs} +206 -72
  147. package/rust/core/plugin/runner/wasm32.rs +44 -0
  148. package/rust/core/preprocessor/loader/inject.rs +313 -0
  149. package/rust/core/preprocessor/loader/loader_helpers.rs +110 -0
  150. package/rust/core/preprocessor/loader/mod.rs +235 -0
  151. package/rust/core/preprocessor/module.rs +55 -60
  152. package/rust/core/preprocessor/{processor.rs → processor/handlers.rs} +107 -114
  153. package/rust/core/preprocessor/processor/mod.rs +1 -0
  154. package/rust/core/preprocessor/resolver/function.rs +69 -69
  155. package/rust/core/preprocessor/resolver/group.rs +122 -94
  156. package/rust/core/preprocessor/resolver/pattern.rs +14 -2
  157. package/rust/core/store/global.rs +57 -61
  158. package/rust/core/store/mod.rs +1 -5
  159. package/rust/lib.rs +323 -308
  160. package/rust/macros/Cargo.toml +14 -0
  161. package/rust/macros/src/lib.rs +52 -0
  162. package/rust/main.rs +336 -143
  163. package/rust/types/Cargo.toml +1 -1
  164. package/rust/types/src/addons.rs +57 -55
  165. package/rust/types/src/config.rs +82 -74
  166. package/rust/types/src/lib.rs +15 -12
  167. package/rust/types/src/plugin.rs +20 -0
  168. package/rust/types/src/store.rs +139 -0
  169. package/rust/types/src/telemetry.rs +85 -85
  170. package/rust/utils/Cargo.toml +5 -2
  171. package/rust/utils/src/file.rs +477 -94
  172. package/rust/utils/src/first_usage.rs +97 -97
  173. package/rust/utils/src/lib.rs +9 -9
  174. package/rust/utils/src/logger.rs +200 -200
  175. package/rust/utils/src/path.rs +158 -88
  176. package/rust/utils/src/signature.rs +41 -41
  177. package/rust/utils/src/spinner.rs +20 -20
  178. package/rust/utils/src/version.rs +58 -27
  179. package/rust/utils/src/watcher.rs +46 -46
  180. package/rust/web/api.rs +5 -5
  181. package/rust/web/auth.rs +5 -0
  182. package/rust/web/cdn.rs +34 -34
  183. package/rust/web/forge.rs +5 -0
  184. package/rust/web/mod.rs +2 -0
  185. package/tests/integration.rs +21 -21
  186. package/typescript/core/functions/index.ts +11 -0
  187. package/typescript/pkg/devalang_core.ts +20 -4
  188. package/typescript/scripts/version/copy-to-binary.ts +82 -0
  189. package/rust/cli/bank/api.rs +0 -122
  190. package/rust/cli/bank/commands.rs +0 -275
  191. package/rust/cli/bank/mod.rs +0 -29
  192. package/rust/cli/install/bank.rs +0 -53
  193. package/rust/cli/install/commands.rs +0 -35
  194. package/rust/cli/install/mod.rs +0 -4
  195. package/rust/cli/install/plugin.rs +0 -61
  196. package/rust/core/audio/engine/sample.rs +0 -366
  197. package/rust/core/audio/engine/synth.rs +0 -325
  198. package/rust/core/audio/interpreter/arrow_call.rs +0 -311
  199. package/rust/core/audio/renderer.rs +0 -54
  200. package/rust/core/parser/driver.rs +0 -584
  201. package/rust/core/preprocessor/loader.rs +0 -637
  202. package/rust/core/store/export.rs +0 -28
  203. package/rust/core/store/function.rs +0 -40
  204. package/rust/core/store/import.rs +0 -28
  205. package/rust/core/store/variable.rs +0 -51
  206. package/rust/core/utils/mod.rs +0 -1
  207. package/rust/core/utils/path.rs +0 -37
package/.devalang CHANGED
@@ -1,10 +1,9 @@
1
- [defaults]
2
- entry = "./examples"
3
- output = "./output"
4
- watch = false
5
- debug = true
6
- compress = true
7
-
8
- [[banks]]
9
- path = "devalang://bank/devaloop.808"
10
- version = "0.0.1"
1
+ [defaults]
2
+ entry = "./examples"
3
+ output = "./output"
4
+ watch = false
5
+ debug = true
6
+ compress = true
7
+ audio_format = "wav16"
8
+ sample_rate = 44100
9
+ output_format = ["wav", "mid"]
package/Cargo.toml CHANGED
@@ -1,80 +1,84 @@
1
- [package]
2
- name = "devalang"
3
- version = "0.0.1-beta.1"
4
- authors = ["Devaloop <contact@devaloop.com>"]
5
- description = "Write music like code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound — in plain text."
6
- license = "MIT"
7
- repository = "https://github.com/devaloop-labs/devalang"
8
- keywords = ["music", "dsl", "audio", "cli"]
9
- categories = ["command-line-utilities", "development-tools", "parser-implementations"]
10
- readme = "README.md"
11
- homepage = "https://devalang.com"
12
- documentation = "https://docs.devalang.com/"
13
- edition = "2024"
14
-
15
- [[bin]]
16
- name = "devalang"
17
- path = "rust/main.rs"
18
-
19
- [lib]
20
- name = "devalang_core"
21
- path = "rust/lib.rs"
22
- crate-type = ["cdylib", "rlib"]
23
-
24
- [profile.release]
25
- opt-level = "s"
26
-
27
- [features]
28
- default = ["cli"]
29
- cli = ["crossterm", "indicatif", "inquire", "zip", "reqwest", "flate2", "tokio"]
30
-
31
- [dependencies]
32
- devalang_types = { path = "rust/types", version = "0.0.2" }
33
- clap = { version = "4.5", features = ["derive"] }
34
- serde = { version = "1.0", features = ["derive"] }
35
- serde_json = "1.0"
36
- rodio = "0.17"
37
- hound = "3.4.0"
38
- toml = "0.8"
39
- notify = "6.1"
40
- fs_extra = "1.3"
41
- include_dir = "0.7"
42
- wasm-bindgen = "0.2"
43
- serde-wasm-bindgen = "0.4"
44
- nom_locate = "4.0.0"
45
- chrono = "0.4"
46
- crossterm = { version = "0.27", optional = true }
47
- indicatif = { version = "0.17", optional = true }
48
- inquire = { version = "0.7.5", optional = true }
49
- js-sys = "0.3"
50
- getrandom = { version = "0.3", features = ["wasm_js"] }
51
- reqwest = { version = "0.12.22", optional = true, features = ["json"] }
52
- flate2 = { version = "1.0", optional = true }
53
- tokio = { version = "1", features = ["full"], optional = true }
54
- zip = { version = "4.3.0", optional = true }
55
- rayon = "1.10.0"
56
- webbrowser = "0.8"
57
- tiny_http = "0.9.0"
58
- dirs = "5"
59
- urlencoding = "2.1"
60
- uuid = { version = "1.18.0", features = ["v4"] }
61
- console_error_panic_hook = "0.1.7"
62
-
63
- [dev-dependencies]
64
- assert_cmd = "2"
65
- predicates = "2"
66
- tempfile = "3"
67
-
68
- # For wasm32, enable wasm-friendly randomness backends and avoid
69
- # pulling in native-only CLI dependencies.
70
- [target.'cfg(target_arch = "wasm32")'.dependencies]
71
- getrandom = { version = "0.3", features = ["wasm_js"] }
72
- uuid = { version = "1.18.0", features = ["v4", "js", "rng-getrandom"] }
73
- # Keep a lightweight linkage to the utils crate for wasm builds without
74
- # enabling native CLI features.
75
- devalang_utils = { path = "rust/utils", default-features = false, version = "0.0.1" }
76
-
77
- # devalang_utils with CLI and wasmtime are only needed for native targets.
78
- [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
79
- devalang_utils = { path = "rust/utils", features = ["cli"], version = "0.0.1" }
80
- wasmtime = "19"
1
+ [package]
2
+ name = "devalang"
3
+ version = "0.0.1-beta.3"
4
+ authors = ["Devaloop <contact@devaloop.com>"]
5
+ description = "Write music like code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound — in plain text."
6
+ license = "MIT"
7
+ repository = "https://github.com/devaloop-labs/devalang"
8
+ license-file = "LICENSE"
9
+ keywords = ["music", "dsl", "audio", "cli", "synthesis"]
10
+ categories = ["command-line-utilities", "development-tools", "parser-implementations"]
11
+ readme = "README.md"
12
+ homepage = "https://devalang.com"
13
+ documentation = "https://docs.devalang.com/"
14
+ edition = "2024"
15
+
16
+ [[bin]]
17
+ name = "devalang"
18
+ path = "rust/main.rs"
19
+
20
+ [lib]
21
+ name = "devalang_core"
22
+ path = "rust/lib.rs"
23
+ crate-type = ["cdylib", "rlib"]
24
+
25
+ [profile.release]
26
+ opt-level = "s"
27
+
28
+ [features]
29
+ default = ["cli"]
30
+ cli = ["crossterm", "indicatif", "inquire", "zip", "reqwest", "flate2", "tokio"]
31
+
32
+ [dependencies]
33
+ devalang_types = { path = "rust/types", version = "0.0.4" }
34
+ devalang_bindings = { path = "rust/bindings", version = "0.0.1" }
35
+ devalang_macros = { path = "rust/macros", version = "0.0.1" }
36
+ clap = { version = "4.5", features = ["derive"] }
37
+ serde = { version = "1.0", features = ["derive"] }
38
+ serde_json = "1.0"
39
+ rodio = "0.17"
40
+ hound = "3.4.0"
41
+ toml = "0.8"
42
+ notify = "6.1"
43
+ fs_extra = "1.3"
44
+ include_dir = "0.7"
45
+ wasm-bindgen = "0.2"
46
+ serde-wasm-bindgen = "0.4"
47
+ nom_locate = "4.0.0"
48
+ chrono = "0.4"
49
+ crossterm = { version = "0.27", optional = true }
50
+ indicatif = { version = "0.17", optional = true }
51
+ inquire = { version = "0.7.5", optional = true }
52
+ js-sys = "0.3"
53
+ getrandom = { version = "0.3", features = ["wasm_js"] }
54
+ reqwest = { version = "0.12.22", optional = true, features = ["json"] }
55
+ flate2 = { version = "1.0", optional = true }
56
+ tokio = { version = "1", features = ["full"], optional = true }
57
+ zip = { version = "4.3.0", optional = true }
58
+ rayon = "1.10.0"
59
+ webbrowser = "0.8"
60
+ tiny_http = "0.9.0"
61
+ dirs = "5"
62
+ urlencoding = "2.1"
63
+ uuid = { version = "1.18.0", features = ["v4"] }
64
+ console_error_panic_hook = "0.1.7"
65
+ midly = "0.5.3"
66
+
67
+ [dev-dependencies]
68
+ assert_cmd = "2"
69
+ predicates = "2"
70
+ tempfile = "3"
71
+
72
+ # For wasm32, enable wasm-friendly randomness backends and avoid
73
+ # pulling in native-only CLI dependencies.
74
+ [target.'cfg(target_arch = "wasm32")'.dependencies]
75
+ getrandom = { version = "0.3", features = ["wasm_js"] }
76
+ uuid = { version = "1.18.0", features = ["v4", "js", "rng-getrandom"] }
77
+ # Keep a lightweight linkage to the utils crate for wasm builds without
78
+ # enabling native CLI features.
79
+ devalang_utils = { path = "rust/utils", default-features = false, version = "0.0.3" }
80
+
81
+ # devalang_utils with CLI and wasmtime are only needed for native targets.
82
+ [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
83
+ devalang_utils = { path = "rust/utils", features = ["cli"], version = "0.0.3" }
84
+ wasmtime = "19"
package/README.md CHANGED
@@ -32,9 +32,8 @@ From studio sketches to live sets, Devalang gives you rhythmic control — with
32
32
  >
33
33
  > Includes synthesis, playback, and rendering features, but is still in early development, and breaking changes may occur.
34
34
  >
35
- > **NEW**: [Devaforge is now available for creating addons](https://github.com/devaloop-labs/devaforge).
35
+ > **NEW**: [Devalang WORKSHOP is now available](https://workshop.devalang.com).
36
36
  >
37
- > **NEW**: Now available for Windows, Linux, and macOS.
38
37
 
39
38
  ## 📚 Quick Access
40
39
 
@@ -65,7 +64,7 @@ npm install -g @devaloop/devalang@latest
65
64
  #### With Rust
66
65
 
67
66
  ```bash
68
- cargo install devalang
67
+ cargo install devalang --version <version>
69
68
  ```
70
69
 
71
70
  #### Initialize a new project
@@ -136,8 +135,8 @@ group myGroup:
136
135
  })
137
136
 
138
137
  # Notes with params
139
- myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
140
- myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
138
+ myLead -> note(G4, { duration: 600, glide: true })
139
+ myLead -> note(B3, { duration: 400, slide: true })
141
140
 
142
141
  # Spawning the group & the pattern to play them in parallel
143
142
  spawn myGroup
@@ -173,8 +172,7 @@ devalang play --repeat
173
172
  ## 🚀 Features
174
173
 
175
174
  - ⚡ **Fast Build & Hot Reload** — optimized build process for quicker iteration.
176
- - 🎵 **Audio Engine & Real-time runner** — low-latency playback, render-to-file, and a realtime runner used by `devalang play` for live feedback.
177
- - ▶️ **Live mode (watch + repeat)** — edit and hear changes instantly with `devalang play --repeat` and watch mode.
175
+ - 🎵 **Audio Engine & Real-time runner** — low-latency playback, render-to-file, and a realtime runner used by `devalang play --repeat` for live feedback.
178
176
  - 🧩 **Language primitives** — synths, notes, ADSR, maps, arrays, loops, conditionals and functions for expressive musical logic.
179
177
  - 🎛️ **Per-note automation & modulators** — `automate` maps, `$mod.*`, `$easing.*` and `$math.*` helpers for envelopes and LFOs.
180
178
  - 🧩 **Module system & structured AST** — import/export variables, stable AST output for debugging and tooling.
@@ -193,11 +191,16 @@ devalang play --repeat
193
191
 
194
192
  ## 📰 What's new
195
193
 
194
+ - **Effects chaining**: Added support for chaining multiple effects on synths and samples.
195
+ - **New addons system**: Revamped the addons system for better management and integration.
196
+ - **MIDI export**: Added the ability to export MIDI files from Devalang scripts.
197
+ - **Synthesizer improvements**: Enhanced the built-in synthesizer with new types and modulation options.
196
198
  - **Devaforge**: Introduced a new system for creating and managing addons, including a CLI for addon generation.
197
199
  - **Documentation updates**: Improved documentation for clarity and completeness.
198
200
  - **Discovering addons**: Introduced a new command to detect addons.
199
201
  - **Public TypeScript API**: Added a public TypeScript API for easier integration.
200
202
  - **Improved error messages**: Enhanced error messages for better debugging.
203
+ - **Major refactor**: Significant codebase refactor for improved maintainability and performance.
201
204
  - **Bug fixes**: Various bug fixes and stability improvements.
202
205
 
203
206
  ## 🛡️ License
package/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,89 @@
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## Version 0.0.1-beta.3 (2025-09-20)
8
+
9
+ ### ✨ Language Features
10
+
11
+ - Implemented `synth` effects chaining to apply effects to individual synth notes.
12
+ - Example: `mySynth -> note(C4) -> slide({ duration: 2000 }) -> reverb({ room_size: 0.8 })`
13
+
14
+ ### 🛠️ CLI & Addons
15
+
16
+ - Introduced a unified addon manager and removed the legacy `install` / `bank` commands:
17
+
18
+ - Use `devalang addon install <publisher>.<name>` to install banks or plugins.
19
+ - Use `devalang addon remove <publisher>.<name>` to remove banks or plugins.
20
+ - Use `devalang addon list` to list installed addons.
21
+
22
+ - Improved the `discover` workflow:
23
+
24
+ - Recursively scans `.deva` for compiled archives (`.tar.gz` / `.tgz`) and proposes them for installation.
25
+ - Pre-classifies addon types by inspecting archive contents so installations can target the correct folder (bank/plugin/preset/template).
26
+ - Robust selection labels and mapping ensure the chosen addon is installed correctly.
27
+
28
+ - Installation and extraction improvements:
29
+
30
+ - Archives are extracted into the appropriate destination based on detected type.
31
+ - Temporary extraction folder is cleaned up only when empty after installation.
32
+ - Added `--no-clear-tmp` flag to `discover` and addon install flows to preserve the temporary folder when desired.
33
+
34
+ - Bugfixes: fixed selection-to-install mapping and improved success/error logging during install flows.
35
+
36
+ ### 🧪 Telemetry & Versioning
37
+
38
+ - Telemetry now uses a runtime-first strategy to resolve the CLI version
39
+
40
+ ### 📦 Packaging & Tools
41
+
42
+ - Added `typescript/scripts/version/copy-to-binary.ts` to copy `project-version.json` next to a packaged binary during release/packaging steps.
43
+
44
+ ### ✅ Bugfixes & Misc
45
+
46
+ - Various fixes around temporary folder cleanup, archive detection, config updates and CLI ergonomics.
47
+
48
+ ## Version 0.0.1-beta.2 (2025-09-07)
49
+
50
+ ### 🛠️ MIDI & format
51
+
52
+ - Added support for `mid` export in `build` command.
53
+ - Example: `devalang build --output-format mid,wav`
54
+ - Added support for `wav16` and `wav32` audio formats in `play` command.
55
+ - Example: `devalang play --audio-format <wav16 | wav32>`
56
+ - Added support for `sample_rate` parameter in `play` and `build` commands.
57
+ - Example: `devalang play --sample-rate <44100 | 48000 | 96000>`
58
+ - Example: `devalang build --sample-rate <44100 | 48000 | 96000>`
59
+
60
+ ### ✨ Language Features
61
+
62
+ - `synth` enhancements:
63
+ - Types:
64
+ - Added `pad` type for lush, evolving sounds.
65
+ - Added `pluck` type for sharp, percussive tones.
66
+ - Added `arp` type for arpeggiated sequences.
67
+ - Added `sub` type for deep bass sounds.
68
+ - LFOs:
69
+ - Added `lfo` parameter to `synth` for low-frequency oscillation modulation.
70
+ - LFO supports `rate`, `depth`, and `target` parameters.
71
+ - Filters:
72
+ - Added `filters` parameter to `synth` for applying filters.
73
+ - `arrow_call` enhancements:
74
+ - Added support for `chord` method to play multiple notes simultaneously.
75
+
76
+ ### 🧠 Architecture & Refactor
77
+
78
+ - Modularized some core components to improve maintainability and readability.
79
+
80
+ ### 📚 Examples
81
+
82
+ - Added `examples/filter.deva` to showcase filter usage in synths.
83
+ - Added `examples/lfo.deva` to illustrate LFO modulation in synths.
84
+ - Added `examples/synth_types.deva` to demonstrate various synth types.
85
+
86
+ ### 📦 WASM
87
+
88
+ - Added `collect_playhead_events` function to the WASM module to collect playhead events during audio rendering.
89
+
7
90
  ## Version 0.0.1-beta.1 (2025-09-02)
8
91
 
9
92
  > First beta of Devalang 0.0.1. Focus on stability, language surface freeze, and developer experience. No breaking changes expected compared to alpha.18; experimental features are gated and may change.
package/docs/ROADMAP.md CHANGED
@@ -9,6 +9,7 @@ Devalang is a work in progress. Here’s what we’re planning next:
9
9
  ## Completed
10
10
 
11
11
  - ✅ **Audio engine**: Integrate the audio engine for sound playback.
12
+ - ✅ **MIDI export**: Implement MIDI export functionality to save compositions as MIDI files.
12
13
  - ✅ **Basic syntax**: Implement the core syntax for Devalang, including data types and basic statements.
13
14
  - ✅ **Watch mode**: Add a watch mode to automatically rebuild on file changes.
14
15
  - ✅ **Module system**: Add support for importing and exporting variables between files using `@import` and `@export`.
@@ -22,13 +23,16 @@ Devalang is a work in progress. Here’s what we’re planning next:
22
23
  - ✅ **Sample loading**: Add `@load` assignment to load samples (.mp3, .wav) for use as values.
23
24
  - ✅ **WASM support**: Compile Devalang to WebAssembly for use in web applications and other environments.
24
25
  - ✅ **VSCode extension**: Create a VSCode extension for syntax highlighting and code completion.
26
+ - ✅ **Addon generator**: Implement addon generation for creating reusable plugins, banks and presets.
27
+ - ✅ **Effect chains**: Implement effect chains for applying multiple effects to a single note or group.
25
28
 
26
29
  ## In Progress
27
30
 
28
- - ⏳ **Addon generator**: Implement addon generation for creating reusable plugins, banks and presets.
29
31
  - ⏳ **Testing**: Expand test coverage for all features.
30
- - ⏳ **Other statements**: Implement `pattern`, and other control structures.
32
+ - ⏳ **Mixing & Routing**: Implement mixing and routing capabilities for advanced audio control.
31
33
 
32
34
  ## Planned
33
35
 
36
+ - ⏳ **MIDI mapping**: Implement MIDI mapping for external control.
37
+ - ⏳ **GUI**: Develop a graphical user interface for easier interaction.
34
38
  - ⏳ **Smart modules**: Let Devalang detect and use groups, samples, and variables without needing to import them manually.
package/docs/TODO.md CHANGED
@@ -41,9 +41,8 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
41
41
  - [x] @import
42
42
  - [x] @export
43
43
  - [x] @load
44
- - [ ] @include
45
44
  - [x] function
46
- - [ ] pattern
45
+ - [x] pattern
47
46
  - [x] group
48
47
  - [x] call
49
48
  - [x] spawn
@@ -58,8 +57,8 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
58
57
 
59
58
  ## Triggers
60
59
 
61
- - [x] Built-in triggers
62
60
  - [x] Custom triggers
61
+ - [x] Event triggers
63
62
 
64
63
  ## Banks
65
64
 
@@ -69,14 +68,4 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
69
68
  ## Plugins
70
69
 
71
70
  - [x] Implement plugin system (e.g. install, remove, list)
72
- - [ ] Create example plugins
73
-
74
- ## Addon generator
75
-
76
- - [x] Implement addon generator
77
- - [ ] Create example addons
78
-
79
- ## Other TODOs
80
-
81
- - [ ] Comment all core components
82
- - [ ] Add unit tests for all core components
71
+ - [ ] Create example plugins
@@ -0,0 +1,10 @@
1
+ # NOTE Planned for future release
2
+
3
+ # let sidechainBus = bus {
4
+ # fx: [
5
+ # { type: "compressor", threshold: -20, ratio: 8, attack: 5, release: 100,
6
+ # sidechain: myKick }
7
+ # ]
8
+ # }
9
+ # route myLead -> sidechainBus -> masterBus
10
+ # route myKick -> myBass -> masterBus
@@ -0,0 +1,19 @@
1
+ let myChord = synth sine
2
+
3
+ myChord -> note(C4)
4
+ -> arp({ pattern: "up", rate: 1/8 })
5
+ -> slide({ duration: 2000 })
6
+ -> echo({ delay: 250, feedback: 0.5 })
7
+ -> reverb({ room_size: 0.8 })
8
+
9
+ myChord -> note(E4)
10
+ -> arp({ pattern: "up", rate: 1/8 })
11
+ -> slide({ duration: 2000 })
12
+ -> echo({ delay: 250, feedback: 0.5 })
13
+ -> reverb({ room_size: 0.8 })
14
+
15
+ myChord -> note(G4)
16
+ -> arp({ pattern: "up", rate: 1/8 })
17
+ -> slide({ duration: 2000 })
18
+ -> echo({ delay: 250, feedback: 0.5 })
19
+ -> reverb({ room_size: 0.8 })
@@ -0,0 +1,2 @@
1
+ # NOTE Planned for future release
2
+ # myChord -> note(C4) -> arp({ pattern: "up", rate: 1/8 }) -> slide({ duration: 2000 }) -> echo({ delay: 250, feedback: 0.5 }) -> reverb({ room_size: 0.8 })
@@ -0,0 +1,11 @@
1
+ let myFilteredSynth = synth sine {
2
+ filters: [
3
+ { type: "lowpass", cutoff: 800.0, resonance: 1.0 },
4
+ { type: "bandpass", cutoff: 400.0, resonance: 1.0 },
5
+ { type: "highpass", cutoff: 200.0, resonance: 1.0 }
6
+ ],
7
+ }
8
+
9
+ myFilteredSynth -> note(C4, { duration: 500 })
10
+ myFilteredSynth -> note(E4, { duration: 500 })
11
+ myFilteredSynth -> note(G4, { duration: 500 })
@@ -0,0 +1,9 @@
1
+ let myLFOSynth = synth sine {
2
+ lfo: {
3
+ rate: 1/4,
4
+ depth: 0.5,
5
+ target: "cutoff"
6
+ }
7
+ }
8
+
9
+ myLFOSynth -> note(C4, { duration: 500 })
@@ -1,16 +1,16 @@
1
1
  # This is an example of using a plugin in Devalang.
2
- # Make sure you have the plugin installed in your Devaloop application. (devalang install plugin <author>.<plugin_name>)
2
+ # Make sure you have the plugin installed in your Devaloop application. (devalang addon install <author>.<addon_name>)
3
3
 
4
4
  @use devaloop.acid as acidPlugin
5
5
 
6
- let acidSynth = synth acidPlugin.synth {
7
- waveform: "saw",
8
- accent: 0.1,
9
- decay: 250
10
- }
6
+ group acidSynthGroup:
7
+ let acidSynth = synth acidPlugin.synth {
8
+ waveform: "saw",
9
+ resonance: 1.0,
10
+ }
11
11
 
12
- group mySynthGroup:
13
- acidSynth -> note(C4, { duration: 600 })
14
- acidSynth -> note(E4, { duration: 600 })
12
+ acidSynth -> note(C4, { duration: 1000 })
13
+ acidSynth -> note(E3, { duration: 1000 })
14
+ acidSynth -> note(B2, { duration: 1000 })
15
15
 
16
- call mySynthGroup
16
+ call acidSynthGroup
@@ -0,0 +1,23 @@
1
+ # NOTE Future version of Deva may include built-in routing capabilities.
2
+
3
+ # @load "./samples/kick-808.wav" as kickCustom
4
+
5
+ # group myLead:
6
+ # let mySynth = synth sine
7
+
8
+ # mySynth -> note(C4, { duration: 400 })
9
+
10
+ # group myKick:
11
+ # .kickCustom 1/4
12
+
13
+ # routing:
14
+ # node $master
15
+ # node myLead
16
+ # node myKick
17
+ # node hallReverb = effect reverb { decay: 3.0, mix: 0.5 }
18
+
19
+ # connect myLead -> hallReverb -> $master
20
+
21
+ # connect myLead -> $master with { delay: { time: 300, feedback: 0.3 } }
22
+
23
+ # connect myKick -> myLead with { sidechain: 0.6 }
@@ -11,4 +11,14 @@ group myLead:
11
11
  mySynth -> note(D4, { duration: 400 })
12
12
  mySynth -> note(B3, { duration: 600 })
13
13
 
14
- @export { myLead }
14
+ group myChords:
15
+ let chordSynth = synth square
16
+
17
+ chordSynth -> chord(Cmaj, { duration: 1600 })
18
+ chordSynth -> chord(Fmaj, { duration: 1600 })
19
+ chordSynth -> chord(Gmaj, { duration: 1600 })
20
+ chordSynth -> chord(Am, { duration: 1600 })
21
+
22
+ # Play both groups together
23
+ spawn myLead
24
+ spawn myChords
@@ -0,0 +1,17 @@
1
+ let myPad = synth sine {
2
+ type: "pad"
3
+ }
4
+
5
+ let myPluck = synth sine {
6
+ type: "pluck"
7
+ }
8
+
9
+ let myArp = synth sine {
10
+ type: "arp",
11
+ rate: 16,
12
+ step: 2
13
+ }
14
+
15
+ let mySub = synth sine {
16
+ type: "sub",
17
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": "0.0.1-beta.3",
3
+ "channel": "beta",
4
+ "lastCommit": "d9c8d5927288897aebf7faceb2b3495b5b8b87eb",
5
+ "build": 2
6
+ }
@@ -30,6 +30,11 @@ export declare function register_playhead_callback(cb: (ev: {
30
30
  line: number;
31
31
  column: number;
32
32
  }) => void): any;
33
+ /**
34
+ * Collects playhead events that have been recorded during playback.
35
+ * @returns Array of playhead events { time, line, column }.
36
+ */
37
+ export declare function collect_playhead_events(): any;
33
38
  /**
34
39
  * Unregisters the JS callback for playhead events.
35
40
  * @returns void
@@ -4,6 +4,7 @@ exports.parse = parse;
4
4
  exports.debug_render = debug_render;
5
5
  exports.render_audio = render_audio;
6
6
  exports.register_playhead_callback = register_playhead_callback;
7
+ exports.collect_playhead_events = collect_playhead_events;
7
8
  exports.unregister_playhead_callback = unregister_playhead_callback;
8
9
  let wasmPkg = undefined;
9
10
  try {
@@ -64,6 +65,16 @@ function register_playhead_callback(cb) {
64
65
  // no-op fallback
65
66
  return;
66
67
  }
68
+ /**
69
+ * Collects playhead events that have been recorded during playback.
70
+ * @returns Array of playhead events { time, line, column }.
71
+ */
72
+ function collect_playhead_events() {
73
+ if (wasmPkg && typeof wasmPkg.collect_playhead_events === "function") {
74
+ return wasmPkg.collect_playhead_events();
75
+ }
76
+ return [];
77
+ }
67
78
  /**
68
79
  * Unregisters the JS callback for playhead events.
69
80
  * @returns void
@@ -2,12 +2,14 @@ export declare function parse(...args: any[]): any;
2
2
  export declare function debug_render(...args: any[]): any;
3
3
  export declare function render_audio(...args: any[]): any;
4
4
  export declare function register_playhead_callback(cb?: any): any;
5
+ export declare function collect_playhead_events(): any;
5
6
  export declare function unregister_playhead_callback(): any;
6
7
  declare const pkg: {
7
8
  parse: typeof parse;
8
9
  debug_render: typeof debug_render;
9
10
  render_audio: typeof render_audio;
10
11
  register_playhead_callback: typeof register_playhead_callback;
12
+ collect_playhead_events: typeof collect_playhead_events;
11
13
  unregister_playhead_callback: typeof unregister_playhead_callback;
12
14
  };
13
15
  export default pkg;
@@ -4,6 +4,7 @@ exports.parse = parse;
4
4
  exports.debug_render = debug_render;
5
5
  exports.render_audio = render_audio;
6
6
  exports.register_playhead_callback = register_playhead_callback;
7
+ exports.collect_playhead_events = collect_playhead_events;
7
8
  exports.unregister_playhead_callback = unregister_playhead_callback;
8
9
  /**
9
10
  * Shim TypeScript source that re-exports the runtime wasm-pack package when
@@ -41,10 +42,24 @@ function register_playhead_callback(cb) {
41
42
  return runtimePkg.register_playhead_callback(cb);
42
43
  return;
43
44
  }
45
+ function collect_playhead_events() {
46
+ if (runtimePkg && typeof runtimePkg.collect_playhead_events === "function") {
47
+ return runtimePkg.collect_playhead_events();
48
+ }
49
+ return [];
50
+ }
44
51
  function unregister_playhead_callback() {
45
- if (runtimePkg && typeof runtimePkg.unregister_playhead_callback === "function")
52
+ if (runtimePkg &&
53
+ typeof runtimePkg.unregister_playhead_callback === "function")
46
54
  return runtimePkg.unregister_playhead_callback();
47
55
  return;
48
56
  }
49
- const pkg = { parse, debug_render, render_audio, register_playhead_callback, unregister_playhead_callback };
57
+ const pkg = {
58
+ parse,
59
+ debug_render,
60
+ render_audio,
61
+ register_playhead_callback,
62
+ collect_playhead_events,
63
+ unregister_playhead_callback,
64
+ };
50
65
  exports.default = pkg;
@@ -1,6 +1,7 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  export const memory: WebAssembly.Memory;
4
+ export const collect_playhead_events: () => [number, number, number];
4
5
  export const debug_render: (a: number, b: number) => [number, number, number];
5
6
  export const parse: (a: number, b: number, c: number, d: number) => [number, number, number];
6
7
  export const register_playhead_callback: (a: any) => void;