forked from trash80/mGB
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow loading custom waveforms via sysex
- Loading branch information
Showing
13 changed files
with
303 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#include "midi_sysex.h" | ||
#include "../mGB.h" | ||
|
||
uint8_t sysexBytesCount; | ||
sysex_payload_t sysexPayload; | ||
uint8_t sysexBuffer[24]; | ||
|
||
// adapted from | ||
// https://github.com/FortySevenEffects/arduino_midi_library/blob/2d64cc3c2ff85bbee654a7054e36c59694d8d8e4/src/MIDI.cpp#L87 | ||
// (MIT licensed) | ||
// Reduced parameter count to improve perf | ||
|
||
/*! | ||
\brief Decode System Exclusive messages. | ||
SysEx messages are encoded to guarantee transmission of data bytes higher | ||
than 127 without breaking the MIDI protocol. Use this static method to | ||
reassemble your received message. | ||
\param outData The output buffer where to | ||
store the decrypted message. | ||
\param inLength The length of the input | ||
buffer. | ||
\return The length of the output buffer. | ||
@see encodeSysEx @see getSysExArrayLength | ||
Code inspired from Ruin & Wesen's SysEx encoder/decoder - http://ruinwesen.com | ||
*/ | ||
static uint8_t decodeSysEx(uint8_t *outData, uint8_t inLength) { | ||
uint8_t count = 0; | ||
uint8_t msbStorage = 0; | ||
uint8_t byteIndex = 0; | ||
|
||
for (uint8_t i = 0; i < inLength; ++i) { | ||
if ((i % 8) == 0) { | ||
msbStorage = sysexBuffer[i]; | ||
byteIndex = 6; | ||
} else { | ||
const uint8_t body = sysexBuffer[i]; | ||
const uint8_t msb = (((msbStorage >> byteIndex) & 1) << 7); | ||
byteIndex--; | ||
outData[count++] = msb | body; | ||
} | ||
} | ||
return count; | ||
} | ||
|
||
void captureSysexByte(uint8_t byte) { | ||
sysexBytesCount++; | ||
systemIdle = false; | ||
|
||
const uint8_t bufferIndex = sysexBytesCount - SYSEX_HEADER_SIZE; | ||
|
||
if (byte == SYSEX_EOF) { | ||
// EMU_printf("sysex EOF: %#02x\n", byte); | ||
sysexPayload.size = decodeSysEx(&sysexPayload.data[0], bufferIndex); | ||
sysexPayload.ready = true; | ||
sysexBytesCount = 0; | ||
return; | ||
} | ||
|
||
switch (sysexBytesCount) { | ||
case 1: | ||
// EMU_printf("sysex status byte: %#02x\n", byte); | ||
// ignored in payload | ||
break; | ||
case 2: | ||
// EMU_printf("sysex id: %#02x\n", byte); | ||
sysexPayload.id = byte; | ||
break; | ||
case 3: | ||
// EMU_printf("sysex device_id: %#02x\n", byte); | ||
sysexPayload.device_id = byte; | ||
break; | ||
case 4: | ||
// EMU_printf("sysex channel: %#02x\n", byte); | ||
sysexPayload.channel = byte; | ||
break; | ||
|
||
default: | ||
// EMU_printf("sysex data: %#02x\n", byte); | ||
sysexBuffer[bufferIndex] = byte; | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#pragma once | ||
|
||
#include <gbdk/platform.h> | ||
#include <stdbool.h> | ||
|
||
#define MIDI_STATUS_SYSEX 0xF0 | ||
#define SYSEX_UNIVERSAL_REALTIME 0x7F | ||
#define SYSEX_UNIVERSAL_NON_REALTIME 0x7E | ||
#define SYSEX_NON_COMMERCIAL 0x7D | ||
#define SYSEX_EOF 0xF7 | ||
|
||
#define SYSEX_MGB_ID 0x69 | ||
|
||
// The size of the SysEx message header before the payload begins | ||
#define SYSEX_HEADER_SIZE 5 | ||
|
||
extern uint8_t sysexBytesCount; | ||
|
||
typedef struct sysex_payload { | ||
// the sysex message id (or manufacturer id) | ||
uint8_t id; | ||
// the payload device id (0xBB for mGB) | ||
uint8_t device_id; | ||
// the device or channel id | ||
uint8_t channel; | ||
// the size of the data | ||
uint8_t size; | ||
// the data payload (24 raw sysex bytes = 21 (3*7) + 3 header blocks) | ||
uint8_t data[21]; | ||
// true if the payload has finished reading from the buffer (has seen an EOF) | ||
bool ready; | ||
} sysex_payload_t; | ||
|
||
// A SysEx payload, captures up to 16 bytes of sysex data. Currently this is | ||
// used to modify the active WAV channel waveform. | ||
extern sysex_payload_t sysexPayload; | ||
|
||
// The buffer to hold the sysexBytes before decoding | ||
// contains enough space to hold 16 bytes = MSB, 7 bytes, MSB, 7 bytes, MSB, 2 | ||
// bytes = 19 bytes | ||
extern uint8_t sysexBuffer[24]; | ||
|
||
// Reads SysEx messages (F0) up until a SysEx EOF packet | ||
// (F7). Data is stored in `sysexPayload` and will set `sysexPayload.ready` when | ||
// it sees the EOF | ||
void captureSysexByte(uint8_t byte); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
#pragma once | ||
|
||
// #include <gbdk/emu_debug.h> | ||
#include <gbdk/platform.h> | ||
#include <stdbool.h> | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.