Is a hires timer faster than 1000 per second possible?

I have an idea, crazy perhaps, I want to explore and for that I need a hires timer that can go from 20 to 20000 times per second. All I need to do in the function, lambda, or whatever, that gets “called” x times per second, is to change the value inside one variable.

The API only allows ms to be defined. But there is a question to ask:
That variable you are changing will be likely accessed from other threads, so you will need to synchronise. So how I see it, it makes no sense, if that other calls don’t occur with the same speed. And even then you get a penalty for synchronising.

May I ask the use case?

This is not possible with a hires timer. Maybe 1000x per second can work, but don’t expect the calls to happen at regular intervals with any timer.

If you want to do audio processing, then the way to go is to get the blocks of samples and calculate the sample offsets for the regular time intervals you need and maybe interpolate.

Thanks. I was exploring if there was any way at all to emulate an analog synth, that use voltage to charge a capacitor, and then hard reset. So say for a 7040Hz note, 7040 times per second I would hard reset my look up table phase pointer.

Why not use the audio samples as a timer? 48kHz without any jitter, or even 192kHz…

Will also work with offline rendering

Yeah thanks Daniel, and I did think of that but 48000/7040 is about 6.81818181, where 192000/7040 is 27.27272727. I think I need a number much closer, if not exactly an integer. As you have probably guessed, I am still exploring if there is any way to get my “hard reset” method to work on my single wavetable, non-bandlimited synth, with higher frequencies. As I am sure others before me have also explored, there may not be, but there is that 1 out of a million chance that I might stumble upon something that others have missed, and I take such chances any day :slight_smile:

1 Like

There is no benefit whatsoever from doing something asynchronously with a high resolution timer. Also, it will jitter like hell, be extremely inefficient and won’t solve the real problem you are likely trying to solve, which is aliasing.
The audio sample clock is the highest resolution timer you can get in the system. For a hard reset, you need to properly interpolate the step in a bandlimited way, which means compute where (in between samples) the step exactly is and then basically insert a BLEP there. If you look up the term, you will likely find what you need. :slight_smile:

1 Like

Adding to that statement that due to the nature of the blockwise processing any change happening from outside cannot be attributed to a certain time within the block, unless it is timestamped, like e.g. the midi messages. Usually that means, it happens at the beginning of the block, which is said jitter.
Or if you try to use atomic variables, it is unknown when it happens, since the execution of the processing is not linearily progressing in time, it’s just happening in short bursts and then “waiting” for the next call (i.e. not running until called again).

That means that every function called outside processBlock is processed between blocks and the value/outcome is ready when the next block “comes”? What I mean is a function call that changes a value/parameter in the audiothread (let’s forget about other threads for now), won’t see it’s value changed in the middle of a processBlock as the whole block is processed as an unit right? I always had the doubt if it will happen between blocks and the value will be already changed for when the next block comes

Yeah thank you very much, I had already come to that conclusion myself, thinking about what would happen.

A thread can’t run two functions at the same time (unless with an explicit mechanism like coroutines), so yes, a parameter change in the audio thread won’t happen in the middle of processBlock, but automation often runs in a separate thread, and the UI runs in the message thread. Still, it’s good to remember this in general. Say you have a pointer holding an object that may be replaced, and a function using that object -if you know the function and the swap will always run in the same thread, you also know the object won’t be replaced during a call to the function.

1 Like