Control-Surface icon indicating copy to clipboard operation
Control-Surface copied to clipboard

Using NoteButtonMatrix to play different scales

Open huggre opened this issue 3 years ago • 9 comments

Hi, I'm trying to get the NoteButtonMatrix to play different scales based on user selection. This means that I have to update the AddressMatrix whenever the user wants to play a different scale. Could you please give me some pointers as how to do this?, I'm no C/C++ expert so that might be the main problem. This is what I was hoping would work (see code), by simply changing the scale index from scales[0] to scales[1] it would play the minor pentatonic scale instead of the chromatic scale. The code compiles correctly and the MIDI note on/off events are being sent correctly. However the notes being played are wrong. Any help is greatly appreciated!!

int scales[2][4][4] = { { { 60, 61, 62, 63 }, //chromatic scale { 64, 65, 66, 67 }, { 68, 69, 70, 71 }, { 72, 73, 74, 75 } }, { { 60, 63, 65, 67 }, //Minor pentatonic scale { 70, 72, 75, 77 }, { 79, 82, 84, 87 }, { 89, 91, 94, 96 } } };

AddressMatrix<4, 4> addresses = {scales[0]};

huggre avatar Oct 17 '20 11:10 huggre

Too easy, you need to compare your schematic and code via ableton to change the note numbers

4dvn avatar Oct 17 '20 11:10 4dvn

Thanks for helping, I'm not using ableton (or any other DAW for that matter) so I'm not sure if your solution would work for me. The primary input devices for this controller would be some hardware synth using a 5pin MIDI cable. By the way; just noticed this example: https://tttapa.github.io/Control-Surface-doc/Doxygen/d0/d41/Bank-Button-Matrix_8ino-example.html If I could store the different scales in different banks, and simply change banks then I guess that would solve my problem. Still need some help implementing it in practice :-)

huggre avatar Oct 17 '20 12:10 huggre

You would use the ManyAddresses module for this purpose: https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/d39/classBankable_1_1ManyAddresses_1_1NoteButtonMatrix.html#adf4ba9b7a9925f7980c2b0a3876039ac

tttapa avatar Oct 17 '20 12:10 tttapa

Cool, thanks. Will read up on this module. Totally new to this library so bear with me. Looks pretty awesome so far!!

huggre avatar Oct 17 '20 12:10 huggre

Basically: just like with the Bank-Button-Matrix example you linked to, you define a Bank object that selects one of N banks. The address of the Bankable MIDI elements depends on the selected bank. For the "normal" Bankable module, the address is simply a linear function of the index of the selected bank (y = mx + q, where y is the address, m is the number of tracks per bank, x is the selected bank, and q is the base address). The ManyAddresses module is much more flexible, it allows you to provide a list of addresses, and the selected bank just determines the index in that list (y = list[x]).

tttapa avatar Oct 17 '20 12:10 tttapa

Thanks of all your guidance.., I'm afraid I don't have time to dig deeper into the ManyAddresses module today; but it would be great if someone would take the time to make an example in line with the other modules. Feel free to use my scales use-case as a basis for the example :-) I'm sure it would useful to others as well.

huggre avatar Oct 17 '20 15:10 huggre

I'm having a really hard time wrapping my head around this ManyAddresses thing so if anyone can point me in the right direction I would very grateful. I was hoping my code below would do the trick but I get the following compile error:

could not convert '{{bank, 1, {{60, 61, 62, 63}, {64, 65, 66, 67}, {68, 89, 70, 71}, {72, 73, 74, 75}}}, {bank, 2, {{60, 63, 65, 67}, {70, 72, 75, 77}, {79, 82, 84, 87}, {89, 91, 94, 96}}}}' from '<brace-enclosed initializer list>' to 'CS::Bankable::ManyAddresses::NoteButtonMatrix<2, 4, 4>'

And here is my code:

Bank<2> bank = {16}; // 2 banks, 16 addresse per banks

Bankable::ManyAddresses::NoteButtonMatrix<2,4,4> notes = {
  {bank, 1, {{60,61,62,63},{64,65,66,67},{68,89,70,71},{72,73,74,75}}}, //chromatic scale
  {bank, 2, {{60,63,65,67},{70,72,75,77},{79,82,84,87},{89,91,94,96}}}, //Minor pentatonic scale
};

Bankable::NoteButtonMatrix<4, 4> buttons = {
  bank,      //
  {0, 9, 2, 3},    // row pins (outputs, driven low-Z low !)
  {7, 6, 5, 4}, // column pins (inputs, hi-Z)
  notes,     //
  CHANNEL_1, //
};

huggre avatar Oct 19 '20 15:10 huggre

Please look at the Bankable::ManyAddresses::NoteButtonMatrix constructor very carefully. The initializers that you are trying to pass to the constructor do not match the constructor arguments at all.

Bankable::ManyAddresses::
NoteButtonMatrix(Bank<NumBanks> &bank,
                 const PinList<nb_rows> &rowPins,
                 const PinList<nb_cols> &colPins,
                 const Array<AddressMatrix<nb_rows, nb_cols>, NumBanks> &notes,
                 const Array<MIDIChannelCN, NumBanks> &channelCNs,
                 uint8_t velocity = 0x7F)

To use it, just specify the correct initializer for each constructor argument.

For reasons I won't go into right now, you need double braces around most arrays, except for the inner levels. When in doubt or if there's any ambiguity, use double braces.

As a hint, if you remove the assignment operator (=) between your variable declaration and the initializer, the compiler will produce a more meaningful error message than just could not convert.

Bank<2> bank = {16}; // 2 banks, 16 addresses per banks

Bankable::ManyAddresses::NoteButtonMatrix<2, 4, 4> buttons {
  bank,
  {0, 9, 2, 3},    // row pins (outputs, driven low-Z low !)
  {7, 6, 5, 4},    // column pins (inputs, hi-Z)
  
  // Now the list of address matrices, one for each bank
  {{
    // First bank
    {{{60,61,62,63},
      {64,65,66,67},
      {68,89,70,71},
      {72,73,74,75}}},
     
    // Second bank
    {{{60,63,65,67},
      {70,72,75,77},
      {79,82,84,87},
      {89,91,94,96}}},
  }},
  
  // Finally, the list of MIDI channels, one for each bank
  {
    CHANNEL_1, // first bank
    CHANNEL_1, // second bank
  },
};

tttapa avatar Oct 19 '20 16:10 tttapa

Wow, this works perfectly :-) And yes, I really need to learn more about constructors and arguments. Reading the documentation and seeing your example together it all makes sense :-) Thank you so very much!!

huggre avatar Oct 19 '20 17:10 huggre