Provide 1:1 examples from original to port and use them tests when building docs.
This commit is contained in:
parent
52bf6e4c95
commit
fe877262d1
|
|
@ -1,12 +0,0 @@
|
||||||
# Getting Started
|
|
||||||
|
|
||||||
cs-midi is a standalone MIDI library for pico-sdk, extracted from [Control Surface](https://github.com/tttapa/Control-Surface). It provides BLE MIDI, Classic BT SPP MIDI, rotary encoders, buttons, potentiometers, LEDs, banks, and a flexible pipe-based routing system.
|
|
||||||
|
|
||||||
## What's included
|
|
||||||
|
|
||||||
- **BLE MIDI** via BTstack (pico-native, no Arduino)
|
|
||||||
- **Output elements**: NoteButton, CCRotaryEncoder, CCPotentiometer, and more
|
|
||||||
- **Input elements**: NoteValue, CCValue, PBValue, LEDs
|
|
||||||
- **Pipe routing**: bidirectional MIDI pipes with filter/transform support
|
|
||||||
- **Banks**: switch between multiple CC/note mappings
|
|
||||||
- **Custom hooks**: extend the library without modifying it
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
# Installation
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- [pico-sdk](https://github.com/raspberrypi/pico-sdk) (v2.0+)
|
|
||||||
- CMake 3.13+
|
|
||||||
- ARM GCC toolchain
|
|
||||||
|
|
||||||
## Adding to your project
|
|
||||||
|
|
||||||
Add cs-midi as a git submodule:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git submodule add https://git.else-if.org/jess/cs-midi.git lib/cs-midi
|
|
||||||
```
|
|
||||||
|
|
||||||
In your `CMakeLists.txt`:
|
|
||||||
|
|
||||||
```cmake
|
|
||||||
add_subdirectory(lib/cs-midi)
|
|
||||||
target_link_libraries(your_target cs_midi)
|
|
||||||
target_include_directories(cs_midi PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
```
|
|
||||||
|
|
||||||
The last line is required so cs-midi can find your project's `btstack_config.h` and `lwipopts.h`.
|
|
||||||
|
|
||||||
## Include
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include <cs_midi.h>
|
|
||||||
```
|
|
||||||
|
|
||||||
This single header pulls in everything: output elements, input elements, pipes, banks, BLE interface, and the Control Surface singleton.
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
# cs-midi
|
||||||
|
|
||||||
|
A standalone pico-sdk extraction of [tttapa/Control-Surface](https://github.com/tttapa/Control-Surface) (GPL-3.0).
|
||||||
|
|
||||||
|
cs-midi provides the core MIDI element system, BLE MIDI transport, banks, selectors, and the declarative `Control_Surface` singleton for use with the Raspberry Pi Pico SDK and the CYW43 radio module (BTstack BLE backend).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButton button {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Differences from Control Surface
|
||||||
|
|
||||||
|
- `#include <cs_midi.h>` replaces `#include <Control_Surface.h>`
|
||||||
|
- `cs::BluetoothMIDI_Interface` replaces `USBMIDI_Interface`
|
||||||
|
- Standard `main()` with `cyw43_arch_init()` replaces Arduino `setup()`/`loop()`
|
||||||
|
- All types live in the `cs::` namespace
|
||||||
|
- No `MCU::` namespace — use raw CC numbers or `MIDI_CC::` constants
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Original library: [Control Surface](https://github.com/tttapa/Control-Surface) by **Pieter P (tttapa)** (GPL-3.0).
|
||||||
|
pico-sdk port: [pszsh](https://else-if.org).
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
title: cs-midi
|
title: cs-midi
|
||||||
author: jess
|
author: Pieter P (tttapa) — pico-sdk port
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,264 @@
|
||||||
|
# Class Reference
|
||||||
|
|
||||||
|
Cross-reference between cs-midi and the original [Control Surface](https://tttapa.github.io/Control-Surface/Doxygen/annotated.html) library.
|
||||||
|
|
||||||
|
## Ported Classes
|
||||||
|
|
||||||
|
These classes are available in cs-midi and work identically to their Control Surface equivalents (within the `cs::` namespace unless noted).
|
||||||
|
|
||||||
|
### MIDI Output Elements
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `NoteButton` | | Note On/Off on button press/release |
|
||||||
|
| `NoteButtonLatched` | | Toggle Note On/Off on each press |
|
||||||
|
| `NoteButtonLatching` | | Note On while held, toggles |
|
||||||
|
| `NoteChordButton` | | Chord (multiple notes) on press |
|
||||||
|
| `NoteButtons` | `<N>` | Array of sequential note buttons |
|
||||||
|
| `NoteButtonMatrix` | `<R, C>` | Row/column scanned note grid |
|
||||||
|
| `CCButton` | | CC 127/0 on press/release |
|
||||||
|
| `CCButtonLatched` | | Toggle CC 127/0 on each press |
|
||||||
|
| `CCButtonLatching` | | CC 127 while held, toggles |
|
||||||
|
| `CCButtons` | `<N>` | Array of sequential CC buttons |
|
||||||
|
| `CCButtonMatrix` | `<R, C>` | Row/column scanned CC grid |
|
||||||
|
| `CCPotentiometer` | | Analog input to CC 0-127 |
|
||||||
|
| `PBPotentiometer` | | Analog input to 14-bit Pitch Bend |
|
||||||
|
| `CCRotaryEncoder` | | Relative CC from encoder |
|
||||||
|
| `BorrowedCCRotaryEncoder` | | Shared encoder reference for CC |
|
||||||
|
| `CCAbsoluteEncoder` | | Absolute CC from encoder position |
|
||||||
|
| `PBAbsoluteEncoder` | | 14-bit Pitch Bend from encoder |
|
||||||
|
| `CCIncrementDecrementButtons` | | Two buttons for CC inc/dec + reset |
|
||||||
|
| `PCButton` | | Program Change on press |
|
||||||
|
| `ProgramChanger` | `<N>` | Selectable program change list |
|
||||||
|
|
||||||
|
### MIDI Input Elements
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `NoteValue` | | Incoming Note value (8-bit) |
|
||||||
|
| `CCValue` | | Incoming CC value (8-bit) |
|
||||||
|
| `KPValue` | | Incoming Key Pressure value (8-bit) |
|
||||||
|
| `PBValue` | | Incoming Pitch Bend value (14-bit) |
|
||||||
|
| `NoteRange` | `<Len>` | Array of incoming Note values |
|
||||||
|
| `CCRange` | `<Len>` | Array of incoming CC values |
|
||||||
|
| `KPRange` | `<Len>` | Array of incoming Key Pressure values |
|
||||||
|
| `NoteLED` | | LED driven by Note On/Off |
|
||||||
|
| `CCLED` | | LED driven by CC value |
|
||||||
|
| `KPLED` | | LED driven by Key Pressure |
|
||||||
|
|
||||||
|
### Bankable Input Elements
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `Bankable::NoteValue` | `<BankSize>` | Bank-switched Note value |
|
||||||
|
| `Bankable::CCValue` | `<BankSize>` | Bank-switched CC value |
|
||||||
|
| `Bankable::KPValue` | `<BankSize>` | Bank-switched Key Pressure value |
|
||||||
|
| `Bankable::PBValue` | `<BankSize>` | Bank-switched Pitch Bend value |
|
||||||
|
| `Bankable::NoteLED` | `<BankSize>` | Bank-switched Note LED |
|
||||||
|
| `Bankable::CCLED` | `<BankSize>` | Bank-switched CC LED |
|
||||||
|
| `Bankable::KPLED` | `<BankSize>` | Bank-switched Key Pressure LED |
|
||||||
|
|
||||||
|
### Banks and Selectors
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `Bank` | `<N>` | N-setting bank for bankable elements |
|
||||||
|
| `Transposer` | `<Min, Max>` | Note transposition bank |
|
||||||
|
| `OutputBank` | | Bank for output elements |
|
||||||
|
| `EncoderSelector` | `<N>` | Bank selection via rotary encoder |
|
||||||
|
| `IncrementSelector` | `<N>` | Bank selection via single button |
|
||||||
|
| `IncrementDecrementSelector` | `<N>` | Bank selection via two buttons |
|
||||||
|
| `ManyButtonsSelector` | `<N>` | Bank selection via N buttons |
|
||||||
|
| `SwitchSelector` | | Two-state selector from switch |
|
||||||
|
| `ProgramChangeSelector` | `<N>` | Bank selection via incoming MIDI PC |
|
||||||
|
| `EncoderSelectorLEDs` | `<N>` | EncoderSelector with LED indicators |
|
||||||
|
| `IncrementSelectorLEDs` | `<N>` | IncrementSelector with LED indicators |
|
||||||
|
| `IncrementDecrementSelectorLEDs` | `<N>` | IncrementDecrementSelector with LEDs |
|
||||||
|
| `ManyButtonsSelectorLEDs` | `<N>` | ManyButtonsSelector with LEDs |
|
||||||
|
| `SwitchSelectorLED` | | SwitchSelector with LED |
|
||||||
|
| `ProgramChangeSelectorLEDs` | `<N>` | ProgramChangeSelector with LEDs |
|
||||||
|
|
||||||
|
### MIDI Interfaces
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `BluetoothMIDI_Interface` | | BLE MIDI via CYW43 BTstack |
|
||||||
|
|
||||||
|
### MIDI Routing
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `MIDI_Pipe` | | Connects a MIDI source to a sink |
|
||||||
|
| `MIDI_PipeFactory` | `<N>` | Creates N unidirectional pipes |
|
||||||
|
| `MIDI_Sink` | | Base class for MIDI receivers |
|
||||||
|
| `MIDI_Source` | | Base class for MIDI senders |
|
||||||
|
|
||||||
|
### Hardware Utilities (`AH::` namespace)
|
||||||
|
|
||||||
|
| Class | Template | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `Button` | | Debounced button with state machine |
|
||||||
|
| `IncrementButton` | | Button with auto-repeat |
|
||||||
|
| `IncrementDecrementButtons` | | Button pair with auto-repeat |
|
||||||
|
| `ButtonMatrix` | `<R, C>` | Row/column button scanner |
|
||||||
|
| `GenericFilteredAnalog` | `<...>` | EMA-filtered analog input with hysteresis |
|
||||||
|
| `AHEncoder` | | Interrupt-driven quadrature encoder |
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `Control_Surface_` | Singleton coordinating all elements (`Control_Surface.begin()` / `.loop()`) |
|
||||||
|
| `MIDIAddress` | Note/CC address with channel and cable |
|
||||||
|
| `MIDIChannelCable` | Channel + cable pair |
|
||||||
|
| `RelativeMIDIAddress` | Relative address offset |
|
||||||
|
| `Channel` | MIDI channel (1-16) |
|
||||||
|
| `Cable` | MIDI cable number |
|
||||||
|
| `DigitalCCSender` | Sends CC 0/127 |
|
||||||
|
| `ContinuousCCSender` | Sends CC 0-127 |
|
||||||
|
| `ContinuousCCSender14` | Sends 14-bit CC |
|
||||||
|
| `DigitalNoteSender` | Sends Note On/Off |
|
||||||
|
| `RelativeCCSender` | Sends relative CC (Mackie, etc.) |
|
||||||
|
| `PitchBendSender` | Sends Pitch Bend |
|
||||||
|
| `ProgramChangeSender` | Sends Program Change |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Not Yet Ported
|
||||||
|
|
||||||
|
These classes exist in the original Control Surface but are not yet available in cs-midi.
|
||||||
|
|
||||||
|
### Bankable Output Elements
|
||||||
|
|
||||||
|
The entire bankable output layer (Phase 11) has not been extracted. This includes bank-switched versions of every output element.
|
||||||
|
|
||||||
|
| Class | Original | Priority |
|
||||||
|
|-------|----------|----------|
|
||||||
|
| `Bankable::NoteButton` | Bankable note button | High |
|
||||||
|
| `Bankable::CCButton` | Bankable CC button | High |
|
||||||
|
| `Bankable::CCPotentiometer` | Bankable CC pot | High |
|
||||||
|
| `Bankable::CCRotaryEncoder` | Bankable CC encoder | High |
|
||||||
|
| `Bankable::CCAbsoluteEncoder` | Bankable absolute encoder | Medium |
|
||||||
|
| `Bankable::PBAbsoluteEncoder` | Bankable PB encoder | Medium |
|
||||||
|
| `Bankable::PBPotentiometer` | Bankable PB pot | Medium |
|
||||||
|
| `Bankable::PCButton` | Bankable program change button | Medium |
|
||||||
|
| `Bankable::NoteButtonLatched` | Bankable latched note | Low |
|
||||||
|
| `Bankable::NoteButtonLatching` | Bankable latching note | Low |
|
||||||
|
| `Bankable::CCButtonLatched` | Bankable latched CC | Low |
|
||||||
|
| `Bankable::CCButtonLatching` | Bankable latching CC | Low |
|
||||||
|
| `Bankable::NoteButtons` | Bankable note button array | Low |
|
||||||
|
| `Bankable::CCButtons` | Bankable CC button array | Low |
|
||||||
|
| `Bankable::NoteButtonMatrix` | Bankable note matrix | Low |
|
||||||
|
| `Bankable::CCButtonMatrix` | Bankable CC matrix | Low |
|
||||||
|
| `Bankable::NoteChordButton` | Bankable chord button | Low |
|
||||||
|
| `Bankable::CCIncrementDecrementButtons` | Bankable inc/dec | Low |
|
||||||
|
| `Bankable::CCSmartPotentiometer` | Smart pot (avoids bank-switch jumps) | Medium |
|
||||||
|
| `Bankable::PBSmartPotentiometer` | Smart PB pot | Medium |
|
||||||
|
|
||||||
|
### Bankable ManyAddresses Output Elements
|
||||||
|
|
||||||
|
Per-bank explicit address lists (alternative to offset-based banking).
|
||||||
|
|
||||||
|
| Class | Original |
|
||||||
|
|-------|----------|
|
||||||
|
| `Bankable::ManyAddresses::NoteButton` | Per-bank note addresses |
|
||||||
|
| `Bankable::ManyAddresses::CCButton` | Per-bank CC addresses |
|
||||||
|
| `Bankable::ManyAddresses::CCPotentiometer` | Per-bank CC pot addresses |
|
||||||
|
| `Bankable::ManyAddresses::CCRotaryEncoder` | Per-bank CC encoder addresses |
|
||||||
|
| `Bankable::ManyAddresses::CCAbsoluteEncoder` | Per-bank absolute encoder addresses |
|
||||||
|
| `Bankable::ManyAddresses::PBAbsoluteEncoder` | Per-bank PB encoder addresses |
|
||||||
|
| `Bankable::ManyAddresses::PBPotentiometer` | Per-bank PB pot addresses |
|
||||||
|
| `Bankable::ManyAddresses::PCButton` | Per-bank PC addresses |
|
||||||
|
| `Bankable::ManyAddresses::NoteButtonMatrix` | Per-bank note matrix |
|
||||||
|
| `Bankable::ManyAddresses::CCButtonMatrix` | Per-bank CC matrix |
|
||||||
|
| `Bankable::ManyAddresses::CCIncrementDecrementButtons` | Per-bank inc/dec |
|
||||||
|
|
||||||
|
### MCU (Mackie Control Universal)
|
||||||
|
|
||||||
|
Full Mackie Control protocol support — VU meters, V-Pots, LCD, time display, etc.
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `MCU::VU` | VU meter input element |
|
||||||
|
| `MCU::VULEDs` | VU meter with LED output |
|
||||||
|
| `MCU::VPotRing` | V-Pot ring value reader |
|
||||||
|
| `MCU::VPotRingLEDs` | V-Pot ring with LED output |
|
||||||
|
| `MCU::LCD` | 112-char LCD display reader |
|
||||||
|
| `MCU::SevenSegmentDisplay` | 7-segment display driver |
|
||||||
|
| `MCU::TimeDisplay` | Time code display |
|
||||||
|
| `MCU::AssignmentDisplay` | Assignment display |
|
||||||
|
| `MCU::Bankable::VU` | Bankable VU meter |
|
||||||
|
| `MCU::Bankable::VULEDs` | Bankable VU with LEDs |
|
||||||
|
| `MCU::Bankable::VPotRing` | Bankable V-Pot ring |
|
||||||
|
| `MCU::Bankable::VPotRingLEDs` | Bankable V-Pot ring with LEDs |
|
||||||
|
|
||||||
|
### USB MIDI
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `USBMIDI_Interface` | USB MIDI device interface |
|
||||||
|
| `USBHostMIDI_Interface` | USB Host MIDI interface |
|
||||||
|
| `GenericUSBMIDI_Interface` | Configurable USB MIDI backend |
|
||||||
|
| `USBDebugMIDI_Interface` | Serial monitor debug output |
|
||||||
|
|
||||||
|
### Serial MIDI
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `HardwareSerialMIDI_Interface` | 5-pin DIN MIDI over UART |
|
||||||
|
| `SoftwareSerialMIDI_Interface` | Software serial MIDI |
|
||||||
|
| `HairlessMIDI_Interface` | Hairless MIDI serial bridge |
|
||||||
|
|
||||||
|
### LED Bars and PWM
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `NoteCCKPLEDBar` | LED bar graph driven by MIDI |
|
||||||
|
| `NoteCCKPLEDPWM` | PWM LED brightness by velocity |
|
||||||
|
| `Bankable::NoteCCKPLEDBar` | Bankable LED bar |
|
||||||
|
| `Bankable::NoteCCKPLEDPWM` | Bankable PWM LED |
|
||||||
|
|
||||||
|
### FastLED (Addressable LEDs)
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `NoteCCKPRangeFastLED` | Addressable LED strip driven by MIDI |
|
||||||
|
| `Bankable::NoteCCKPRangeFastLED` | Bankable variant |
|
||||||
|
|
||||||
|
### Extended I/O Hardware
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `AH::AnalogMultiplex` | CD74HC4067 / CD74HC4051 multiplexer |
|
||||||
|
| `AH::ShiftRegisterOut` | 74HC595 shift register output |
|
||||||
|
| `AH::SPIShiftRegisterOut` | SPI-based shift register |
|
||||||
|
| `AH::ShiftRegisterOutRGB` | RGB LED shift register |
|
||||||
|
| `AH::MAX7219` | MAX7219 LED driver |
|
||||||
|
| `AH::MAX7219SevenSegmentDisplay` | MAX7219 7-segment display |
|
||||||
|
| `AH::LEDs` | Array of simple LEDs |
|
||||||
|
| `AH::DotBarDisplayLEDs` | Dot/bar mode LED array |
|
||||||
|
| `AH::MultiPurposeButton` | Long press / double press detection |
|
||||||
|
| `AH::RegisterEncoders` | Multiple encoders via registers |
|
||||||
|
|
||||||
|
### Display
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `DisplayElement` | Base for on-screen elements |
|
||||||
|
| `DisplayInterface` | Abstract display driver |
|
||||||
|
| `SSD1306_DisplayInterface` | SSD1306 OLED driver |
|
||||||
|
| `BitmapDisplay` | Bitmap rendering on display |
|
||||||
|
|
||||||
|
### Audio
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `AudioVU` | Audio level analysis |
|
||||||
|
| `AudioVULEDs` | Audio VU with LED output |
|
||||||
|
| `VolumeControl` | Audio volume knob |
|
||||||
|
|
||||||
|
### Motor Fader
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `MotorFader` | Motorized fader with touch sense |
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# NoteButton
|
||||||
|
|
||||||
|
Sends Note On/Off on button press/release.
|
||||||
|
|
||||||
|
> Original: `NoteButton.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButton button {
|
||||||
|
5, // push button on GPIO 5
|
||||||
|
{MIDI_Notes::C[4], Channel_1}, // note C4, channel 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# CCButton
|
||||||
|
|
||||||
|
Sends CC 127 on press, CC 0 on release.
|
||||||
|
|
||||||
|
> Original: `CCButton.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCButton button {
|
||||||
|
5,
|
||||||
|
{MIDI_CC::General_Purpose_Controller_1, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# PCButton
|
||||||
|
|
||||||
|
Sends Program Change on button press.
|
||||||
|
|
||||||
|
> Original: `PCButton.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
PCButton pcBtn {
|
||||||
|
2,
|
||||||
|
{MIDI_PC::Steel_Drums, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# NoteChordButton
|
||||||
|
|
||||||
|
Plays a chord on button press.
|
||||||
|
|
||||||
|
> Original: `NoteChordButton.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
constexpr Channel channel = Channel_1;
|
||||||
|
|
||||||
|
NoteChordButton buttons[] {
|
||||||
|
{2, {MIDI_Notes::C[4], channel}, Bass::Double + Chords::Major},
|
||||||
|
{3, {MIDI_Notes::D[4], channel}, Bass::Double + Chords::Minor},
|
||||||
|
{4, {MIDI_Notes::E[4], channel}, Bass::Double + Chords::Minor},
|
||||||
|
{5, {MIDI_Notes::F[4], channel}, Bass::Double + Chords::MajorFirstInv},
|
||||||
|
{6, {MIDI_Notes::G[4], channel}, Bass::Double + Chords::MajorSecondInv},
|
||||||
|
{7, {MIDI_Notes::A[4], channel}, Bass::Double + Chords::MinorSecondInv},
|
||||||
|
{8, {MIDI_Notes::B[4], channel}, Bass::Double + Chords::Diminished},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# NoteButtonLatched
|
||||||
|
|
||||||
|
First press sends Note On, second press sends Note Off.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButtonLatched button {
|
||||||
|
5,
|
||||||
|
{MIDI_Notes::C[4], Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# NoteButtonLatching
|
||||||
|
|
||||||
|
Note On while held, Note Off on release; toggles state.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButtonLatching button {
|
||||||
|
5,
|
||||||
|
{MIDI_Notes::C[4], Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# NoteButtons
|
||||||
|
|
||||||
|
Multiple note buttons with sequential addresses.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButtons<4> buttons {
|
||||||
|
{2, 3, 4, 5}, // GPIO pins
|
||||||
|
{MIDI_Notes::C[4], Channel_1}, // base address
|
||||||
|
1, // increment between addresses
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
# NoteButtonMatrix
|
||||||
|
|
||||||
|
Grid of note buttons using row/column scanning.
|
||||||
|
|
||||||
|
> Original: `NoteButtonMatrix.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButtonMatrix<2, 3> matrix {
|
||||||
|
{0, 1}, // row pins
|
||||||
|
{2, 3, 4}, // column pins
|
||||||
|
{{
|
||||||
|
{MIDI_Notes::C[4], MIDI_Notes::D[4], MIDI_Notes::E[4]},
|
||||||
|
{MIDI_Notes::F[4], MIDI_Notes::G[4], MIDI_Notes::A[4]},
|
||||||
|
}},
|
||||||
|
Channel_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# CCButtonLatched
|
||||||
|
|
||||||
|
First press sends CC 127, second press sends CC 0.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCButtonLatched button {
|
||||||
|
5,
|
||||||
|
{MIDI_CC::General_Purpose_Controller_1, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# CCButtonLatching
|
||||||
|
|
||||||
|
CC 127 while held, CC 0 on release; toggles state.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCButtonLatching button {
|
||||||
|
5,
|
||||||
|
{MIDI_CC::General_Purpose_Controller_1, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# CCButtons
|
||||||
|
|
||||||
|
Multiple CC buttons with sequential addresses.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCButtons<4> buttons {
|
||||||
|
{2, 3, 4, 5},
|
||||||
|
{MIDI_CC::General_Purpose_Controller_1, Channel_1},
|
||||||
|
1,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# CCButtonMatrix
|
||||||
|
|
||||||
|
Grid of CC buttons using row/column scanning.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCButtonMatrix<2, 3> matrix {
|
||||||
|
{0, 1}, // row pins
|
||||||
|
{2, 3, 4}, // column pins
|
||||||
|
{{
|
||||||
|
{16, 17, 18},
|
||||||
|
{19, 20, 21},
|
||||||
|
}},
|
||||||
|
Channel_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# CCPotentiometer
|
||||||
|
|
||||||
|
Analog input mapped to CC value 0-127.
|
||||||
|
|
||||||
|
> Original: `Control-Change-Potentiometer.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCPotentiometer pot {
|
||||||
|
26, // ADC pin (GPIO 26 = ADC0)
|
||||||
|
{MIDI_CC::Channel_Volume, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# PBPotentiometer
|
||||||
|
|
||||||
|
Analog input mapped to 14-bit Pitch Bend.
|
||||||
|
|
||||||
|
> Original: `Pitch-Bend-Potentiometer.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
PBPotentiometer pot {
|
||||||
|
26, // ADC pin
|
||||||
|
Channel_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# CCRotaryEncoder
|
||||||
|
|
||||||
|
Relative CC encoder for DAW parameter control.
|
||||||
|
|
||||||
|
> Original: `RotaryEncoder.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCRotaryEncoder enc {
|
||||||
|
{0, 2}, // encoder pins A and B (constructs AHEncoder)
|
||||||
|
{16, Channel_1}, // CC address
|
||||||
|
1, // speed multiplier
|
||||||
|
4, // pulses per step
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE);
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
# CCAbsoluteEncoder
|
||||||
|
|
||||||
|
Encoder position mapped to absolute CC value.
|
||||||
|
|
||||||
|
> Original: `AbsoluteRotaryEncoder.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCAbsoluteEncoder enc {
|
||||||
|
{0, 2}, // encoder pins
|
||||||
|
MIDI_CC::Pan, // CC address
|
||||||
|
1, // speed multiplier
|
||||||
|
4, // pulses per step
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# PBAbsoluteEncoder
|
||||||
|
|
||||||
|
Encoder position mapped to 14-bit Pitch Bend.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
PBAbsoluteEncoder enc {
|
||||||
|
{0, 2}, // encoder pins
|
||||||
|
Channel_1,
|
||||||
|
127, // large multiplier for PB's 14-bit range
|
||||||
|
4, // pulses per step
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# CCIncrementDecrementButtons
|
||||||
|
|
||||||
|
Two buttons for CC increment/decrement with optional reset.
|
||||||
|
|
||||||
|
> Original: `CCIncrementDecrementButtons.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCIncrementDecrementButtons buttons {
|
||||||
|
{5, 6}, // increment pin, decrement pin
|
||||||
|
{16, Channel_1}, // CC address
|
||||||
|
1, // multiplier
|
||||||
|
{0x45, Channel_1}, // reset note (sent when both pressed)
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE);
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
# ProgramChanger
|
||||||
|
|
||||||
|
Sends different program changes based on selector state.
|
||||||
|
|
||||||
|
> Original: `Program-Changer.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
ProgramChanger<4> programChanger {
|
||||||
|
{{
|
||||||
|
MIDI_PC::Acoustic_Grand_Piano,
|
||||||
|
MIDI_PC::Rock_Organ,
|
||||||
|
MIDI_PC::Steel_Drums,
|
||||||
|
MIDI_PC::Pad_2,
|
||||||
|
}},
|
||||||
|
Channel_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
IncrementDecrementSelector<4> selector {
|
||||||
|
programChanger,
|
||||||
|
{2, 3},
|
||||||
|
Wrap::Wrap,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Multiple CCPotentiometers
|
||||||
|
|
||||||
|
Several analog inputs mapped to CC on different channels.
|
||||||
|
|
||||||
|
> Original: `Multiple-Control-Change-Potentiometers.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCPotentiometer pots[] {
|
||||||
|
{26, {MIDI_CC::Channel_Volume, Channel_1}},
|
||||||
|
{27, {MIDI_CC::Channel_Volume, Channel_2}},
|
||||||
|
{28, {MIDI_CC::Channel_Volume, Channel_3}},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
# BorrowedCCRotaryEncoder
|
||||||
|
|
||||||
|
Shared encoder reference for CC output, allowing multiple elements to read the same physical encoder.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
AHEncoder encoder {0, 2};
|
||||||
|
|
||||||
|
BorrowedCCRotaryEncoder enc {
|
||||||
|
encoder,
|
||||||
|
{16, Channel_1},
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# MIDI Output Elements
|
||||||
|
|
||||||
|
Output elements read physical controls (buttons, potentiometers, encoders) and send MIDI messages.
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# NoteLED
|
||||||
|
|
||||||
|
LED responds to incoming Note On/Off messages.
|
||||||
|
|
||||||
|
> Original: `1.Note-LED.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteLED led {
|
||||||
|
13, // LED pin
|
||||||
|
{MIDI_Notes::C[4], Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
# NoteRangeLEDs
|
||||||
|
|
||||||
|
Multiple LEDs respond to a range of incoming notes.
|
||||||
|
|
||||||
|
> Original: `2.Note-Range-LEDs.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteLED leds[] {
|
||||||
|
{2, {MIDI_Notes::C[4], Channel_1}},
|
||||||
|
{3, {MIDI_Notes::D[4], Channel_1}},
|
||||||
|
{4, {MIDI_Notes::E[4], Channel_1}},
|
||||||
|
{5, {MIDI_Notes::F[4], Channel_1}},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# CCValue
|
||||||
|
|
||||||
|
Reads incoming CC messages and stores the value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCValue ccVal {
|
||||||
|
{MIDI_CC::Channel_Volume, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = ccVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# PBValue
|
||||||
|
|
||||||
|
Reads incoming Pitch Bend messages (14-bit).
|
||||||
|
|
||||||
|
> Original: `Pitch-Bend-Value.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
PBValue pbVal {Channel_1};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint16_t val = pbVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# NoteValue
|
||||||
|
|
||||||
|
Reads incoming Note On values (8-bit).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteValue noteVal {{MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = noteVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# KPValue
|
||||||
|
|
||||||
|
Reads incoming Key Pressure (aftertouch) values.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
KPValue kpVal {{MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = kpVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# CCLED
|
||||||
|
|
||||||
|
LED responds to incoming CC messages.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCLED led {
|
||||||
|
13,
|
||||||
|
{MIDI_CC::General_Purpose_Controller_1, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# NoteRange
|
||||||
|
|
||||||
|
Reads a contiguous range of incoming Note values.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteRange<4> noteRange {{MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
uint8_t val = noteRange.getValue(i);
|
||||||
|
(void)val;
|
||||||
|
}
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# CCRange
|
||||||
|
|
||||||
|
Reads a contiguous range of incoming CC values.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCRange<8> ccRange {{MIDI_CC::General_Purpose_Controller_1, Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
uint8_t val = ccRange.getValue(i);
|
||||||
|
(void)val;
|
||||||
|
}
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# MIDI Input Elements
|
||||||
|
|
||||||
|
Input elements receive MIDI messages and drive outputs (LEDs, stored values).
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# BLE MIDI
|
||||||
|
|
||||||
|
Basic Bluetooth Low Energy MIDI interface setup. Replaces `USBMIDI_Interface` from the original library.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButton button {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
CCRotaryEncoder enc {{0, 2}, {16, Channel_1}, 1, 4};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# MIDI Pipes
|
||||||
|
|
||||||
|
Routing between MIDI interfaces using pipe operators.
|
||||||
|
|
||||||
|
> Original: `MIDI_Pipes-Routing.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface ble;
|
||||||
|
|
||||||
|
NoteButton button {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# MIDI Interfaces
|
||||||
|
|
||||||
|
Interface setup and routing between MIDI transports.
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Bank with CC Values
|
||||||
|
|
||||||
|
Bank switching with bankable input elements. Bank switching changes the CC address listened to.
|
||||||
|
|
||||||
|
> Original: `Bank.ino` (adapted)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
// 4 banks, 2 tracks per bank
|
||||||
|
Bank<4> bank(2);
|
||||||
|
|
||||||
|
// Selector: two buttons to increment/decrement the active bank
|
||||||
|
IncrementDecrementSelector<4> selector {
|
||||||
|
bank,
|
||||||
|
{2, 3},
|
||||||
|
Wrap::Wrap,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bankable CC value readers — bank switching changes the CC address.
|
||||||
|
// Bank 1: reads CC 16, CC 17
|
||||||
|
// Bank 2: reads CC 18, CC 19
|
||||||
|
// Bank 3: reads CC 20, CC 21
|
||||||
|
// Bank 4: reads CC 22, CC 23
|
||||||
|
Bankable::CCValue<4> ccVal1 {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{16, Channel_1},
|
||||||
|
};
|
||||||
|
Bankable::CCValue<4> ccVal2 {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{17, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t v1 = ccVal1.getValue();
|
||||||
|
uint8_t v2 = ccVal2.getValue();
|
||||||
|
(void)v1;
|
||||||
|
(void)v2;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Transposer
|
||||||
|
|
||||||
|
Note transposition via increment/decrement buttons.
|
||||||
|
|
||||||
|
> Original: `Transposer.ino`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Transposer<-12, +12> transposer;
|
||||||
|
|
||||||
|
NoteButton button {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
|
||||||
|
IncrementDecrementSelector<25> selector {
|
||||||
|
transposer,
|
||||||
|
{2, 3},
|
||||||
|
Wrap::Clamp,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
# EncoderSelector
|
||||||
|
|
||||||
|
Bank selection via rotary encoder.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Bank<4> bank(2);
|
||||||
|
|
||||||
|
Bankable::CCValue<4> ccVal {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{16, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
EncoderSelector<4> selector {
|
||||||
|
bank,
|
||||||
|
{0, 2},
|
||||||
|
4,
|
||||||
|
Wrap::Wrap,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = ccVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# ManyButtonsSelector
|
||||||
|
|
||||||
|
One button per bank for direct bank selection.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Bank<4> bank(2);
|
||||||
|
|
||||||
|
Bankable::CCValue<4> ccVal {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{16, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
ManyButtonsSelector<4> selector {
|
||||||
|
bank,
|
||||||
|
{2, 3, 4, 5},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = ccVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# SwitchSelector
|
||||||
|
|
||||||
|
Two-state bank selection from a toggle switch.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Bank<2> bank(1);
|
||||||
|
|
||||||
|
Bankable::CCValue<2> ccVal {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{16, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
SwitchSelector selector {
|
||||||
|
bank,
|
||||||
|
5,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = ccVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# ProgramChangeSelector
|
||||||
|
|
||||||
|
Bank selection triggered by incoming MIDI Program Change messages.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Bank<8> bank(1);
|
||||||
|
|
||||||
|
Bankable::CCValue<8> ccVal {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
{16, Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
ProgramChangeSelector<8> selector {
|
||||||
|
bank,
|
||||||
|
{Channel_1, Cable_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
uint8_t val = ccVal.getValue();
|
||||||
|
(void)val;
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Bankable NoteLED
|
||||||
|
|
||||||
|
Bank-switched LED responds to different notes per bank.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
Bank<4> bank(1);
|
||||||
|
|
||||||
|
IncrementDecrementSelector<4> selector {
|
||||||
|
bank,
|
||||||
|
{2, 3},
|
||||||
|
Wrap::Wrap,
|
||||||
|
};
|
||||||
|
|
||||||
|
Bankable::NoteLED<4> led {
|
||||||
|
{bank, BankType::ChangeAddress},
|
||||||
|
13,
|
||||||
|
{MIDI_Notes::C[4], Channel_1},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Banks and Selectors
|
||||||
|
|
||||||
|
Bank switching allows a single physical control to address multiple MIDI parameters.
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
Each example is a 1:1 adaptation of the corresponding [Control Surface example](https://tttapa.github.io/Control-Surface/Doxygen/d4/de9/examples.html), rewritten for pico-sdk conventions. All examples are compile-verified.
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
# cs-midi Roadmap
|
||||||
|
|
||||||
|
Extraction status of [tttapa/Control-Surface](https://github.com/tttapa/Control-Surface) (GPL-3.0) into cs-midi for pico-sdk + BTstack.
|
||||||
|
|
||||||
|
## Implemented
|
||||||
|
|
||||||
|
### MIDI Output Elements
|
||||||
|
- [x] `NoteButton` — momentary note on/off
|
||||||
|
- [x] `NoteButtons<N>` — multiple sequential note buttons
|
||||||
|
- [x] `NoteButtonLatched` — toggle note on first press, off second
|
||||||
|
- [x] `NoteButtonLatching` — note on while held, toggles state
|
||||||
|
- [x] `NoteButtonMatrix<R,C>` — row/column scanned note grid
|
||||||
|
- [x] `NoteChordButton` — plays chord on press
|
||||||
|
- [x] `CCButton` — momentary CC 127/0
|
||||||
|
- [x] `CCButtons<N>` — multiple sequential CC buttons
|
||||||
|
- [x] `CCButtonLatched` — toggle CC
|
||||||
|
- [x] `CCButtonLatching` — latching CC
|
||||||
|
- [x] `CCButtonMatrix<R,C>` — row/column scanned CC grid
|
||||||
|
- [x] `CCPotentiometer` — analog input to CC 0-127
|
||||||
|
- [x] `PBPotentiometer` — analog input to 14-bit Pitch Bend
|
||||||
|
- [x] `CCRotaryEncoder` — relative CC encoder
|
||||||
|
- [x] `CCAbsoluteEncoder` — absolute CC encoder
|
||||||
|
- [x] `PBAbsoluteEncoder` — absolute Pitch Bend encoder
|
||||||
|
- [x] `CCIncrementDecrementButtons` — inc/dec CC with reset
|
||||||
|
- [x] `PCButton` — Program Change on press
|
||||||
|
- [x] `ProgramChanger<N>` — bank-selectable program changes
|
||||||
|
|
||||||
|
### MIDI Input Elements
|
||||||
|
- [x] `NoteValue` / `CCValue` / `KPValue` — 8-bit value readers
|
||||||
|
- [x] `PBValue` — 14-bit Pitch Bend reader
|
||||||
|
- [x] `NoteRange<N>` / `CCRange<N>` / `KPRange<N>` — range readers
|
||||||
|
- [x] `NoteLED` / `CCLED` / `KPLED` — LED output from MIDI input
|
||||||
|
- [x] All bankable variants (`Bankable::NoteValue<N>`, etc.)
|
||||||
|
|
||||||
|
### Banks & Selectors
|
||||||
|
- [x] `Bank<N>` — groups bankable elements, manages bank switching
|
||||||
|
- [x] `Transposer<Min,Max>` — specialized bank for note transposition
|
||||||
|
- [x] `EncoderSelector<N>` — rotary encoder bank selection
|
||||||
|
- [x] `IncrementDecrementSelector<N>` — two-button bank selection
|
||||||
|
- [x] `IncrementSelector<N>` — single-button wrapping selector
|
||||||
|
- [x] `ManyButtonsSelector<N>` — direct bank selection per button
|
||||||
|
- [x] `SwitchSelector` — two-state toggle selector
|
||||||
|
- [x] `ProgramChangeSelector<N>` — MIDI-driven bank selection
|
||||||
|
|
||||||
|
### MIDI Interfaces
|
||||||
|
- [x] `BluetoothMIDI_Interface` — BLE MIDI via BTstack (pico-native)
|
||||||
|
- [x] `MIDI_Pipe` / `MIDI_PipeFactory<N>` / `BidirectionalMIDI_PipeFactory<N>`
|
||||||
|
- [x] `Control_Surface` singleton — declarative begin/loop lifecycle
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
- [x] `AHEncoder` — pico-native interrupt-driven rotary encoder
|
||||||
|
- [x] `ExtendedInputOutput` — GPIO abstraction (direct pins)
|
||||||
|
- [x] MIDI constants (notes, CC numbers, PC programs, chords/intervals)
|
||||||
|
- [x] Platform shim (`pico_shim.h`) — replaces Arduino runtime
|
||||||
|
|
||||||
|
## Not Yet Implemented
|
||||||
|
|
||||||
|
### Bankable Output Elements
|
||||||
|
- [ ] `Bankable::NoteButton` / `Bankable::CCButton` / etc.
|
||||||
|
- [ ] `Bankable::CCPotentiometer` / `Bankable::PBPotentiometer`
|
||||||
|
- [ ] `Bankable::CCRotaryEncoder` / `Bankable::CCAbsoluteEncoder`
|
||||||
|
- [ ] `Bankable::NoteChordButton` (with Transposer)
|
||||||
|
- [ ] `Bankable::NoteButtonMatrix` / `Bankable::CCButtonMatrix`
|
||||||
|
|
||||||
|
*Blocked Phase 11 of the extraction. Required for Bank.ino and Transposer.ino
|
||||||
|
output-side examples.*
|
||||||
|
|
||||||
|
### Additional MIDI Interfaces
|
||||||
|
- [ ] USB MIDI Interface (TinyUSB)
|
||||||
|
- [ ] Serial/Hardware MIDI Interface
|
||||||
|
- [ ] Debug MIDI Interface (serial monitor output)
|
||||||
|
|
||||||
|
### Display Elements
|
||||||
|
- [ ] OLED display support
|
||||||
|
- [ ] VU meter elements
|
||||||
|
- [ ] NoteLEDBar
|
||||||
|
|
||||||
|
### Hardware Expansion
|
||||||
|
- [ ] MCP23017 I2C I/O expander
|
||||||
|
- [ ] MAX7219 LED driver
|
||||||
|
- [ ] Shift register chains (74HC595, etc.)
|
||||||
|
- [ ] FastLED / NeoPixel integration
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
- [ ] MIDI input fine-grained callbacks (per-message-type)
|
||||||
|
- [ ] SysEx send/receive helpers
|
||||||
|
- [ ] AppleMIDI (RTP-MIDI over WiFi)
|
||||||
Loading…
Reference in New Issue