Giter VIP home page Giter VIP logo

Comments (10)

AngleCreDible avatar AngleCreDible commented on May 24, 2024 1

Oops, I didn't know that!
I thought I had to assign codes for each led.
Anyway, it works really fine.
Thank you.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024 1

For a limited number of LEDs, you can do something like this:

#include <FastLED.h>
#include <Control_Surface.h>

Array<CRGB, 3> leds = {};
constexpr uint8_t ledpin = 2;

USBMIDI_Interface midi;

using namespace MIDI_Notes;
NoteValueFastLED<> midileds[leds.length] = {
  {leds[0], note(C, 0)},
  {leds[1], note(D, 4)},
  {leds[2], note(G, 2)},
};

void setup() {
  // See FastLED examples and documentation for more information.
  FastLED.addLeds<NEOPIXEL, ledpin>(leds.data, leds.length);
  FastLED.setCorrection(TypicalPixelString);
  FastLED.setBrightness(128);
  Control_Surface.begin();
}

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

However, each LED takes up at least 17 bytes of RAM, and matching is more expensive as well (looking up the LED to turn on/off when a MIDI message comes in).

A more efficient approach would be the following:
Basically, you write your own handler/callback that is executed whenever a new MIDI value is received. You can then pass this custom callback to the GenericNoteCCRange class. This class listens for MIDI Note or Control Change events in a given range (e.g. all notes between C0 and D4), and calls the callback if it receives such a MIDI event.

#include <FastLED.h>
#include <Control_Surface.h>

USBMIDI_Interface midi;

Array<CRGB, 3> leds = {};
constexpr uint8_t ledpin = 2;

using namespace MIDI_Notes;

constexpr uint8_t firstNote = note(C, 0);
constexpr uint8_t lastNote = note(D, 4);

/// This is a custom callback that's executed when MIDI values (note velocity or
/// controller change) change. It's used by the GenericNoteCCRange class below.
class MyNoteCCFastLED {
  public:
    /// This function is called upon initialization of the GenericNoteCCRange 
    /// object that owns this callback.
    template <class T>
    void begin(const T &t) {
        update(t);
    }

    /// This function is called when a single value changes.
    /// @param  t
    ///         The GenericNoteCCRange object that had a value change.
    /// @param  index
    ///         The index of the value that changed. It is in the range
    ///         [0, t.length() - 1]
    template <class T>
    void update(const T &t, uint8_t index) {
        uint8_t value = t.getValue(index); // Value is the MIDI value [0, 127]
        // Use the index and value here to turn on/off the right LED
        uint8_t noteIndex = firstNote + index;
        if (noteIndex == note(C, 0))
          leds[0] = CRGB{16, 255, 192}.nscale8_video(value * 2); // first LED
        else if (noteIndex == note(D, 4))
          leds[1] = CRGB{16, 255, 192}.nscale8_video(value * 2); // second LED
        else if (noteIndex == note(G, 2))
          leds[2] = CRGB{16, 255, 192}.nscale8_video(value * 2); // third LED
    }

    /// This function is called when all values change and everything has to be
    /// updated.
    /// @param  t
    ///         The GenericNoteCCRange object that has to be updated entirely.
    template <class T>
    void update(const T &t) {
        // loop over the entire range, and update every note individually.
        for (uint8_t index = 0; index < t.length(); ++index)
            update(t, index);
    }
};

GenericNoteCCRange<MIDIInputElementNote,     // Type: Note or CC
                   lastNote - firstNote + 1, // Length of the range
                   MyNoteCCFastLED           // Callback when value changes
                  > midileds = {
  firstNote, // address of the first note (or controller) in the range
  {},        // default initialization of MyNoteCCFastLED callback
};

void setup() {
  // See FastLED examples and documentation for more information.
  FastLED.addLeds<NEOPIXEL, ledpin>(leds.data, leds.length);
  FastLED.setCorrection(TypicalPixelString);
  FastLED.setBrightness(128);
  Control_Surface.begin();
}

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

This example seems to compile without errors, but I can't test it on real hardware at the moment.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

There's a Neopixel example here. You can specify your own color mapper if you have to.

from control-surface.

AngleCreDible avatar AngleCreDible commented on May 24, 2024

Thank you for your kind answer.
But there's one thing I'm still confused about.
How do I map RGB values by Velocity?

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

You have to create a struct with a call operator that takes the velocity (as a uint8_t) as a parameter, and returns an object of type Color containing the R, G and B values.

struct MyColorMapper {
     Color operator()(uint8_t velocity) const {
        if (velocity == 0)
            return {0, 0, 0}; // black
        else if (velocity < 64)
            return {0, 255, 0}; // green
        else 
            return {255, 0, 0}; // red
     }
 };

Then you can supply that color mapper to the NoteRangeFastLED class in the example:

NoteRangeFastLED<leds.length, MyColorMapper> midiled = {leds, note(C, 4)};

from control-surface.

AngleCreDible avatar AngleCreDible commented on May 24, 2024

I am using using NEOPIXEL RGB led strip, and your example code works fine for me.
But only the first LED on the strip lights up and the rest do not work.
I want to know how to operate the 16 LEDs on the strip, each in a different note.

Thank you for always good library and kind answers.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

That's strange, I just tried it here with a piece of Chinese Neopixel LED strip, and it works as expected. What notes are you sending?

The first LED should be C4, the second C#4, the third D4, D#4, E4, F4, etc. increasing in half steps.

from control-surface.

tttapa avatar tttapa commented on May 24, 2024

For future reference, I added the LED index as a parameter to the color mapper, allowing you to get a different color for different LEDs.

A "Rainbow" example can be found here: https://tttapa.github.io/Control-Surface/Doc/Doxygen/d9/d6d/10_8Note-FastLED-ColorMapper_8ino-example.html

from control-surface.

AngleCreDible avatar AngleCreDible commented on May 24, 2024

Thank you for your efforts!
Lastly, let me ask you a question.
Can I map notes to each LED on the LEDstrip?
(e.g. LED#1 : C0, LED#2 : D4, LED#3 : G2)

from control-surface.

AngleCreDible avatar AngleCreDible commented on May 24, 2024

Awesome, thanks!

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.