A header-only, platform-independent C++ library for implementing the Elektron TurboMIDI protocol. This library enables MIDI communication at speeds up to 20x the standard MIDI rate (31.25 kbit/s).
TurboMIDI is a proprietary protocol developed by Elektron that allows compatible devices to negotiate and communicate at higher MIDI speeds. This library provides a complete implementation of the protocol specification, making it easy to add TurboMIDI support to your hardware or software projects.
- High-Speed MIDI Communication: Support for multipliers from 1x to 20x (31.25 kbit/s to 625 kbit/s)
- Header-Only Library: Single header file with no external dependencies
- Platform Independent: Abstract interface allows easy porting to any platform
- Complete Protocol Implementation: All 9 TurboMIDI commands fully implemented
- Robust Communication: Built-in timeout handling, active sensing, and error recovery
- Master and Slave Modes: Can function as either protocol master or slave device
- Speed Certification: Support for both certified and uncertified speed negotiations
Multiplier | Speed (kbit/s) | Multiplier | Speed (kbit/s) |
---|---|---|---|
1x | 31.25 | 8x | 250 |
2x | 62.5 | 10x | 312.5 |
3.3x | 103.125 | 13.3x | 415.625 |
4x | 125 | 16x | 500 |
5x | 156.25 | 20x | 625 |
6.6x | 206.25 |
- C++11 or later
- Platform-specific MIDI/Serial implementation
Simply copy TurboMidi.hpp
to your project and include it:
#include "TurboMidi.hpp"
- Download the library as a ZIP file
- In Arduino IDE: Sketch → Include Library → Add .ZIP Library
- Select the downloaded ZIP file
- Include in your sketch:
#include <TurboMidiArduino.hpp>
Or install manually:
- Copy the entire folder to your Arduino libraries directory
- Windows:
Documents\Arduino\libraries\
- macOS:
~/Documents/Arduino/libraries/
- Linux:
~/Arduino/libraries/
- Windows:
#include "TurboMidi.hpp"
// 1. Implement the platform interface for your system
class MyPlatform : public TurboMIDI::IPlatform {
public:
void sendMidiData(const uint8_t* data, size_t length) override {
// Send data via your MIDI/serial interface
}
size_t receiveMidiData(uint8_t* buffer, size_t maxLength) override {
// Receive available MIDI data (non-blocking)
return bytesRead;
}
uint32_t getMillis() override {
// Return milliseconds since start
return millis();
}
void setBaudRate(uint32_t baudRate) override {
// Set your UART/serial baud rate
}
void delayMs(uint32_t ms) override {
// Platform-specific delay
}
};
// 2. Create TurboMIDI instance
MyPlatform platform;
TurboMIDI::TurboMIDI turbo(&platform, TurboMIDI::DeviceRole::MASTER);
// 3. Configure supported speeds
turbo.setSupportedSpeed(TurboMIDI::SpeedMultiplier::SPEED_2X, true); // certified
turbo.setSupportedSpeed(TurboMIDI::SpeedMultiplier::SPEED_4X, true); // certified
turbo.setSupportedSpeed(TurboMIDI::SpeedMultiplier::SPEED_8X, false); // uncertified
// 4. Negotiate speed with connected device
if (turbo.negotiateSpeed(TurboMIDI::SpeedMultiplier::SPEED_4X)) {
// Successfully negotiated 4x speed
}
// 5. Main loop
while (running) {
turbo.handleIncomingData();
turbo.sendActiveSense(); // Required for speeds > 1x
}
Using the Arduino-specific wrapper (recommended):
#include <TurboMidiArduino.hpp>
using namespace TurboMIDI;
// Create TurboMIDI instance using Serial1 as slave device
TurboMIDIArduino turboMidi(Serial1, DeviceRole::SLAVE);
void setup() {
// Initialize serial for debugging
Serial.begin(115200);
// Initialize TurboMIDI
turboMidi.begin();
// Configure supported speeds
turboMidi.setSupportedSpeed(SpeedMultiplier::SPEED_2X, true); // certified
turboMidi.setSupportedSpeed(SpeedMultiplier::SPEED_4X, true); // certified
turboMidi.setSupportedSpeed(SpeedMultiplier::SPEED_8X, false); // uncertified
// Set callbacks
turboMidi.onSpeedChanged([](SpeedMultiplier speed) {
Serial.print("Speed changed to: ");
Serial.print(static_cast<int>(speed));
Serial.println("x");
});
turboMidi.onSpeedRequest([]() {
Serial.println("Speed request received");
});
}
void loop() {
// Process TurboMIDI protocol
turboMidi.update();
// Your MIDI processing here
if (turboMidi.available()) {
// Process incoming MIDI data
}
}
For more examples, see:
examples/TurboMIDI_Basic/
- Basic bidirectional usageexamples/TurboMIDI_Master/
- Master device with speed negotiationexamples/TurboMIDI_Slave/
- Slave device with DIP switch configuration
To use TurboMIDI on your platform, implement the IPlatform
interface:
Method | Description |
---|---|
sendMidiData() |
Send raw MIDI bytes |
receiveMidiData() |
Non-blocking receive of available MIDI data |
getMillis() |
Return milliseconds elapsed (for timeouts) |
setBaudRate() |
Change UART/serial baud rate for speed changes |
delayMs() |
Platform-specific delay function |
The library includes TurboMidiArduino.hpp
which provides:
ArduinoPlatform
: Hardware UART implementation ofIPlatform
TurboMIDIArduino
: Ready-to-use wrapper combining platform and protocol- Automatic baud rate switching for all Arduino boards
- Built-in active sensing management
For Arduino usage, you'll need:
- Arduino board with at least one hardware UART
- MIDI input circuit (optocoupler, resistors)
- MIDI output circuit (buffer, resistors)
- For speeds above 8x: Arduino Due, Teensy, or ESP32 recommended
Note: Standard Arduino Uno/Nano can reliably handle up to 4x-8x speed depending on your code complexity.
The library implements all TurboMIDI protocol commands:
Command | ID | Direction | Description |
---|---|---|---|
SPEED_REQ | 0x10 | Any | Request speed capabilities |
SPEED_ANSWER | 0x11 | Any | Report supported/certified speeds |
SPEED_NEG | 0x12 | Master | Negotiate speed change |
SPEED_ACK | 0x13 | Slave | Acknowledge negotiation |
SPEED_TEST | 0x14 | Master | First test pattern |
SPEED_RESULT | 0x15 | Slave | First test result |
SPEED_TEST2 | 0x16 | Master | Second test pattern |
SPEED_RESULT2 | 0x17 | Slave | Second test result |
SPEED_PUSH | 0x20 | Master | Force speed change |
- Master timeout: 30ms minimum
- Slave timeout: 15ms minimum, 25ms maximum
- Active sensing timeout: 300ms (reverts to 1x speed)
- Master sends SPEED_REQ
- Slave responds with SPEED_ANSWER listing capabilities
- Master sends SPEED_NEG with test and target speeds
- Slave sends SPEED_ACK if acceptable
- If uncertified speed: Master/Slave perform speed test
- On success: Both switch to negotiated speed
- Both devices send active sensing to maintain connection
TurboMIDI(IPlatform* platform, DeviceRole role = DeviceRole::ANY)
void setSupportedSpeed(SpeedMultiplier speed, bool certified = false)
bool negotiateSpeed(SpeedMultiplier targetSpeed, uint32_t timeoutMs = 30)
void pushSpeed(SpeedMultiplier speed)
void handleIncomingData()
void sendActiveSense()
SpeedMultiplier getCurrentSpeed() const
std::function<void(SpeedMultiplier)> onSpeedChanged
std::function<void()> onSpeedRequest
This library is provided as-is for use with Elektron devices and compatible hardware. Please refer to the LICENSE file for details.
Contributions are welcome! Please submit pull requests or open issues on GitHub.
Protocol documentation provided by Elektron Music Machines.