【问题标题】:MIDI tick to millisecond?MIDI刻度到毫秒?
【发布时间】:2014-07-12 20:32:12
【问题描述】:

我意识到这里有很多关于将 MIDI 刻度转换为毫秒的问题(例如:How to convert midi timeline into the actual timeline that should be playedMidi Ticks to Actual PlayBack Seconds !!! ( Midi Music)Midi timestamp in seconds),我已经查看了所有这些问题,并尝试实施这些建议,但我仍然没听懂。

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

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

低音方法

打勾

// 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 

更新

我的困惑仍在继续,但基于blog post,我认为我的代码是正确的——至少输出看起来是准确的。相反,下面@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 

【问题讨论】:

  • 你知道速度可以在文件中间改变吗?你无法逃避使用even more math
  • BASS 提供的每四分音符已经有微秒。你说的不是你要找的吗?
  • @Brad - 不,我正在尝试计算特定滴答声的毫秒数

标签: midi bass


【解决方案1】:

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

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

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

有效地使用整数算术

currentMillis = tick * 60000 / ppqn / tempo

【讨论】:

  • 抱歉,我还是没听明白。如果可以,您会使用我在问题中发布的变量来编辑您的答案吗?查看使用的特定变量将帮助我理解您上面描述的公式以及它是如何应用的。 (欢迎来到我迟钝的世界... ;-)
  • 第一行是理论上的。第二行是将理论版本转换为您的变量,第三行将变量重新排序为您将在代码中编写的格式。
  • 谢谢。我已经用您的示例和代码的方法和输出以及我在本网站 (lastrayofhope.co.uk/2009/12/23/midi-delta-time-ticks-to-seconds/…) 上找到的解释更新了我的问题。这两种方法的输出非常不同,我不明白为什么。操作顺序?
【解决方案2】:

这行得通:

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

【讨论】:

  • 我使用的是 MIDICSV 格式,这对我有用。 currentMs = tempo / 1000.0f / PPQ * currentClock;
猜你喜欢
  • 1970-01-01
  • 2013-08-29
  • 2021-03-19
  • 2020-12-02
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-08
  • 2014-08-07
相关资源
最近更新 更多