tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.23k stars 137 forks source link

Bank Button MCU (mute, rec_rdy, etc...) #215

Open zeysh opened 4 years ago

zeysh commented 4 years ago

Hi,

That's my first post here, so I want to thank you for your awesome work!

I need some help for something like this:

What I try to do:

2 buttons for bank select => IncrementDecrementSelector<4> bankselector each of 4 banks select 1 track in the DAW => Bank<4> bank(1) for each track selected, I want:

Here i don't understand how can I switch from MUTE_1 to MUTE_2 with the bank selector. I'm not sure about BankType::CHANGE_CHANNEL or maybe I have to use something else.

Thanks for your help!

Examples that inspired me: https://tttapa.github.io/Control-Surface-doc/Doxygen/dd/d42/MCU-OLED-SSD1306_8ino-example.html

https://tttapa.github.io/Control-Surface-doc/Doxygen/d0/d74/Bank_8ino-example.html

#include <Control_Surface.h> // Include the Control Surface library

// Instantiate a MIDI over USB interface
USBMIDI_Interface midi;

// ------------------------------- Bank setup ------------------------------- //
// ========================================================================== //

/*
   Create a bank and a bank selector to change its setting.
*/
Bank<4> bank(1); // create a new bank with two tracks per bank
//   │       └───── number of tracks per bank
//   └───────────── number of banks

// Instantiate a Bank selector to control which one of the four Banks is active.
IncrementDecrementSelector<4> bankselector = {
    bank,       // Bank to manage
    {5, 6},     // push button pins (increment, decrement)
    Wrap::Wrap, // Wrap around
};

// -------------------------- MIDI Input Elements --------------------------- //
// ========================================================================== //

/*
   Define all elements that listen for MIDI messages.
*/

// Mute
Bankable::NoteButton mute1 = {
  {bank, BankType::CHANGE_CHANNEL},
  7,
  {MCU::MUTE_1},
};

void setup() {
  RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
  Control_Surface.begin(); // Initialize Control Surface
}

void loop() {
  Control_Surface.loop(); // Update the Control Surface
}
tttapa commented 4 years ago

MCU::MUTE_1 appears in the address field of the MIDI address, so you have to use BankType::CHANGE_ADDRESS.

zeysh commented 4 years ago

@tttapa Thanks works good.

I also found an old example which seems to works.

Is that also a correct way to do that ? Many thanks again for your help!

I tested it with Live and it's ok but with Ardour I have a strange behaviour... It seems that 'mute', for example, is activated on all tracks.

/**
 * @brief 
 * for each tracks, it changes:
 * mute, solo, record ready.
 *
 * Using a BankSelector, it displays 1 channel at once, and you can
 * cycle through 16 banks to display all 16 tracks.
 *
 * mute, solo, record, can be activated by buttons for the selected track,
 */

//#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library

USBMIDI_Interface midi;

Bank<16> bank(1);

IncrementDecrementSelector<16> bankselector(bank, {8, 9});

// Instantiate the buttons
Bankable::NoteButton channelButtons[] = {
    {bank, 5, MCU::MUTE_1},
    {bank, 6, MCU::SOLO_1},
    {bank, 7, MCU::REC_RDY_1},
};

// Mute
Bankable::NoteValue<16> mute = {bank, MCU::MUTE_1};

// Solo
Bankable::NoteValue<16> solo = {bank, MCU::SOLO_1};

NoteValue rudeSolo = {MCU::RUDE_SOLO};

// Record arm / ready
Bankable::NoteValue<16> recrdy = {bank, MCU::REC_RDY_1};

// --------------------------------- Setup ---------------------------------- //
// ========================================================================== //

void setup() {
    RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE); // Correct mode for
                                                        // MCU rotary encoders
    Control_Surface.begin(); // Initialize Control Surface
}

// ---------------------------------- Loop ---------------------------------- //
// ========================================================================== //

void loop() {
    Control_Surface.loop(); // Refresh all elements
}
tttapa commented 4 years ago

Yes, that's also correct. BankType::CHANGE_ADDRESS is the default for most bankable objects.

One thing that concerns me is the bank size of 16. MCU only supports 8 tracks, so bank 9 of MUTE_1 will not be MUTE_9 but SELECT_1.

I've never tried this with Ardour, so I'm afraid I can't really help you with that right now. I'll see if I can install it tomorrow.

zeysh commented 4 years ago

Is there a way to manage more that 8 tracks ?

tttapa commented 4 years ago

If you use a custom MIDI controller, there's no 8-track limitation, so you can use larger banks.
With the MCU protocol, you'll always have the 8-track limitation, unless you use MCU Extenders. This is supported by Control Surface, but only on Teensy 3.x and 4.x boards, and it requires a more involved bank configuration.
I think the easiest way would be to leave out the Control Surface Banks, and use just the MCU banks. There's some info about it here: https://github.com/tttapa/Control-Surface/issues/147#issuecomment-605671653

zeysh commented 4 years ago

Thanks a lot.

My board is a Teensy 4.0.

With this code I can navigate between tracks and for each mute, rec, solo. That's what I'm looking for, to create a footswitch to control each commands on track individually.

I'll try the same but with MCU bank if I want to control more than one track at a time on the footswitch.

The other function I would like, is a 'mode' button to change the action of a button, and another (let's say action button) toggle the 'status' of the selected 'mode'.

The 'mode' button cycle between REC, MUTE, SOLO. And If I select mode: REC the button 'action' toggle the ARM of the track.

But I didn't really search for this function yet. If you know some examples of issues that's will help.

Many thanks for your time and your precious help!

/**
 * @brief 
 * for each tracks, it changes:
 * mute, solo, record ready.
 *
 * Select track with MCU::CHANNEL_LEFT and MCU::CHANNEL_RIGHT,
 * and you can switch: mute, solo, record, with buttons for the selected track.
 */

//#include <Encoder.h> // Include the Encoder library.
// This must be done before the Control Surface library.
#include <Control_Surface.h> // Include the Control Surface library

USBMIDI_Interface midi;

// Instantiate the buttons for switch between tracks
NoteButton chan_nav[] = {
    {
      5,
      MCU::CHANNEL_LEFT,
    },
    {
      6,
      MCU::CHANNEL_RIGHT
    },
};

// Instantiate buttons to toggle rec, mute, solo for the selected track
// Rec
NoteButton rec = {
  7,                // pin 7
  {MCU::REC_RDY_1}, // Note to ARM the track
};
// Mute
NoteButton mute = {
  8,                // pin 8
  {MCU::MUTE_1},    // Note to toggle MUTE on the track
};
// Solo
NoteButton solo = {
  9,                // pin 9
  {MCU::SOLO_1},    // Note to toggle SOLO on the track
};

// --------------------------------- Setup ---------------------------------- //
// ========================================================================== //

void setup() {
    Serial.begin(115200);
    RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE); // Correct mode for                                                     
    Control_Surface.begin(); // Initialize Control Surface
}

// ---------------------------------- Loop ---------------------------------- //
// ========================================================================== //

void loop() {
    Control_Surface.loop(); // Refresh all elements
}