Giter Site home page Giter Site logo

pw-viz's Introduction

pw-viz

A simple and elegant, pipewire graph editor

demo image

This is still a WIP, node layouting is kinda jank at the moment.

Installation

A compiled binary is available on the releases page.

Building from source

To build pw-viz, you will need to have Rust installed. The recommended way to install Rust is from the official download page, using rustup.

Stable Release

Download and extract the source code to the latest release over on the releases page.

Main branch

Alternatively, you can clone the main branch, although its NOT guaranteed to be stable or bug free.

git clone https://github.com/Ax9D/pw-viz

Dependencies

You'll need a few dependencies installed on your system depending on your distro to build pw-viz.

Arch

pacman -S pipewire pkg-config clang libxcb

Fedora

sudo dnf install pipewire pipewire-devel clang libxcb-devel

Other

If you are building on another distro, you can help fill in this section by opening a pull request.

Build

Next, cd into your source folder and then start the build using:

cargo build --release

Then you can copy the resulting binary(pw-viz) which will be found inside target/release to a directory in your $PATH, like /usr/bin/

Controls

Description
Left Click + Drag Move nodes, create links between ports
Alt + Left Click + Drag Remove links
Middle Mouse + Drag Pan the graph
Ctrl Shows pipewire ids of nodes and ports

Zooming is not supported currently

Libraries Used

Thanks / Alternatives

Pipewire connection code is inspired by helvum's implementation

  • helvum: A GTK patchbay for pipewire.

License

pw-viz is licensed under the terms of the GNU General Public License v3.0. See LICENSE for more information.

pw-viz's People

Contributors

atakku avatar ax9d avatar jansol avatar mkrasnitski avatar msmafra avatar spyrosroum avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pw-viz's Issues

Request: Snap screen back to origin

If someone is dealing with a great number of nodes, the arrange function is really nice, but sometimes manually panning somewhere, then clicking arrange, can cause the user to need to hunt them down, it would be nice if it would also snap the user back to origin, or have a dedicated button to do so.

Fails to build: cannot find function `eventfd` in crate `libc`

error[E0425]: cannot find function `eventfd` in crate `libc`
   --> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/channel.rs:220:34
    |
220 |     let eventfd = unsafe { libc::eventfd(0, libc::EFD_CLOEXEC) };
    |                                  ^^^^^^^ not found in `libc`

error[E0425]: cannot find function `pw_init` in crate `pw_sys`
   --> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/lib.rs:156:49
    |
156 |     INITIALIZED.get_or_init(|| unsafe { pw_sys::pw_init(ptr::null_mut(), ptr::null_mut()) });
    |                                                 ^^^^^^^ not found in `pw_sys`

error[E0425]: cannot find function `pw_deinit` in crate `pw_sys`
   --> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/lib.rs:165:13
    |
165 |     pw_sys::pw_deinit()
    |             ^^^^^^^^^ not found in `pw_sys`

The libc crate does contain this function for FreeBSD-13:

libc-0.2.107/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs: pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;

rev.04ffced
FreeBSD 13.1 STABLE

Add ability to hide specific nodes

I'd like the ability to hide certain nodes on the graph, maybe through a right-click context menu on the node, or otherwise with a keypress or mouse button. For example, I have an external DAC and the extra links to it from every other node in the graph make everything more cluttered. I'm never going to need to make links to or from it since it's the only output device I use. In addition, it would be good to have a dropdown menu from the top bar, say "View > Nodes" which contains a list of every node by name and a checkbox next to it which toggles visibility.

Auto-layout

Did you have any plans regarding the layout algorithm yet? If so, feel free to just close this.

Overall I quite like the auto-layout and grouping features in patchage, although I wish it would also re-center the viewport when re-generating the layout. This is a feature I would love to see in pw-viz as well, or maybe even re-layout on the fly as nodes appear and disappear from the graph? Live re-layout should probably not touch the viewport and needs an option to toggle it on and off.

image

As for the algorithm itself a good start would probably be a basic mass-spring system where the nodes 1) have a "gravity" towards left/right based on their ports' directions to determine the rough initial position and 2) push each other away to avoid overlap. Links would act as springs pulling the connected nodes together. For things like effect chains I suppose it's a matter of complexity and preference whether a left-to-right or top-down flow would be preferrable. There is probably a decent heuristic to detect effect nodes (such as 'has "input" and "output" ports but no others' connected) and flip the direction in which the springs are pulling

To reduce clutter it would be handy to be able to collapse nodes into only the title and the layout algorithm could potentially collapse by default nodes that don't currently have any links. This would probably require keeping track of nodes that the user manually expands. Collapsed nodes should also probably have some indicator for what kind of ports they have, not sure what the best way to handle that would be.

Support dropping nodes in the middle of existing links

Another feature from Blender's node editor that would be neat to have.

When dragging a node and dropping it on top of an existing link, the Blender node editor tries to insert that node between the two endpoints of that link. This should be fairly usable for stuff like building effect chains.

Say you have a graph: A-->B where A has a mono output or monitor and B has a mono input. Now dragging a node with a mono input and output in top of that link would make it easy to disconnect the link and create links A-->C-->B using the matching port names. This can be extended to stereo, 5.1, 7.1 etc as long as the port name suffixes match.

AUXn ports could be considered to match named ones with a simple heuristic like, if there is only one link whatever AUXn is involved matches MONO, if there are two then the one with the lower AUXn number matches FL and the higher one FR, if there are more they match the named ports for 5.1, 7.1 etc in a fixed order starting from the first AUXn index of the existing links between the A and B.

Ports marked as UNK are more complicated, not sure what can be done about those. Is there a port number regardless of names in the pipewire API? Those could be used in this case.

Worst case (i.e. when it's not possible to infer the right ports) could be something like flash the dragged node and the link in question and then not doing anything.

Not sure if/how much modding this requires in egui-nodes. The heuristic for choosing the relevant ports should classify as "good first issue" so the difficulty is going to depend largely on how to do it in egui-nodes.

Show controls at the bottom à la Blender

Fairly straightforward feature that does a lot for user friendliness. Blender updates these dynamically when modifier keys are pressed or a tool is in use, but in the case of pw-viz just showing a static list that also shows the modifier keys is probably enough.

image

error[E0425]: cannot find value `PW_KEY_NODE_TARGET` in crate `pw_sys`

I'm unable to build pw-viz because:

   Compiling pipewire v0.5.0
   Compiling simple_logger v4.0.0
error[E0425]: cannot find value `PW_KEY_NODE_TARGET` in crate `pw_sys`
   --> /home/johnb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pipewire-0.5.0/src/auto/keys.rs:164:28
    |
164 | key_constant!(NODE_TARGET, PW_KEY_NODE_TARGET,
    |                            ^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `PW_KEY_NODE_NAME`
    |
   ::: /home/johnb/Applications/pw-viz/target/release/build/pipewire-sys-40594b83031eb6b0/out/bindings.rs:165:1
    |
165 | pub const PW_KEY_NODE_NAME: &[u8; 10usize] = b"node.name\0";
    | ------------------------------------------ similarly named constant `PW_KEY_NODE_NAME` defined here

   Compiling rand v0.8.5
For more information about this error, try `rustc --explain E0425`.
error: could not compile `pipewire` (lib) due to previous error
warning: build failed, waiting for other jobs to finish...

Delete selected links using the delete key

Links can currently be selected but no action can be taken within that context. I use Alt as my mod key in i3wm, so can't currently use the UI to delete links between nodes, as alt-dragging controls the window position and size for me. I think letting links be deleted by selecting them and hitting Delete would work well. By the way, what controls these keybinds? Do they come from egui_nodes are from some other crate?

app crashes and does not start

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GlutinCreationError(NoAvailablePixelFormat)', /home/atri/.cargo/registry/src/github.com-1ecc6299db9ec823/egui_glium-0.15.0/src/epi_backend.rs:45:70
stack backtrace:
   0:     0x563c69a88abd - <unknown>
   1:     0x563c698a62cc - <unknown>
   2:     0x563c69a87364 - <unknown>
   3:     0x563c69a87ac0 - <unknown>
   4:     0x563c69a86fa1 - <unknown>
   5:     0x563c69aa7ab8 - <unknown>
   6:     0x563c69aa7a36 - <unknown>
   7:     0x563c69aa79f2 - <unknown>
   8:     0x563c69867d70 - <unknown>
   9:     0x563c698680a2 - <unknown>
  10:     0x563c699940df - <unknown>
  11:     0x563c698afb0c - <unknown>
  12:     0x563c69a34c83 - <unknown>
  13:     0x563c69a19213 - <unknown>
  14:     0x563c69a33925 - <unknown>
  15:     0x7fc3ee77afd0 - __libc_start_call_main
                               at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  16:     0x7fc3ee77b07d - __libc_start_main_impl
                               at ./csu/../csu/libc-start.c:409:3
  17:     0x563c6988293e - <unknown>
  18:                0x0 - <unknown>

Allow labeling of objects

image

As you can see I have several different sof-hda-dsp, I would like to label them to differentiate between them.
Thanks.

Arch KDE window is extremely small

Running from terminal crashes the terminal, running from gdb shows that the app is running. but no window is visible.

EDIT: Window is extremely small when it opens

Allow object labeling

image

As you can see I have several different sof-hda-dsp and there's no way to tell them apart, labeling will allow me to add some comment to see what I'm working with.

Thanks.

Unification of multiple nodes belonging to the same application

In comparison to using QjackCtl, if an application has multiple outputs or inputs, they each appear as separate nodes in the graph. Helvum also suffers from this problem. For example, if I open pavucontrol, each separate input is on a separate node, one for each currently running application, whereas QjackCtl unifies them into a single node. Here's a screenshot of QjackCtl:
image

Compared to pw-viz:
image

You'll notice QjackCtl doesn't unify everything. It puts inputs and outputs in the same node, but not monitors. pw-viz does the opposite, putting inputs and monitors together, but not outputs. I think it would be great to put them all in one node. Additionally, on the pavucontrol node, all the left channels are stacked together, and then the right channels. I think it'd be better to stack pairs together.

[Feature request] Alternate pan

Currently panning uses the middle mouse button. This is impossible on for example laptops, due to not having a middle mouse button.

Possible solutions:

  • CTRL+drag
  • arrow keys
  • scroll (vertical) and shift+scroll (horizontal)

Panic on Zoom disconnect

pw-viz panics on Zoom disconnect on my box (Debian unstable pipewire 0.3.42).

Upgrading the dependency on simple_logger to 2.1.0 and then rebuilding seems to fix it.

Add CI

Automatically run rustfmt and perform a build test on push/PRs to main.

  • Figure out how to install pipewire and dependencies
  • Test run pw-viz in headless mode on Xorg ( xvfb? )
  • Test run pw-viz in headless mode on Wayland

nixOS: Failed to build libspa-sys

I had a failed build on nixOS (output linked below). I'm just reporting this and happy to assist with any debugging that may be needed to find root cause.

This is from the pkgs repository and I'm adding it to my user packages with the below structure in my configuration.nix file.

users.users = {
    sighnwaive = {
      ...;
      packages = with pkgs; [
        pw-viz
        wireplumber
      ];
      ...;
    };

nix_output.txt

Build fails: cannot find function `pw_init` in crate `pw_sys`

error[E0425]: cannot find function `pw_init` in crate `pw_sys`
   --> /wrkdirs/usr/ports/multimedia/pw-viz/work/pw-viz-0.3.0/cargo-crates/pipewire-0.8.0/src/lib.rs:158:49
    |
158 |     INITIALIZED.get_or_init(|| unsafe { pw_sys::pw_init(ptr::null_mut(), ptr::null_mut()) });
    |                                                 ^^^^^^^ not found in `pw_sys`

error[E0425]: cannot find function `pw_deinit` in crate `pw_sys`
   --> /wrkdirs/usr/ports/multimedia/pw-viz/work/pw-viz-0.3.0/cargo-crates/pipewire-0.8.0/src/lib.rs:167:13
    |
167 |     pw_sys::pw_deinit()
    |             ^^^^^^^^^ not found in `pw_sys`

Version: 0.3.0
FreeBSD 14.1

Please describe runtime dependencies in the README

pw-viz uses egui and the binary isn't linked with any graphics-related shared libraries.

When the binary runs it loads these:
/usr/local/lib/libGL.so.1.7.0
/usr/local/lib/libGLX.so.0.0.0
/usr/local/lib/libGLX_nvidia.so.0
/usr/local/lib/libGLdispatch.so.0.0.0
/usr/local/lib/libX11-xcb.so.1.0.0
/usr/local/lib/libX11.so.6.4.0
/usr/local/lib/libXau.so.6.0.0
/usr/local/lib/libXcursor.so.1.0.2
/usr/local/lib/libXdmcp.so.6.0.0
/usr/local/lib/libXext.so.6.4.0
/usr/local/lib/libXfixes.so.3.1.0
/usr/local/lib/libXi.so.6.1.0
/usr/local/lib/libXrandr.so.2.2.0
/usr/local/lib/libXrender.so.1.3.0
/usr/local/lib/libdbus-1.so.3.32.1
/usr/local/lib/libnvidia-glcore.so.1
/usr/local/lib/libnvidia-glsi.so.1
/usr/local/lib/libnvidia-tls.so.1
/usr/local/lib/libpipewire-0.3.so.0.362.0
/usr/local/lib/libxcb-glx.so.0.0.0
/usr/local/lib/libxcb.so.1.1.0

egui can use a variety of external libraries, depending on the backend that is used.

What is the minimal set of run-time dependencies for pw-viz?

Support cycles

Hello and thank you for this project, it looks great!

The only issue I've seen so far from my very limited testing, is that pw-viz does not support cycles. The usecase I had was using Ardour, an audio work station:

I have a session with two tracks (Top and Bottom in the screenshot), whose audio is routed to the Master bus, and the Master bus is then forwarded to the speakers.

Here's how it looks in Patchage:

screenshot

In pw-viz, the message ERROR [pw_viz::ui::graph] Cycle detected is displayed on the terminal.
Here's how it looks:

20211117_19h10m28s_grim

Thanks again!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.