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

adding mute mcu 9 10 11...16

Open benwadub opened this issue 3 years ago • 14 comments

hi Pieter I need to have mutes for 16 tracks, I just saw that you implemented that only for track 1 to 8, I tried modifying mcu.hpp and keywords.txt but that seems to not be enough, is there a reason for you didn't it for the 16 tracks or just because nobody needed that?

benwadub avatar Oct 03 '20 20:10 benwadub

I can have the 8 first track mute showing on the screen but when I switch bank I only see my tracks number and mute doesn't t show anything maybe I made a mistake in the code?

#include <Control_Surface.h>

#include <Encoder.h> // Include the Encoder library.
#include "Control_Surface.h"
#include <Display/DisplayInterfaces/DisplayInterfaceSSD1306.hpp>

//#include <name.c>
// celà doit etre écrit avant la library control surface
 //USBDebugMIDI_Interface midi = 115200; // enlever les // en début de ligne pour entrer en mode debug usb et voir dans le panneau de control si vos controler envoient bien les infos

//auto &serial = Serial1;// Selectionne le port série à utiliser remplacer par serial pour une arduino
//SerialMIDI_Interface<decltype(serial)> midi = {serial, MIDI_BAUD};// démarre une interface midi serial au midi baud rate par defaut
USBMIDI_Interface usbmidi;// enlever les / en debut de ligne pour activer l'interface usb, penser à désactiver l'interface série(din)
HardwareSerialMIDI_Interface midiser = Serial1;
 
 
MIDI_PipeFactory<8> pipes;
// ----------------------------- Display setup ------------------------------ //
// ========================================================================== //

/*
   Instantiate and initialize the SSD1306 OLED display
*/

constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;

constexpr int8_t OLED_DC = 19;    // Data/Command pin of the display
constexpr int8_t OLED_reset = -1; // Use the external RC circuit for reset
constexpr int8_t OLED_CS = 10;   //wired on 13

constexpr uint32_t SPI_Frequency = SPI_MAX_SPEED;

// Instantiate the displays
Adafruit_SSD1306 ssd1306Display = {
  SCREEN_WIDTH, SCREEN_HEIGHT, &SPI,          OLED_DC,
  OLED_reset,   OLED_CS,       SPI_Frequency,
};

// --------------------------- Display interface ---------------------------- //
// ========================================================================== //

// Implement the display interface, specifically, the begin and drawBackground
// methods.
class MySSD1306_DisplayInterface : public SSD1306_DisplayInterface {
 public:
  MySSD1306_DisplayInterface(Adafruit_SSD1306 &display)
    : SSD1306_DisplayInterface(display) {}

  void begin() override {
    // Initialize the Adafruit_SSD1306 display
    if (!disp.begin())
      FATAL_ERROR(F("SSD1306 allocation failed."), 0x1306);

    // If you override the begin method, remember to call the super class method
    SSD1306_DisplayInterface::begin();
  }

  void drawBackground() override { disp.drawLine(1, 8, 126, 8, WHITE); }

} display = ssd1306Display;

/*
CD74HC4067 mux1 = {
  14,       // numéro de broche de l'arduino
  {9, 3, 4, 5} // numéro de pins de l'arduino sur lesquels sont branchés tous les multiplexeurs apellés mux S0, S1, S2
};

CD74HC4067 mux2 = {
  15,              
  {9, 3, 4, 5}, 
};

CD74HC4067 mux3 = {
  16,       
  {9, 3, 4, 5} 
};
CD74HC4067 mux4 = {
  17,       
  {9, 3, 4, 5} 
};
CD74HC4067 mux5 = {
  18,      
  {9, 3, 4, 5} 
};
*/
Bank<2> bank = {8}; // active 2 bank avec 8 adresses par bank
IncrementDecrementSelector<2> selector = {
    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.
*/

// Time display keeps track of the bar counter
MCU::TimeDisplay timedisplay = {};

// Play / Record
NoteValue play = {MCU::PLAY};
NoteValue record = {MCU::RECORD};

// Mute
Bankable::NoteValue<2> mute[] = {
  {bank, MCU::MUTE_1},
  {bank, MCU::MUTE_2},
  {bank, MCU::MUTE_3},
  {bank, MCU::MUTE_4},
  {bank, MCU::MUTE_5},
  {bank, MCU::MUTE_6},
  {bank, MCU::MUTE_7},
  {bank, MCU::MUTE_8},

  
  
};

// Solo
Bankable::NoteValue<2> solo[] = {
  {bank, MCU::SOLO_1},
  {bank, MCU::SOLO_2},
};

NoteValue rudeSolo = {MCU::RUDE_SOLO};

// Record arm / ready
Bankable::NoteValue<2> recrdy[] = {
  {bank, MCU::REC_RDY_1},
  {bank, MCU::REC_RDY_2},
};

// VU meters
MCU::Bankable::VU<2> vu[] = {
  {bank, 1, MCU::VUDecay::Hold},
  {bank, 2, MCU::VUDecay::Hold},
};


// ---------------------------- Display Elements ---------------------------- //
// ========================================================================== //

/*
   Define all display elements that display the state of the input elements.
*/

// Time display
MCU::TimeDisplayDisplay timedisplaydisplay = {
  // position (0, 0), font size (1)
  display, timedisplay, {0, 0}, 1, WHITE,
};

// Play / Record
NoteBitmapDisplay playDisp = {
  display, play, XBM::play_7, {16 + 64, 0}, WHITE,
};
NoteBitmapDisplay recordDisp = {
  display, record, XBM::record_7, {26 + 64, 0}, WHITE,
};

// Mute
NoteBitmapDisplay muteDisp[] = {
  {display, mute[0], XBM::mute_10B, {10, 13}, WHITE},
  {display, mute[1], XBM::mute_10B, {42, 13}, WHITE},
  {display, mute[2], XBM::mute_10B, {74, 13}, WHITE},
  {display, mute[3], XBM::mute_10B, {106, 13}, WHITE},
  {display, mute[4], XBM::mute_10B, {10, 38}, WHITE},
  {display, mute[5], XBM::mute_10B, {42, 38}, WHITE},
  {display, mute[6], XBM::mute_10B, {74, 38}, WHITE},
  {display, mute[7], XBM::mute_10B, {106, 38}, WHITE},
  
 
};
/*
// Solo
NoteBitmapDisplay soloDisp[] = {
  {display, solo[0], XBM::solo_10B, {14, 50}, WHITE},
  {display, solo[1], XBM::solo_10B, {14 + 64, 50}, WHITE},
};

NoteBitmapDisplay rudeSoloDisp = {
  display, rudeSolo, XBM::solo_7, {36 + 64, 0}, WHITE};

// Record arm / ready
NoteBitmapDisplay recrdyDisp[] = {
  {display, recrdy[0], XBM::rec_rdy_10B, {14 + 14, 50}, WHITE},
  {display, recrdy[1], XBM::rec_rdy_10B, {14 + 14 + 64, 50}, WHITE},
};

// VU meters
MCU::VUDisplay vuDisp[] = {
  // position (32+11, 60), width (16), bar height (3) px, bar spacing (1) px
  {display, vu[0], {32 + 11, 60}, 16, 3, 1, WHITE},
  {display, vu[1], {32 + 11 + 64, 60}, 16, 3, 1, WHITE},
};

// VPot rings
/*MCU::VPotDisplay vpotDisp[] = {
  // position (0, 10), outer radius (16) px, inner radius (13) px
  {display, vpot[0], {0, 10}, 4, 2, WHITE},
  {display, vpot[1], {32, 10}, 4, 2, WHITE},
  
};
*/
// Bank seting
BankDisplay bankDisp[] = {
  // first track of the bank (1), position (0, 50), font size (2)
  {display, bank, 1, {3, 10}, 1, WHITE},
  {display, bank, 2, {35, 10}, 1, WHITE},
  {display, bank, 3, {67, 10}, 1, WHITE},
  {display, bank, 4, {99, 10}, 1, WHITE},
  {display, bank, 5, {3, 35}, 1, WHITE},
  {display, bank, 6, {35, 35}, 1, WHITE},
  {display, bank, 7, {67, 35}, 1, WHITE},
  {display, bank, 8, {99, 35}, 1, WHITE},
 
};

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

  Control_Surface.begin(); // initialise la library surface de control
  usbmidi >> pipes >> midiser; // all incoming midi from USB is sent to serial
  usbmidi << pipes << midiser; // all incoming midi from Serial is sent to USB
  usbmidi >> pipes >> usbmidi; // all incoming midi from USB is looped back
  midiser << pipes << midiser;
  Control_Surface >> pipes >> usbmidi;
  Control_Surface << pipes << usbmidi;
  Control_Surface >> pipes >> midiser;
  Control_Surface << pipes << midiser;
  usbmidi.begin();
  midiser.begin();
 // The default SPI MOSI pin (11) is used for I²S, so we need to use the
  // alternative MOSI pin (7)
  SPI.setMOSI(11);
  // Correct relative mode for MCU rotary encoders
  RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
  Control_Surface.begin(); // Initialize Control Surface

}                           
void loop() {
  

  Control_Surface.loop(); // Update the Control Surface
  usbmidi.update();
  midiser.update();
}

benwadub avatar Oct 04 '20 09:10 benwadub

The standard MCU protocol only supports 8 tracks. If you want more, you either have to use MCU XT (Extenders) by using MCU::MUTE_1 on the second virtual MIDI USB cable, or you have to use the MCU banks (not the Control Surface banks).

See https://github.com/tttapa/Control-Surface/issues/147#issuecomment-605671653.

There's nothing magical about the MCU constants, and changing them won't work, because then they won't match the MCU protocol anymore, so your DAW gets confused.

tttapa avatar Oct 04 '20 11:10 tttapa

hi, i m back to this project! could you show me how to use cable please? I didn't t found example using this. i d like to send mute from tracks 9 to 16 to my teensy

benwadub avatar Nov 02 '21 14:11 benwadub

The cable is just an additional argument in the MIDI address, see https://tttapa.github.io/Control-Surface-doc/Doxygen/d3/df7/midi-tutorial.html#midi_md-midi-addresses.

For instance:

NoteValue mute[] = {
  {{MCU::MUTE_1, CABLE_2}}, // Mute track #9
  // ...
};

You'll have to enable multiple MIDI cables in the Tools > USB type menu in the Arduino IDE, and then map this as an MCU Extender (XT) in your DAW.

tttapa avatar Nov 03 '21 22:11 tttapa

I am on the Arduino IDE > Tools but can't see USB type menu there. The closest thing I see is Port. I guess that's not the right thing?

Is there a way within the same board to have the first 8 channels and then another 8 on CABLE_2 and an expander to act as the whole controller of 16 channels, MCU and MCU XT altogether?

gringow831 avatar Jan 28 '22 17:01 gringow831

Are you using a teensy? Not sure arduino are able to act as teensy on different USB port a t a time

benwadub avatar Jan 28 '22 18:01 benwadub

That's right, the wrong board was selected. By selecting the Midi Cable it means MIDIx4 and MIDIx16 right?

gringow831 avatar Jan 28 '22 18:01 gringow831

Midix4 will show 4 différent controllers in any midi application on your computer and midix16 will show 16 controllers so midi x4 will be enough if you only need two cables

benwadub avatar Jan 29 '22 07:01 benwadub

Hey Benwadub, have been testing what I have done with my previous Leonardo Board. The PBPotentiometer is not working in full, it does start working after the 25%/30% while on the Leonardo worked in full from 0%. Do you happen to have solve that?

gringow831 avatar Jan 31 '22 12:01 gringow831

Not sure to understand what you mean sorry, but I think that for pitch bend you have to send absolute value instead of relative for many daw, maybe that could help you finding your problem?

benwadub avatar Jan 31 '22 12:01 benwadub

That’s exactly what I though. Not sure what the difference is between a teensy and a leonardo as with the Leonardo everything worked correctly except for not having CABLE_ which I need

gringow831 avatar Jan 31 '22 15:01 gringow831

You use exactly the same code and same schematic? I m not an expert but I think that if that is working on the Leonardo the exact same thing would work on the teensy.

benwadub avatar Jan 31 '22 15:01 benwadub

Yes. That’s what I thought too unless with the LC the absolute value needs to be specified. I haven’t seen if that’s possible with PBPotentiomenters and MCU and couldn’t figure it out

gringow831 avatar Jan 31 '22 16:01 gringow831

Found the solution. The voltage on the pins of the Teensy LC is 3.3v rather than 5v and this shouldn't be applied. As the voltage is divided being the lowest value 5V it only starts working around the 3.3V (at 33% of the actual potentiometer)

I can only make My Teensy LC work with cables on Serial+MIDIx4 and can't find the solution to not having the serial on the USB type

gringow831 avatar Feb 02 '22 12:02 gringow831