99 lines
4.0 KiB
C++
99 lines
4.0 KiB
C++
// intellectual property is bullshit bgdc
|
|
|
|
#ifndef SYSEX_HPP
|
|
#define SYSEX_HPP
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "midi.hpp"
|
|
|
|
// All sysex messages start with manuf id 7D (prototyping, test, private use,
|
|
// and experimentation).
|
|
//
|
|
//
|
|
// 7D 01 - storage commands
|
|
// 7D 02 - front panel controls
|
|
// 7D 7F - status codes
|
|
//
|
|
//
|
|
// -- Storage commands --
|
|
//
|
|
// Storage commands interface with the onboard storage (SD card). Large
|
|
// arguments are generally encoded using base64, while smaller arguments are
|
|
// generally ascii hex.
|
|
//
|
|
// 7D 01 01 cksum ... - data response message, base64
|
|
// 7D 01 02 AAAAAAAA - request SD block AAA... (hex, data sent via 7D 01 01)
|
|
// 7D 01 03 AAAAAAAA - open SD block AAA... for write (hex). If a
|
|
// write is ongoing, will return STATUS_BUSY.
|
|
// 7D 01 04 cksum ... - append data to the write buffer.
|
|
// 7D 01 05 - commit the in-progress write
|
|
// 7D 01 06 - cancel the in-progress write
|
|
//
|
|
// -- Status codes --
|
|
// 7D 7F 01 - general ACK
|
|
// 7D 7F 02 - message format error
|
|
//
|
|
//
|
|
// == Writing data to storage ==
|
|
//
|
|
// To write a sector to the storage card, the sector must be opened using
|
|
// MIDI_SYSEX_STORAGE_OPENWR. The argument is a 32-bit (hex encoded) sector
|
|
// number, in 512-byte sectors. Following this, MIDI_SYSEX_STORAGE_WRDATA is
|
|
// sent repeatedly to append data to the write buffer. This data is encoded
|
|
// using base64, and up to (MIDIX_SYSEX_LEN - 8) base64 characters representing
|
|
// 42 bytes of data (assuming MIDIX_SYSEX_LEN is 64) may be sent at once. If
|
|
// more than 512 bytes are sent, the extras are dropped; if fewer than 512
|
|
// bytes are sent, the sector is padded with undefined data. Once the write
|
|
// buffer is full, commit it with MIDI_SYSEX_STORAGE_COMMIT or cancel the
|
|
// write with MIDI_SYSEX_STORAGE_CANCEL. TODO: add a command to query this
|
|
// length limit
|
|
//
|
|
// No matter how many midi ports exist on the system, there is only one storage
|
|
// buffer, so you must expect to receive MIDI_SYSEX_STATUS_BUSY in response to
|
|
// OPENWR. In this case, poll with the same message to await completion. A user-
|
|
// confirmed hard cancel may be performed by sending MIDI_SYSEX_STORAGE_CANCEL
|
|
// (this can cancel the buffer regardless of which interface holds it).
|
|
//
|
|
// == Reading data from storage ==
|
|
//
|
|
// To read a sector from the storage card, send the sector number in the same
|
|
// format as for a write, using MIDI_SYSEX_STORAGE_READ. The data will be sent
|
|
// back in a series of MIDI_SYSEX_STORAGE_RESPONSE packets, followed by a
|
|
// MIDI_SYSEX_STATUS_ACK to acknowledge completion, or a MIDI_SYSEX_STATUS_IOERR
|
|
// at any point to terminate the process and report an error.
|
|
//
|
|
// == Storage checksums ==
|
|
//
|
|
// Both MIDI_SYSEX_STORAGE_RESPONSE and MIDI_SYSEX_STORAGE_WRDATA contain a
|
|
// checksum byte. This byte is simply the bit-inverted lower 7 bits of the sum
|
|
// of all data bytes in the message, prior to encoding as base64. If you send
|
|
// data and it is received with a bad checksum, a MIDI_SYSEX_STATUS_CKSUM will
|
|
// be sent back to you; you must cancel the write operation and retry it.
|
|
// If you receive a bad checksum, your recourse is to request it again.
|
|
|
|
#define MIDI_MANUF_ID 0x7D
|
|
|
|
#define MIDI_SYSEX_STORAGE_GRP 0x01
|
|
#define MIDI_SYSEX_STORAGE_RESPONSE 0x01
|
|
#define MIDI_SYSEX_STORAGE_READ 0x02
|
|
#define MIDI_SYSEX_STORAGE_OPENWR 0x03
|
|
#define MIDI_SYSEX_STORAGE_WRDATA 0x04
|
|
#define MIDI_SYSEX_STORAGE_COMMIT 0x05
|
|
#define MIDI_SYSEX_STORAGE_CANCEL 0x06
|
|
|
|
#define MIDI_SYSEX_STATUS_GRP 0x7F
|
|
#define MIDI_SYSEX_STATUS_ACK 0x01
|
|
#define MIDI_SYSEX_STATUS_FMT_ERR 0x02
|
|
#define MIDI_SYSEX_STATUS_UNKNOWN 0x03
|
|
#define MIDI_SYSEX_STATUS_BUSY 0x04
|
|
#define MIDI_SYSEX_STATUS_IOERR 0x05
|
|
#define MIDI_SYSEX_STATUS_CKSUM 0x06
|
|
|
|
// Handle a sysex message
|
|
void sysex_handle(struct midi_message const * msg);
|
|
|
|
#endif // !defined(SYSEX_HPP)
|