Documentation
Midi
MIDI (an acronym for Musical Instrument Digital Interface) is a technical standard that describes a communications protocol, digital interface, and electrical connectors that connect a wide variety of electronic musical instruments, computers, and related audio devices for playing, editing, and recording music.
For more information about MIDI, see midi.org.
Using MIDI in Spektar
MIDI components come with default installation and should work with all MIDI hardware. Select MIDI components from help or the library to review documentation. Examples folder also has a few good examples of how to use the included components.
Encoding and decoding MIDI messages
Internally, Spektar translates MIDI messages into 32 bit format suitable for signal paths. All built-in components and scripts have full support for these transformations so this is transparent for end users that use GUI only. However, if you encounter a use case where you need to make these conversions, we have documented how this can be done below.
In scripts and scripted components
Script functions are available for conversions:
Function | Description | Example |
---|---|---|
int #midi:status(float $midiFloat) | Get midi status from float coded message | int $status = #midi:status( $midi_in ); |
int #midi:data1(float $midiFloat) | Get midi data byte 1 from float coded message | int $status = #midi:data1( $midi_in ); |
int #midi:data2(float $midiFloat) | Get midi data byte 2 from float coded message | int $status = #midi:data2( $midi_in ); |
float #midi:frequency(float $data1) | Get midi note frequency | float $freq = #midi:frequency($data1); |
In Java
Utility functions are provided for conversion between float and javax.sound.midi.MidiMessage in dsp.midi.MidiDataType. Code is reproduced here:
public ShortMessage convert(float value) { int rawbits = Float.floatToRawIntBits(value); int status = 0xff & (rawbits>>24); int data1 = 0xff & (rawbits>>16); int data2 = 0xff & (rawbits>>8); try { return new ShortMessage(status, data1, data2); } catch (InvalidMidiDataException e) { throw new RuntimeException("Invalid midi message ", e); } } public float convert(MidiMessage value) { int rawbits = 0; if ( value instanceof ShortMessage) { ShortMessage m = (ShortMessage)value; rawbits |= 0xff000000 & (m.getStatus()<<24); rawbits |= 0xff0000 & (m.getData1()<<16); rawbits |= 0xff00 & (m.getData2()<<8); } return Float.intBitsToFloat(rawbits); }
In C / C++ / VST / VSTi export
If you export your design to e.g. C, C++ or VSTi you may encounter a use case where you need to do this translation yourself. Here we will summarise exactly how this is done.
In pseudo-code, the routine to pack MIDI message to float may look like this:
int midiInt = 0xff000000 & (midimsg.getStatus() << 24 ); midiInt |= 0x00ff0000 & (midimsg.getData1() << 16 ); midiInt |= 0x0000ff00 & (midimsg.getData2() << 8 ); float midiFloat = *((float*)(&midiInt));
Conversely, to unpack the value from float:
// get midiFloat from Spektar design float midiFloat = myComponentOutput; // now unpack int midiInt = *((int*)(&midiFloat)); int status = 0xff & ( midiInt >> 24 ); int data1 = 0xff & ( midiInt >> 16 ); int data2 = 0xff & ( midiInt >> 8 );
Since if most cases the data bytes actually carry only 7 bits 0xff for data1 and data2 could be replaced by 0x7f.