wwmm / easyeffects

Limiter, compressor, convolver, equalizer and auto volume and many other plugins for PipeWire applications
GNU General Public License v3.0
6.56k stars 270 forks source link

The GTK4 port has started :D #904

Closed wwmm closed 3 years ago

wwmm commented 3 years ago

GTK4 branch GTK4 https://github.com/wwmm/pulseeffects/tree/gtk4. There is still a long way to go. So far there is only a bare-bones main window and the presets menu. There are many small changes that will have to be done in all the interface files. And I will have to update each interface xml manually. So the whole process may take a while...

I have been thinking about the port and there are a few things I would like to implement in a different way:

This list will be updated when more things come to my mind. In the last days I have been playing with the presets menu. The new listview concept in GTK4 is interesting. And adding search functionality to the presets menu was quite easy Screenshot from 2021-02-26 21-47-01

I have decided to take the opportunity to do a redesign of a few things in this menu. And to show the last used preset in the menu bottom instead of the menu button. As we have input and output effects but both of them were updating the same button things were too confusing. I would not say that the new design is final. I will test it while I start the work in the settings menu.

wwmm commented 3 years ago

Something has to be done about issue #559. I have an idea about how to improve this situation

What I am thinking about is adding a "bottom panel" with a stack switcher at the center. This switcher will have to entries: Applications and Plugins. Similar to what happens in the settings menu. I think this will remove the current confusion. I also intend to move some of the audio information displayed in our headerbar to this bottom panel together with the global volume level meters that at this moment are besides the "Application" label in the plugins list.

wwmm commented 3 years ago

I testing new ideas for the settings menu. And for our SpinButtons Screenshot from 2021-02-28 16-03-00

Screenshot from 2021-02-28 15-54-21

At least to me it seems good.

Mlocik97 commented 3 years ago

I like it. But I would little rearange these color settings in spectrum so there is no that much blank white space. Maybe put it to 2nd column in grid between these spinButtons and numfields.

wwmm commented 3 years ago

But I would little rearange these color settings in spectrum so there is no that much blank white space

I've noticed this. Not sure what to do about it. When the menu has too much width things are not nice for tiling window manager users #885. But at the same time I do not know if it is possible to offer good support for them with the amount of widgets we have to control...

wwmm commented 3 years ago

New Players tab

Screenshot from 2021-03-09 15-03-33

This new approach fixes #559. New Plugins tab

Screenshot from 2021-03-09 15-04-45

It should fix #725. But the hardest part comes now. Implementing the plugin selection under the hoods. I will see how complicated it will be to do that in a 100 % PipeWire solution without GStreamer. If things get too hard it will be done with GStreamer.

I will have to rethink the spinbuttons in the first menus images. Gtk4 did not like the idea of inserting labels into them. Random crashes and warnings...

Mlocik97 commented 3 years ago

This is starting to look really great. I love it.

wwmm commented 3 years ago

It took me some time but I was finally able to write a simple wrapper for LV2 plugins. With it I could finally take the decision of moving the effects pipeline from GStreamer to native PipeWire filters. This is a huge improvement. There is no need for us to manage real time priorities anymore. PipeWire will handle that for the filters threads. The code to handle the plugins is simpler now. There is no need anymore to launch recording streams for our effects pipelines. Now I can just link the sink to the first filter and the last one to the output device. No need for something in the middle. And hopefully the bugs that usually come when we have to take data away from the server to an external framework, GStreamer in our case, and back to the server will all be gone :-).

I have already ported a few plugins Screenshot from 2021-03-17 23-12-35

I think I will be able to port almost all the plugins we used before to PipeWire filters. The RNNoise may be a little harder with its requirement of buffer of 480 samples =/... But it should be possible. But the WebRTC plugin may be problematic. The one we use right now is a GStreamer plugin. I do not know which alternative could be used... Let's see if some ideas come in the future.

wwmm commented 3 years ago

And there is also the test signal pipeline. I still have to see how much work will be necessary to replace GStreamer there...

Ikkevoid commented 3 years ago

A lot of developers started to round the bottom corners in the apps, starting from gtk4 you can do it from css easily. What do you think about doing this in pulseeffects? https://www.flathub.org/apps/details/com.usebottles.bottles https://www.flathub.org/apps/details/org.gnome.gitlab.YaLTeR.Identity

wwmm commented 3 years ago

What do you think about doing this in pulseeffects?

I do not see any problems in doing that. The top corners are already round. So the bottom ones could be too. Do you know what they are putting in the css files?

Ikkevoid commented 3 years ago

Unfortunately I don't know, sorry. You can look at souk https://gitlab.gnome.org/haecker-felix/souk It's written in gtk4, and it has rounded corners, maybe it will help you somehow. Good luck, you are doing an amazing job!

wwmm commented 3 years ago

You can look at souk https://gitlab.gnome.org/haecker-felix/souk

Although I could not find the code that makes its window corners rounded it helped to find a way to do it Screenshot from 2021-03-24 20-10-25

Ikkevoid commented 3 years ago

I was thinking about it, and I feel that pulse effects started to be cluttered a little, so I made a mock-up with settings in its own window. Also, the plugins reordering icons only show when you hover at the plugin. What do you think about it?

pulseeffects mockup

wwmm commented 3 years ago

I feel that pulse effects started to be cluttered a little

Being honest it has always been cluttered a lot since its early days XD. The problem is that for more advanced users(myself included) it is important to have easy access to some information and functionality.

I made a mock-up with settings in its own window

It is not a problem to have the global settings in its own window. But I did not understand how this window is being called in your mock-up. I did not notice any visible button to open it.

Also, the plugins reordering icons only show when you hover at the plugin

I agree. These buttons do not have to be shown all the time. But I did not understand how that icon besides the trash icon is supposed to be used. Only one icon to move up and down? I also did not understand if the icon in front of the plugin name has a purpose or if it is only for the looks.

What do you think about it?

I like the looks but there is one big problem in this approach. Having only one Players tab is not enough because the input effects pipeline has a different application list Screenshot from 2021-03-25 10-26-19 I did not show this image before because I am not working in the microphone pipeline yet. But this is something that is already the case in all PulseEffects releases. One pipeline has players and the other applications that record the microphone. So at least one more tab like Recorders would be needed.

I am also not sure I like the idea of not having status information easily visible all the time. In this kind of application more advanced users need to be able to see the global level meters all the time. Having to open a new section to see this kind of information is annoying because we have to get out from the plugins controls we are using.

wwmm commented 3 years ago

In the presets menu proposal i s the new preset name entered where the Preset word is located? We also need place for a preset importing button.

As the input and the output pipeline use different presets this menu would have to be synced somehow when switching between sections. I think that it can be done. I am not sure about how the users will react to the fact that they will need to switch sections to access the presets of another pipeline. But it is not the end of the world.

Ikkevoid commented 3 years ago

About the reordering: https://cdn.dribbble.com/users/951993/screenshots/6314238/drag_reorder_1.gif

It is not a problem to have the global settings in its own window. But I did not understand how this window is being called in your mock-up. I did not notice any visible button to open it.

Those global settings is called when you click the edit icon on the preset, but when I start to think about it, it's not such a good idea.

wwmm commented 3 years ago

But I did not understand how that icon besides the trash icon is supposed to be used

Same question in the presets menu. One button should be doing preset autoloading. Is the load button replaced by direct clicks in the line?

https://cdn.dribbble.com/users/951993/screenshots/6314238/drag_reorder_1.gif

I suspected that. The only problem is that it was ridiculously not obvious how to implement row dragging in gtk3 and I still have no idea about how this is supposed to be implemented in gtk4. I would need to find some code examples.

wwmm commented 3 years ago

Those global settings is called when you click the edit icon on the preset, but when I start to think about it, it's not such a good idea.

Definitely not. They are totally unrelated.

Ikkevoid commented 3 years ago

Same question in the presets menu. One button should be doing preset autoloading. Is the load button replaced by direct clicks in the line?

Yes, probably direct clicks, and the checkmark icon is next to the used preset

I agree. These buttons do not have to be shown all the time. But I did not understand how that icon besides the trash icon is supposed to be used. Only one icon to move up and down? I also did not understand if the icon in front of the plugin name has a purpose or if it is only for the looks.

It looks good, I was thinking about making a unique icon for every plugin, So it would be easier to move around the plugins.

Ikkevoid commented 3 years ago

I suspected that. The only problem is that it was ridiculously not obvious how to implement row dragging in gtk3 and I still have no idea about how this is supposed to be implemented in gtk4. I would need to find some code examples.

If you use gnome, in the language and region settings there is a list reordering that uses one button, https://gitlab.gnome.org/GNOME/gnome-control-center/-/tree/master/panels/region

wwmm commented 3 years ago

It looks good, I was thinking about making a unique icon for every plugin, So it would be easier to move around the plugins.

It sounds interesting but it may be hard to keep this going as more and more plugins are added. Specially because I have no icon design abilities and I am the one usually adding plugins. So some kind of generic icon is necessary. Maybe one icon for each kind of plugin. But even then it may be hard to make different icons for each.

Ikkevoid commented 3 years ago

image I could make all the icons for the plugins, and if you add a new plugin there would be a generic icon until I/someone else makes the icon, how about it?

Ikkevoid commented 3 years ago

I was thinking about moving the settings somehow, But the more I think about it the more I think it's a bad idea, I'll try to think about ordering the items in the tooltip better, but you've made an excellent job in making them. So the settings will have to stay the same

wwmm commented 3 years ago

I could make all the icons for the plugins, and if you add a new plugin there would be a generic icon until I/someone else makes the icon, how about it?

In this case no problems. Considering that we have more than one plugin of the same type(compressors and gates for example) it may be a good idea to think about icons for categories of plugins. But if you are in the middle of a very creative moment go ahead :-)

If you follow the category path you can have some idea of the possible categories reading this link https://lv2plug.in/ns/lv2core#Plugin

wwmm commented 3 years ago

image

The presets menu apply settings to the output pipeline or to the input pipeline. Wouldn't be better to have the names and icons of the sections matching the ones in the main window?

wwmm commented 3 years ago

And we also have to think how the test signals will be accessed. Right now this is done through the "sine wave" button in the header bar. Maybe it should become another section like input, output and info

wwmm commented 3 years ago

I am having some difficulties showing both title and icons in the stack switcher. For example the one with the speakers icon followed by the title Output. I know this is possible but I don't know how people do that. For some reason gtk shows only the icon even if the title is also set =/

wwmm commented 3 years ago

I wonder if people use a listbox with custom rows instead of a stackswitcher. It is really dumb that the stackswitcher can show an icon or a title individually but not both at the same time =/

Ikkevoid commented 3 years ago

image

The presets menu apply settings to the output pipeline or to the input pipeline. Wouldn't be better to have the names and icons of the sections matching the ones in the main window?

I was thinking the same, but I didn't know if I should do it, bcs I know too little about presets and use cases of them.

Ikkevoid commented 3 years ago

And we also have to think how the test signals will be accessed. Right now this is done through the "sine wave" button in the header bar. Maybe it should become another section like input, output and info

I think it's a good idea, It'll be easily accessible to the users.

Ikkevoid commented 3 years ago

I am having some difficulties showing both title and icons in the stack switcher. For example the one with the speakers icon followed by the title Output. I know this is possible but I don't know how people do that. For some reason gtk shows only the icon even if the title is also set =/

I think they use libhandy's hdyviewswitcher, https://gitlab.gnome.org/GNOME/libhandy take a look if you need some inspiration https://gnome.pages.gitlab.gnome.org/libhandy/doc/1.2/HdyViewSwitcher.html

wwmm commented 3 years ago

I think that for gtk4 the corresponding library would be libadwaita. But I hope using such libraries isn't the only way to achieve that result. PulseEffects is a GTKMM4 application. There is a high probability that working together with these libraries isn't even possible or that it requires a lot of work. And even if it works we would be adding one more dependency only for this.

I will try to get something close to this using only GTKMM and css.

wwmm commented 3 years ago

I will try to get something close to this using only GTKMM and css.

Even that is complicated. What the likes of libhandy do is creating a custom headerbar from scratch. Too much work... I think we will have to be happy with an approach similar to the one done in Gnome Calendar. The old and boring StackSwitcher showing only text.

Ikkevoid commented 3 years ago

Maybe you could use gmmproc to generate c++ headers from the GIR of libadwaita? https://developer.gnome.org/gtkmm-tutorial/unstable/chapter-wrapping-c-libraries.html

wwmm commented 3 years ago

Maybe you could use gmmproc to generate c++ headers from the GIR of libadwaita?

I saw someone recommending that approach in reddit... gtkmm is a C++ wrapper for gtk. By using that I will be trying to wrap a C library based on gtk. This feels like opening the door for even more bugs... I am not very fond of the idea. Specially because libadwaita is probably in its early days and I do not know how much I can rely on it still being actively maintained in the next years.

I will try to do some compromise and following as much as possible from the mock-up using only gtkmm. I think that the rest is doable. It is only that style in the headerbar that is requiring the usage of libraries I would like to avoid for now.

By the way what is the name of the icon in the plugin button?

Ikkevoid commented 3 years ago

It's "puzzle-piece-symbolic" when I was making the mock-up https://www.flathub.org/apps/details/org.gnome.design.IconLibrary this app really helped me. Good luck with your work!

wwmm commented 3 years ago

It is getting close. But I doubt it will ever become equal to the mock-up Screenshot from 2021-03-28 19-25-47

I think that the new Pipewire info side panel will also be better with some icons Screenshot from 2021-03-28 19-25-09

Ikkevoid commented 3 years ago

It looks really nice, It's such a big improvement, You did an amazing job. I'll try to get all the icons done until May, is that okay with you?

One thing that comes to my mind looking at the first screenshot, There's no border on the right of the sidebar. I think if it merges with the whole content, it looks a little odd, what do you think about it?

wwmm commented 3 years ago

I'll try to get all the icons done until May, is that okay with you?

No problems. There is still much to be done. I do not know when this branch will be ready to be released. And I will probably try to do something about #874 before making a release.

I think if it merges with the whole content, it looks a little odd, what do you think about it?

I will see how it looks with a border. Usually the white background in the listview is enough to avoid this confusion. But I am not if this is going to be the case in every gtk theme.

I am also considering a split in the presets menu and moving it to the bottom bar in a similar way as I did to the blocklist menu. The reason is that now we need more space in the headerbar because the switcher is larger.

wwmm commented 3 years ago

New plugins side panel Screenshot from 2021-03-29 15-39-57

It is better with the separation.

sp1ritCS commented 3 years ago

Hi, I'm currently trying to get the gtk4 port running, however it segfaults after built. (doesn't write anything to stdout before that)

I'll attach a valgrind log, because I have no idea how to debug it :/. pulseeffects.log.gz

OS: openSUSE Tumbleweed 20210408 Pipewire version: 0.3.24 GStreamer version: 1.18.3

I'm modifying the meson.build and set c++20 to c++2a (my meson doesn't know c++20 yet ¯\_(ツ)_/¯), however if I remove the cpp_std entirely and add add_global_arguments('-std=c++20', language : 'cpp') the same issue occurs (with gcc/g++. clang/clang++ fails to build)

wwmm commented 3 years ago

I'll attach a valgrind log, because I have no idea how to debug it :/.

Usually for segmentation fault it is better to use gdb. But my guess is that you may be not setting some environment variables that are not obvious that should be set. If I am not forgetting anything these are the steps to run from the source folder after compiling

git clone -b gtk4 --depth=1 https://github.com/wwmm/pulseeffects.git
cd pulseeffects
glib-compile-schemas data/schemas/
meson build
cd build
ninja
cd src
source ../../util/environmental_variables.sh
./pulseeffects

I'm modifying the meson.build and set c++20 to c++2a (my meson doesn't know c++20 yet ¯_(ツ)_/¯)

The problem may be your compiler version. Which one do you have? Here on Arch Linux I have gcc 10.2.0

clang/clang++ fails to build

As I am using some std::ranges features it is possible that clang is not supporting them yet.

As it is really convenient to use std::span c++20 will remain as the minimum c++ version. But depending on the circumstances I could reconsider the use of some std::ranges features if it becomes too hard for people on other distributions to compile the new sources.

wwmm commented 3 years ago

If you try to run from the compiled source with the steps above and it is still crashing you can run it with gdb gdb ./pulseeffects. When you get to gdb prompt type run and press enter. After the crash execute bt in gdb prompt. Among the many lines printed there will be some showing the source code line where the segmentation fault is happening.

sp1ritCS commented 3 years ago

If I am not forgetting anything these are the steps to run from the source folder after compiling

nope, but now it writes stuff to stdout first pulseeffects.log.gz

Which one do you have? Here on Arch Linux I have gcc 10.2.0 gcc (SUSE Linux) 10.2.1 20210401 [revision 892024d4af83b258801ff7484bf28f0cf1a1a999]

I'm quite sure that meson is the issue, as meson is also the one to throw if I try to generate ninja files with cpp_std=c++20. But again c++2a seems to work too which my meson supports.

Currently meson has version 0.56.2 for me but upstream already has 0.57.2. It doesn't seem like anybody is interested in updating it tho for Factory: devel:tools:building/meson but I could actually do this tomorrow

As I am using some std::ranges features it is possible that clang is not supporting them yet.

yeah, gcc is the default for me and I'm entirely fine with using it. It was more about that maybe clang could fix this segfault issue I have, because I didn't know what compiler you are using.

After the crash execute bt in gdb prompt. Among the many lines printed there will be some showing the source code line where the segmentation fault is happening.

It's also telling me that I should install (alot of [130 to be precise]) debuginfo packages.

#0  PluginBase::get_node_id() const (this=0x0) at ../src/plugin_base.cpp:154
#1  0x00000000005af32e in StreamOutputEffects::connect_filters() (this=0x79b0c0)
    at /usr/include/c++/10/bits/shared_ptr_base.h:1324
#2  0x00000000005b0057 in StreamOutputEffects::StreamOutputEffects(PipeManager*)
    (this=0x79b0c0, pipe_manager=<optimized out>) at ../src/stream_output_effects.cpp:76
#3  0x0000000000446215 in std::make_unique<StreamOutputEffects, PipeManager*>(PipeManager*&&) ()
    at /usr/include/c++/10/bits/unique_ptr.h:961
#4  Application::on_startup() (this=0x792ab0) at ../src/application.cpp:120
#5  0x00007ffff6ca6a4b in Gio::Application_Class::startup_callback(_GApplication*) ()
    at /usr/lib64/libgiomm-2.68.so.1
#6  0x00007ffff7cf82ee in  () at /usr/lib64/libgobject-2.0.so.0
#7  0x00007ffff7d10ac9 in g_signal_emit_valist () at /usr/lib64/libgobject-2.0.so.0
#8  0x00007ffff7d1103f in g_signal_emit () at /usr/lib64/libgobject-2.0.so.0
#9  0x00007ffff7370ef2 in g_application_register () at /usr/lib64/libgio-2.0.so.0
#10 0x00007ffff73712da in  () at /usr/lib64/libgio-2.0.so.0
#11 0x00007ffff6ca64c9 in Gio::Application::local_command_line_vfunc(char**&, int&) ()
    at /usr/lib64/libgiomm-2.68.so.1
#12 0x00007ffff6ca684e in Gio::Application_Class::local_command_line_vfunc_callback(_GApplication*, char***, int*) () at /usr/lib64/libgiomm-2.68.so.1
#13 0x00007ffff737160e in g_application_run () at /usr/lib64/libgio-2.0.so.0
#14 0x000000000043e5ca in main(int, char**) (argc=1, argv=0x7fffffffd988)
    at /usr/include/c++/10/bits/shared_ptr_base.h:1324

I'm a but unsure if this is already enough or if there is benefit to installing these 130 packages.

wwmm commented 3 years ago

I'm a but unsure if this is already enough or if there is benefit to installing these 130 packages.

I think this would be needed only if the bug were outside of PulseEffects sources. Compiling our code with debug symbols should be enough.

Based on gdb output the crash is happening when calling get_node_id inside StreamOutputEffects::connect_filters()

PluginBase::get_node_id() const (this=0x0) at ../src/plugin_base.cpp:154

Honestly I did not see yet how this could be happening if the code compiled.

wwmm commented 3 years ago

Maybe you configuration keys have values that are making plugins that were not reimplemented yet to be called. I have to think about this a little and maybe to do some tests after resetting my configuration.

sp1ritCS commented 3 years ago

Maybe you configuration keys have values that are making plugins that were not reimplemented yet to be called.

if you meant that my config files are outdated, I've already tried deleting ~/.config/PulseEffects and rerunning - still the same result 😦

wwmm commented 3 years ago

I've already tried deleting ~/.config/PulseEffects and rerunning - still the same result

Almost all of our configuration keys are stored in a dconf database. To reset them you will have to call pulseeffects -r or use dconf-editor. But this could be a problem with my configuration too. I did not reset my configurations yet. So I may have keys that are not being defined in a clean install.

sp1ritCS commented 3 years ago

Yeah, now it seems to work :D

Using dconf reset -f "/com/github/wwmm/" fixed it.

But this could be a problem with my configuration too.

However it fist threw that it was failing to open a directory:

** (pulseeffects:20319): ERROR **: 22:44:30.168: 
unhandled exception (type std::exception) in signal handler:
what: filesystem error: directory iterator cannot open directory: No such file or directory [/home/admin/.config/PulseEffects/irs]

manually creating it seems to fix it tho


Once I started PulseEffects, my audio is entirely muted. That is because it defaults to the PulseEffects Sink. However it doesn't link up PulseEffects Source with my headphones. I can do that manually with catia (pavucontrol doesn't list the pulseeffects source) tho.

I'm unable to configure any plugins and I'm only seeing this screen: 2021-04-13_23:07:11 Rga (changed color of bars, default was white) shoudn't I see this?

After a bit of trying, once I added the "pitch" or "crystallizer" plugin it segfaulted again. This might be the cause

wwmm commented 3 years ago

However it fist threw that it was failing to open a directory:

As I already have the folder I did not notice that. For some reason it is not creating it. Strange.

However it doesn't link up PulseEffects Source with my headphones

Are you talking about your headphone microphone? I did not have much time to work in the mic pipeline yet. So it may be broken.

I'm unable to configure any plugins and I'm only seeing this screen:

Try to add more plugins. There is a bug in the selection I still have to fix. With more plugins and clicking in the others it should be possible to configure them.

(changed color of bars, default was white) shoudn't I see this?

I did not understand. The spectrum is blue even if the color in the menu is white?

After a bit of trying, once I added the "pitch" or "crystallizer" plugin it segfaulted again. This might be the cause

These 2 plugins and the webrtc plugin were not implemented with PipeWire filters yet. So it is going to crash if you try to enable them. At this moment I am working on the crystalizer plugin. I still do not know if I will be able to bring the webrtc plugin to this branch as the one used before is made for GStreamer.