0

我意识到这里有很多关于将 MIDI 滴答声转换为毫秒的问题(例如:如何将 midi 时间线转换为应该播放的实际时间线Midi Ticks 到实际播放秒数!!!(Midi 音乐)Midi 时间戳以秒为单位)我已经查看了所有内容,尝试实施这些建议,但我仍然没有得到它。

(我有没有提到我有点“数学恐惧症”)

谁能帮我做一个实际的例子?我正在使用来自 un4seen 的 Bass 库。我有我需要的所有数据——我只是不相信我的计算。

低音方法

打钩

// position of midi stream
uint64_t tick = BASS_ChannelGetPosition(midiFileStream, BASS_POS_MIDI_TICK)

PPQN

//The Pulses Per Quarter Note (or ticks per beat) value of a MIDI stream.
float ppqn;
BASS_ChannelGetAttribute(handle, BASS_ATTRIB_MIDI_PPQN, &ppqn);

速度

 //tempo in microseconds per quarter note.
 uint32_t tempo = BASS_MIDI_StreamGetEvent( midiFileStream, -1, MIDI_EVENT_TEMPO);

我尝试计算刻度的 MS 值:

float currentMilliseconds = tick * tempo / (ppqn * 1000);

我得到的值看起来是正确的,但我对它没有任何信心,因为我不太了解这个公式。

printf("tick %llu\n",tick);
printf("ppqn %f\n",ppqn);
printf("tempo %u\n",tempo);
printf("currentMilliseconds %f \n", currentMilliseconds);

示例输出:

tick 479
ppqn 24.000000
tempo 599999
currentMilliseconds 11974.980469 

更新

我的困惑仍在继续,但根据这篇文,我认为我的代码是正确的——至少输出看起来是准确的。相反,下面@Strikeskids 提供的答案会产生不同的结果。也许我在那里有操作顺序问题?

float kMillisecondsPerQuarterNote = tempo / 1000.0f;
float kMillisecondsPerTick = kMillisecondsPerQuarterNote / ppqn;
float deltaTimeInMilliseconds = tick * kMillisecondsPerTick;
printf("deltaTimeInMilliseconds %f \n", deltaTimeInMilliseconds);

.

float currentMillis = tick * 60000.0f / ppqn / tempo;
printf("currentMillis %f \n", currentMillis);

输出:

 deltaTimeInMilliseconds 11049.982422 
 currentMillis 1.841670 
4

2 回答 2

3

速度以每分钟节拍为单位。因为你想得到时间,所以你应该把它放在分数的分母中。

currentTime = currentTick * (beats / tick) * (minutes / beat) * (millis / minute)

millis = tick * (1/ppqn) * (1/tempo) * (1000*60)

有效地使用整数算术

currentMillis = tick * 60000 / ppqn / tempo

于 2014-07-12T20:40:43.540 回答
3

这有效:

float kMillisecondsPerQuarterNote = tempo / 1000.0f;
float kMillisecondsPerTick = kMillisecondsPerQuarterNote / ppqn;
float deltaTimeInMilliseconds = tick * kMillisecondsPerTick;
printf("deltaTimeInMilliseconds %f \n", deltaTimeInMilliseconds);
于 2014-07-23T16:50:12.287 回答