SkillAgentSearch skills...

Midimessage

Extensive library for MIDI constants, un-/packers, parser, cli and unified human-readable formatters/parser for MIDI Messages (embedded friendly)

Install / Use

/learn @tschiemer/Midimessage
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

midimessage

https://github.com/tschiemer/midimessage

Extensive library for MIDI constants, un-/packers, parser, cli and unified human-readable formatters/parser for MIDI Messages.

Intended for usage with frameworks (such as https://github.com/thestk/rtmidi) that do not provide these basics.

No particular structures are enforced such that you can take from it what you want.

Features

  • (many) MIDI Message constants + enumerations (see include/midimessage.h)
  • structs and types help to create a unified interface and make handling easier
  • Manufacturer Id list (see include/midimessage/manufacturerids.h)
  • tool to generate up-to-date header, run make manufacturerids (requires wget + php)
  • Standard/Common CC list (see include/midimessage/commonccs.h)
  • DLS Proprietary Chunk ids (see include/midimessage/dlsproprietarychunkids.h)
  • Basic note helpers (see include/midimessage/notes.h)
  • packers construct the right byte sequence for a particular message ASSERTing valid parameters (see include/midimessage/packers.h)
  • unpackers for a specific message type try to parse the given byte sequence thereby validating the byte sequence (could be used in any combination) (see include/midimessage/packers.h)
  • packers and unpackers are always complementary and are available as literal-based and struct-based variants
  • generic MIDI stream parser respecting Running Status and interleaved system real time messages (see include/midimessage/parser.h)
  • stringifier struct to turn (binary) MIDI messages into a uniform human-readable format and vice versa (see include/midimessage/stringifier.h; see src/cli.cpp for application)
  • Command line utility to turn human-readable commands into corresponding byte sequence and vice versa (see src/cli.cpp and below)

tt = to test

| Feature Set | Feature / Message | Message Family | Status* | |-----|-----|----|:-----:| | Channel Voice Message | Note On / Off | | tt | | | Polyphonic Key Pressure (Aftertouch) | | tt | | | Control Change | | tt | | | Program Change | | tt | | | Channel Pressure (Aftertouch) | | tt | | | Pitch Bend Change | | tt | | Channel Mode Messages | Specific Control Change (All Sound Off, Reset All Controllers, etc) | Control Change | tt | | System Common Messages | Song position pointer | | tt | | | Song select | | tt | | | Tune request | | tt | | | Quarter Frames -> MIDI Time Code | | | | System Real Time Messages | Timing clock | | tt | | | Start | | tt | | | Continue | | tt | | | Stop | | tt | | | Active Sensing | | tt | | | Reset | | tt | | MIDI Time Code (MTC) | Quarter Frames | System Common | tt | | | Full Message + User Bits| SysEx Real Time | tt | | | Real Time MTC Cueing | SysEx Real Time | tt | | | Non Real Time MTC Cueing | SysEx Non-Real Time | tt | | General SysEx NonRT Handshaking | wait, cancel, ack, nak, end of file | SysEx Non-Real Time | tt | | MIDI Machine Control (MMC) | | | work in progress | | MIDI Show Control (MSC) | All | SysEx Real Time | tt | | MIDI Visual Control (MVC)| Set Parameter Message (all) | SysEx Non-Real Time | tt | | MIDI Tuning Standard | | | TODO | | Experimental messages | | SysEx Experimental | tt | | Manufacturer messages (+ manufacturer ids)| | SysEx Manufacturer | tt | | General MIDI (GM) | System on/off | SysEx Non-Real Time | tt | | General Information | Identify request/reply | SysEx Non-Real Time | tt | | Device Control | Master volume, balance, coarse/fine tuning, global parameters | SysEx Real Time | tt | | Controller Destination Settings | Channel/Key pressure, control change | SysEx Real Time | tt | | Key-based Instrument Control | | SysEx Real Time | tt | | Sample Dump | (Extended) Header, Request, DataPacket, (Extended) Loop Point Request & Transmission, Name Request & Transmission | SysEx Non-Real Time | tt | | File Dump | Request, Header, DataPacket | Non-Real Time | tt | | Downloadable Sounds | | Non-Real Time | TODO | | Notation Information | Bar Number, Time Signature (delayed, immediate) | Real Time | tt | | Capability Inquiry (MIDI-CI) | | SysEx Non-Real Time | TODO | | Scalable Polyphony MIDI MIP (SP-MIDI MIP)| | SysEx Real Time | TODO | | Mobile Phone Control | on, off, reset, set level, set color, follow MIDI channels, manufacturer specific | SysEx Real Time | tt |

Requirements

  • midimessage-cli requires getopt and c-utils
  • target manufacturerids requires wget and php(-cli)

Building

git clone --recursive https://github.com/tschiemer/midimessage.git
cd midimessage

cmake .
make

make examples
make docs
make manufacturerids

To include as library in a cmake-based project (something like) the following in your CMakeLists.txt:

# path to root of midimessage
set(MIDIMESSAGE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/midimessage)

# midimessage include dir
# in your source files: #include <midimessage.h> or <midimessage/...>
set(MIDIMESSAGE_INCLUDES ${MIDIMESSAGE_DIR}/include)

# add the subproject
add_subdirectory(${MIDIMESSAGE_DIR} EXCLUDE_FROM_ALL)

# don't forget to add the include directory 
target_include_directories(myTarget ${MIDIMESSAGE_INCLUDES})

# link library with your own target
target_link_libraries(myTarget midimsg)

Code Example


void receivedMidiMessageFromSomewhere( uint8_t * buf, int len ){

    MidiMessage::Message_t msg, msg2;
    uint8_t msgBuf[128], msgBuf2[128];

    msg.Data.SysEx.ByteData = msgBuf;
    msg2.Data.SysEx.ByteData = msgBuf2;

    uint8_t buf2[256];
    int len2;

    static uint8_t pitch = 0;


    if (!MidiMessage::unpack( buf, len, &msg )) {
        std::cout << "Discarding invalid message" << std::endl;
        return;
    }

    if (!MidiMessage::isChannelVoiceMessage(&msg)){

        std::cout << "Discarding non-ChannelVoice message" << std::endl;

        return;
    }

    // Struct based approach to create messages
    // (the final message packaging is unified)
    msg2.StatusClass = MidiMessage::StatusClassNoteOn;
    msg2.Channel = msg.Channel;
    msg2.Data.Note.Key = 40 + pitch;
    msg2.Data.Note.Velocity = 100;

    pitch = (pitch + 1) % 13;

    len2 = MidiMessage::pack( buf2, &msg2 );
    if (len2 > 0){
        sendMidiMessageToSomewhere( buf2, len2 );
    }

    // direct approach
    len2 = MidiMessage::packNoteOff( buf2, msg2.Channel, msg2.Data.Note.Key, 50 );
    if (len2 > 0){
        sendMidiMessageToSomewhere( buf2, len2 );
    }
}

Command Line Utility

Usage:
	 midimessage-cli [-h?]
	 midimessage-cli [--running-status|-r] [--timed|-t[milli|micro]] (--parse|-p) [-d] [--nprn-filter]
	 midimessage-cli [--running-status|-r] [--timed|-t[milli|micro]] (--generate|-g) [-x0|-x1] [-v[N]] [--prefix=<prefix>] [--suffix=<suffix] [<cmd> ...]
	 midimessage-cli --convert=(nibblize|denibblize|sevenbitize|desevenbitize) [--hex] [<data xN>]

Options:
	 -h|-? 				 show this help
	 --running-status|-r 		 Accept (when parsing) or generate messages that rely on the running status (see MIDI specs)
	 --timed|-t[milli|micro] 	 Enables the capture or playback of delta-time information (ie the time between messages). Optionally the time resolution (milliseconds or microseconds) can be specified (default = micro)
	 --parse|-p [<binary-data>] 	 Enter parse mode and optionally pass as first argument (binary) message to be parsed. If no argument is provided starts reading binary stream from STDIN. Each successfully parsed message will be printed to STDOUT and terminated with a newline.
	 -d 				 In parsing mode only, instead of silent discarding output any discarded data to STDERR.
	 --nrpn-filter 				 In parsing mode only, assume CC-sequences 99-98-96 (increment), 99-98-97 (decrement), 99-98-6-38 (data entry) are NRPN sequences, thus these will be filtered even if impartial (!! ie, 99-98-6-2 will only output the message for 2; this is a convenience feature and can not be solved for the general case)
	 --generate|-g [<cmd> ...] 	 Enter generation mode and optionally pass command to be generated. If no command is given, expects one command from STDIN per line. Generated (binary) messages are written to STDOUT.
	 --prefix=<prefix> 		 Prefixes given string (max 32 bytes) before each binary sequence (only when in generation mode). A single %d can be given which will be replaced with the length of the following binary message (incompatible with running-status mode).
	 --suffix=<suffix> 		 Suffixes given string (max 32 bytes) before each binary sequence (only when in generation mode).
	 -x0, -x1 			 In generation mode, exit on input error (-x1) or continue processing (-x0). Default := continue (-x0).
	 -v0, -v1 			 In generation mode, print command parsing result (on error only) to STDERR. Default := do NOT print (-v0).
	 --convert=.. 			 Enter convertion mode, ie transform incoming STDIN using convertion method and write to STDOUT (raw bytes).
	 --hex 				 In convertion mode (only), hex input/output

Fancy pants note: the parsing output format is identical to the generation command format ;)

Data types:
	 uN := N bit unsigned integer)
		 u4 (data nibble) < 15 (0x0F)
		 u7 <= 127 (0x7F)
		 u14 <= 16383 (0x3FFF)
		 u21 <= 2097151 (0x1FFFFF)
		 u28 <= 268435455 (0x0FFFFFFF)
		 u35 <= 34359738367 (0x7FFFFFFFF)
	 sN := N bit signed integer
	 strN ((max) N byte ascii string)
	 xN (N byte hex string <> 2Ns) (note: data bytes must be <= 0x7F)

Voice Commands:
	 note (on|off) <channel (u4)> <key (u7)> <velocity (u7)>
	 cc <channel (u4)> <controller (u7)> <value (u7)>
	 pc <channel (u4)> <program (u7)>
	 pressure <channel (u4)> <pressure (u7)>
	 pitch <channel (u4)> <pitch (u14)>
	 poly <channel (u4)> <key (u7)> <pressure (u7)>

System Commands:
	 start
	 stop
	 continue
	 reset
	 active-sensing
	 tune-request
	 timing-clock
	 quarter-frame <messageType (u3)> <nibble (u4)>
	 song-position <position (u14)>
	 song-select <songNumber (u7)>

(Basic) System Exclusives:
	 sysex experimental <data (xN)>
	 sysex manufacturer <manufacturer-id (x1..3)> <data
View on GitHub
GitHub Stars8
CategoryDevelopment
Updated1mo ago
Forks2

Languages

C++

Security Score

75/100

Audited on Mar 6, 2026

No findings