Timing issues with clock generator

Greetings all,

I’m working on a clock generator of sorts and I’m having problems with timing drift. I’ve been trying to use rack::dsp::TTimer as a phase accumulator along with std::fmod to tap off various time divisions.

If someone could take a look at my code, that would be much appreciated:

I have worked out that if I change line 221 from this:

    if(_time >= 128.f) { TIMER.reset(); }

to this:

    if(_time >= 1.f) { TIMER.reset(); }

I can improve the timing greatly, however I would like to reset the TIMER after 128 to allow for longer time divisions.

I feel like I’m hitting some kind of rounding or accumulative error type problem, but I’m not sure. Does anyone know what’s causing the drift?

Thanks in advance!

Not sure of the cause, but I was about to report this to you.

1 Like

Thanks!

Yeah I was a bit hasty in posting the pre-release, but better to find the issues now I guess. I’m new to C++ and VCV development, so it’s bound to happen

Here’s the line where i do the accumulation (line 244):

TIMER.process(freq * args.sampleTime); // accumulate!!!

I noticed that the accumulator in the VCV Plugin Development Tutorial (VCV Manual - Plugin Development Tutorial) does not use a dsp::TTimer, just a regular variable:

	// Accumulate the phase
	phase += freq * args.sampleTime;
	if (phase >= 0.5f)
		phase -= 1.f;

I would assume that producing a sine wave at audio rate needs relatively tight timing, so I take it this sort of accumulator is sufficient for the task. I have tried using a regular variable for the accumulator, and I have the same timing drift issues. So, I guess the issue is somewhere else?

Also, I would have to ask, what’s the purpose of the dsp::TTimer? is there some benefit to using one over a regular variable?

Anyway, any thoughts or tips on this would be most appreciated

1 Like

For most situations this is fine, but in my experience (working with another audio software project that I was involved in) I’ve found that it’s often better to keep from doing conversions for time per sample (each one usually adding a small amount of error) and count samples instead.

I don’t have time to look over your code at the moment, but the first, and probably easiest, thing you could try is to convert your phase variable (and calculations) to a double instead of a float. If it drifts less then at least you will know that this accuracy is the source of your issues.

3 Likes

Thanks muchly for the reply! I will try a double, see what that does and report back :+1:

2 Likes

Amazing!

I changed the timer to use a double:

rack::dsp::TTimer<double> TIMER; // main timer

…and I changed the freq variable to a double since it’s used to accumulate the timer. Now the timing seems perfect!

Thank you for the help :+1:

1 Like

Cool - I’m glad that has helped you. I’ve had a few bugs, in some private modules, related to precision with the default 32-bit float type. I think the last time this happened was using the SlewLimiter.

1 Like

Great to know :+1: Yeah, a bit of a gotcha for someone like me, who’s new to both C++ and VCV dev.

Super happy with my modules now, got them working great together, really excited to get creating with them :slight_smile:

1 Like