Improve mixer patch selection

• Jun 4, 2015 - 09:35
Reported version
2.1
Type
Graphical (UI)
Severity
S5 - Suggestion
Status
active
Project
Tags

The issue is described in my post in the Feature Request Forum about this issue, repeated here for information.....

Now that we can use multiple soundfonts in MuseScore 2, a weakness in the current mixer patch list has emerged.

Currently the list runs through all the patches in the soundfont in numerical order and then if there are other banks of patches as in FluidR3 it lists those after it, again in numerical order. It then does the same with the next soundfont in the list.

Consequently if you are looking for a particular trumpet sound, for example, you have to scroll through dozens of instruments you don't want.

I propose that we create a two tier sound list; the first listing the type of sound in GM order ie beginning with Pianos and ending with Sound Effects, and the second listing the actual sounds available for that category in each bank and soundfont.

I am familiar enough with the Soundfont format to be able to interrogate a soundfont file and extract Patch, Bank and Patchname information. If someone is able to help me with the C++ coding we can get this done relatively simply, although it's pretty certain we will be able to modify the existing patchlist creation code.

See https://musescore.org/en/node/57166 for the full discussion.

There has also been a request for numeric feedback for the dial controls in the mixer which we could perhaps address at the same time - discussion here...
https://musescore.org/en/node/42876

I am now a couple of weeks away from my workload easing considerably, and will have some time to work on this...

Can anyone point me to the existing mixer Patch menu code?


Comments

The mixer is in mixer.cpp. Each "line" in the mixer is a PartEdit object.

I would prefer to deal with each feature request separately. Changing the order of the patch list is one thing which doesn't require design skills and can be deal separately. Adding numeric feedback is impacting the design and I would prefer to have some discussion before heading to any direction. So far, the mockup for a better mixer are not good in my opinion since they make the mixer less clear.

Also, for anyone reading along, note that igevorse is adding channel and port selection http://summer.cs.pdx.edu/node/238 so we need to cope with that in any design change.

Title Overhaul mixer interface Improve mixer patch selection

That sounds fine Nicolas.

Title amended accordingly

I will start a discussion about how the mixer interface should look in the forum.

Ok the good news is that, as I already surmised, there is already code to read patch name, bank and program number from each soundfont.

This is stored in the structure MidiPatch as defined in midipatch.h to be found in the synthesiser subdirectory of MuseScore.

Currently this is read into a Qlist using the patchListChanged function in mixer.cpp.

What is required is to modify this behaviour to generate a two stage menu the first showing the GM sound category and the second listing the patchnames in each category in program number order.

My current thinking is that a switch structure would be the best way to implement this, unless there is a Qt function which would simplify it.

Ok I didn't get you wanted a two level list. I though you wanted to just change the order.
I don't know what you mean by "switch structure".

I can think of different solutions.

1/ Keep on using a QComboBox but override the list by a QTreeWidget. See http://doc.qt.io/qt-5/qcombobox.html#setView to display a tree, with section header as first level and patches as second level.

2/ Add a button with the name of the current patch. When the button is clicked, a dialog opens. In the dialog we have all the real estate in the world to go crazy and sort in any way.

3/ Add a button and on click use a "QMenu" to display the first level with submenus for the other levels.

Just beginning to get back on this......

A switch structure is a more readable form of a bank of if/else statements one function of which is to read data into an array or in this case a Qt menu structure.

The C++ syntax is.....

switch (expression)
{
  case constant1:
     group-of-statements-1;
     break;
  case constant2:
     group-of-statements-2;
     break;
  .
  .
  .
  default:
     default-group-of-statements
}

In practice this would become something like.....

switch(PatchNumber)
     {
          case 0:
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:
          case 7:
               \\code to store in Pianos menu
               break;
          case 8:
          case 9:
          case 10:
          case 11:
          case 12:
          case 13:
          case 14:
          case 15:
               \\code to store in Chromatic Percussion menu
               break;
          case 16:
          .
          .
          .
          etc
     }

So basically we feed the Program number from Midipatch into the switch and it then reads the patch information into the second menu level based on the Program Number.

The code executes as far as the break statement each time - if break were omitted it would continue to execute the code until the next break was found or the end of the structure was reached.

In my prior existence as a Pascal/BBC BASIC V programmer I would have fed the Patch Bank and Program information into a 3 dimensional array, then extracted it to the menu creation code using such a structure.

My problem is that my lack of knowledge of Qt's structures are impeding this :)

Watch this space.

The only problem with this is when users are using a soundfont not compatible with GM2, GS or XG - you could end up with a trumpet being listed under pianos purely because of the program number it has been assigned in the soundfont.

when we have several soundfonts, for example GM fonts, it's quite difficult to identify which instrument is from which soundfont. Getting the same of the soundfont after the instrument name would help a lot!

for example:

Oboe (TimGM6mb)
Oboe (FluidR3mono)