Function reference
All members of the MidiInfoAPI struct (the function table). Version is MIDIINFO_API_VERSION = 1.
Entry point
MidiInfo_GetAPI
const MidiInfoAPI* MidiInfo_GetAPI(uint32_t requested_version);The only function exported by MidiInfoObject.aux2. Resolve it with GetProcAddress(h, MIDIINFO_GETAPI_SYMBOL).
requested_version… theMIDIINFO_API_VERSIONthe caller was built against.- Returns … a pointer to the function table, or
NULLifrequested_versionis newer than what the host provides.
Types
MidiInfoNoteSpan
A single note span (seconds). Binary-compatible with the internal representation.
typedef struct MidiInfoNoteSpan {
float start; // note-on time (seconds)
float end; // note-off time (seconds)
uint16_t track; // track number
uint8_t channel; // 0..15
uint8_t _reserved; // padding
uint32_t color; // 0xRRGGBB (display color per color mode)
uint32_t seq; // file appearance order (ordering of simultaneous notes)
} MidiInfoNoteSpan;MidiInfoAnalysis
An opaque handle to an acquired analysis. Obtain it with acquire and free it with release. Contents are not exposed.
MidiInfoAPI
The function table itself. It starts with uint32_t struct_size and uint32_t version, followed by the function pointers below.
Shared state & colors
get_shared_path
int (*get_shared_path)(wchar_t* buf, int cap);Copies the shared MIDI path (UTF-16) into buf up to cap chars (NUL-terminated) and returns the required length (including NUL). Pass buf = NULL to query the required length only.
get_shared_time
double (*get_shared_time)(void);The shared playback time (seconds) broadcast by MIDI Source. NaN when unavailable (test with t != t).
channel_color
uint32_t (*channel_color)(int channel);Display color 0xRRGGBB for a channel (0..15).
note_color
uint32_t (*note_color)(int channel, int track);Display color 0xRRGGBB for (channel, track), honoring the color mode.
color_mode
int (*color_mode)(void);Color mode. 0=Channel / 1=Track / 2=Channel+Track.
Acquire & release
acquire
MidiInfoAnalysis* (*acquire)(const wchar_t* path);Acquire an analysis handle. path = NULL uses the shared MIDI (what MIDI Source loaded); a path uses that file. Returns non-NULL even while loading (check with is_ok); NULL only on failure.
acquire_wait
MidiInfoAnalysis* (*acquire_wait)(const wchar_t* path, int timeout_ms);Like acquire but blocks until analysis finishes (timeout_ms <= 0 uses an internal cap). For encoding, to avoid empty frames while loading.
release
void (*release)(MidiInfoAnalysis* handle);Free a handle from acquire / acquire_wait. Always call this. After release, array pointers from note_spans for that handle become invalid.
Metadata
| Function | Returns | Description |
|---|---|---|
is_ok(an) | int | 1 if a valid analysis |
duration(an) | double | Total length (seconds) |
tpqn(an) | uint16_t | Ticks per quarter note |
total_notes(an) | uint64_t | Total notes |
max_nps(an) | uint32_t | Max NPS |
max_polyphony(an) | uint32_t | Max simultaneous voices |
max_note_density(an) | uint32_t | Max note density |
first_note_seconds(an) | double | First note time (seconds); +Inf if none |
Each returns 0 (or a default) when an is invalid / not yet loaded.
Time-axis queries
bpm_at
double (*bpm_at)(const MidiInfoAnalysis*, double seconds);BPM at the given time.
signature_at
void (*signature_at)(const MidiInfoAnalysis*, double seconds, uint8_t* num, uint8_t* den);Writes the time signature at seconds to *num / *den (4/4 when invalid).
key_sf_at
int (*key_sf_at)(const MidiInfoAnalysis*, double seconds);Key signature sf value (-7..+7, negative = flats / positive = sharps). 0 if none.
bar_number_at / beat_in_bar_at
uint64_t (*bar_number_at)(const MidiInfoAnalysis*, double seconds); // 1-based bar number
double (*beat_in_bar_at)(const MidiInfoAnalysis*, double seconds); // beat position in the barquarter_beats_at / seconds_at_beat
double (*quarter_beats_at)(const MidiInfoAnalysis*, double seconds); // seconds -> cumulative quarter beats
double (*seconds_at_beat)(const MidiInfoAnalysis*, double beats); // beats -> secondsConvert between seconds and beats.
Counts & density
count_at
uint32_t (*count_at)(const MidiInfoAnalysis*, double seconds, int note_offs);Cumulative note count up to seconds. With note_offs != 0, the cumulative note-off count. (e.g. current voices ≈ count_at(an,t,0) - count_at(an,t,1))
nps_at
uint32_t (*nps_at)(const MidiInfoAnalysis*, double seconds);Instantaneous NPS (notes per second).
Notes
note_spans
int (*note_spans)(const MidiInfoAnalysis*, int pitch, const MidiInfoNoteSpan** out);Returns the span array for pitch (0..127) in *out and the element count. The array is sorted by start and stays valid until the handle is released. Returns 0 and *out=NULL if none.
const MidiInfoNoteSpan* spans;
int n = api->note_spans(an, 60, &spans);
for (int i = 0; i < n; ++i) {
float on = spans[i].start, off = spans[i].end;
// ...
}active_keys_at
void (*active_keys_at)(const MidiInfoAnalysis*, double seconds, int* span_index_out);Writes the span index to display for each key into span_index_out (128 elements). -1 for keys not pressed.
int idx[128];
api->active_keys_at(an, t, idx);
for (int p = 0; p < 128; ++p)
if (idx[p] >= 0) { /* pitch p is held; span is note_spans(an,p,..)[idx[p]] */ }active_span_at
int (*active_span_at)(const MidiInfoAnalysis*, int pitch, float t, int channel_filter);The index of the front-most (later track / newer note) span holding pitch at time t (seconds). With channel_filter >= 0, only that channel. -1 if not held.
Versioning policy
- Additions to the table are append-only; no reordering or removal.
- Breaking changes bump
MIDIINFO_API_VERSION. - Callers can inspect
api->version/api->struct_sizeto detect available features.