Skip to content

Function reference

All members of the MidiInfoAPI struct (the function table). Version is MIDIINFO_API_VERSION = 1.

Entry point

MidiInfo_GetAPI

c
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 … the MIDIINFO_API_VERSION the caller was built against.
  • Returns … a pointer to the function table, or NULL if requested_version is newer than what the host provides.

Types

MidiInfoNoteSpan

A single note span (seconds). Binary-compatible with the internal representation.

c
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

c
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

c
double (*get_shared_time)(void);

The shared playback time (seconds) broadcast by MIDI Source. NaN when unavailable (test with t != t).

channel_color

c
uint32_t (*channel_color)(int channel);

Display color 0xRRGGBB for a channel (0..15).

note_color

c
uint32_t (*note_color)(int channel, int track);

Display color 0xRRGGBB for (channel, track), honoring the color mode.

color_mode

c
int (*color_mode)(void);

Color mode. 0=Channel / 1=Track / 2=Channel+Track.

Acquire & release

acquire

c
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

c
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

c
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

FunctionReturnsDescription
is_ok(an)int1 if a valid analysis
duration(an)doubleTotal length (seconds)
tpqn(an)uint16_tTicks per quarter note
total_notes(an)uint64_tTotal notes
max_nps(an)uint32_tMax NPS
max_polyphony(an)uint32_tMax simultaneous voices
max_note_density(an)uint32_tMax note density
first_note_seconds(an)doubleFirst note time (seconds); +Inf if none

Each returns 0 (or a default) when an is invalid / not yet loaded.

Time-axis queries

bpm_at

c
double (*bpm_at)(const MidiInfoAnalysis*, double seconds);

BPM at the given time.

signature_at

c
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

c
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

c
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 bar

quarter_beats_at / seconds_at_beat

c
double (*quarter_beats_at)(const MidiInfoAnalysis*, double seconds);  // seconds -> cumulative quarter beats
double (*seconds_at_beat)(const MidiInfoAnalysis*, double beats);     // beats -> seconds

Convert between seconds and beats.

Counts & density

count_at

c
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

c
uint32_t (*nps_at)(const MidiInfoAnalysis*, double seconds);

Instantaneous NPS (notes per second).

Notes

note_spans

c
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.

c
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

c
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.

c
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

c
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_size to detect available features.