[Jack-Devel] Odp: Re: JackTransport vs VST ppqPos

PrevNext  Index
DateWed, 15 May 2013 06:31:20 +0200
From Pawel <[hidden] at wp dot pl>
Tojack-devel <[hidden] at lists dot jackaudio dot org>
Follow-UpStéphane Letz Re: [Jack-Devel] JackTransport vs VST ppqPos
Follow-UpPaul Davis Re: [Jack-Devel] Odp: Re: JackTransport vs VST ppqPos
Dnia Niedziela, 12 Maja 2013 11:45 Stéphane Letz <[hidden]> napisa³(a) 
> 
> Le 9 mai 2013 ? 03:22, Pawel <[hidden]> a écrit :
> 
> > Hi,
> > 
> > I discover strange problem while improving JackTransport support in FSTHost.
> > 
> > Most VST plugins while trying to synchronize with host usually ask for such things:
> > 1) tempo ( == jack_pos.beats_per_minute)
> > 
> > 2) ppqPos - which I understand like "current quarter note" == current jack_pos.beat.
> > 
> > 3) barStartPos .. ok, this one is not a subject in this case ;-)
> > 
> > 4) samplePos == jack_pos.frame
> > 
> > 5) sampleRate == jack_pos.frame_rate
> > 
> > The problem is which pppPos. There are two ideas how to compute this:
> > 
> > 1) Using BBT (which should be a preferred option here, right ?)
> > double ppqBar = (jp.bar - 1) * jp.beats_per_bar;
> > double ppqBeat = jp.beat - 1;
> > double ppqTick = (double) jp.tick / jp.ticks_per_beat;
> > 
> > ppqPos = ppqBar + ppqBeat + ppqTick;
> > 
> > 2) Using sample rate / current frame / tempo - this is a standard way in VST world. We count how much samples is in quarter note (beat) ..
> > 
> > double ppq = jp.frame_rate * 60 / jp.beats_per_minute;
> > ppqPos = jp.frame / ppq;
> > 
> > The problem is that .. this second counter "hurry" (sorry can't find better word for this issue in english ;-)
> > I made really simple , example app for observe this issue - it is included in FSTHost repository:
> > http://sourceforge.net/p/fsthost/code/HEAD/tree/trunk/jt-test.c
> > 
> > Frame: 0013314048 | Bar: 0068 | Beat: 3 | Tick: 1680 | CBFF: 277.38 | CBFBBT: 270.88
> > Frame: 0013410304 | Bar: 0069 | Beat: 1 | Tick: 1600 | CBFF: 279.38 | CBFBBT: 272.83
> > Frame: 0013506048 | Bar: 0069 | Beat: 3 | Tick: 1500 | CBFF: 281.38 | CBFBBT: 274.78
> > Frame: 0013602304 | Bar: 0070 | Beat: 1 | Tick: 1420 | CBFF: 283.38 | CBFBBT: 276.74
> > Frame: 0013698560 | Bar: 0070 | Beat: 3 | Tick: 1340 | CBFF: 285.39 | CBFBBT: 278.70
> > Frame: 0013794304 | Bar: 0071 | Beat: 1 | Tick: 1240 | CBFF: 287.38 | CBFBBT: 280.65
> > Frame: 0013890560 | Bar: 0071 | Beat: 3 | Tick: 1160 | CBFF: 289.39 | CBFBBT: 282.60
> > 
> > Please look that after a while CBFF > CBFBBT, and trend is that difference will grow. I tested this with either Hydrogen and jack_transport as master. The funny thing is that - when I skip location to for example in jack_transport:
> > jack_transport> stop
> > jack_transport> locate 0
> > jack_transport> locate 51111111
> > jack_transport> play
> > 
> > CBFF and CBFBBT back to normal (almost) .. aha - so we know that formulas are good - and problem is in Jack.
> > Frame: 0051936967 | Bar: 0271 | Beat: 2 | Tick: 1184 | CBFF: 1082.02 | CBFBBT: 1081.62
> > Frame: 0052033223 | Bar: 0271 | Beat: 4 | Tick: 1104 | CBFF: 1084.03 | CBFBBT: 1083.58
> > 
> > This was tested only with Jack2 (1.9.8 and 1.9.9.5).
> > 
> > Any ideas ?
> > 
> > Best Regards
> > Pawel / Xj
> > 
> 
> 
> JACK does not do anything regarding those values: the timebase master *client* is responsible to update extended position information, counting beats, timecode, etc. (see : http://jackaudio.org/files/docs/html/transport-design.html)
> 
> I don't see any specific issues here on OSX testing either with jack_transport or Ardour as timebase master (well I see CBFBBT value staying the same while CBFF moving with jack_transport  at very low tempo like 1 or 2)
> 
> Can you try with Ardour also?
> 
> Stéphane 

Thanks for answer Stephane.
Meantime I dig a little and I think that found a reason of this issue, If you look on this line from transport.c (jack_transport example client):
pos->tick += nframes * pos->ticks_per_beat * pos->beats_per_minute / (pos->frame_rate * 60);

IMHO it mean "how many ticks are in current period". If nframes is 256 and frame rate is 96k  and BPM is 5 (or less) you got 0.928798 ... but pos->tick is uint32_t .. so you actually got 0 ;-). OFC this is related to your settings and that's way YMMV. Well ... in some cases jack_transport will not push BBT at all ;-)

The problem is in Transport design itself - because BBT master works always in current cycle space/context - I mean - it  doesn't look at the history (anyway it can't if we want to have tempo changes, right ?), and because ticks are uint32_t  we will have always some rounding.

The most simple way to fix this that I see is push tick to double - but this probably made some compatibility issues :(

Or maybe someone have better idea - maybe we can use pos->frame to adjust pos->tick in next frame ?

Pawel / Xj
PrevNext  Index

1368592291.30117_0.ltw:2,a <51930f984657c3.87876285 at wp dot pl>