Time Accuracy and Latency Compensation

Alec Gordon's icon

Hey,

I'm trying to figure out how to compensate for timing issues in max. I'm trying to record a loop and have it play back immediately. I can get it almost without delay but it still goes out of time after maybe 20 loops. I have this patch which is a composite of some other patches I found on here, but it's still not perfect.

Can anyone suggest a way to get accurate timing?

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

You are doing that wrong...

As first , only chance that player and loop would stay in sync

would be if you set count~ maximum to file length in samples.

I see that what you posted originates from one of my example patches.

The latency in there means something else :

to compensate I/O latency of audio hardware,

so that one can overdub precisely.

If you want to have playback of audio file as master,

then use sync out of whatever player you use

to run loop recorder.

Alec Gordon's icon

I don't totally get what you mean here. I did borrow your patch - all I'm trying to do here is to record a loop into a buffer and have it play back in time with the loop I'm recording. In practice the length would be undetermined but in the version I linked here I'm using a known length (drumLoop.aif) so I have an understanding of how far of it is.

My logic with the recording into the buffer in the right was that I can get an idea of how much delay there is between recording and an actual file, but that practicality of that is a pure guess.

Can you expand more on the latency compensation you use in that example?
In this version it starts out of phase and goes dramatically out of phase after about 50 iterations of the loop. I understand probably I need to correct it, but I'm not sure where you're getting the value of 480 and 51 from. I tried using the sample rate and vector size from the settings (and variations of these numbers) but it doesn't really help me

Max Patch
Copy patch and select New From Clipboard in Max.

Wil's icon

this is the important guts of your player

before overdubbing understand single dub

sample length should be dynamic (change for different size files) and accurate

using [snapshot] without a number never works for me

you have a lot of hard coded numbers that should be dynamic (especially the compensation-latency)

that patch is a nightmare (the stuff added beyond Source Audio original)


Alec Gordon's icon

The added stuff is just a very quick way of getting it to record into the buffer once and loop. It's a very quick sketch to test timings.
I understand the image you linked, I was doing some testing with timing accuracies but I found count to be pretty useless.

Ultimately the length of the recording would be unknown - which as far as I can tell is what source is doing with the 1323000 value in the patch. In the image you linked, what value are you using for the compensation? This is essentially what I'm asking for and can't find an answer for anywhere

Alec Gordon's icon

This is what I'm trying to do - the count~ duration seems to always be off, but I can't figure out how I'm supposed to correct it. In Source Audio's example it's close but I can't figure out which values to correct with.


Source Audio's icon

What compensation are you talking about ?

your recording length is not unknown at all.

it should be as long as that drum loop.

so you don't need to measure anything, just tell

count to go from 0 to length of that drum loop.

If you use bang to get current count~ time, then you need to add vector size

because you are switching from non signal to signal world.

That all has nothing to do with latency compensation I used in that patch.

what I used is needed to play recorded audio from external source in advance,

otherwise it would lag for latency time , and one would not overdub preciselly.

Latency for internal playback recorded into buffer is not needed at all.

Wil's icon
what value are you using for the compensation?

that's my sample rate 48000 - so 1000 * 48 compensation would be one second

I adjusted manually when I was testing using laptop microphone and a latency problem

when I plug in external mic or bass through interface no latency

//

also just pressing where you said press start doesn't work at all

just a buzzing sound

//

im getting my samples like this

recorders built in RNBO so I can't share them right now

I'm trying to record a loop and have it play back immediately.

you need to figure out how to stop recorder and start player at the same time

no need for testing with sound file

Alec Gordon's icon

Ok, what I mean is the drum loop is a proxy for literally any recorded buffer. I'm testing with the drum loop because I know how long it should be, meaning I have a rough idea of how inaccurate the timing is.

What I'm trying to do is this -

Max Patch
Copy patch and select New From Clipboard in Max.

Where the subpatcher "some_kind_of_timing_solution" is whatever allows me to record and playback something that stays in time with the input. In the patch I shared above I was using the drumloop as a trigger because I knew how long it was, and it's very easy to tell if drums are in time with themselves, but I don't want to actually use a fixed duration.

In the image I shared above, I was illustrating timing attempts I've made but none of them are actually in time - they gradually phase out so that there's about 20ms of delay after about 10 repetitions or so. This made me realise I need to do some kind of compensation for the latency between recording and playing back. I realised that the recorded length and the actual length of the samples were also different, which is what led me to Source Audio's patch.

Which is what I'm asking - how do I make up for this, or what am I doing wrong that is generating this? Would the delays disappear if I do everything in the signal realm? I tried an example from Graham Wakefield in gen but the same problem occurs.

Wil's icon

I know what you are saying -

Ok, what I mean is the drum loop is a proxy for literally any recorded buffer. I'm testing with the drum loop because I know how long it should be, meaning I have a rough idea of how inaccurate the timing is.

But think about what you want to do and map it out

Forget proxy

I gave you 1/4 note in samples

I gave you basic player

what's missing to get from A to (B)?

you need a recorder that will start and stop automatically - the 'stop' starts the player

here is what I use to auto- stop

Max Patch
Copy patch and select New From Clipboard in Max.

from this thread

like I mentioned earlier - I plug this into RNBO recorder

you need only need to find a recorder

edit - you need this extra bit to get into that counter


// and you have to do some very basic math to beat count and measure count * samples


Alec Gordon's icon

I have no idea what you mean here - the thing you linked seems irrelevant to what I'm asking.

The thing to get me from A to B is I'm trying to find an accurate way of measuring duration so that my recorded buffer reflects the real duration of what I want to record so that it plays without phasing.
I understand what you mean with getting from record to play. Actually in the patch I linked if you add a 'delay~ 1' between the input signal and recording, it's synced in playback, but the issue is that the timing method I'm using changes depending on if you're processing other things, which makes it completely useless if I'm doing anything other than recording a loop.
I can't find a way from what's given above that can do it either

Wil's icon
I'm trying to figure out how to compensate for timing issues in max. I'm trying to record a loop and have it play back immediately.

You asked about recording loops

I gave everything you need

Spent 3 years working on it

timing is completely dynamic

All you need is recorder

Put the pieces together

(4 beats * 4 measures * 1 beat samples = total samples for

, buffet size, and playback)

Rock solid

Wil's icon

If 1000 ms = 48000 samples

Then 1 = 48 samples

-1 will never work

You going about it all wrong

Rethink

Alec Gordon's icon

But at no point are you measuring the length of time - you're defining the length from the beginning no?

This image you are defining the duration of the recording and player.


Here you are counting from 0 to the defined length and reading out a buffer


This seems to just be a sequencer?


From what you linked I came up with this - which seems to be relatively accurate (it's off by 100 samples or so, depending on the length of the input), but I don't have any justification for that value of 12, except from it gets me close to where I want to be.

Wil's icon
But at no point are you measuring the length of time - you're defining the length from the beginning no?

You asked for a looper that stay in sync.

I'm trying to figure out how to compensate for timing issues in max. I'm trying to record a loop and have it play back immediately. I can get it almost without delay but it still goes out of time after maybe 20 loops. I have this patch which is a composite of some other patches I found on here, but it's still not perfect.

Goes of time with what? You never said what it goes out of time with.

This image you are defining the duration of the recording and player.

Yes. that's what loopers do.

Here you are counting from 0 to the defined length and reading out a buffer

Yes that's the player

This seems to just be a sequencer?

Thats the counter (sample accurate timekeeper)

From what you linked I came up with this - which seems to be relatively accurate (it's off by 100 samples or so, depending on the length of the input), but I don't have any justification for that value of 12, except from it gets me close to where I want to be.

That's that's the player I sent - updated and destroyed

//

Please tell where do want to start - at the beginning or at the end?



Alec Gordon's icon

I don't think you understand what I'm asking for, and I also don't think I explained it very well.

I'm trying to build a looper. I know how to record and play back audio. All I am trying to do is measure the amount of time elapsed from me starting and stopping the recording, so that I can resize/playback my recording for a correct amount of time.
I've tried a bunch of ways and I can't find a good way to do it.

It seems that what you're doing in the images you shared are saying you want to record for certain amount of time, then recording for that amount of time. But that doesn't help me. It could be that I'm misunderstand the patches that you're sharing but I don't think so.

Also, like what is this about?

That's that's the player I sent - updated and destroyed

Alec Gordon's icon

This seems to be the solution -



Roman Thilenius's icon

to safely measure the time elapsed between two signal events you would use [count~], not much different from the above gen~ patch.

if you put a [del 0] behind your your start and stop buttons which control the signal objects, it will remain sampleexact from there (i.e. from data rate or "mouse") as well.

Alec Gordon's icon

Thanks a lot, this is basically what I was looking for!

Alec Gordon's icon

I ultimately decided to write it as an external. It is instantaneous and outputs a ramp to easily sync other loops. You can download it here, it only works on m1 and m2 - http://gobi10k.nl/externals.html