A low-level windowing system geared towards making audio plugin UIs.

Overview

baseview

A low-level windowing system geared towards making audio plugin UIs.

baseview abstracts the platform-specific windowing APIs (winapi, cocoa, xcb) into a platform-independent API, but otherwise gets out of your way so you can write plugin UIs.

Interested in learning more about the project? Join us on discord, channel #plugin-gui.

Roadmap

Below is a proposed list of milestones (roughly in-order) and their status. Subject to change at any time.

Feature Windows Mac OS Linux
Spawns a window, no parent ✔️ ✔️ ✔️
Cross-platform API for window spawning ✔️ ✔️ ✔️
Can find DPI scale factor ✔️ ✔️
Basic event handling (mouse, keyboard) ✔️ ✔️ ✔️
Parent window support ✔️ ✔️ ✔️

Prerequisites

Linux

Install dependencies, e.g.,

sudo apt-get install libx11-dev libxcursor-dev libxcb-dri2-0-dev libxcb-icccm4-dev libx11-xcb-dev

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Baseview by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Add beginnings of abstract Message struct and message receiver. Add compiler argument for choosing between OpenGL and wgpu.

    Add beginnings of abstract Message struct and message receiver. Add compiler argument for choosing between OpenGL and wgpu.

    I made some tweaks to begin integrating baseview into iced_baseview.

    • Added abstract Message structs.
    • Added Receiver trait.
    • Added compiler arguments for choosing between OpenGL and wgpu. (I haven't added any wgpu stuff yet).
    • Refactored some of the code in x11/window.rs into x11/opengl_util.rs.
    • Made x11/window.rs return Message messages to the Receiver.
    • Updated example.

    These changes are only tested in Linux.

    opened by BillyDM 17
  • Scaling issues on MacOS Retina

    Scaling issues on MacOS Retina

    I'm seeing issues with the rendering of a VST UI in Reaper on a Macbook with a Retina display.

    This happens both with imgui-baseview and with egui-baseview.

    Here's what happens with the Gain example from https://github.com/DGriffin91/imgui_baseview_test_vst2, for instance (this is Reaper's "FX Chain" UI btw):

    Scaling issue

    The same thing happens with any other imgui or egui example. There is some rendering going on though: changing the clear_color of the window has effect, for instance. The only way I can fix this is by hard-coding the scale_factor of the window to 1.0 here. Supplying a WindowScalePolicy::ScaleFactor(1.0) in the WindowOpenOptions should do the same thing, but does not seem to have any effect.

    If I manually double the window size in the example code here, then I do see the outlines of some UI being rendered, completely off-center and clipped:

    Scaling issue 2

    Stepping through the baseview code, I do see that the logical size is the size that is being configured by me and the physical size is double that (since scale_factor is calculated to be 2.0). I am assuming the issue is not related specifically to either the imgui or egui renderers since they both exhibit the same behaviour. Additionally, running the imgui-baseview examples by themselves (i.e. outside of the VST host) works fine as well. So I'm a bit stumped on what the root cause could be.

    opened by sagacity 5
  • Fix: Check for remaining events in the internal X11/xcb buffers

    Fix: Check for remaining events in the internal X11/xcb buffers

    I went to #xcb on Freenode and psychon was so kind to point me to: https://docs.rs/x11rb/0.8.0/x11rb/event_loop_integration/index.html

    It seems that while events are being handled new events can be queued up in the internal buffers. And so the next poll() will wait even though there are still events to be handled.

    This is a race condition, so that might be why this does only occur on some systems.

    opened by WeirdConstructor 3
  • Ignore unknown X11 events

    Ignore unknown X11 events

    I am getting many (many) Unhandled event type: 65 prints when testing my GUI. That event number is way beyond the defined X11 events, and I guess it makes sense to just not print anything for these events for now.

    opened by WeirdConstructor 3
  • bump raw_window_handle to 0.5.0

    bump raw_window_handle to 0.5.0

    hi! i made some changes so that raw_window_handle can be updated to 0.5.0 (this because im using it in conjunction with softbuffer for a personal project).

    i only made the changes necessary for this pull request to work on macos since i don't have any access to another machine/os at the moment, but i'll leave this pr here in case there's initiative to update raw_window_handle in the future.

    opened by saucesaft 2
  • macOS: scroll event handling

    macOS: scroll event handling

    Adds handling of mouse scrolling using the mouse wheel or touch pad for macOS. Although basic event handling for macOS had been added before in #52, it looks to me like support for this was still missing. I had a look at all other public forks of this library and could not find someone working on this.

    So I looked up the API documentation for it [1] and had a look at the existing code for mouse_move to make a change that feels consistent with the existing code. There seem to be two kinds of scroll delta values [2] [3] [4], precise and imprecise ones. I expect the precise deltas to be used when a touchpad is used and the imprecise ones if a mouse wheel is use. But I can only test the mouse wheel scenario, as I have a desktop computer and thus no touch pad to test with.

    If this is something you'd like to merge, feel free to do so. If this code needs to be improved, give me feedback and I will try to address it or just make adjustments yourself. But if you have other plans and do not want to merge this, that's fine too.

    [1] https://developer.apple.com/documentation/appkit/nsresponder/1534192-scrollwheel?language=objc [2] https://developer.apple.com/documentation/appkit/nsevent/1525758-hasprecisescrollingdeltas [3] https://developer.apple.com/documentation/appkit/nsevent/1524505-scrollingdeltax

    opened by ingo-dsp 2
  • Add frame_interval_secs to WindowOpenOptions

    Add frame_interval_secs to WindowOpenOptions

    To achieve lower input latency in iced, I need the frame interval to run at 120fps. Iced sets the wgpu swapchain to Mailbox mode, so rendering still happens at 60fps. However, this causes less misses for the current frame reducing the perceived latency.

    opened by BillyDM 2
  • Allow taking ownership of the OpenGL context

    Allow taking ownership of the OpenGL context

    This is a follow up to #115. Having the window own the context seemed like a sensible approach to me since there's an on_frame() callback where you'd do your rendering, but some integrations like @BillyDM's iced_baseview do the rendering from a separate Send + Sync + 'static context, and you thus need to be able to move the OpenGL context into there. This change means that you'll need to move the GlContext into your window handle struct when first creating it by calling window.gl_context().take().

    opened by robbert-vdh 1
  • Add the active keyboard modifiers to the mouse events

    Add the active keyboard modifiers to the mouse events

    This builds on top of #115, so I marked this as a draft until that has been merged.

    Every mouse event now has a modifier field containing the current keyboard modifiers. Most window management APIs work like this, and it solves things like #116 by making sure that whenever a window receives a mouse event, it also knows the up to date keyboard modifier status.

    opened by robbert-vdh 1
  • Merge raw-gl-context into baseview to allow OpenGL contexts to be created during window creation

    Merge raw-gl-context into baseview to allow OpenGL contexts to be created during window creation

    As discussed on the Rust Audio Discord, this is necessary to be able to create an OpenGL context under X11. The OpenGL context configuration determines which framebuffer configuration should be used, but the framebuffer configuration in turn determines which visual should be used for the window the context will be used with. Because of that, it's not possible to create an OpenGL context for an X11 window after the fact. Because of that, the context creation from raw-gl-context's X11 module has now been split up into two parts: initializing the framebuffer config and determining a visual, and another one for actually creating the context after the window has been created. All of the other code from raw-gl-context is unchanged. The version of raw-gl-context used is from @prokopyl's PR adding more error checks on X11 (https://github.com/glowcoil/raw-gl-context/pull/15).

    This is all put behind a new opengl feature that's disabled by default. The idea is that you can provide the OpenGL context options alongside the other window options, and if that's provided then calling window.gl_context() will return an Option<&GlContext> so you can access the OpenGL context in your window handler.

    I've also taken the liberty to fix a lot of warnings. The main things remaining are a lot of unused cursor functions in the X11 implementation, and the immutable reference to mutable reference cast in the macOS implementation.

    I've only tested this on Linux, so I would very much appreciate it if someone on macOS or Windows could test those implementations! On Linux it solves https://github.com/glowcoil/raw-gl-context/issues/2 for both NVIDIA drivers and Mesa, and for 0 and 8 bit alpha buffers. There's currently no example in the repo, but you can try this version of egui-baseview that's updated to work with these changes instead:

    git clone https://github.com/robbert-vdh/egui-baseview.git -b fix/update-dependencies
    cargo run --example simple_demo
    

    This supersedes #114.

    opened by robbert-vdh 1
  • Create the X11 window with a depth of 32-bits

    Create the X11 window with a depth of 32-bits

    This was supposed to fix https://github.com/glowcoil/raw-gl-context/issues/2, but it seems like setting the correct visual wasn't the magic bullet. Still, having the windows created with a 32-bit visual seems like a good idea since almost everything does that and now you can rely on the baseview window always having the same depth instead of it being dependent on the parent window.

    opened by robbert-vdh 1
  • Allow freeing NSView based on parent window closing notifications.

    Allow freeing NSView based on parent window closing notifications.

    In order to use third party crates that, under the hood, may increase the ref count of the given NSView, we add an additional "window closing" check by querying the given NSView for its NSWindow parent, and subscribing to the NSWindowWillCloseNotification message.

    Note that in DAWs such as Reaper, we share a parent window with other plugins, so this approach is not reliable (since you can switch between different plugins but the window persists). Those cases may require another solution.

    (Mostly) fixes #124

    opened by kunalarya 0
  • Support resizing windows after creation

    Support resizing windows after creation

    I've implemented this for Linux back in March, and I only just added Windows support. Still need to add macOS support, but I thought I'd submit a draft PR already because the changes needed for Windows support are pretty invasive. So we may want to discuss the best course of action first.

    Resizing the window sends a WM_SIZE event and a couple other events to the window, so the window procedure and WindowState had to be changed to use interior mutability everywhere instead of wrapping the entire struct in a RefCell. This resolves most of the reentrant event call concerns from #130, but I'm not sure if it also prevents panics in that specific example To make this work there's now a deferred_tasks queue for handling tasks that are the result of a call to one of the Window methods in an event handler that may also indirectly emit other events. Perhaps Window::close() should also be implemented this way.

    The Linux implementation was extremely straightforward, and I'll get to the macOS one next.

    This closes #121.

    opened by robbert-vdh 4
  • Don't panic when reentering wnd_proc due to mouse move or timer

    Don't panic when reentering wnd_proc due to mouse move or timer

    Explanation:

    • Reentering wnd_proc can happen, e.g. when opening the system web browser in an event handler via webbrowser crate.
    • That's why this PR uses try_borrow_mut to fall back to the default window procedure if wnd_proc is reentered.
    • I didn't convert each borrow_mut to try_borrow_mut, just the ones necessary to make the webbrowser crate work, see this PR for egui-baseview: https://github.com/BillyDM/egui-baseview/pull/12.
    opened by helgoboss 4
  • The initial click is ignored on macOS, requires mouse movement before the second click works correctly

    The initial click is ignored on macOS, requires mouse movement before the second click works correctly

    When embedding a baseview window inside another window using the open_parented() function on macOS, the first click on the window only focuses the window and doesn't trigger a mouse button down event for the window handler. Additionally, after this first click the user needs to wiggle their mouse around a bit because up until that point no mouse movement event will have been sent to the window. The view overrides the acceptsFirstMouse method, but it never seems to be fired. And the tracking areas should allow the plugin to receive mouse movement updates when the user hovers over an unfocused baseview window but that also doesn't seem to work.

    I tested this on macOS Catalina with the NIH-plug plugins and OctaSine, and also with the NIH-plug standalones which embed a baseview window inside of another blocking baseview window.

    opened by robbert-vdh 0
Owner
Free and useful Audio, DSP and music libraries written in Rust. Discourse https://rust-audio.discourse.group/ Discord https://discord.gg/b3hjnGw
null
Simple examples to demonstrate full-stack Rust audio plugin dev with baseplug and iced_audio

iced baseplug examples Simple examples to demonstrate full-stack Rust audio plugin dev with baseplug and iced_audio WIP (The GUI knobs do nothing curr

Billy Messenger 10 Sep 12, 2022
MVC audio plugin framework for rust

__ __ | |--.---.-.-----.-----.-----.| |.--.--.-----. | _ | _ |__ --| -__| _ || || | | _ | |

william light 93 Dec 23, 2022
API-agnostic audio plugin framework written in Rust

Because everything is better when you do it yourself - Rust VST3 and CLAP framework and plugins

Robbert van der Helm 415 Dec 27, 2022
Capture system output audio in rust.

RUHear A simple crate that allows you to capture system output audio (what aRe yoU HEARing). Dependencies On windows and linux: cpal On macos: screenc

Charles 3 Feb 7, 2024
A song analysis library for making playlists

bliss-rs is the Rust improvement of bliss, a library used to make playlists by analyzing songs, and computing distance between them.

null 49 Dec 25, 2022
Cross-platform audio I/O library in pure Rust

CPAL - Cross-Platform Audio Library Low-level library for audio input and output in pure Rust. This library currently supports the following: Enumerat

null 1.8k Jan 8, 2023
Rust audio playback library

Audio playback library Rust playback library. Playback is handled by cpal. MP3 decoding is handled by minimp3. WAV decoding is handled by hound. Vorbi

null 1.2k Jan 1, 2023
Rust bindings for the soloud audio engine library

soloud-rs A crossplatform Rust bindings for the soloud audio engine library. Supported formats: wav, mp3, ogg, flac. The library also comes with a spe

Mohammed Alyousef 38 Dec 8, 2022
A collection of filters for real-time audio processing

Audio Filters A collection of filters for real-time audio processing Feature Progress #![no_std] (via libm) f32 & f64 capable (via num-traits) SIMD Do

null 42 Nov 5, 2022
A discord.py experimental extension for audio recording

discord-ext-audiorec This project is currently under development. We do not guarantee it works.

Tomoya Ishii 11 Jan 2, 2023
Implements the free and open audio codec Opus in Rust.

opus-native Overview Implements the free and open audio codec Opus in Rust. Status This crate is under heavy development. Most functionality is not wo

Nils Hasenbanck 9 Nov 28, 2022
An open-source and fully-featured Digital Audio Workstation, made by musicians, for musicians

Meadowlark An open-source and fully-featured Digital Audio Workstation, made by musicians, for musicians. *Current design mockup, not a functioning pr

Meadowlark 1k Jan 7, 2023
this tool visualizes audio input

audiovis I tried to create a high quality classic audio visualiser with cpal as audio backend and wgpu as accelerated video frontend demo bar visualis

null 35 Dec 16, 2022
Symphonia is a pure Rust audio decoding and media demuxing library supporting AAC, FLAC, MP3, MP4, OGG, Vorbis, and WAV.

Pure Rust multimedia format demuxing, tag reading, and audio decoding library

Philip Deljanov 1k Jan 2, 2023
A simple CLI audio player with strange features.

legacylisten legacylisten is a simple CLI audio player I wrote because no existing one fulfilled my needs. The main feature is that you can change how

Matthias Kaak 3 Jun 8, 2022
Rust - Augmented Audio Libraries

Augmented Audio Libraries In this repository I'll push some experiments trying to use Rust for audio programming. Goals Goal 1: Learn & have fun This

Pedro Tacla Yamada 116 Dec 18, 2022
CLI Rust Audio Visualizer

crav Console-based Rust Audio Visualizer It can run in the terminal but also has a 3D accelerated backend implemented in wgpu. demo compatibility The

null 20 Oct 16, 2022
A tool that switch default audio playback device on windows.

AudioSwitch A tool built by Rust that can switch default audio playback device on windows. How to use specify which device you want to use Execute it

null 2 Aug 28, 2022
simple-eq is a crate that implements a simple audio equalizer in Rust.

simple-eq A Simple Audio Equalizer simple-eq is a crate that implements a simple audio equalizer in Rust. It supports a maximum of 32 filter bands. Us

Mike Hilgendorf 11 Sep 17, 2022