関数リファレンス
MidiInfoAPI 構造体(関数テーブル)の全メンバです。バージョンは MIDIINFO_API_VERSION = 1。
エントリポイント
MidiInfo_GetAPI
const MidiInfoAPI* MidiInfo_GetAPI(uint32_t requested_version);MidiInfoObject.aux2 がエクスポートする唯一の関数。GetProcAddress(h, MIDIINFO_GETAPI_SYMBOL) で取得します。
requested_version… 利用側がビルド時に知っているMIDIINFO_API_VERSION。- 戻り値 … 関数テーブルへのポインタ。
requested_versionが提供側より新しい場合はNULL。
型
MidiInfoNoteSpan
1 つのノート区間(秒)。内部表現とバイナリ互換です。
typedef struct MidiInfoNoteSpan {
float start; // 発音時刻(秒)
float end; // 消音時刻(秒)
uint16_t track; // トラック番号
uint8_t channel; // 0..15
uint8_t _reserved; // パディング
uint32_t color; // 0xRRGGBB(色モードに応じた表示色)
uint32_t seq; // MIDIファイル上の登場順(同時刻ノートの前後)
} MidiInfoNoteSpan;MidiInfoAnalysis
取得した解析への不透明ハンドル。acquire で得て release で解放します。中身は公開されません。
MidiInfoAPI
関数テーブル本体。先頭に uint32_t struct_size と uint32_t version を持ち、以降が下記の関数ポインタです。
共有状態・色
get_shared_path
int (*get_shared_path)(wchar_t* buf, int cap);共有 MIDI のパス(UTF-16)を buf に最大 cap 文字(NUL 終端込み)コピーし、必要文字数(NUL 込み) を返します。buf=NULL で必要長だけ問い合わせできます。
get_shared_time
double (*get_shared_time)(void);MIDI Source が発信している共有再生時刻(秒)。有効な値が無いときは NaN(t != t で判定)。
channel_color
uint32_t (*channel_color)(int channel);チャンネル(0..15)の表示色 0xRRGGBB。
note_color
uint32_t (*note_color)(int channel, int track);色モードを反映した (channel, track) の表示色 0xRRGGBB。
color_mode
int (*color_mode)(void);色モード。0=Channel / 1=Track / 2=Channel+Track。
取得・解放
acquire
MidiInfoAnalysis* (*acquire)(const wchar_t* path);解析ハンドルを取得します。path=NULL で 共有 MIDI(MIDI Source が読み込んだもの)、パス指定でそのファイル。未ロードでも非 NULL を返す(is_ok で判定)。失敗時のみ NULL。
acquire_wait
MidiInfoAnalysis* (*acquire_wait)(const wchar_t* path, int timeout_ms);acquire と同じだが、解析完了までブロックします(timeout_ms <= 0 で内部上限)。エンコード時にロード中の空フレームを避ける用途。
release
void (*release)(MidiInfoAnalysis* handle);acquire / acquire_wait で得たハンドルを解放します。必ず呼んでください。 解放後、そのハンドル由来の配列ポインタ(note_spans の結果)は無効になります。
メタ情報
| 関数 | 戻り値 | 説明 |
|---|---|---|
is_ok(an) | int | 有効な解析なら 1 |
duration(an) | double | 全体長(秒) |
tpqn(an) | uint16_t | 四分音符あたり tick |
total_notes(an) | uint64_t | 総ノート数 |
max_nps(an) | uint32_t | 最大 NPS |
max_polyphony(an) | uint32_t | 最大同時発音数 |
max_note_density(an) | uint32_t | 最大ノート密度 |
first_note_seconds(an) | double | 最初のノート時刻(秒)。無ければ +Inf |
いずれも an が無効/未ロードのときは 0(または既定値)を返します。
時間軸クエリ
bpm_at
double (*bpm_at)(const MidiInfoAnalysis*, double seconds);指定秒の BPM。
signature_at
void (*signature_at)(const MidiInfoAnalysis*, double seconds, uint8_t* num, uint8_t* den);指定秒の拍子を *num / *den に書きます(無効時は 4/4)。
key_sf_at
int (*key_sf_at)(const MidiInfoAnalysis*, double seconds);調号の sf 値(-7..+7、負=♭ / 正=♯)。無ければ 0。
bar_number_at / beat_in_bar_at
uint64_t (*bar_number_at)(const MidiInfoAnalysis*, double seconds); // 1 始まりの小節番号
double (*beat_in_bar_at)(const MidiInfoAnalysis*, double seconds); // 小節内の拍位置quarter_beats_at / seconds_at_beat
double (*quarter_beats_at)(const MidiInfoAnalysis*, double seconds); // 秒 → 累積四分音符拍
double (*seconds_at_beat)(const MidiInfoAnalysis*, double beats); // 拍 → 秒秒↔拍の相互変換。
カウント・密度
count_at
uint32_t (*count_at)(const MidiInfoAnalysis*, double seconds, int note_offs);指定秒までの累積ノート数。note_offs != 0 でノートオフ側の累積。 (例: 現在の発音数 ≒ count_at(an,t,0) - count_at(an,t,1))
nps_at
uint32_t (*nps_at)(const MidiInfoAnalysis*, double seconds);指定秒の瞬間 NPS(notes per second)。
ノート
note_spans
int (*note_spans)(const MidiInfoAnalysis*, int pitch, const MidiInfoNoteSpan** out);pitch(0..127)の区間配列を *out に返し、要素数を返します。配列は start 昇順で、ハンドルが release されるまで有効です。該当なしは 0 を返し *out=NULL。
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);指定秒で各鍵に表示すべき区間の添字を span_index_out(要素数 128)に書きます。押下なしは -1。
int idx[128];
api->active_keys_at(an, t, idx);
for (int p = 0; p < 128; ++p)
if (idx[p] >= 0) { /* pitch p が押下中。区間は note_spans(an,p,..)[idx[p]] */ }active_span_at
int (*active_span_at)(const MidiInfoAnalysis*, int pitch, float t, int channel_filter);pitch を時刻 t(秒)で押下中の、最優先(後のトラック・新しい音が手前)の区間添字。channel_filter >= 0 でそのチャンネルのみ対象。押下なしは -1。
バージョニング方針
- 関数テーブルへの追加は末尾のみ。並び替え・削除はしません。
- 破壊的変更時に
MIDIINFO_API_VERSIONを上げます。 - 利用側は
api->version/api->struct_sizeを見て、必要なら機能の有無を判定できます。