Я понимаю, что здесь есть много вопросов, касающихся преобразования тактов MIDI в миллисекунды (например: Как преобразовать временную шкалу midi в фактическую временную шкалу, которую следует воспроизвести, Midi Ticks to Actual PlayBack Seconds !!! (Midi Music), Midi timestamp в секундах), и я просмотрел их все, попытался реализовать предложения, но до сих пор не понял.
(Я упоминал, что я немного «математический фоб»)
Может ли кто-нибудь помочь мне работать на практическом примере? Я использую библиотеку Bass от 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
Обновить
Мое замешательство продолжается, но на основе этого сообщение в блоге Я думаю, что у меня правильный код - по крайней мере, вывод кажется точным. И наоборот, ответ, предоставленный @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