|
Operator SDK
Build MIDI processing and UI modes for the Operator device
|
The mock device a mode is tested against on a host machine. More...
Functions | |
| const OperatorApi * | get_api () |
| The mock OperatorApi, ready to hand to a mode's init. | |
| void | reset_state () |
| Put the device back to how it starts: the clock at zero, the queues and the framebuffer empty, every param zero, no seeded files. | |
| void | apply_param_defaults (const ::op::modes::ParamSpec *specs, std::uint8_t count) |
| Seed the params with the defaults a mode declares, the way the device does before it starts one. | |
| void | advance_tick (std::uint32_t microseconds) |
| Move the virtual clock forward, in microseconds. | |
| void | set_pulse_count (std::uint32_t pulse) |
| Set what api->get_pulse_count() reads. | |
| void | set_beat_position (float beat) |
| Set the pulse count in beats. | |
| void | set_clock_state (std::uint8_t state) |
| Set what api->get_clock_state() reads. | |
| std::uint32_t | get_last_clock_period_us () |
| Read the period a mode last asked for with api->set_clock_period_us(). | |
| void | set_output_active (std::uint8_t output_index, bool active) |
| Take one output away, so a mode meets an output that is not there. | |
| std::uint16_t | drain_outgoing_midi (std::uint8_t output_index, OpMidiMessage *out, std::uint16_t max_messages) |
| Read back the MIDI a mode sent to one output, up to max_messages of it, and empty the queue. | |
| void | capture_framebuffer (std::uint8_t out[kFramebufferBytes]) |
| Copy the framebuffer out, as it stands after every draw a mode has made since the last reset_state(). | |
| void | seed_extras_file (const char *mode_name, const char *filename, const std::uint8_t *data, std::uint32_t size) |
| Put a file where a mode will find it, at /extras/<mode name>/<filename>. | |
| void | pick_filename (std::uint8_t param_id, const char *filename) |
| Pick a file for a FilePicker param, as a player would on the device. | |
| void | set_current_mode_name (const char *mode_name) |
| Name the mode, which is what scopes its storage to /extras/<mode name>/. | |
Variables | |
| constexpr std::size_t | kFramebufferBytes = 1024 |
| The size of the framebuffer, so a capture buffer can be stack-allocated. | |
The mock device a mode is tested against on a host machine.
| void op::sim::advance_tick | ( | std::uint32_t | microseconds | ) |
Move the virtual clock forward, in microseconds.
api->get_tick() reads the total. It only ever moves forward.
| void op::sim::apply_param_defaults | ( | const ::op::modes::ParamSpec * | specs, |
| std::uint8_t | count ) |
Seed the params with the defaults a mode declares, the way the device does before it starts one.
reset_state() zeroes the params, because the harness holds no table of its own. A mode whose first read expects its declared default (a Numeric that starts at 64, an Enum that starts on its second option) needs this, called after reset_state() and before mode_init.
Slots are walked the way the device walks them, so what is seeded lines up with what get_param_value(slot) reads back. A Section holds no value and takes no slot. A Range or NoteRange takes two, seeded low then high, so the pair starts as a valid range.
| void op::sim::capture_framebuffer | ( | std::uint8_t | out[kFramebufferBytes] | ) |
Copy the framebuffer out, as it stands after every draw a mode has made since the last reset_state().
The layout is the device's: byte page * 128 + column, lowest bit at the top row.
| std::uint16_t op::sim::drain_outgoing_midi | ( | std::uint8_t | output_index, |
| OpMidiMessage * | out, | ||
| std::uint16_t | max_messages ) |
Read back the MIDI a mode sent to one output, up to max_messages of it, and empty the queue.
Returns how many messages were written into out.
| const OperatorApi * op::sim::get_api | ( | ) |
The mock OperatorApi, ready to hand to a mode's init.
The pointer is stable for the life of the process and survives reset_state(), so a fixture can hold on to it.
| std::uint32_t op::sim::get_last_clock_period_us | ( | ) |
Read the period a mode last asked for with api->set_clock_period_us().
This is how a clock-generating mode is checked: at 120 BPM it should ask for 20833 microseconds. Reads 0 until a mode asks for something, as on the device.
| void op::sim::pick_filename | ( | std::uint8_t | param_id, |
| const char * | filename ) |
Pick a file for a FilePicker param, as a player would on the device.
Storage is read-only and a mode never lists a directory, so a FilePicker mode is stood up with both halves: seed_extras_file puts the contents in place, and this says which file was picked. Call it after mode_init and before the first mode_process, so the mode's first read sees it. A null or empty filename clears the slot back to empty.
| void op::sim::reset_state | ( | ) |
Put the device back to how it starts: the clock at zero, the queues and the framebuffer empty, every param zero, no seeded files.
Call this at the top of every test. The tick starts at zero, so a mode that seeds a random sequence from it runs the same way every time.
| void op::sim::seed_extras_file | ( | const char * | mode_name, |
| const char * | filename, | ||
| const std::uint8_t * | data, | ||
| std::uint32_t | size ) |
Put a file where a mode will find it, at /extras/<mode name>/<filename>.
Seeding the same file twice overwrites it.
| void op::sim::set_beat_position | ( | float | beat | ) |
Set the pulse count in beats.
A beat is 24 pulses, so a beat of 2.5 is a pulse count of 60.
| void op::sim::set_clock_state | ( | std::uint8_t | state | ) |
Set what api->get_clock_state() reads.
The value is a clock state: 0 for Active (a clock is running), 1 for NoClock (idle), or 2 for Mode (the clock source is a mode with no clock generator loaded).
| void op::sim::set_current_mode_name | ( | const char * | mode_name | ) |
Name the mode, which is what scopes its storage to /extras/<mode name>/.
Reads as "default" until it is set.
| void op::sim::set_output_active | ( | std::uint8_t | output_index, |
| bool | active ) |
Take one output away, so a mode meets an output that is not there.
Every output is present after reset_state().
| void op::sim::set_pulse_count | ( | std::uint32_t | pulse | ) |
Set what api->get_pulse_count() reads.
The pulse count is the timing a mode works from, at 24 pulses to the beat, and a mode finds the beat and the bar inside it by modulus.
|
constexpr |
The size of the framebuffer, so a capture buffer can be stack-allocated.
The display is 128 columns across 8 pages of 8 rows, one bit per pixel.