News:

SMF for DIYStompboxes.com!

Main Menu

LFO Tap tempo help

Started by tss, October 26, 2014, 09:46:14 AM

Previous topic - Next topic

tss

I'm trying to write code for a an LFO with target freq. range of 0.5Hz to 20Hz, the actual output is made by an external DAC to an AVR. To generate the output I use a phase accumulator which is just a 32bit variable to which I add various "adders" (values) at a fixed interval. The top 8 bits are used as index to a LUT containing the waveforms. The adder values are stored inside an array.

Normally I would like to use the potentiometer to set the freq. so because the ADC resolution is 10 bits I made the array with the adders 1024 long and I simply use the converted value as index. So far all good...

I measure the time between 2 button presses inside an interrupt routine which fires every 1ms. This way I can calculate the time between the two presses and I get the reading in ms. My problem is that I don't know how to convert the ms reading to the correct index required to add the right value to the phase accumulator. Any thoughts on this?

slacker

#1
This is mostly thinking out loud so might not be right but,
Assuming your pot goes from slowest anti clockwise to fastest clockwise

0.5Hz = 2000ms = 0 on your pot
20Hz = 50ms = 1023 on your pot

So you've got a range of 2000 - 50 = 1950ms mapped to 1024 indexes.

If you do 2000 - tapped value in ms / 1950 * 1023 that will map the tapped value across the same range of indexes as the pot.

2000 - 2000 / 1950 * 1023 = 0
2000 - 50 / 1950 * 1023 = 1023

In theory this could end up giving a value of greater then 1023 because you could get a value as low as 1ms, in practice this probably doesn't matter as you can't tap that fast. You can always add code to mask off higher values.
That will only work if your adders are linear though, if you're using them to create a fake log response from the pot or something it won't give you the correct speed.

ElectricDruid

Quote from: tss on October 26, 2014, 09:46:14 AM
I'm trying to write code for a an LFO with target freq. range of 0.5Hz to 20Hz, the actual output is made by an external DAC to an AVR. To generate the output I use a phase accumulator which is just a 32bit variable to which I add various "adders" (values) at a fixed interval. The top 8 bits are used as index to a LUT containing the waveforms. The adder values are stored inside an array.

Normally I would like to use the potentiometer to set the freq. so because the ADC resolution is 10 bits I made the array with the adders 1024 long and I simply use the converted value as index. So far all good...

I measure the time between 2 button presses inside an interrupt routine which fires every 1ms. This way I can calculate the time between the two presses and I get the reading in ms. My problem is that I don't know how to convert the ms reading to the correct index required to add the right value to the phase accumulator. Any thoughts on this?

The way I dealt with it was to avoid doing a lookup for tapped tempos. Unfortunately this means you need to do a division instead. The freq_inc (what you call the "adder"), the frequency, and the sample rate are related by the following:

  freq_increment = 2^32 * freq / sample_rate

We can replace "freq" with "1/period" since it's the same thing:

  freq_increment = 2^32  / (sample_rate * period)

Since 2^32 / sample_rate is a constant we can reduce that a bit:

  constant =  2^32  / sample_rate

  freq_increment = constant  / period

The final result of all this is that you work out the constant for your LFO, then you measure the period and divide one by the other. It works, but like I said, the division is a pain.

Alternatively, if the frequencies in your table of adders are linear (like Slacker said - I'm following him around today!) then you ought to be able to multiply the tap tempo timer count by some multiplier and use that for a lookup index. The value of the multiplier would depend on the count units (milliseconds or whatever). Bonus points if you can arrange things so that the multiplier finishes up binary-friendly and can be done with shifts.

HTH,
Tom



gena_p1

really, you don't need "normal" time for measurements , internal ticks would be enough.

ElectricDruid

Quote from: gena_p1 on May 18, 2015, 04:16:39 AM
really, you don't need "normal" time for measurements , internal ticks would be enough.

No, absolutely. I used sample clocks, and it made things much simpler.