// // pianoleds.h // // Maps incoming MIDI note events onto a WS2812B strip mounted above an // 88-key keybed. // #ifndef _pianoleds_h #define _pianoleds_h #include #include #include #include "config.h" class CPianoLEDs { public: CPianoLEDs (void); ~CPianoLEDs (void); boolean Initialize (void); // Attach to a USB MIDI device. Safe to call again after the gadget has // been re-enumerated, which destroys and recreates the device object. void AttachMIDIDevice (CUSBMIDIDevice *pMIDIDevice); // Push pending state to the strip. Call from the main loop only; this // blocks for ~5.3ms of SPI traffic and must never run in IRQ context. // Does nothing when no state has changed since the last call. void Update (void); // Extinguish every pixel and forget all held notes. void AllOff (void); private: // Called in IRQ context by the USB MIDI driver. static void MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength, unsigned nDevice, void *pParam); void OnMIDIPacket (const u8 *pPacket, unsigned nLength); void SetKey (u8 ucNote, u8 ucVelocity, boolean bHint); // Scale a colour channel by velocity and the global brightness ceiling. static u8 Scale (u8 ucChannel, u8 ucVelocity); static boolean ChannelMatches (u8 ucChannel, u8 ucWanted); private: CWS28XXStripe m_Stripe; // Written in IRQ context, read by Update(). Index is // note - MIDI_NOTE_MIN. Zero means the key is not lit. volatile u8 m_KeyVelocity[KEY_COUNT]; volatile u8 m_HintVelocity[KEY_COUNT]; volatile boolean m_bDirty; }; #endif