Operator SDK
Build MIDI processing and UI modes for the Operator device
Loading...
Searching...
No Matches
op::sdk::HeldNotes< Capacity, Payload > Class Template Reference

Remembers the notes a mode is sounding and the pitch each one went out on. More...

#include <held_notes.h>

Classes

struct  Entry
 One key that is down, and what the mode sounded for it. More...
struct  PressResult
 Whether press recorded the key, and whether the note should sound. More...
struct  ReleaseResult
 Whether release found the key, and whether the note should stop. More...

Public Member Functions

PressResult press (uint8_t port, uint8_t channel, uint8_t input_note, uint8_t output_note, Payload payload={})
 Record a key going down and report whether it should sound.
ReleaseResult release (uint8_t port, uint8_t channel, uint8_t input_note)
 Take a press back and report whether the note should stop.
const Entry * newest_on_channel (uint8_t channel) const
 The most recently pressed key still held on a channel, or null.
void clear ()
 Forget every held note.

Detailed Description

template<uint8_t Capacity = 64, typename Payload = NoNotePayload>
class op::sdk::HeldNotes< Capacity, Payload >

Remembers the notes a mode is sounding and the pitch each one went out on.

The key is the port, the channel and the incoming note number together. A global mode sees every input in one batch and each message carries the port it arrived on, so the port keeps a note held on one input distinct from the same note arriving on another.

Payload rides along with each entry and comes back untouched. A mode that recomputes everything from the pitch alone leaves it at NoNotePayload and keeps four-byte entries. A mode that has to reproduce something it derived at press time, a tuning offset for instance, names its own type here and gets it handed back on release.

Every member carries a default initializer, so an instance needs no constructor and is safe to declare at file scope.

Member Function Documentation

◆ clear()

template<uint8_t Capacity = 64, typename Payload = NoNotePayload>
void op::sdk::HeldNotes< Capacity, Payload >::clear ( )
inline

Forget every held note.

A mode calls this as it starts and as it stops, so each run begins with nothing held.

◆ newest_on_channel()

template<uint8_t Capacity = 64, typename Payload = NoNotePayload>
const Entry * op::sdk::HeldNotes< Capacity, Payload >::newest_on_channel ( uint8_t channel) const
inline

The most recently pressed key still held on a channel, or null.

The channel alone is the key here, with the port left out. A channel's pitch bend reaches every note sounding on it whichever input that note arrived from, so a mode restoring per-channel state wants all of them.

◆ press()

template<uint8_t Capacity = 64, typename Payload = NoNotePayload>
PressResult op::sdk::HeldNotes< Capacity, Payload >::press ( uint8_t port,
uint8_t channel,
uint8_t input_note,
uint8_t output_note,
Payload payload = {} )
inline

Record a key going down and report whether it should sound.

Parameters
portThe input the note arrived on.
channelThe MIDI channel nibble, 0 to 15.
input_noteThe note number the key sent.
output_noteThe note number the mode is about to emit.
payloadAnything the mode wants handed back when the key lifts.
Returns
first_holder true the first time an output note is claimed on this port and channel, which is the moment to emit the note-on.

A key already down keeps the entry it has and reports first_holder false, so the pitch its release carries stays the one that is sounding.

A press the registry has no room for reports tracked false and first_holder true, so the note still sounds. Its release comes back with found false, leaving the mode to work the pitch out from its current mapping. Only that one note goes without an entry, and nothing already on record is displaced to make room.

◆ release()

template<uint8_t Capacity = 64, typename Payload = NoNotePayload>
ReleaseResult op::sdk::HeldNotes< Capacity, Payload >::release ( uint8_t port,
uint8_t channel,
uint8_t input_note )
inline

Take a press back and report whether the note should stop.

Parameters
portThe input the note arrived on.
channelThe MIDI channel nibble, 0 to 15.
input_noteThe note number the key sent.
Returns
last_holder true when the release gives up the output note for good, which is the moment to emit the note-off on output_note.

The newest entry matching the key is the one removed, and the entries left keep the order they were pressed in.


The documentation for this class was generated from the following file: