[PD] libPd timing issue, seemingly caused by processing multiple 'ticks' of audio blocks.

Chris McCormick chris at mccormick.cx
Wed Nov 11 03:42:08 CET 2015


Hello!

On 11/11/15 09:18, i go bananas wrote:
> We're trying to implement various sync options in an iOS libPd-based
> app, and have run across a noticeable drift in the timing.

 From Oliver's previous email I guess you're also trying to integrate 
Abelton's "link sync" with your libpd based apps.

https://www.ableton.com/en/link/

> The app uses
> 8 'ticks' of 64 samples for faster devices, and 16 ticks for slower ones.
> Basically what this means, is that messages are only being processed on
> these larger multi-block boundaries of 512 or 1024 samples.  And that's
> not good enough for keeping timing tight.
>
> Of course, the first question is:  Has anyone already made a workaround
> to this issue???

You can't really work around physics.

> Or does anyone know of a way to make sure libPd processes messages with
> proper timing, even with the 'ticks' value set quite high?
>
> I have an idea for adding time delay messages to clock signals...so that
> they can be sent through a [pipe] in pd to arrive at the correct time
> during the block processing. But it looks quite tricky to implement, and
> i'll wait to see if there is maybe a better solution first.

I don't think that will work.

 From your and Oliver's description (multiple blocks processed at once) 
you seem to be using libpd's PROCESS macro under the hood.

https://github.com/libpd/libpd/blob/master/libpd_wrapper/z_libpd.c#L164

Here is a diagram of what is happening (time goes from left to right). 
Hopefully I have this right:

a: >XX|XX|X_|__|*_|__|__|__>

b: >XX|XX|XX|XX|*X|XX|X_|__>

  * The time between the greater than pipe symbols is the real time that 
each block boundary would occur.
  * The time between the greater than signs is the real time that your 
8-ticks of one block each would take.
  * The X's are Pd crunching the numbers to produce output audio for all 
8 ticks in the next set.
  * The asterisk symbol is a MIDI or other network based event that 
might come in.
  * You don't hear the audio produced by the X's until the final greater 
than sign.

As you can see in (a) sometimes the number crunching for the entire 8 
ticks is done well before the final greater than sign. Other times, as 
in (b) it only just completes just in time for the audio to come out of 
the speaker, which is presumably why you need to process 8 blocks at 
once. If a sync event arrives, what is libpd and Pd supposed to do? It 
has to wait until the next block of 8 ticks to process the event.

What you propose (using a pipe internally) only delays it within the 
following block so the sync would be even worse.

Your only option is to use less ticks, if you can afford the constraints 
on CPU. In general it's a good strategy to be conservative with regards 
to CPU when doing audio on mobile devices. That might let you get away 
with less ticks.

Hopefully I have this right. If I don't I am sure one of the many people 
on this list smarter than me will correct this. :)

This is all a bit confusing to me because my experience with iOS is that 
one is able to do 20ms block delay/latency quite comfortably for 
anything I have thrown at it.

By the way if anybody is interested in a local-area-network based music 
syncing solution over UDP that is Free Software and unencumbered by 
proprietary licenses, closed SDK, etc. here is a link to the SyncJams 
repository. :)

https://github.com/chr15m/SyncJams

One thing I am super excited about is I heard a rumor that Katja is 
working on a Raspberry Pi based alternative to running Pd on iOS touch 
devices which I imagine should have even lower latency - great for 
building effects units and the like with Pd. I for one welcome our new 
apple crushing raspberries.

Cheers,

Chris.

-- 
http://mccormick.cx/



More information about the Pd-list mailing list