1
0
Fork 0

Compare commits

...

27 commits

Author SHA1 Message Date
Alex Janka 0e54080a1d raw-window-handle 0.6.0 2024-05-26 10:57:52 +10:00
Robbert van der Helm cd9b589d23 Fix invalid debug assertions check 2024-05-06 00:57:29 +02:00
Robbert van der Helm 9e2b9cc06e Update to the latest Vizia
This fixes crashes when opening more than one instance of a plugin GUI
on Windows and macOS.
2024-05-06 00:57:29 +02:00
Robbert van der Helm b3038b458c Fix race condition in RunLoopEventHandler 2024-05-05 23:22:01 +02:00
joe 8eed04fe5f bump dependencies 2024-05-05 23:12:42 +02:00
Robbert van der Helm 31583d42e7 Document egui update 2024-05-05 22:53:38 +02:00
Robbert van der Helm e0913b16de Document MIDI change from #111 2024-05-05 22:50:19 +02:00
rbmj 442d54ba50 Fix bug where aftertouch messages may not be processed 2024-05-05 22:49:19 +02:00
Robbert van der Helm 916dfc16a2 Document the CPAL buffer size handling 2024-05-05 22:43:58 +02:00
Robbert van der Helm a5abe896ed Mark the Sine example struct pub
For standalone testing. The `Cargo.toml` and `main.rs` changes aren't
committed since these plugins don't really need standalones, but it's
still nice for debugging.
2024-05-05 22:25:35 +02:00
Robbert van der Helm 1c03d4adc6 Merge branch 'jwq_cpal-buffer-fix'
Fix CPAL buffer bug (standalone)

https://github.com/robbert-vdh/nih-plug/pull/142
2024-05-05 22:24:21 +02:00
Robbert van der Helm d270d1221f Fix in-place checks in buffer management
The previous implementation didn't work correctly, and would thus result
in soundness issues. Rust 1.78 finally fixes debug assertions in the
standard library so this was caught immediately.
2024-05-04 20:55:50 +02:00
Robbert van der Helm 10aabe3a38 Use default-features instead of default_features
The latter is deprecated.
2024-05-04 20:27:44 +02:00
Marcus Ramse ed72de7cbf Fix CPAL buffer bug (thanks @jesnor) 2024-04-16 16:45:54 +00:00
Robbert van der Helm bb274976ca Parse target dir location from cargo metadata 2024-03-23 11:51:11 +01:00
Robbert van der Helm 245add6530 Return kNotImplemented for the VST3 input events 2024-03-18 21:48:39 +01:00
Robbert van der Helm 1ad6d6cc5c Rename .cargo/config to the new .cargo/config.toml 2024-03-17 21:48:40 +01:00
Robbert van der Helm e9dff5b0eb Prevent nih_plug_* from enabling default features
Which would otherwise make compiling without VST3 support impossible.
2024-03-10 21:09:26 +01:00
Robbert van der Helm 57db4b57ed Use the 2021 edition resolver in the workspace 2024-03-10 21:06:05 +01:00
Robbert van der Helm 369ef886e4 Ensure that the lockfile is up to date on CI
So build failures related to this can't happen again.
2024-03-10 20:39:59 +01:00
Robbert van der Helm 37cd6b34f1 Update lockfile
These changes apparently weren't commit.
2024-03-10 20:37:10 +01:00
Robbert van der Helm 8a1cbcd094 Remove reference to the Rust Audio Discord
People are starting to join for non-development support questions
en-masse. Better to just not mention it at all.
2024-03-10 14:42:19 +01:00
Billy Messenger 0d608592b5 fix panic when setting mouse cursor in nih_plug_egui 2024-03-03 15:51:45 +01:00
Robbert van der Helm b2586ded48 Mention the nih_plug_egui update in the changelog 2024-02-22 21:01:19 +01:00
Billy Messenger 80ed8b5384 don't need this import here 2024-02-22 20:54:58 +01:00
Billy Messenger 0017efae0a forgot to remove this 2024-02-22 20:54:58 +01:00
Billy Messenger 0dccb4501f update egui and egui_baseview 2024-02-22 20:54:58 +01:00
29 changed files with 515 additions and 214 deletions

View file

@ -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:

View file

@ -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
View file

@ -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]]

View file

@ -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 }

View file

@ -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

View file

@ -14,4 +14,4 @@ quote = "1.0"
proc-macro2 = "1.0"
[dev-dependencies]
nih_plug = { path = ".." }
nih_plug = { path = "..", default-features = false }

View file

@ -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

View file

@ -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)
}

View file

@ -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;

View file

@ -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;

View file

@ -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,
));
}
}
}

View file

@ -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 {

View file

@ -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"] }

View file

@ -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

View file

@ -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

View file

@ -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" }

View file

@ -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()),
}
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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"

View file

@ -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,

View file

@ -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

View file

@ -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)?,
))
}
})
})
}
}

View file

@ -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,

View file

@ -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 {

View file

@ -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:?}"),
};

View file

@ -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

View file

@ -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(&notify_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
);
}
}
}