Mapping MIDI time to frame count
I looked up TimePosition and BarBeatTick, but they don't seem to have informations to map MIDI time to frame count.
I'd like to get following informations:
- Length of tick, beat or bar in frames.
- Frame count to reach next tick, beat or bar from the start of current buffer.
Or is it expected to handle MIDI time code directly?
It also looks like VstTimeInfo in vestige.h has all relevant information.
DPF follows the JACK transport API when it comes to tempo. https://jackaudio.org/api/structjack__position__t.html https://distrho.github.io/DPF/structTimePosition_1_1BarBeatTick.html
ticksPerBeat tells you how many ticks there are in a beat.
beatsPerBar tells you how many beats there are in a bar.
Ticks are unrelated to frames. Frame is monotonic, increases as long as host keeps playing without reposition of timeline. The amount of ticks in a beat varies between applications, some provide more resolution than others. for example, LMMS uses 48, while MusE uses 1920
So tempo and ticksPerBeat can be used to get the length of the tick in seconds.
auto ticksPerSecond = bbt.ticksPerBeat * bbt.beatsPerMinute / 60;
auto secondsPerTick = 1.0 / ticksPerSecond;
Thank you for the explanation.
It is best not to do things based on tick count though. Being an integer value, it does not have full precision.
I guess I can make it a double.. JACK standalones do not have this fine precision, but LV2 and VST2 plugins do. Let me know if you run into issues.
Hi. I have another question.
I'm trying to make a CV plugin which outputs trigger signal at the start of bar/beat. I wrote a code like following:
void run(const float **, float **outputs, uint32_t frames) override
{
const auto timePos = getTimePosition();
if (timePos.bbt.valid) {
auto &bbt = timePos.bbt;
double secondsPerTick = 60.0 / (bbt.ticksPerBeat * bbt.beatsPerMinute);
double tickLength = sampleRate * secondsPerTick;
double beatLength = tickLength * bbt.ticksPerBeat;
double barLength = beatLength * bbt.beatsPerBar;
double barStartFrame = tickLength * bbt.barStartTick;
double beatStartFrame = barStartFrame + beatLength * (bbt.beat - 1);
double tickStartFrame = beatStartFrame + tickLength * bbt.tick;
double offsetToNextTick = timePos.frame - tickStartFrame;
// ...
}
}
I'm trying to calculate frame offset from the start of current buffer to the next tick as offsetToNextTick. The code above is assuming that bbt.tick indicates latest tick count right before the start of current buffer. However, offsetToNextTick can be both positive or negative when I tested.
The question is that where exactly is bbt.tick indicating? Is it something like the closest tick to the start of current buffer?
Following is a drawing of my understanding of relation about tick and the start of buffer. Start of buffer is more close to B. I'd like to know which of tick A or tick B becomes bbt.tick. Or could it be possible that bbt.tick indicates completely different time?

the transport information refers to the frame 0 of each process cycle. so yes, closest to the start of each buffer
Thanks for the answer.
I tested more and found that the code on previous comment breaks when tempo is changed. I looked up LV2 metronome example, and it seems like they are using barBeat which is provided by float.
Is it possible to add barBeat to BarBeatTick?
hey, sorry for the lack of news on this. to make things clear... I am slowing down a bit on the hobby-project work, focusing on a specific project at a time. I have scheduled on my calendar time that I will dedicate to each project. First carla, then cadence, then jack2, then distrho-ports and finally DPF. I will get back to DPF full-force in november. someone else has been asking about exactly the same thing (in regards to needing a precise timing source)
I'd like to say thanks for your works. DPF and Carla made my plugin development far easier.
Just one thing, I know a person who got mentally ill for working too hard, so please take your time and get a break when feeling tired. It's OK to procrastinate.
For anyone stumbled upon this issue, I have temporary patches to solve this issue on here (DistrhoPlugin*.patch). Example snippet is also available. Hope this helps.
In hvcc I'm doing this: https://github.com/Wasted-Audio/hvcc/blob/develop/hvcc/generators/c2dpf/templates/HeavyDPF.cpp#L192
Here we generate MTC clock signals, which is 24 ticks per beat, that are scheduled into the hvcc processing buffer. Any remaining frames are taken over to the next processing cycle cycle and handled there. This way the window of midi ticks vs processing frames moves along. I use a double to count samples, should that be enough?
CardinalPlugin does something similar here, right? -> https://github.com/DISTRHO/Cardinal/blob/main/src/CardinalPlugin.cpp#L926
It would be nice to know some best-practice around this stuff in DPF.
MTC in plugins doesnt make sense though. Cardinal purposefully ignores this old MIDI thing and uses the host time information instead (which is much more accurate)
The midi time code in cardinal only for start/stop/continue triggers.
In hvcc it's all puredata logic to do stuff. so having a sample accurate MTC is nice there. You have no other way to sync to anything otherwise. So yeah it's just midi paradigm you generally have to work with.