-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Output combo boxes for Jack driver #7919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Output combo boxes for Jack driver #7919
Conversation
Add two combo boxes and a Jack client to the Jack setup dialog. The combo boxes display the available Jack inputs. Please note that in Jack terminology these are called "outputs". The own Jack client is necessary because the setup dialog does not have any access to the actual driver. So a new client is created when the dialog is opened and deleted when it is closed, i.e. when the dialog is deleted itself. The available inputs are collected via `AudioJack::setupWidget::getAudioInputNames` and are then put into the combo boxes via `AudioJack::setupWidget::populateComboBox`. `AudioJack::setupWidget::saveSettings` saves the selections that have been made in the combo boxes into the configuration. Add the method `handleRegistrationEvent` to `AudioJack` and register it in `AudioJack::initJackClient` via `jack_set_port_registration_callback`. Currently it will only output information about the port via `printf` but not do anything else. It can likely be removed again because the `AudioJack::setupWidget` uses it's own client and must register its own callbacks in case it wants to react to changed inputs and outputs while the setup dialog is open. * Do the same for the inputs * Read the information stored in the configuration when the driver is initialized. Gracefully handle when selections are not available, e.g. because the device is not plugged in. * Decide if the setup dialog should react to changed ports while it is open. This might complicate selections that are currently made, i.e. it has to be ensured that the user experience is good. * Remove printf statements
Extend the Jack setup dialog with combo boxes that present the available outputs. Save the selected outputs in the configuration. Add `AudioJack::setupWidget::getAudioPortNames` which takes the type of port and then collects all port names which match. Make the new `getAudioOutputNames` and `getAudioInputNames` delegate to that method with the appropriate type. This also hides the different terminologies a bit.
Attempt to reconnect the inputs and outputs from the configuration during startup of the Jack driver. Nothing will be done for inputs and outputs that are not available at startup. Example: the users might have saved some inputs when a device was available. The device is then disconnected and LMMS restarted. The stored inputs cannot be used anymore. To give the users the least surprise nothing is done. `AudioJack::attemptToConnect` does the actual reconnection and also prints some information for now. `attemptToReconnectOutput` and `attemptToReconnectInput` delegate to `attemptToConnect` with the right parameters.
When populating the combo boxes select the current input/output as saved in the configuration.
Show a warning message in the Jack setup dialog if some inputs or outputs that are set in the configuration are missing in the system. This might for example be caused by disconnected devices. Let `populateComboBox` return a boolean which indicates if the selected port can be found in the list of displayed ports or not.
Remove `AudioJack::handleRegistrationEvent` as it was only used for debugging so far.
Replace repeated hard-coded strings with references to static constant variables in the anonymous namespace. This should prevent subtle mistakes when working with the configuration values of the Jack driver.
Input selection does not make sense for master now because recording is not implemented/merged yet. However, being able to select the inputs from a combo box instead of having to use an external connection manager already brings benefit to users. Hence we remove input selection for now. There will be a separate branch/commit which will revert this commit, i.e. which will add input selection again once it makes sense for master.
Introduce input selection for the Jack driver similar to how it is done for the outputs, i.e. saving to configuration, reconnection at driver start, etc.
Present the available inputs and outputs in a hierarchical sorted menu which shows clients with their ports. The heavy lifting of creating the menu for the tool button is done in the new method `buildMenu`. It takes the input/output names in Jack's "Client name:Port name" format. If an input/output name can be successfully split into the client name and port name then a sub menu with the client name is created (if it was not already created before) and the port name is added as an entry. If the name cannot be split into exactly two components then it is simply added to the top level menu as is. Ports of the LMMS client are filtered out to prevent loops. The menu starts with the client's sub menus in alphabetical order. Then the top level entries are added in alphabetical order as well. The callbacks for the `QAction` instances are implemented with lambdas because MOC does not support nested classes like the setup widget is. For now the used lambda only sets the text of the `QToolButton` as these are used for persisting the configuration anyway. Replace the `QComboxBox` instances with `QToolButton`.
I made a few tests. Some first points I noted:
|
Thanks for checking @JohannesLorenz! Regarding your observations:
That's a fundamental shortcoming of the current
Yes, it is assumed that there are some main outputs/inputs. More complex setups would have to be created with a session manager because IMO it does not make sense to implement a full-fledged session manager with all possibilities in LMMS. 😅
Yes, it is intended as a default setting that is reestablished on each start.
The LMMS client is already filtered in my local branch that's shown in #7918 (comment). It has some further improvements like for example grouping by Jack client, sorting, etc. I wonder if I should ditch this PR, push the changes from the comment into #7920, make that PR the main one and comment/define out everything related to inputs. This would mean that if recording is merged the inputs could be reinstated quickly.
Do you mean the labels? IMO they should not change according to the selection. However, your comment made me come to the conclusion that it might be better to change the labels to "Output L", "Output R", "Input L" and "Input R". What do you think? Potential fixes for the Setup DialogThere are several options to fix the restart problem of the setup dialog:
|
I don't have a strong opinion here. Though, this remark of mine (numbered "4") was a very minor observation, so it does not need to give rise to change the branching strategy.
I mean, in So, if qjackctl shows you
Then LMMS should IMO show you the setup dialogue as
(The
I think there may be another solution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finished 1st review:
- Checked code
- Checked style
- Tested
Let the tool buttons stretch so that they look uniform and use all the available space.
Remove the printing of the audio port names in `getAudioPortNames`.
Show the technical output and input port names used by LMMS in the setup dialog. Note: these are the names that are shown in tools like `qjackctl` or `qpwgraph`. This was proposed in a review. Personally I like the non-technical names better but let's see what's accepted.
Switch the popup mode of the tool buttons from `MenuButtonPopup` back to `InstantPopup` so that users can click everywhere. This works better now because the buttons use all the space and the little triangle can be seen better.
Make CodeFactor happy.
@JohannesLorenz: I have merged the changes of the now closed PR #7920 into this PR. The rationale is that the SDL driver dialog already sports input selection as well although the feature itself is not implemented yet. Here's what the feature currently looks like: The dialog now also sports the technical Jack output/input names. I am not a big fan of that but let's see what's the option of others. In case the input selection should be hidden until the feature is implemented then this could be done with a handful of |
Moving some of the discussion here so that we are not confined to that small code review discussion.
Yes, it was much too hot today. 😅 It can give great flexibility if one is allowed to route the output of one or more tracks into another track (as long as there are no feedback loops I guess). For example here are the options that are provided for the output of a track in Bitwig: In this example the output of track "Audio 2" is routed to the track "Audio 3". As can be seen in the menu it is even possible to route it to other applications which should come natural for a PipeWire or Jack driver. In general it is for example also possible to route track A, B and C to track D, enable recording for D and then create a quick bounce while doing so and then to continue working with that new sample. I assume that this is not possible in LMMS if it routes tracks to the mixer with no other options. Another use case could be to create effect tracks/busses by routing tracks accordingly.
Because it's a very huge undertaking. 😅 One would have to implement some kind of interface which would provide at least the following functionality:
That interface would need to abstract lots of the stuff provided by the different drivers and provide it in a uniform way to LMMS' code. All drivers would be affected by that design change because every driver would need to cater to that interface as good as possible, e.g. each driver would need to map its own inputs and outputs to the inputs and outputs provided by the staging area. Each driver would need to copy its buffers to the staging area, etc. The interface would also need to be designed in such a way that everything still works even if some drivers cannot provide all features. It might for example be the case that some drivers do not allow for devices to appear or disappear during runtime. Because its a large undertaking this PR only intends to (slowly) move towards this direction by providing some rudimentary routing functionality which can then be used by the also rudimentary sample recording functionality/branch. |
Generalize the number of inputs and outputs by using for loops. This affects the number of widgets that are created and the amount of configuration that is stored. This change is a result of a code review discussion. In my opinion it adds unnecessary complexity to something that should later be implemented completely different anyway. It is for example now necessary to compute the key names that are used during the saving of the configuration based on the channel number. The commit exists so that its changes can be discussed further. It might be reverted in one of the next commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code and style OK
@bratpeki, do you want to test this? |
Sure! I run PW, not native Jack, is that sufficient? |
Great! 🙂 I run PipeWire as well and I think it should be sufficient. Please note that the recording feature in not integrated yet (this is another PR). However, this PR brings the Jack setup dialog to a similar state like the SDL dialog which also lets users select inputs although nothing is done with them yet. |
Alright, I'll do a UI/UX test and check the code to make sense of it. |
@bratpeki, if you want to test the feature in the full context of recording then you can follow the steps described here: #7786 (comment). |
Implements #7918. The dialog looks as follows with the PR:
Edit: I should have renamed the branch. It contained code for input selection as well but does not anymore. The reason is that this PR already brings benefits to users and can go into master without the sample recording feature.