Native event conversion¶
NativeEventV1 and include/RavetNativeEvent.h define one fixed v1 in-process
C record for every portable event kind. The record is 56 bytes on the validated
macOS arm64 ABI: eight u32 fields, one f64 value, four numeric u32 words. It is
native endian/aligned rather than a wire or preset format. Kind tags 1..15 and
expression/gesture selectors are explicit; optional channel/key/id scope uses
presence bits 1/2/4. Unset means wildcard; full-u32 IDs, including UINT32_MAX, are
ordinary IDs. Endpoint routing remains in the consumer shim.
Global values/modulation and note velocities use exactly widened f32 values; decoding rejects lossy conversion, including a direct double 0.1 when an exact widened float is required. Scoped values/modulation and expressions retain full f64 precision. Volume accepts finite 0..=4; zero means mute, and signed-zero bits survive. CLAP boundaries independently reject zero because its native volume range is strictly positive; no ABI layout or kind selector changes. See decision 0159. MIDI stores validated short-message bytes in increasing shifts of words[0]. UMP stores one complete packet of numeric words in specification order, including reserved framed types. This supplies no SysEx assembly or protocol negotiation. NoteEnd offsets retain portable delivery ordering semantics.
from_event/to_event convert individual records without block timing policy.
encode_native_events/decode_native_events accept at most 1024 events and use
caller-prepared destinations. They validate the complete stream's values,
offsets/order and capacity before writing anything. Same-frame order and tails
remain intact; zero frames accept only offset zero. Unknown tags/scope bits,
nonzero unused fields, malformed MIDI/UMP and invalid scalars reject atomically.
Used negative-zero scalar bits survive; unused value must be positive zero.
Successful converted slices borrow caller storage and allocate nothing.
NativeParameterEvent/decode_parameter_events share Gain's existing global
parameter layout and whole-stream preflight. Gain uses this decoder in both
precisions without adopting the tagged event ABI or changing its C signatures.
Consumers decode to prepared portable input storage, call the audio adapter, then
encode generated events into separate prepared native output storage before
host delivery. No generic exported factory/state/editor or additional SDK mapping
is implied. Rust tests cover every tag/scope, all UMP framing types, rejected
prefixes and 1000 complete f32/f64 native instrument cycles. C and C++ contracts
check the headers, legacy layout and numeric conventions on the actual build ABI.
See decision 0143.