Compare commits
27 commits
a54abb48e7
...
0e54080a1d
Author | SHA1 | Date | |
---|---|---|---|
Alex Janka | 0e54080a1d | ||
cd9b589d23 | |||
9e2b9cc06e | |||
b3038b458c | |||
8eed04fe5f | |||
31583d42e7 | |||
e0913b16de | |||
442d54ba50 | |||
916dfc16a2 | |||
a5abe896ed | |||
1c03d4adc6 | |||
d270d1221f | |||
10aabe3a38 | |||
ed72de7cbf | |||
bb274976ca | |||
245add6530 | |||
1ad6d6cc5c | |||
e9dff5b0eb | |||
57db4b57ed | |||
369ef886e4 | |||
37cd6b34f1 | |||
8a1cbcd094 | |||
0d608592b5 | |||
b2586ded48 | |||
80ed8b5384 | |||
0017efae0a | |||
0dccb4501f |
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
|
@ -54,8 +54,9 @@ jobs:
|
|||
uses: dtolnay/rust-toolchain@nightly
|
||||
- name: Run the tests
|
||||
# Don't use --all-features as that will enable a whole bunch of
|
||||
# conflicting iced features
|
||||
run: cargo test --workspace --features "simd,standalone,zstd"
|
||||
# conflicting iced features. `--locked` ensures that the lockfile is up
|
||||
# to date. We only really need this in one of the builds.
|
||||
run: cargo test --locked --workspace --features "simd,standalone,zstd"
|
||||
|
||||
# This makes sure that NIH-plug can be compiled without VST3 support
|
||||
build-without-vst3:
|
||||
|
|
56
CHANGELOG.md
56
CHANGELOG.md
|
@ -10,6 +10,62 @@ Since there is no stable release yet, the changes are organized per day in
|
|||
reverse chronological order. The main purpose of this document in its current
|
||||
state is to list breaking changes.
|
||||
|
||||
## [2024-05-05]
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- `nih_plug_egui` has been updated from egui 0.26.1 to egui 0.27.2.
|
||||
- `nih_plug_vizia` has been updated to the latest version with some a additional
|
||||
patches. This includes a workaround for the problem where opening multiple
|
||||
instances of a plugin's GUI on Windows or macOS would result in crashes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Two byte slices are now accepted in `NoteEvent::from_midi()` if the event
|
||||
doesn't use the third byte.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a race condition in the VST3 GUI event loop on Linux. This could cause
|
||||
panics with certain versions of Carla.
|
||||
- The CPAL backend now correctly handles situations where it receives fewer
|
||||
samples than configured.
|
||||
- Fixed the handling of multichannel audio in the CPAL backend.
|
||||
|
||||
## [2024-05-04]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a soundness issue in the buffer management where in-place input/output
|
||||
buffers may not have been recognized properly before.
|
||||
|
||||
## [2024-03-23]
|
||||
|
||||
### Added
|
||||
|
||||
- `nih_plug_xtask` now detects and uses non-standard `target` directory
|
||||
locations if overridden through Cargo's settings.
|
||||
|
||||
## [2024-03-18]
|
||||
|
||||
### Changed
|
||||
|
||||
- (Keyboard) input events sent by the host through VST3's `IPlugView` interface
|
||||
are now explicitly ignored. This may allow a couple more keyboard events to
|
||||
reach through to plugin windows in hosts that use these.
|
||||
|
||||
## [2024-02-23]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `nih_plug_egui` panicking due to cursor icons not yet being implemented in baseview for MacOS and Windows.
|
||||
|
||||
## [2024-02-22]
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- `nih_plug_egui` has been updated from egui 0.22.0 to using egui 0.26.1.
|
||||
|
||||
## [2023-12-30]
|
||||
|
||||
### Breaking changes
|
||||
|
|
310
Cargo.lock
generated
310
Cargo.lock
generated
|
@ -280,6 +280,12 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "as-raw-xcb-connection"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
|
||||
|
||||
[[package]]
|
||||
name = "assert_no_alloc"
|
||||
version = "1.1.2"
|
||||
|
@ -459,7 +465,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -521,7 +527,7 @@ checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -637,6 +643,40 @@ dependencies = [
|
|||
"xcb-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "baseview"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/RustAudio/baseview.git?rev=45465c5f46abed6c6ce370fffde5edc8e4cd5aa3#45465c5f46abed6c6ce370fffde5edc8e4cd5aa3"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"core-foundation",
|
||||
"keyboard-types",
|
||||
"nix 0.22.3",
|
||||
"objc",
|
||||
"raw-window-handle 0.5.2",
|
||||
"uuid",
|
||||
"winapi",
|
||||
"x11",
|
||||
"x11rb 0.13.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "baseview"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/RustAudio/baseview.git#579130ecb4f9f315ae52190af42f0ea46aeaa4a2"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"core-foundation",
|
||||
"keyboard-types",
|
||||
"nix 0.22.3",
|
||||
"objc",
|
||||
"raw-window-handle 0.5.2",
|
||||
"uuid",
|
||||
"winapi",
|
||||
"x11",
|
||||
"x11rb 0.13.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.1"
|
||||
|
@ -654,7 +694,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -749,7 +789,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -770,6 +810,15 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-nih-plug"
|
||||
version = "0.1.0"
|
||||
|
@ -777,6 +826,29 @@ dependencies = [
|
|||
"nih_plug_xtask",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
|
@ -891,7 +963,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1020,10 +1092,22 @@ dependencies = [
|
|||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"smithay-clipboard",
|
||||
"x11-clipboard 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "copypasta"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d35364349bf9e9e1c3a035ddcb00d188d23a3c40c50244c03c27a99fc6a65ae"
|
||||
dependencies = [
|
||||
"clipboard-win",
|
||||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"x11-clipboard 0.8.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
@ -1293,7 +1377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1399,7 +1483,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1446,18 +1530,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ecolor"
|
||||
version = "0.22.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e479a7fa3f23d4e794f8b2f8b3568dd4e47886ad1b12c9c095e141cb591eb63"
|
||||
checksum = "20930a432bbd57a6d55e07976089708d4893f3d556cf42a0d79e9e321fa73b10"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui"
|
||||
version = "0.22.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3aef8ec3ae1b772f340170c65bf27d5b8c28f543a0116c844d2ac08d01123e7"
|
||||
checksum = "584c5d1bf9a67b25778a3323af222dbe1a1feb532190e103901187f92c7fe29a"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"epaint",
|
||||
|
@ -1466,28 +1550,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "egui-baseview"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/BillyDM/egui-baseview.git?rev=27c027c22a83d2eb214074f922ba4115f712e483#27c027c22a83d2eb214074f922ba4115f712e483"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/BillyDM/egui-baseview.git?rev=68c4d0e8e5c1c702a888a245f4ac50eddfdfcaed#68c4d0e8e5c1c702a888a245f4ac50eddfdfcaed"
|
||||
dependencies = [
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=1d9806d5bd92275d0d8142d9c9c90198757b9b25)",
|
||||
"copypasta 0.8.2",
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=45465c5f46abed6c6ce370fffde5edc8e4cd5aa3)",
|
||||
"copypasta 0.10.0",
|
||||
"egui",
|
||||
"egui_glow",
|
||||
"keyboard-types",
|
||||
"raw-window-handle 0.4.3",
|
||||
"log",
|
||||
"raw-window-handle 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui_glow"
|
||||
version = "0.22.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f8c2752cdf1b0ef5fcda59a898cacabad974d4f5880e92a420b2c917022da64"
|
||||
checksum = "e0e5d975f3c86edc3d35b1db88bb27c15dde7c55d3b5af164968ab5ede3f44ca"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
"glow 0.12.3",
|
||||
"glow 0.13.1",
|
||||
"log",
|
||||
"memoffset 0.6.5",
|
||||
"memoffset 0.9.0",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
@ -1500,9 +1585,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
|||
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.22.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3857d743a6e0741cdd60b622a74c7a36ea75f5f8f11b793b41d905d2c9721a4b"
|
||||
checksum = "e4c3a552cfca14630702449d35f41c84a0d15963273771c6059175a803620f3f"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
@ -1525,23 +1610,23 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.22.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09333964d4d57f40a85338ba3ca5ed4716070ab184dcfed966b35491c5c64f3b"
|
||||
checksum = "b381f8b149657a4acf837095351839f32cd5c4aec1817fc4df84e18d76334176"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"ahash",
|
||||
"atomic_refcell",
|
||||
"bytemuck",
|
||||
"ecolor",
|
||||
"emath",
|
||||
"nohash-hasher",
|
||||
"parking_lot 0.12.1",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1886,7 +1971,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1992,6 +2077,26 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
|
@ -2082,6 +2187,18 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glow"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"slotmap",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glow_glyph"
|
||||
version = "0.5.1"
|
||||
|
@ -2902,7 +3019,7 @@ dependencies = [
|
|||
"atomic_float",
|
||||
"atomic_refcell",
|
||||
"backtrace",
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=2c1b1a7b0fef1a29a5150a6a8f6fef6a0cbab8c4)",
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git)",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"clap",
|
||||
|
@ -2920,7 +3037,7 @@ dependencies = [
|
|||
"nih_plug_derive",
|
||||
"objc",
|
||||
"parking_lot 0.12.1",
|
||||
"raw-window-handle 0.5.2",
|
||||
"raw-window-handle 0.6.0",
|
||||
"rtrb",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -2949,14 +3066,13 @@ dependencies = [
|
|||
name = "nih_plug_egui"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=1d9806d5bd92275d0d8142d9c9c90198757b9b25)",
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=45465c5f46abed6c6ce370fffde5edc8e4cd5aa3)",
|
||||
"crossbeam",
|
||||
"egui",
|
||||
"egui-baseview",
|
||||
"lazy_static",
|
||||
"nih_plug",
|
||||
"parking_lot 0.12.1",
|
||||
"raw-window-handle 0.4.3",
|
||||
"raw-window-handle 0.5.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -2991,6 +3107,7 @@ name = "nih_plug_xtask"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata",
|
||||
"goblin",
|
||||
"reflink",
|
||||
"serde",
|
||||
|
@ -3149,7 +3266,7 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3636,9 +3753,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.71"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -3671,9 +3788,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -3789,6 +3906,12 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.8.0"
|
||||
|
@ -4043,13 +4166,13 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.23.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cssparser",
|
||||
|
@ -4082,25 +4205,28 @@ name = "semver"
|
|||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4122,7 +4248,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4359,9 +4485,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.43"
|
||||
version = "2.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4433,7 +4559,7 @@ checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4555,7 +4681,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4680,7 +4806,7 @@ checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4"
|
|||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
|
@ -4762,7 +4888,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
[[package]]
|
||||
name = "vizia"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"vizia_baseview",
|
||||
"vizia_core",
|
||||
|
@ -4772,7 +4898,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_baseview"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"baseview 0.1.0 (git+https://github.com/RustAudio/baseview.git?rev=2c1b1a7b0fef1a29a5150a6a8f6fef6a0cbab8c4)",
|
||||
"femtovg",
|
||||
|
@ -4786,7 +4912,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_core"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"bitflags 2.4.1",
|
||||
|
@ -4817,7 +4943,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4827,12 +4953,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_id"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
|
||||
[[package]]
|
||||
name = "vizia_input"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"keyboard-types",
|
||||
|
@ -4842,7 +4968,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_storage"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"morphorm",
|
||||
"vizia_id",
|
||||
|
@ -4851,7 +4977,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_style"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cssparser",
|
||||
|
@ -4864,7 +4990,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_window"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"morphorm",
|
||||
|
@ -4875,7 +5001,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "vizia_winit"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2023-12-30#0a4af1999d24f866d8e274a7810c4b61eea95a91"
|
||||
source = "git+https://github.com/robbert-vdh/vizia.git?tag=patched-2024-05-06#e3fab5530cda9cb90f679508d9f058bd62189d36"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_winit",
|
||||
|
@ -4981,7 +5107,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -5015,7 +5141,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -5531,7 +5657,16 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464"
|
||||
dependencies = [
|
||||
"x11rb",
|
||||
"x11rb 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-clipboard"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41aca1115b1f195f21c541c5efb423470848d48143127d0f07f8b90c27440df"
|
||||
dependencies = [
|
||||
"x11rb 0.12.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5551,11 +5686,37 @@ version = "0.10.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507"
|
||||
dependencies = [
|
||||
"gethostname",
|
||||
"gethostname 0.2.3",
|
||||
"nix 0.24.3",
|
||||
"winapi",
|
||||
"winapi-wsapoll",
|
||||
"x11rb-protocol",
|
||||
"x11rb-protocol 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a"
|
||||
dependencies = [
|
||||
"gethostname 0.3.0",
|
||||
"nix 0.26.4",
|
||||
"winapi",
|
||||
"winapi-wsapoll",
|
||||
"x11rb-protocol 0.12.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a"
|
||||
dependencies = [
|
||||
"as-raw-xcb-connection",
|
||||
"gethostname 0.4.3",
|
||||
"libc",
|
||||
"rustix 0.38.28",
|
||||
"x11rb-protocol 0.13.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5567,6 +5728,21 @@ dependencies = [
|
|||
"nix 0.24.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb-protocol"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc"
|
||||
dependencies = [
|
||||
"nix 0.26.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb-protocol"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34"
|
||||
|
||||
[[package]]
|
||||
name = "xcb"
|
||||
version = "0.9.0"
|
||||
|
@ -5729,7 +5905,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
28
Cargo.toml
28
Cargo.toml
|
@ -11,6 +11,7 @@ description = "A simple but modern API-agnostic audio plugin framework"
|
|||
repository = "https://github.com/robbert-vdh/nih-plug"
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"nih_plug_derive",
|
||||
"nih_plug_egui",
|
||||
|
@ -53,7 +54,14 @@ assert_process_allocs = ["dep:assert_no_alloc"]
|
|||
# Enables an export target for standalone binaries through the
|
||||
# `nih_export_standalone()` function. Disabled by default as this requires
|
||||
# building additional dependencies for audio and MIDI handling.
|
||||
standalone = ["dep:baseview", "dep:clap", "dep:cpal", "dep:jack", "dep:midir", "dep:rtrb"]
|
||||
standalone = [
|
||||
"dep:baseview",
|
||||
"dep:clap",
|
||||
"dep:cpal",
|
||||
"dep:jack",
|
||||
"dep:midir",
|
||||
"dep:rtrb",
|
||||
]
|
||||
# Enables the `nih_export_vst3!()` macro. Enabled by default. This feature
|
||||
# exists mostly for GPL-compliance reasons, since even if you don't use the VST3
|
||||
# wrapper you might otherwise still include a couple (unused) symbols from the
|
||||
|
@ -82,27 +90,35 @@ backtrace = "0.3.65"
|
|||
bitflags = "1.3"
|
||||
cfg-if = "1.0"
|
||||
# This supports CLAP 1.1.8
|
||||
clap-sys = { git = "https://github.com/robbert-vdh/clap-sys.git", branch = "feature/cstr-macro" }
|
||||
clap-sys = { git = "https://github.com/robbert-vdh/clap-sys.git", branch = "feature/cstr-macro" }
|
||||
crossbeam = "0.8"
|
||||
lazy_static = "1.4"
|
||||
log = { version = "0.4", features = ["std", "release_max_level_info"] }
|
||||
midi-consts = "0.1"
|
||||
nih_log = "0.3.1"
|
||||
parking_lot = "0.12"
|
||||
raw-window-handle = "0.5"
|
||||
raw-window-handle = "0.6"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
widestring = "1.0.0-beta.1"
|
||||
|
||||
# Used for the `assert_process_allocs` feature
|
||||
assert_no_alloc = { git = "https://github.com/robbert-vdh/rust-assert-no-alloc.git", branch = "feature/nested-permit-forbid", features = ["backtrace", "log"], optional = true }
|
||||
assert_no_alloc = { git = "https://github.com/robbert-vdh/rust-assert-no-alloc.git", branch = "feature/nested-permit-forbid", features = [
|
||||
"backtrace",
|
||||
"log",
|
||||
], optional = true }
|
||||
|
||||
# Used for the `standalone` feature
|
||||
# NOTE: OpenGL support is not needed here, but rust-analyzer gets confused when
|
||||
# some crates do use it and others don't
|
||||
baseview = { git = "https://github.com/RustAudio/baseview.git", rev = "2c1b1a7b0fef1a29a5150a6a8f6fef6a0cbab8c4", features = ["opengl"], optional = true }
|
||||
baseview = { git = "https://github.com/RustAudio/baseview.git", features = [
|
||||
"opengl",
|
||||
], optional = true }
|
||||
# All the claps!
|
||||
clap = { version = "4.1.8", features = ["derive", "wrap_help"], optional = true }
|
||||
clap = { version = "4.1.8", features = [
|
||||
"derive",
|
||||
"wrap_help",
|
||||
], optional = true }
|
||||
cpal = { version = "0.15", optional = true }
|
||||
jack = { version = "0.11.4", optional = true }
|
||||
midir = { version = "0.9.1", optional = true }
|
||||
|
|
|
@ -11,9 +11,8 @@ keeping the amount of magic to minimum and making it easy to experiment with
|
|||
different approaches to things. See the [current features](#current-features)
|
||||
section for more information on the project's current status.
|
||||
|
||||
Come join us on the [Rust Audio Discord](https://discord.gg/ykxU3rt4Cb), check
|
||||
out the [documentation](https://nih-plug.robbertvanderhelm.nl/), or use the
|
||||
[cookiecutter template](https://github.com/robbert-vdh/nih-plug-template) to
|
||||
Check out the [documentation](https://nih-plug.robbertvanderhelm.nl/), or use
|
||||
the [cookiecutter template](https://github.com/robbert-vdh/nih-plug-template) to
|
||||
quickly get started with NIH-plug.
|
||||
|
||||
### Table of contents
|
||||
|
|
|
@ -14,4 +14,4 @@ quote = "1.0"
|
|||
proc-macro2 = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
nih_plug = { path = ".." }
|
||||
nih_plug = { path = "..", default-features = false }
|
||||
|
|
|
@ -8,27 +8,19 @@ license = "ISC"
|
|||
description = "An adapter to use egui GUIs with NIH-plug"
|
||||
|
||||
[features]
|
||||
default = ["egui-default-features", "opengl"]
|
||||
|
||||
# Use egui's default features
|
||||
egui-default-features = ["egui/default"]
|
||||
default = ["opengl", "default_fonts"]
|
||||
# `nih_plug_egui` always uses OpenGL since egui's wgpu backend is still unstable
|
||||
# depending on the platform
|
||||
opengl = []
|
||||
opengl = ["egui-baseview/opengl"]
|
||||
default_fonts = ["egui-baseview/default_fonts"]
|
||||
rayon = ["egui-baseview/rayon"]
|
||||
|
||||
[dependencies]
|
||||
nih_plug = { path = ".." }
|
||||
|
||||
# The currently targeted version of baseview uses a different version of
|
||||
# `raw_window_handle` than NIH-plug, so we need to manually convert between them
|
||||
raw-window-handle = "0.4"
|
||||
|
||||
baseview = { git = "https://github.com/RustAudio/baseview.git", rev = "1d9806d5bd92275d0d8142d9c9c90198757b9b25" }
|
||||
nih_plug = { path = "..", default-features = false }
|
||||
raw-window-handle = "0.5"
|
||||
baseview = { git = "https://github.com/RustAudio/baseview.git", rev = "45465c5f46abed6c6ce370fffde5edc8e4cd5aa3" }
|
||||
crossbeam = "0.8"
|
||||
# The `egui-default-features` feature enables the default features. This makes
|
||||
# it possible to opt out of this if needed.
|
||||
egui = { version = "0.22", default-features = false }
|
||||
egui-baseview = { git = "https://github.com/BillyDM/egui-baseview.git", rev = "27c027c22a83d2eb214074f922ba4115f712e483" }
|
||||
egui-baseview = { git = "https://github.com/BillyDM/egui-baseview.git", rev = "68c4d0e8e5c1c702a888a245f4ac50eddfdfcaed", default-features = false }
|
||||
lazy_static = "1.4"
|
||||
parking_lot = "0.12"
|
||||
# To make the state persistable
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use baseview::gl::GlConfig;
|
||||
use baseview::{Size, WindowHandle, WindowOpenOptions, WindowScalePolicy};
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
use egui::Context;
|
||||
use egui_baseview::egui::Context;
|
||||
use egui_baseview::EguiWindow;
|
||||
use nih_plug::prelude::{Editor, GuiContext, ParamSetter, ParentWindowHandle};
|
||||
use parking_lot::RwLock;
|
||||
|
@ -37,17 +37,17 @@ unsafe impl HasRawWindowHandle for ParentWindowHandleAdapter {
|
|||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
match self.0 {
|
||||
ParentWindowHandle::X11Window(window) => {
|
||||
let mut handle = raw_window_handle::XcbHandle::empty();
|
||||
let mut handle = raw_window_handle::XcbWindowHandle::empty();
|
||||
handle.window = window;
|
||||
RawWindowHandle::Xcb(handle)
|
||||
}
|
||||
ParentWindowHandle::AppKitNsView(ns_view) => {
|
||||
let mut handle = raw_window_handle::AppKitHandle::empty();
|
||||
let mut handle = raw_window_handle::AppKitWindowHandle::empty();
|
||||
handle.ns_view = ns_view;
|
||||
RawWindowHandle::AppKit(handle)
|
||||
}
|
||||
ParentWindowHandle::Win32Hwnd(hwnd) => {
|
||||
let mut handle = raw_window_handle::Win32Handle::empty();
|
||||
let mut handle = raw_window_handle::Win32WindowHandle::empty();
|
||||
handle.hwnd = hwnd;
|
||||
RawWindowHandle::Win32(handle)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::sync::Arc;
|
|||
compile_error!("There's currently no software rendering support for egui");
|
||||
|
||||
/// Re-export for convenience.
|
||||
pub use egui;
|
||||
pub use egui_baseview::egui;
|
||||
|
||||
mod editor;
|
||||
pub mod widgets;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use egui::{TextStyle, Ui, Vec2};
|
||||
use egui_baseview::egui::{self, TextStyle, Ui, Vec2};
|
||||
use nih_plug::prelude::{Param, ParamFlags, ParamPtr, ParamSetter, Params};
|
||||
|
||||
use super::ParamSlider;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use egui::{vec2, Key, Response, Sense, Stroke, TextEdit, TextStyle, Ui, Vec2, Widget, WidgetText};
|
||||
use egui_baseview::egui::{
|
||||
self, emath, vec2, Key, Response, Sense, Stroke, TextEdit, TextStyle, Ui, Vec2, Widget,
|
||||
WidgetText,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use nih_plug::prelude::{Param, ParamSetter};
|
||||
use parking_lot::Mutex;
|
||||
|
@ -199,8 +202,7 @@ impl<'a, P: Param> ParamSlider<'a, P> {
|
|||
response.mark_changed();
|
||||
} else {
|
||||
let proportion =
|
||||
egui::emath::remap_clamp(click_pos.x, response.rect.x_range(), 0.0..=1.0)
|
||||
as f64;
|
||||
emath::remap_clamp(click_pos.x, response.rect.x_range(), 0.0..=1.0) as f64;
|
||||
self.set_normalized_value(proportion as f32);
|
||||
response.mark_changed();
|
||||
Self::set_drag_amount_memory(ui, 0.0);
|
||||
|
@ -301,7 +303,12 @@ impl<'a, P: Param> ParamSlider<'a, P> {
|
|||
.layout()
|
||||
.align_size_within_rect(text.size(), response.rect.shrink2(padding))
|
||||
.min;
|
||||
text.paint_with_visuals(ui.painter(), text_pos, &visuals);
|
||||
|
||||
ui.painter().add(egui::epaint::TextShape::new(
|
||||
text_pos,
|
||||
text,
|
||||
visuals.fg_stroke.color,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Utilities for creating these widgets.
|
||||
|
||||
use egui::Color32;
|
||||
use egui_baseview::egui::{self, Color32};
|
||||
|
||||
/// Additively modify the hue, saturation, and lightness [0, 1] values of a color.
|
||||
pub fn add_hsv(color: Color32, h: f32, s: f32, v: f32) -> Color32 {
|
||||
|
|
|
@ -56,7 +56,7 @@ async-std = ["iced_baseview/async-std"]
|
|||
smol = ["iced_baseview/smol"]
|
||||
|
||||
[dependencies]
|
||||
nih_plug = { path = ".." }
|
||||
nih_plug = { path = "..", default-features = false }
|
||||
nih_plug_assets = { git = "https://github.com/robbert-vdh/nih_plug_assets.git" }
|
||||
|
||||
# The currently targeted version of baseview uses a different version of
|
||||
|
@ -67,6 +67,6 @@ atomic_refcell = "0.1"
|
|||
baseview = { git = "https://github.com/RustAudio/baseview.git", rev = "1d9806d5bd92275d0d8142d9c9c90198757b9b25" }
|
||||
crossbeam = "0.8"
|
||||
# This targets iced 0.4
|
||||
iced_baseview = { git = "https://github.com/robbert-vdh/iced_baseview.git", branch = "feature/update-baseview", default_features = false }
|
||||
iced_baseview = { git = "https://github.com/robbert-vdh/iced_baseview.git", branch = "feature/update-baseview", default-features = false }
|
||||
# To make the state persistable
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
@ -9,7 +9,7 @@ configurations. To use wgpu instead, include the crate with the following
|
|||
options:
|
||||
|
||||
```toml
|
||||
nih_plug_iced = { git = "https://github.com/robbert-vdh/nih-plug.git", default_features = false, features = ["wgpu"] }
|
||||
nih_plug_iced = { git = "https://github.com/robbert-vdh/nih-plug.git", default-features = false, features = ["wgpu"] }
|
||||
```
|
||||
|
||||
Iced has many more optional features. Check the `Cargo.toml` file for more
|
||||
|
|
|
@ -8,13 +8,13 @@ license = "ISC"
|
|||
description = "An adapter to use VIZIA GUIs with NIH-plug"
|
||||
|
||||
[dependencies]
|
||||
nih_plug = { path = ".." }
|
||||
nih_plug = { path = "..", default-features = false }
|
||||
nih_plug_assets = { git = "https://github.com/robbert-vdh/nih_plug_assets.git" }
|
||||
|
||||
baseview = { git = "https://github.com/RustAudio/baseview.git", rev = "2c1b1a7b0fef1a29a5150a6a8f6fef6a0cbab8c4" }
|
||||
# This contains an as of writing not yet merged patch for rounding errors when
|
||||
# resizing, and a workaround for certain events not firing when resizing
|
||||
vizia = { git = "https://github.com/robbert-vdh/vizia.git", tag = "patched-2023-12-30", default_features = false, features = ["baseview", "clipboard", "x11"] }
|
||||
vizia = { git = "https://github.com/robbert-vdh/vizia.git", tag = "patched-2024-05-06", default-features = false, features = ["baseview", "clipboard", "x11"] }
|
||||
|
||||
crossbeam = "0.8"
|
||||
# To make the state persistable
|
||||
|
|
|
@ -8,6 +8,7 @@ license = "ISC"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
cargo_metadata = "0.18.1"
|
||||
goblin = "0.6.1"
|
||||
# Version 0.1.3 from crates.io assumes a 64-bit toolchain
|
||||
reflink = { git = "https://github.com/nicokoch/reflink.git", rev = "e8d93b465f5d9ad340cd052b64bbc77b8ee107e2" }
|
||||
|
|
|
@ -14,9 +14,6 @@ mod util;
|
|||
/// Re-export for the main function.
|
||||
pub use anyhow::Result;
|
||||
|
||||
/// The base directory for the bundler's output.
|
||||
const BUNDLE_HOME: &str = "target/bundled";
|
||||
|
||||
fn build_usage_string(command_name: &str) -> String {
|
||||
format!(
|
||||
"Usage:
|
||||
|
@ -79,6 +76,11 @@ pub fn main() -> Result<()> {
|
|||
/// `std::env::args()` before passing it to this function.
|
||||
pub fn main_with_args(command_name: &str, args: impl IntoIterator<Item = String>) -> Result<()> {
|
||||
chdir_workspace_root()?;
|
||||
let cargo_metadata = cargo_metadata::MetadataCommand::new()
|
||||
.manifest_path("./Cargo.toml")
|
||||
.exec()
|
||||
.context("Could not parse `cargo-metadata`")?;
|
||||
let target_dir = cargo_metadata.target_directory.as_std_path();
|
||||
|
||||
let mut args = args.into_iter();
|
||||
let usage_string = build_usage_string(command_name);
|
||||
|
@ -96,9 +98,9 @@ pub fn main_with_args(command_name: &str, args: impl IntoIterator<Item = String>
|
|||
// As explained above, for efficiency's sake this is a two step process
|
||||
build(&packages, &other_args)?;
|
||||
|
||||
bundle(&packages[0], &other_args, false)?;
|
||||
bundle(target_dir, &packages[0], &other_args, false)?;
|
||||
for package in packages.into_iter().skip(1) {
|
||||
bundle(&package, &other_args, false)?;
|
||||
bundle(target_dir, &package, &other_args, false)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -134,9 +136,9 @@ pub fn main_with_args(command_name: &str, args: impl IntoIterator<Item = String>
|
|||
|
||||
// This `true` indicates a universal build. This will cause the two sets of built
|
||||
// binaries to beq lipo'd together into universal binaries before bundling
|
||||
bundle(&packages[0], &other_args, true)?;
|
||||
bundle(target_dir, &packages[0], &other_args, true)?;
|
||||
for package in packages.into_iter().skip(1) {
|
||||
bundle(&package, &other_args, true)?;
|
||||
bundle(target_dir, &package, &other_args, true)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -214,7 +216,7 @@ pub fn build(packages: &[String], args: &[String]) -> Result<()> {
|
|||
/// Normally this respects the `--target` option for cross compilation. If the `universal` option is
|
||||
/// specified instead, then this will assume both `x86_64-apple-darwin` and `aarch64-apple-darwin`
|
||||
/// have been built and it will try to lipo those together instead.
|
||||
pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
||||
pub fn bundle(target_dir: &Path, package: &str, args: &[String], universal: bool) -> Result<()> {
|
||||
let mut build_type_dir = "debug";
|
||||
let mut cross_compile_target: Option<String> = None;
|
||||
for arg_idx in (0..args.len()).rev() {
|
||||
|
@ -252,7 +254,8 @@ pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
|||
// We can bundle both library targets (for plugins) and binary targets (for standalone
|
||||
// applications)
|
||||
if universal {
|
||||
let x86_64_target_base = target_base(Some("x86_64-apple-darwin"))?.join(build_type_dir);
|
||||
let x86_64_target_base =
|
||||
target_base(target_dir, Some("x86_64-apple-darwin"))?.join(build_type_dir);
|
||||
let x86_64_bin_path = x86_64_target_base.join(binary_basename(
|
||||
package,
|
||||
CompilationTarget::MacOS(Architecture::X86_64),
|
||||
|
@ -262,7 +265,8 @@ pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
|||
CompilationTarget::MacOS(Architecture::X86_64),
|
||||
));
|
||||
|
||||
let aarch64_target_base = target_base(Some("aarch64-apple-darwin"))?.join(build_type_dir);
|
||||
let aarch64_target_base =
|
||||
target_base(target_dir, Some("aarch64-apple-darwin"))?.join(build_type_dir);
|
||||
let aarch64_bin_path = aarch64_target_base.join(binary_basename(
|
||||
package,
|
||||
CompilationTarget::MacOS(Architecture::AArch64),
|
||||
|
@ -281,6 +285,7 @@ pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
|||
eprintln!();
|
||||
if build_bin {
|
||||
bundle_binary(
|
||||
target_dir,
|
||||
package,
|
||||
&[&x86_64_bin_path, &aarch64_bin_path],
|
||||
CompilationTarget::MacOSUniversal,
|
||||
|
@ -288,6 +293,7 @@ pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
|||
}
|
||||
if build_lib {
|
||||
bundle_plugin(
|
||||
target_dir,
|
||||
package,
|
||||
&[&x86_64_lib_path, &aarch64_lib_path],
|
||||
CompilationTarget::MacOSUniversal,
|
||||
|
@ -295,7 +301,8 @@ pub fn bundle(package: &str, args: &[String], universal: bool) -> Result<()> {
|
|||
}
|
||||
} else {
|
||||
let compilation_target = compilation_target(cross_compile_target.as_deref())?;
|
||||
let target_base = target_base(cross_compile_target.as_deref())?.join(build_type_dir);
|
||||
let target_base =
|
||||
target_base(target_dir, cross_compile_target.as_deref())?.join(build_type_dir);
|
||||
let bin_path = target_base.join(binary_basename(package, compilation_target));
|
||||
let lib_path = target_base.join(library_basename(package, compilation_target));
|
||||
if !bin_path.exists() && !lib_path.exists() {
|
||||
|
@ -314,10 +321,10 @@ to your Cargo.toml file?"#,
|
|||
|
||||
eprintln!();
|
||||
if bin_path.exists() {
|
||||
bundle_binary(package, &[&bin_path], compilation_target)?;
|
||||
bundle_binary(target_dir, package, &[&bin_path], compilation_target)?;
|
||||
}
|
||||
if lib_path.exists() {
|
||||
bundle_plugin(package, &[&lib_path], compilation_target)?;
|
||||
bundle_plugin(target_dir, package, &[&lib_path], compilation_target)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,10 +335,12 @@ to your Cargo.toml file?"#,
|
|||
/// combined into a single binary using a method that depends on the compilation target. For
|
||||
/// universal macOS builds this uses lipo.
|
||||
fn bundle_binary(
|
||||
target_dir: &Path,
|
||||
package: &str,
|
||||
bin_paths: &[&Path],
|
||||
compilation_target: CompilationTarget,
|
||||
) -> Result<()> {
|
||||
let bundle_home_dir = bundle_home(target_dir);
|
||||
let bundle_name = match load_bundler_config()?.and_then(|c| c.get(package).cloned()) {
|
||||
Some(PackageConfig { name: Some(name) }) => name,
|
||||
_ => package.to_string(),
|
||||
|
@ -340,7 +349,7 @@ fn bundle_binary(
|
|||
// On MacOS the standalone target needs to be in a bundle
|
||||
let standalone_bundle_binary_name =
|
||||
standalone_bundle_binary_name(&bundle_name, compilation_target);
|
||||
let standalone_binary_path = Path::new(BUNDLE_HOME).join(&standalone_bundle_binary_name);
|
||||
let standalone_binary_path = bundle_home_dir.join(&standalone_bundle_binary_name);
|
||||
|
||||
fs::create_dir_all(standalone_binary_path.parent().unwrap())
|
||||
.context("Could not create standalone bundle directory")?;
|
||||
|
@ -363,7 +372,7 @@ fn bundle_binary(
|
|||
})?;
|
||||
}
|
||||
|
||||
let standalone_bundle_home = Path::new(BUNDLE_HOME).join(
|
||||
let standalone_bundle_home = bundle_home_dir.join(
|
||||
Path::new(&standalone_bundle_binary_name)
|
||||
.components()
|
||||
.next()
|
||||
|
@ -390,10 +399,12 @@ fn bundle_binary(
|
|||
/// the libraries will be combined into a single library using a method that depends on the
|
||||
/// compilation target. For universal macOS builds this uses lipo.
|
||||
fn bundle_plugin(
|
||||
target_dir: &Path,
|
||||
package: &str,
|
||||
lib_paths: &[&Path],
|
||||
compilation_target: CompilationTarget,
|
||||
) -> Result<()> {
|
||||
let bundle_home_dir = bundle_home(target_dir);
|
||||
let bundle_name = match load_bundler_config()?.and_then(|c| c.get(package).cloned()) {
|
||||
Some(PackageConfig { name: Some(name) }) => name,
|
||||
_ => package.to_string(),
|
||||
|
@ -419,7 +430,7 @@ fn bundle_plugin(
|
|||
|
||||
if bundle_clap {
|
||||
let clap_bundle_library_name = clap_bundle_library_name(&bundle_name, compilation_target);
|
||||
let clap_lib_path = Path::new(BUNDLE_HOME).join(&clap_bundle_library_name);
|
||||
let clap_lib_path = bundle_home_dir.join(&clap_bundle_library_name);
|
||||
|
||||
fs::create_dir_all(clap_lib_path.parent().unwrap())
|
||||
.context("Could not create CLAP bundle directory")?;
|
||||
|
@ -428,7 +439,7 @@ fn bundle_plugin(
|
|||
|
||||
// In contrast to VST3, CLAP only uses bundles on macOS, so we'll just take the first
|
||||
// component of the library name instead
|
||||
let clap_bundle_home = Path::new(BUNDLE_HOME).join(
|
||||
let clap_bundle_home = bundle_home_dir.join(
|
||||
Path::new(&clap_bundle_library_name)
|
||||
.components()
|
||||
.next()
|
||||
|
@ -447,7 +458,7 @@ fn bundle_plugin(
|
|||
}
|
||||
if bundle_vst2 {
|
||||
let vst2_bundle_library_name = vst2_bundle_library_name(&bundle_name, compilation_target);
|
||||
let vst2_lib_path = Path::new(BUNDLE_HOME).join(&vst2_bundle_library_name);
|
||||
let vst2_lib_path = bundle_home_dir.join(&vst2_bundle_library_name);
|
||||
|
||||
fs::create_dir_all(vst2_lib_path.parent().unwrap())
|
||||
.context("Could not create VST2 bundle directory")?;
|
||||
|
@ -456,7 +467,7 @@ fn bundle_plugin(
|
|||
|
||||
// VST2 only uses bundles on macOS, so we'll just take the first component of the library
|
||||
// name instead
|
||||
let vst2_bundle_home = Path::new(BUNDLE_HOME).join(
|
||||
let vst2_bundle_home = bundle_home_dir.join(
|
||||
Path::new(&vst2_bundle_library_name)
|
||||
.components()
|
||||
.next()
|
||||
|
@ -475,7 +486,7 @@ fn bundle_plugin(
|
|||
}
|
||||
if bundle_vst3 {
|
||||
let vst3_lib_path =
|
||||
Path::new(BUNDLE_HOME).join(vst3_bundle_library_name(&bundle_name, compilation_target));
|
||||
bundle_home_dir.join(vst3_bundle_library_name(&bundle_name, compilation_target));
|
||||
|
||||
fs::create_dir_all(vst3_lib_path.parent().unwrap())
|
||||
.context("Could not create VST3 bundle directory")?;
|
||||
|
@ -604,13 +615,18 @@ fn compilation_target(cross_compile_target: Option<&str>) -> Result<CompilationT
|
|||
}
|
||||
}
|
||||
|
||||
/// The directory bundled plugins should be written to.
|
||||
fn bundle_home(target_directory: &Path) -> PathBuf {
|
||||
target_directory.join("bundled")
|
||||
}
|
||||
|
||||
/// The base directory for the compiled binaries. This does not use [`CompilationTarget`] as we need
|
||||
/// to be able to differentiate between native and cross-compilation.
|
||||
fn target_base(cross_compile_target: Option<&str>) -> Result<PathBuf> {
|
||||
fn target_base(target_directory: &Path, cross_compile_target: Option<&str>) -> Result<PathBuf> {
|
||||
match cross_compile_target {
|
||||
// Unhandled targets will already be handled in `compilation_target`
|
||||
Some(target) => Ok(Path::new("target").join(target)),
|
||||
None => Ok(PathBuf::from("target")),
|
||||
Some(target) => Ok(target_directory.join(target)),
|
||||
None => Ok(target_directory.to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ fn top_bar(cx: &mut Context) {
|
|||
// Try to open the Diopser plugin's page when clicking on the title. If this
|
||||
// fails then that's not a problem
|
||||
let result = open::that(Diopser::URL);
|
||||
if cfg!(debug) && result.is_err() {
|
||||
if cfg!(debug_assertions) && result.is_err() {
|
||||
nih_debug_assert_failure!("Failed to open web browser: {:?}", result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use atomic_float::AtomicF32;
|
||||
use nih_plug::prelude::*;
|
||||
use nih_plug_egui::{create_egui_editor, egui, widgets, EguiState};
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -12,7 +12,7 @@ description = "A simple gain plugin with an vizia GUI"
|
|||
crate-type = ["cdylib", "lib"]
|
||||
|
||||
[dependencies]
|
||||
nih_plug = { path = "../../../", features = ["assert_process_allocs", "standalone"] }
|
||||
nih_plug = { path = "../../../", features = ["standalone"] }
|
||||
nih_plug_vizia = { path = "../../../nih_plug_vizia" }
|
||||
|
||||
atomic_float = "0.1"
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||
|
||||
/// A test tone generator that can either generate a sine wave based on the plugin's parameters or
|
||||
/// based on the current MIDI input.
|
||||
struct Sine {
|
||||
pub struct Sine {
|
||||
params: Arc<SineParams>,
|
||||
sample_rate: f32,
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ fn main_column(cx: &mut Context) {
|
|||
// Try to open the plugin's page when clicking on the title. If this
|
||||
// fails then that's not a problem
|
||||
let result = open::that(SpectralCompressor::URL);
|
||||
if cfg!(debug) && result.is_err() {
|
||||
if cfg!(debug_assertions) && result.is_err() {
|
||||
nih_debug_assert_failure!(
|
||||
"Failed to open web browser: {:?}",
|
||||
result
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Traits for working with plugin editors.
|
||||
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
use raw_window_handle::{HasWindowHandle, RawWindowHandle, WindowHandle};
|
||||
use std::any::Any;
|
||||
use std::ffi::c_void;
|
||||
use std::sync::Arc;
|
||||
|
@ -90,24 +90,33 @@ pub enum ParentWindowHandle {
|
|||
Win32Hwnd(*mut c_void),
|
||||
}
|
||||
|
||||
unsafe impl HasRawWindowHandle for ParentWindowHandle {
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
match *self {
|
||||
ParentWindowHandle::X11Window(window) => {
|
||||
let mut handle = raw_window_handle::XcbWindowHandle::empty();
|
||||
handle.window = window;
|
||||
RawWindowHandle::Xcb(handle)
|
||||
}
|
||||
ParentWindowHandle::AppKitNsView(ns_view) => {
|
||||
let mut handle = raw_window_handle::AppKitWindowHandle::empty();
|
||||
handle.ns_view = ns_view;
|
||||
RawWindowHandle::AppKit(handle)
|
||||
}
|
||||
ParentWindowHandle::Win32Hwnd(hwnd) => {
|
||||
let mut handle = raw_window_handle::Win32WindowHandle::empty();
|
||||
handle.hwnd = hwnd;
|
||||
RawWindowHandle::Win32(handle)
|
||||
}
|
||||
}
|
||||
impl HasWindowHandle for ParentWindowHandle {
|
||||
fn window_handle(
|
||||
&self,
|
||||
) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
|
||||
Ok(unsafe {
|
||||
WindowHandle::borrow_raw(match *self {
|
||||
ParentWindowHandle::X11Window(window) => {
|
||||
RawWindowHandle::Xcb(raw_window_handle::XcbWindowHandle::new(
|
||||
window
|
||||
.try_into()
|
||||
.map_err(|_| raw_window_handle::HandleError::Unavailable)?,
|
||||
))
|
||||
}
|
||||
ParentWindowHandle::AppKitNsView(ns_view) => {
|
||||
RawWindowHandle::AppKit(raw_window_handle::AppKitWindowHandle::new(
|
||||
std::ptr::NonNull::new(ns_view)
|
||||
.ok_or(raw_window_handle::HandleError::Unavailable)?,
|
||||
))
|
||||
}
|
||||
ParentWindowHandle::Win32Hwnd(hwnd) => {
|
||||
RawWindowHandle::Win32(raw_window_handle::Win32WindowHandle::new(
|
||||
(hwnd as isize)
|
||||
.try_into()
|
||||
.map_err(|_| raw_window_handle::HandleError::Unavailable)?,
|
||||
))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
21
src/midi.rs
21
src/midi.rs
|
@ -419,11 +419,11 @@ impl<S: SysExMessage> NoteEvent<S> {
|
|||
pub fn from_midi(timing: u32, midi_data: &[u8]) -> Result<Self, u8> {
|
||||
let status_byte = midi_data.first().copied().unwrap_or_default();
|
||||
let event_type = status_byte & midi::EVENT_TYPE_MASK;
|
||||
let channel = status_byte & midi::MIDI_CHANNEL_MASK;
|
||||
|
||||
if midi_data.len() >= 3 {
|
||||
// TODO: Maybe add special handling for 14-bit CCs and RPN messages at some
|
||||
// point, right now the plugin has to figure it out for itself
|
||||
let channel = status_byte & midi::MIDI_CHANNEL_MASK;
|
||||
match event_type {
|
||||
// You thought this was a note on? Think again! This is a cleverly disguised note off
|
||||
// event straight from the 80s when Baud rate was still a limiting factor!
|
||||
|
@ -464,13 +464,6 @@ impl<S: SysExMessage> NoteEvent<S> {
|
|||
pressure: midi_data[2] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
midi::CHANNEL_KEY_PRESSURE => {
|
||||
return Ok(NoteEvent::MidiChannelPressure {
|
||||
timing,
|
||||
channel,
|
||||
pressure: midi_data[1] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
midi::PITCH_BEND_CHANGE => {
|
||||
return Ok(NoteEvent::MidiPitchBend {
|
||||
timing,
|
||||
|
@ -487,6 +480,18 @@ impl<S: SysExMessage> NoteEvent<S> {
|
|||
value: midi_data[2] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
if midi_data.len() >= 2 {
|
||||
match event_type {
|
||||
midi::CHANNEL_KEY_PRESSURE => {
|
||||
return Ok(NoteEvent::MidiChannelPressure {
|
||||
timing,
|
||||
channel,
|
||||
pressure: midi_data[1] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
midi::PROGRAM_CHANGE => {
|
||||
return Ok(NoteEvent::MidiProgramChange {
|
||||
timing,
|
||||
|
|
|
@ -702,6 +702,8 @@ impl CpalMidir {
|
|||
.main_input_channels
|
||||
.map(NonZeroU32::get)
|
||||
.unwrap_or(0) as usize;
|
||||
// This may contain excess unused space at the end if we get fewer samples than configured
|
||||
// from CPAL
|
||||
let mut main_io_storage = vec![vec![0.0f32; buffer_size]; num_output_channels];
|
||||
|
||||
// This backend does not support auxiliary inputs and outputs, so in order to have the same
|
||||
|
@ -824,8 +826,16 @@ impl CpalMidir {
|
|||
}
|
||||
|
||||
{
|
||||
// Even though we told CPAL that we wanted `buffer_size` samples, it may still give
|
||||
// us fewer. If we receive more than what we configured, then this will panic.
|
||||
let actual_sample_count = data.len() / num_output_channels;
|
||||
assert!(
|
||||
actual_sample_count <= buffer_size,
|
||||
"Received {actual_sample_count} samples, while the configured buffer size is \
|
||||
{buffer_size}"
|
||||
);
|
||||
let buffers = unsafe {
|
||||
buffer_manager.create_buffers(0, buffer_size, |buffer_sources| {
|
||||
buffer_manager.create_buffers(0, actual_sample_count, |buffer_sources| {
|
||||
*buffer_sources.main_output_channel_pointers = Some(ChannelPointers {
|
||||
ptrs: NonNull::new(main_io_channel_pointers.get().as_mut_ptr())
|
||||
.unwrap(),
|
||||
|
@ -893,11 +903,10 @@ impl CpalMidir {
|
|||
|
||||
// The buffer's samples need to be written to `data` in an interlaced format
|
||||
// SAFETY: Dropping `buffers` allows us to borrow `main_io_storage` again
|
||||
for (output_sample, buffer_sample) in data
|
||||
.iter_mut()
|
||||
.zip(main_io_storage.iter().flat_map(|channels| channels.iter()))
|
||||
{
|
||||
*output_sample = T::from_sample(*buffer_sample);
|
||||
for (i, output_sample) in data.iter_mut().enumerate() {
|
||||
let ch = i % num_output_channels;
|
||||
let n = i / num_output_channels;
|
||||
*output_sample = T::from_sample(main_io_storage[ch][n]);
|
||||
}
|
||||
|
||||
if let Some(output_event_rb_producer) = &mut output_event_rb_producer {
|
||||
|
|
|
@ -3,7 +3,7 @@ use baseview::{EventStatus, Window, WindowHandler, WindowOpenOptions};
|
|||
use crossbeam::channel::{self, Sender};
|
||||
use crossbeam::queue::ArrayQueue;
|
||||
use parking_lot::Mutex;
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use raw_window_handle::HasWindowHandle;
|
||||
use std::any::Any;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||
|
@ -345,18 +345,20 @@ impl<P: Plugin, B: Backend<P>> Wrapper<P, B> {
|
|||
gl_config: None,
|
||||
},
|
||||
move |window| {
|
||||
let parent_handle = match window.raw_window_handle() {
|
||||
let parent_handle = match window.window_handle().unwrap().as_raw() {
|
||||
raw_window_handle::RawWindowHandle::Xlib(handle) => {
|
||||
ParentWindowHandle::X11Window(handle.window as u32)
|
||||
}
|
||||
raw_window_handle::RawWindowHandle::Xcb(handle) => {
|
||||
ParentWindowHandle::X11Window(handle.window)
|
||||
ParentWindowHandle::X11Window(handle.window.into())
|
||||
}
|
||||
raw_window_handle::RawWindowHandle::AppKit(handle) => {
|
||||
ParentWindowHandle::AppKitNsView(handle.ns_view)
|
||||
ParentWindowHandle::AppKitNsView(handle.ns_view.as_ptr())
|
||||
}
|
||||
raw_window_handle::RawWindowHandle::Win32(handle) => {
|
||||
ParentWindowHandle::Win32Hwnd(handle.hwnd)
|
||||
ParentWindowHandle::Win32Hwnd(
|
||||
handle.hwnd.get() as *mut core::ffi::c_void
|
||||
)
|
||||
}
|
||||
handle => unimplemented!("Unsupported window handle: {handle:?}"),
|
||||
};
|
||||
|
|
|
@ -51,6 +51,7 @@ unsafe impl Sync for BufferManager {}
|
|||
|
||||
/// Host data that the plugin's [`Buffer`]s should be created from. Leave these fields as `None`
|
||||
/// values
|
||||
#[derive(Debug)]
|
||||
pub struct BufferSource<'a> {
|
||||
pub main_input_channel_pointers: &'a mut Option<ChannelPointers>,
|
||||
pub main_output_channel_pointers: &'a mut Option<ChannelPointers>,
|
||||
|
@ -219,25 +220,28 @@ impl BufferManager {
|
|||
self.main_input_channel_pointers,
|
||||
self.main_output_channel_pointers,
|
||||
) {
|
||||
// If the host processes the main IO out of place then the inputs need to be copied to
|
||||
// the output buffers. Otherwise the input should already be there.
|
||||
if input_channel_pointers.ptrs != output_channel_pointers.ptrs {
|
||||
self.main_buffer.set_slices(num_samples, |output_slices| {
|
||||
for (channel_idx, output_slice) in output_slices
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.take(input_channel_pointers.num_channels)
|
||||
{
|
||||
let input_channel_pointer =
|
||||
input_channel_pointers.ptrs.as_ptr().add(channel_idx);
|
||||
self.main_buffer.set_slices(num_samples, |output_slices| {
|
||||
for (channel_idx, output_slice) in output_slices
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.take(input_channel_pointers.num_channels)
|
||||
{
|
||||
let input_channel_pointer =
|
||||
*input_channel_pointers.ptrs.as_ptr().add(channel_idx);
|
||||
debug_assert!(channel_idx < output_channel_pointers.num_channels);
|
||||
let output_channel_pointer =
|
||||
*output_channel_pointers.ptrs.as_ptr().add(channel_idx);
|
||||
|
||||
// If the host processes the main IO out of place then the inputs need to be
|
||||
// copied to the output buffers. Otherwise the input should already be there.
|
||||
if input_channel_pointer != output_channel_pointer {
|
||||
output_slice.copy_from_slice(std::slice::from_raw_parts_mut(
|
||||
(*input_channel_pointer).add(sample_offset),
|
||||
input_channel_pointer.add(sample_offset),
|
||||
num_samples,
|
||||
))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Any excess channels will need to be filled with zeroes since they'd otherwise point
|
||||
// to whatever was left in the buffer
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::ffi::{c_void, CStr};
|
|||
use std::mem;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use vst3_sys::base::{kInvalidArgument, kResultFalse, kResultOk, tresult, TBool};
|
||||
use vst3_sys::base::{kInvalidArgument, kNotImplemented, kResultFalse, kResultOk, tresult, TBool};
|
||||
use vst3_sys::gui::{IPlugFrame, IPlugView, IPlugViewContentScaleSupport, ViewRect};
|
||||
use vst3_sys::utils::SharedVstPtr;
|
||||
use vst3_sys::VST3;
|
||||
|
@ -225,12 +225,8 @@ impl<P: Vst3Plugin> RunLoopEventHandler<P> {
|
|||
self.tasks.push(task)?;
|
||||
|
||||
// We need to use a Unix domain socket to let the host know to call our event handler. In
|
||||
// theory eventfd would be more suitable here, but Ardour does not support that.
|
||||
// XXX: This can technically lead to a race condition if the host is currently calling
|
||||
// `on_fd_is_set()` on another thread and the task has already been popped and executed
|
||||
// and this value has not yet been written to the socket. Doing it the other way around
|
||||
// gets you the other situation where the event handler could be run without the task
|
||||
// being posted yet. In practice this won't cause any issues however.
|
||||
// theory eventfd would be more suitable here, but Ardour does not support that. This is
|
||||
// read again in `Self::on_fd_is_set()`.
|
||||
let notify_value = 1i8;
|
||||
const NOTIFY_VALUE_SIZE: usize = std::mem::size_of::<i8>();
|
||||
assert_eq!(
|
||||
|
@ -337,7 +333,7 @@ impl<P: Vst3Plugin> IPlugView for WrapperView<P> {
|
|||
unsafe fn on_wheel(&self, _distance: f32) -> tresult {
|
||||
// We'll let the plugin use the OS' input mechanisms because not all DAWs (or very few
|
||||
// actually) implement these functions
|
||||
kResultOk
|
||||
kNotImplemented
|
||||
}
|
||||
|
||||
unsafe fn on_key_down(
|
||||
|
@ -346,7 +342,7 @@ impl<P: Vst3Plugin> IPlugView for WrapperView<P> {
|
|||
_key_code: i16,
|
||||
_modifiers: i16,
|
||||
) -> tresult {
|
||||
kResultOk
|
||||
kNotImplemented
|
||||
}
|
||||
|
||||
unsafe fn on_key_up(
|
||||
|
@ -355,7 +351,7 @@ impl<P: Vst3Plugin> IPlugView for WrapperView<P> {
|
|||
_key_code: i16,
|
||||
_modifiers: i16,
|
||||
) -> tresult {
|
||||
kResultOk
|
||||
kNotImplemented
|
||||
}
|
||||
|
||||
unsafe fn get_size(&self, size: *mut ViewRect) -> tresult {
|
||||
|
@ -398,7 +394,7 @@ impl<P: Vst3Plugin> IPlugView for WrapperView<P> {
|
|||
}
|
||||
|
||||
unsafe fn on_focus(&self, _state: TBool) -> tresult {
|
||||
kResultOk
|
||||
kNotImplemented
|
||||
}
|
||||
|
||||
unsafe fn set_frame(&self, frame: *mut c_void) -> tresult {
|
||||
|
@ -472,21 +468,34 @@ impl<P: Vst3Plugin> IPlugViewContentScaleSupport for WrapperView<P> {
|
|||
#[cfg(target_os = "linux")]
|
||||
impl<P: Vst3Plugin> IEventHandler for RunLoopEventHandler<P> {
|
||||
unsafe fn on_fd_is_set(&self, _fd: FileDescriptor) {
|
||||
// There should be a one-to-one correlation to bytes being written to `self.socket_read_fd`
|
||||
// and events being pushed to `self.tasks`, but because the process of pushing a task and
|
||||
// notifying this thread through the socket is not atomic we can't reliably just read a byte
|
||||
// from this socket for every task we process. For instance, if `Self::post_task()` gets
|
||||
// called while this loop is already running, it could happen that we pop and execute the
|
||||
// task before the byte gets written to the socket. To avoid this, we'll clear the socket
|
||||
// upfront, and then execute the tasks afterwards. If this situation does happen, then the
|
||||
// worst thing that can happen is that this function is called a second time while
|
||||
// `self.tasks()` is already empty.
|
||||
let mut notify_value = [0; 32];
|
||||
loop {
|
||||
let read_result = libc::read(
|
||||
self.socket_read_fd,
|
||||
&mut notify_value as *mut _ as *mut c_void,
|
||||
std::mem::size_of_val(¬ify_value),
|
||||
);
|
||||
|
||||
// If after the first loop the socket contains no more data, then the `read()` call will
|
||||
// return -1 and `errno` will have been set to `EAGAIN`
|
||||
if read_result <= 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This gets called from the host's UI thread because we wrote some bytes to the Unix domain
|
||||
// socket. We'll read that data from the socket again just to make REAPER happy.
|
||||
while let Some(task) = self.tasks.pop() {
|
||||
self.inner.execute(task, true);
|
||||
|
||||
let mut notify_value = 1i8;
|
||||
const NOTIFY_VALUE_SIZE: usize = std::mem::size_of::<i8>();
|
||||
assert_eq!(
|
||||
libc::read(
|
||||
self.socket_read_fd,
|
||||
&mut notify_value as *mut _ as *mut c_void,
|
||||
NOTIFY_VALUE_SIZE
|
||||
),
|
||||
NOTIFY_VALUE_SIZE as isize
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue