@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.
- package/.devalang +9 -10
- package/Cargo.toml +84 -80
- package/README.md +10 -7
- package/docs/CHANGELOG.md +83 -0
- package/docs/ROADMAP.md +6 -2
- package/docs/TODO.md +3 -14
- package/examples/bus.deva +10 -0
- package/examples/chain.deva +19 -0
- package/examples/effect.deva +2 -0
- package/examples/filter.deva +11 -0
- package/examples/lfo.deva +9 -0
- package/examples/plugin.deva +10 -10
- package/examples/routing.deva +23 -0
- package/examples/synth.deva +11 -1
- package/examples/synth_types.deva +17 -0
- package/out-tsc/bin/project-version.json +6 -0
- package/out-tsc/core/functions/index.d.ts +5 -0
- package/out-tsc/core/functions/index.js +11 -0
- package/out-tsc/pkg/devalang_core.d.ts +2 -0
- package/out-tsc/pkg/devalang_core.js +17 -2
- package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +1 -0
- package/out-tsc/scripts/version/copy-to-binary.d.ts +1 -0
- package/out-tsc/scripts/version/copy-to-binary.js +79 -0
- package/package.json +23 -10
- package/project-version.json +3 -3
- package/rust/bindings/Cargo.toml +9 -0
- package/rust/bindings/src/lib.rs +86 -0
- package/rust/cli/addon/commands.rs +35 -0
- package/rust/cli/addon/download.rs +234 -0
- package/rust/cli/addon/install.rs +33 -0
- package/rust/cli/addon/list.rs +224 -0
- package/rust/cli/addon/metadata.rs +124 -0
- package/rust/cli/addon/mod.rs +8 -0
- package/rust/cli/addon/remove.rs +271 -0
- package/rust/cli/addon/update.rs +305 -0
- package/rust/cli/{install/addon.rs → addon/utils.rs} +34 -43
- package/rust/cli/build/commands.rs +153 -103
- package/rust/cli/build/mod.rs +2 -2
- package/rust/cli/build/process.rs +165 -146
- package/rust/cli/check/mod.rs +208 -208
- package/rust/cli/discover/commands.rs +53 -31
- package/rust/cli/discover/config.rs +2 -4
- package/rust/cli/discover/install.rs +139 -28
- package/rust/cli/discover/metadata.rs +3 -3
- package/rust/cli/login/commands.rs +124 -124
- package/rust/cli/me/commands.rs +52 -0
- package/rust/cli/me/mod.rs +1 -0
- package/rust/cli/mod.rs +2 -2
- package/rust/cli/parser.rs +76 -70
- package/rust/cli/play/commands.rs +375 -324
- package/rust/cli/play/mod.rs +5 -5
- package/rust/cli/play/process.rs +159 -150
- package/rust/cli/play/realtime.rs +91 -91
- package/rust/cli/telemetry/commands.rs +22 -22
- package/rust/cli/telemetry/event_creator.rs +80 -80
- package/rust/cli/telemetry/mod.rs +3 -3
- package/rust/cli/telemetry/send.rs +51 -51
- package/rust/cli/template/commands.rs +69 -69
- package/rust/config/driver.rs +112 -103
- package/rust/config/mod.rs +3 -3
- package/rust/config/ops.rs +26 -26
- package/rust/config/settings.rs +101 -101
- package/rust/core/audio/engine/driver.rs +237 -0
- package/rust/core/audio/engine/export.rs +169 -0
- package/rust/core/audio/engine/helpers.rs +178 -170
- package/rust/core/audio/engine/mod.rs +56 -7
- package/rust/core/audio/engine/notes/dsp.rs +88 -0
- package/rust/core/audio/engine/notes/mod.rs +53 -0
- package/rust/core/audio/engine/notes/params.rs +294 -0
- package/rust/core/audio/engine/sample/insert.rs +300 -0
- package/rust/core/audio/engine/sample/mod.rs +40 -0
- package/rust/core/audio/engine/sample/padding.rs +170 -0
- package/rust/core/audio/evaluator/condition.rs +61 -0
- package/rust/core/audio/evaluator/mod.rs +9 -0
- package/rust/core/audio/{evaluator.rs → evaluator/numeric.rs} +152 -310
- package/rust/core/audio/evaluator/rhs.rs +16 -0
- package/rust/core/audio/evaluator/string_expr.rs +94 -0
- package/rust/core/audio/interpreter/driver.rs +574 -542
- package/rust/core/audio/interpreter/mod.rs +2 -14
- package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +179 -0
- package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +398 -0
- package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +323 -0
- package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +3 -0
- package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +371 -0
- package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +3 -0
- package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +192 -0
- package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +24 -0
- package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +116 -0
- package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +97 -0
- package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +100 -0
- package/rust/core/audio/interpreter/{automate.rs → statements/automate.rs} +2 -4
- package/rust/core/audio/interpreter/{call.rs → statements/call.rs} +36 -5
- package/rust/core/audio/interpreter/{condition.rs → statements/condition.rs} +72 -71
- package/rust/core/audio/interpreter/{function.rs → statements/function.rs} +24 -26
- package/rust/core/audio/interpreter/{let_.rs → statements/let_.rs} +36 -38
- package/rust/core/audio/interpreter/{load.rs → statements/load.rs} +17 -19
- package/rust/core/audio/interpreter/{loop_.rs → statements/loop_.rs} +115 -114
- package/rust/core/audio/interpreter/statements/mod.rs +12 -0
- package/rust/core/audio/interpreter/{sleep.rs → statements/sleep.rs} +28 -28
- package/rust/core/audio/interpreter/{spawn.rs → statements/spawn.rs} +54 -4
- package/rust/core/audio/interpreter/{tempo.rs → statements/tempo.rs} +40 -40
- package/rust/core/audio/interpreter/{trigger.rs → statements/trigger.rs} +242 -239
- package/rust/core/audio/loader/trigger.rs +98 -97
- package/rust/core/audio/mod.rs +6 -7
- package/rust/core/audio/special/easing.rs +189 -189
- package/rust/core/audio/special/env.rs +45 -45
- package/rust/core/audio/special/math.rs +134 -134
- package/rust/core/audio/special/modulator.rs +143 -143
- package/rust/core/builder/mod.rs +129 -86
- package/rust/core/debugger/{module.rs → logs.rs} +52 -55
- package/rust/core/debugger/mod.rs +30 -30
- package/rust/core/debugger/store.rs +38 -40
- package/rust/core/error/mod.rs +269 -269
- package/rust/core/lexer/driver.rs +2 -4
- package/rust/core/mod.rs +9 -10
- package/rust/core/parser/driver/block.rs +111 -0
- package/rust/core/parser/driver/cursor.rs +82 -0
- package/rust/core/parser/driver/driver_impl.rs +159 -0
- package/rust/core/parser/driver/mod.rs +6 -0
- package/rust/core/parser/driver/parse_array.rs +120 -0
- package/rust/core/parser/driver/parse_map.rs +247 -0
- package/rust/core/parser/driver/parser.rs +160 -0
- package/rust/core/parser/handler/arrow_call.rs +90 -15
- package/rust/core/parser/handler/at.rs +279 -279
- package/rust/core/parser/handler/bank.rs +104 -104
- package/rust/core/parser/handler/condition.rs +83 -83
- package/rust/core/parser/handler/dot.rs +148 -148
- package/rust/core/parser/handler/identifier/automate.rs +254 -254
- package/rust/core/parser/handler/identifier/call.rs +91 -91
- package/rust/core/parser/handler/identifier/emit.rs +70 -70
- package/rust/core/parser/handler/identifier/function.rs +113 -113
- package/rust/core/parser/handler/identifier/group.rs +89 -89
- package/rust/core/parser/handler/identifier/let_.rs +173 -173
- package/rust/core/parser/handler/identifier/mod.rs +55 -55
- package/rust/core/parser/handler/identifier/on.rs +107 -107
- package/rust/core/parser/handler/identifier/print.rs +49 -49
- package/rust/core/parser/handler/identifier/sleep.rs +96 -43
- package/rust/core/parser/handler/identifier/spawn.rs +91 -91
- package/rust/core/parser/handler/identifier/synth.rs +39 -3
- package/rust/core/parser/handler/loop_.rs +194 -194
- package/rust/core/parser/handler/pattern.rs +25 -2
- package/rust/core/parser/handler/tempo.rs +105 -57
- package/rust/core/parser/statement.rs +10 -11
- package/rust/core/plugin/loader.rs +137 -137
- package/rust/core/plugin/runner/mod.rs +11 -0
- package/rust/core/plugin/{runner.rs → runner/non_wasm.rs} +206 -72
- package/rust/core/plugin/runner/wasm32.rs +44 -0
- package/rust/core/preprocessor/loader/inject.rs +313 -0
- package/rust/core/preprocessor/loader/loader_helpers.rs +110 -0
- package/rust/core/preprocessor/loader/mod.rs +235 -0
- package/rust/core/preprocessor/module.rs +55 -60
- package/rust/core/preprocessor/{processor.rs → processor/handlers.rs} +107 -114
- package/rust/core/preprocessor/processor/mod.rs +1 -0
- package/rust/core/preprocessor/resolver/function.rs +69 -69
- package/rust/core/preprocessor/resolver/group.rs +122 -94
- package/rust/core/preprocessor/resolver/pattern.rs +14 -2
- package/rust/core/store/global.rs +57 -61
- package/rust/core/store/mod.rs +1 -5
- package/rust/lib.rs +323 -308
- package/rust/macros/Cargo.toml +14 -0
- package/rust/macros/src/lib.rs +52 -0
- package/rust/main.rs +336 -143
- package/rust/types/Cargo.toml +1 -1
- package/rust/types/src/addons.rs +57 -55
- package/rust/types/src/config.rs +82 -74
- package/rust/types/src/lib.rs +15 -12
- package/rust/types/src/plugin.rs +20 -0
- package/rust/types/src/store.rs +139 -0
- package/rust/types/src/telemetry.rs +85 -85
- package/rust/utils/Cargo.toml +5 -2
- package/rust/utils/src/file.rs +477 -94
- package/rust/utils/src/first_usage.rs +97 -97
- package/rust/utils/src/lib.rs +9 -9
- package/rust/utils/src/logger.rs +200 -200
- package/rust/utils/src/path.rs +158 -88
- package/rust/utils/src/signature.rs +41 -41
- package/rust/utils/src/spinner.rs +20 -20
- package/rust/utils/src/version.rs +58 -27
- package/rust/utils/src/watcher.rs +46 -46
- package/rust/web/api.rs +5 -5
- package/rust/web/auth.rs +5 -0
- package/rust/web/cdn.rs +34 -34
- package/rust/web/forge.rs +5 -0
- package/rust/web/mod.rs +2 -0
- package/tests/integration.rs +21 -21
- package/typescript/core/functions/index.ts +11 -0
- package/typescript/pkg/devalang_core.ts +20 -4
- package/typescript/scripts/version/copy-to-binary.ts +82 -0
- package/rust/cli/bank/api.rs +0 -122
- package/rust/cli/bank/commands.rs +0 -275
- package/rust/cli/bank/mod.rs +0 -29
- package/rust/cli/install/bank.rs +0 -53
- package/rust/cli/install/commands.rs +0 -35
- package/rust/cli/install/mod.rs +0 -4
- package/rust/cli/install/plugin.rs +0 -61
- package/rust/core/audio/engine/sample.rs +0 -366
- package/rust/core/audio/engine/synth.rs +0 -325
- package/rust/core/audio/interpreter/arrow_call.rs +0 -311
- package/rust/core/audio/renderer.rs +0 -54
- package/rust/core/parser/driver.rs +0 -584
- package/rust/core/preprocessor/loader.rs +0 -637
- package/rust/core/store/export.rs +0 -28
- package/rust/core/store/function.rs +0 -40
- package/rust/core/store/import.rs +0 -28
- package/rust/core/store/variable.rs +0 -51
- package/rust/core/utils/mod.rs +0 -1
- 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
|
-
|
|
9
|
-
|
|
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.
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
[
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
devalang_utils = { path = "rust/utils", features =
|
|
80
|
-
|
|
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**: [
|
|
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
|
|
140
|
-
myLead -> note(B3, { duration: 400, slide: true
|
|
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
|
-
- ⏳ **
|
|
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
|
-
- [
|
|
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,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 })
|
package/examples/plugin.deva
CHANGED
|
@@ -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
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
6
|
+
group acidSynthGroup:
|
|
7
|
+
let acidSynth = synth acidPlugin.synth {
|
|
8
|
+
waveform: "saw",
|
|
9
|
+
resonance: 1.0,
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
acidSynth -> note(
|
|
14
|
-
acidSynth -> note(
|
|
12
|
+
acidSynth -> note(C4, { duration: 1000 })
|
|
13
|
+
acidSynth -> note(E3, { duration: 1000 })
|
|
14
|
+
acidSynth -> note(B2, { duration: 1000 })
|
|
15
15
|
|
|
16
|
-
call
|
|
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 }
|
package/examples/synth.deva
CHANGED
|
@@ -11,4 +11,14 @@ group myLead:
|
|
|
11
11
|
mySynth -> note(D4, { duration: 400 })
|
|
12
12
|
mySynth -> note(B3, { duration: 600 })
|
|
13
13
|
|
|
14
|
-
|
|
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
|
|
@@ -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 &&
|
|
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 = {
|
|
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;
|