Giter VIP home page Giter VIP logo

Comments (18)

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024 1

Thanks for all the help :-)

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

I have figured it out and is clearly a very noob mistake.

switchOctave.set(map(controlPots[2].getValue(), 0, 124, 15, 0));

I have only defined 9 banks, 0 to 8. Mapping a value even if it wasn't greater than 8 seemed to cause quite a crash. That's why this worked: switchOctave.set(3); for eg.

So I guess my next question is, what should I be using as a selector for changing banks if I am using a potentiometer as my physical selector ? So that I don't programatically make these simple mistakes of setting out of bounds values :-)

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Also, is there a way to have the change of channel banks affect both the midi notes channel and the effect channel ? So when changing the midi channel the midi notes travel with the midi cc to the next channel ?

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

When you try to select a non-existent setting, you get an error. The on-board LED should start blinking in that case, and if you enable debugging in src/Settings/Settings.hpp, it'll print the error message:

[static CS::setting_t CS::Selectable<N>::validateSetting(CS::setting_t) [with unsigned char N = 9; CS::setting_t = unsigned char] @ line 24]:	Error: Setting 9 is not less than the number of settings (9) (0xFFFE)

So I guess my next question is, what should I be using as a selector for changing banks if I am using a potentiometer as my physical selector ? So that I don't programatically make these simple mistakes of setting out of bounds values :-)

Compile-time checking is done by specifying the number of settings as a template parameter (between the <>). You could create your own class for potentiometer selectors, and make it a template, so it can only be combined with a bank with the same number of settings.

This is the code I used for testing your code, by the way:

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

USBMIDI_Interface midi; // Instantiate a MIDI Interface to use

Bank<9> channelBank(1);

FilteredAnalog<7> controlPot = A2;

void setup() {
  Control_Surface.begin(); // Setup the Control Surface
  Serial.begin(115200); // Setup Serial output
}

void loop() {
  if (controlPot.update()) {
    uint8_t setting = map(controlPot.getValue(), 0, 124, 0, 15);
    Serial.println(setting);
    channelBank.select(setting);
  }
  Control_Surface.loop();
}

Also, is there a way to have the change of channel banks affect both the midi notes channel and the effect channel ? So when changing the midi channel the midi notes travel with the midi cc to the next channel ?

No, this is not supported at the moment.

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Thanks so much for the help, I do appreciate it. I will attempt to create a potentiometer selector class using one of the existing classes as a basis to work from. I'm not overly confident at this point but I'm willing to give it a go. Thanks for the pointers.

Is it possible to create another bank selector to change channels on the midi notes so that there is a bank to change the octave and a bank to change the midi channel ?

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

I think something like this would work:

#define protected public  // Forgive me, Father :(

#include <Control_Surface.h>

BEGIN_CS_NAMESPACE

namespace Bankable {

class TwoBanks {
  public:
    TwoBanks(OutputBankConfig config1, OutputBankConfig config2, 
             MIDICNChannelAddress address)
        : bankable1{config1}, bankable2{config2}, address(address) {}

    void lock() {
        bankable1.lock();
        bankable2.lock();
    }

    void unlock() {
        bankable1.unlock();
        bankable2.unlock();
    }

    MIDICNChannelAddress getBaseAddress() const { return address; }

    MIDICNChannelAddress getActiveAddress() const {
        return getBaseAddress() 
             + bankable1.getAddressOffset() 
             + bankable2.getAddressOffset();
    }

  private:
    BankableMIDIOutput bankable1;
    BankableMIDIOutput bankable2;
    MIDICNChannelAddress address;
};

class TwoBanksNoteButton : public MIDIButton<TwoBanks, DigitalNoteSender> {
  public:
    TwoBanksNoteButton(const OutputBankConfig &config1, 
                       const OutputBankConfig &config2, 
                       pin_t pin,
                       const MIDICNChannelAddress &address,
                       const DigitalNoteSender &sender = {})
        : MIDIButton<TwoBanks, DigitalNoteSender>{
          {config1, config2, address}, pin, sender} {}
};

} // namespace Bankable

END_CS_NAMESPACE

USBDebugMIDI_Interface midi;

Bank<16> channelBank(1);
Bank<9> pitchBank(12);

using namespace MIDI_Notes;

Bankable::TwoBanksNoteButton button = {
  {channelBank, CHANGE_CHANNEL},
  {pitchBank, CHANGE_ADDRESS},
  2, // pin
  note(C, 0), // address
};

void setup() {
  Control_Surface.begin();
  channelBank.select(CHANNEL_10.getRaw());
  pitchBank.select(4);
}

void loop() {
  Control_Surface.loop();
}

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Wow, that was quick. You have really given me a lot to go through and use. Again I really do appreciate your time and help.

I will be looking into attempting to create the potentiometer selector class.

Great work on this library it really has saved me a lot of work and time in trying to figure things out myself :-)

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

This seems to work:

#include <Control_Surface.h>

USBMIDI_Interface midi;

MAX7219SevenSegmentDisplay display = {10}; // MAX7219 connected to SPI bus, load pin to pin 10

template <setting_t N>
class PotSelector : public Updatable<> {
  public:
    PotSelector(Selectable<N> &selectable, pin_t analogPin, uint8_t displayPosition = 0) 
      : selectable(selectable), pot{analogPin}, displayPosition(displayPosition) {}

    void begin() override {}
    
    void update() override {
      if (pot.update()) {
        setting_t setting = map(pot.getValue(), 0, 64, 0, N);
        selectable.select(setting);
        static_assert(N <= 16, "Can only display 0-15");
        display.printHex(displayPosition, setting);
      }
    }

  private:
    Selectable<N> &selectable;
    FilteredAnalog<6, 3, 3> pot; // tweak filter and bit depth if necessary
    uint8_t displayPosition;
};

Bank<9> pitchBank(12);
Bank<16> channelBank(1);

PotSelector<9> pitchSel = {
  pitchBank, A2, 0,
};

PotSelector<16> channelSel = {
  channelBank, A3, 7,
};

void setup() {
  display.begin();
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop();
}

I added the printHex method in the latest commit: d8471ba, so you might have to update.

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Pieter, you are a scholar and a gentleman ... thank you :-) You have helped immensely. I will try this out today. I am a few steps closer to having everything that I need working.

Your code for the TwoBanksNoteButton works perfectly and for now I can manipulate the banks using an Increment selector setting the banks manually reading from the pots. I started looking into the potSelector code and seeing how I can use that.

My last thing to figure out is to create banks of effects that I can apply to a group of slide potentiometers. eg.

Bank 1 = Reverb, Chorus, Tremelo, Phaser
Bank 2 = Pitchbend, Modulation, Breath, Portamento
Bank 3 = Release, Attack, Cutoff, Variation
etc ...

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

I'm not sure I understand what you mean. Does each effect have a certain CC number?

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Yes they would have their own Midi CC number except for Pitch Bend which seems to be on it's own. So the banks would look like this with midi cc:

Bank 1 = 91, 93, 92, 95
Bank 2 = ??, 1, 2, 5
Bank 3 = 72, 73, 74, 70

I'm not sure how many banks I could come up with, but grouping together certain effects that are related to each other in some way could give me a few more.

So for eg. when bank 1 is selected the 4 slide potentiometers are assigned Reverb, Chorus, Tremolo and Phaser. Bank 2 they get assigned Modulation, Breath, Portamento ... etc.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

Okay, I see. For the normal CC numbers, you can use Bankable::ManyAddresses:CCPotentiometer. I didn't add any examples yet, but maybe you can figure it out from the documentation: https://tttapa.github.io/Control-Surface/Doc/Doxygen/d5/d71/classBankable_1_1ManyAddresses_1_1CCPotentiometer.html
If I have time tonight, I'll try to add an example.

For the pitch bend, you'll have to check the bank setting, disable the CCPotentiometer, and enable the PBPotentiometer when appropriate. They have enable() and disable() methods, and you can call getSelection() on the Bank, IIRC.

If you get stuck, just let me know, and I'll try to look into it tonight.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

Turns out you don't even need enable and disable, you can just specify an invalid address, so that it won't send anything.

See the example I added in 4bddc91.

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Pieter, your code works perfectly. Exactly what I needed to get done. Using the bankable ManyAddresses works exactly like you described and a simple copy/paste of your example code is doing the job.

Thank you again for your time and effort in helping out with this. I really do appreciate it. I now need to put everything into a box so I can bash the buttons proper, as a friend said to me today. :-)

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

Glad I could help :-)

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Created an include file to take your class definition for TwoBanks out of the main code. I don't have my project with me at work today so can't test if it works correctly however it seems to compile ok after adding the files to my Project directory. Not sure if I've done it correctly, but when I added the include #include "TwoBanks.h" while the original code was there the compiler did complain about a redeclaration, so I assume it had included it correctly.

TwoBanks.cpp

#ifdef TEST_COMPILE_ALL_HEADERS_SEPARATELY
#include "TwoBanks.h"
#endif

TwoBanks.h

#pragma once

#include <MIDI_Outputs/Abstract/MIDIButton.hpp>
#include <MIDI_Senders/DigitalNoteSender.hpp>

BEGIN_CS_NAMESPACE

namespace Bankable {

class TwoBanks {
  public:
    TwoBanks(OutputBankConfig config1, OutputBankConfig config2, 
             MIDICNChannelAddress address)
        : bankable1{config1}, bankable2{config2}, address(address) {}

    void lock() {
        bankable1.lock();
        bankable2.lock();
    }

    void unlock() {
        bankable1.unlock();
        bankable2.unlock();
    }

    MIDICNChannelAddress getBaseAddress() const { return address; }

    MIDICNChannelAddress getActiveAddress() const {
        return getBaseAddress() 
             + bankable1.getAddressOffset() 
             + bankable2.getAddressOffset();
    }

  private:
    BankableMIDIOutput bankable1;
    BankableMIDIOutput bankable2;
    MIDICNChannelAddress address;
};

class TwoBanksNoteButton : public MIDIButton<TwoBanks, DigitalNoteSender> {
  public:
    TwoBanksNoteButton(const OutputBankConfig &config1, 
                       const OutputBankConfig &config2, 
                       pin_t pin,
                       const MIDICNChannelAddress &address,
                       const DigitalNoteSender &sender = {})
        : MIDIButton<TwoBanks, DigitalNoteSender>{
          {config1, config2, address}, pin, sender} {}
};

} // namespace Bankable

END_CS_NAMESPACE

from control-surface.

JohnnyReggae avatar JohnnyReggae commented on May 24, 2024

Managed to test it all this evening, and it works perfectly just including the .h file in my project directory :-)

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

Great, glad to hear!

from control-surface.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.