Common Types and Scaling Helpers
January 31, 2026 ยท View on GitHub
Code examples can be found in types.examples.cpp.
Common Types
To improve readability, the library defines type aliases for several MIDI entities:
using uint2_t = std::uint8_t;
using uint4_t = std::uint8_t;
using uint7_t = std::uint8_t;
using uint8_t = std::uint8_t;
using uint14_t = std::uint16_t;
using uint16_t = std::uint16_t;
using uint28_t = std::uint32_t;
using uint32_t = std::uint32_t;
using int32_t = std::int32_t;
using size_t = std::size_t;
using group_t = uint4_t;
using status_t = uint8_t;
using channel_t = uint4_t;
using note_nr_t = uint7_t;
using controller_t = uint7_t;
using program_t = uint7_t;
using muid_t = uint28_t;
using manufacturer_t = uint32_t;
using protocol_t = uint8_t;
using extensions_t = uint8_t;
Intentionally no strong types are used, this may change in a future version, maybe configurable by a cmake option.
Additionally strong types are available for core MIDI concepts:
struct velocity;
struct pitch_bend;
struct pitch_increment;
struct pitch_7_9;
struct pitch_7_25;
struct pitch_bend_sensitivity;
struct controller_increment;
struct controller_value;
struct device_identity;
Instances of these types can be initialized with native MIDI 1 bit depths (7 or 14) and with high resolution values (16 or 32 bits).
auto v = velocity{ uint7_t{ 44 } };
auto pb1 = pitch_bend{ uint32_t { 0x62311258 } };
auto pb2 = pitch_bend{ -0.128 };
auto p1 = pitch_7_25{ 81.3f };
auto p2 = pitch_7_25{ note_nr_t { 68 } };
auto c1 = controller_value{ uint7_t{ 126 } };
auto c2 = controller_value{ 0.93 };
One can query the underlying value for different bit depths / types:
auto pb1 = pitch_bend{ uint32_t { 0x62311258 } }.as_double(); // [-1.0 .. 1.0]
auto pb2 = pitch_bend{ -0.128 }.as_uint14(); // 14 bit MIDI 1
auto p1 = pitch_7_25{ 81.3f }.as_float(); // [0.0 .. 128.0)
auto c1 = controller_value{ uint7_t{ 126 } }.as_double(); // [0.0 .. 1.0]
There are numerical operators to do math with related types:
pitch_7_25 p1 += pitch_increment{ -199 };
pitch_increment pbi = pitch_bend{ -0.128 } * pitch_bend_sensitivity{ note_nr_t{ 2 } };
pitch_7_25 p3 = p1 + pbi;
pitch_7_25 p4 = p3 + 0.011f;
controller_value v1 = controller_value{ 0.44 } + controller_increment{ -1234 };
v1 += controller_increment{ 0x4000 };
Scaling Helpers
The MIDI 2 specifications stricly defines how values should be down- and upscaled between different bit depths.
There are predefined helper functions for the typical use cases:
auto as7bit1 = downsample_16_to_7bit(0x1234);
auto as7bit2 = downsample_32_to_7bit(0xFEDCBA98);
auto as14bit = downsample_32_to_7bit(0xFEDCBA98);
auto as16bit = upsample_7_to_16bit(uint7_t{ 42 });
auto as32bit1 = upsample_7_to_32bit(uint7_t{ 42 });
auto as32bit2 = upsample_14_to_32bit(uint14_t{ 0x0567 });
Additionally there is a function that upsamples values between arbitrary bit depths:
auto as14bit = upsample_x_to_ybit(0x34, 6, 14);
Different to upsampling downsampling can be implemented using standard bit shifting:
auto as14bit = 20bitValue >> 6;