0
mirror of https://github.com/torvalds/GuitarPedal.git synced 2026-06-07 04:55:36 +00:00
Files
Linus Torvalds a12dec9c37 Bring in audio effect headers
The whole project is designed around a "self-contained header with all
code", so the header files aren't just the declarations, they are the
whole thing.

Note: these were also in the 'AudioNoise' project, which is where I was
doing some non-hardware simulation of the effects.  But at some point
the UI became a pretty big part of some of the effects too, so it's not
just about the audio code, it's also about the 'potentiometer'
descriptions (really rotary encoders) and about how to show the end
result graphically in of the 10-band EQ, for example.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-05-13 14:32:42 -07:00

91 lines
1.9 KiB
C

//
// Our LFO generates a quarter cycle (0 .. 1) from a 30-bit cycle
// and when it overflows it changes the quarter counter, which
// then turns 0..1 into a series of [ 0..1 , 1..0 , 0..-1, -1..0 ]
//
// The quarter information is naturally in the two high
// bits of the index
//
// Every audio cycle we update the LFO counter by 'lfo_step',
// so the cycle of one quarter is
//
// t = 2**30 / SAMPLES_PER_SEC / lfo_step
//
// and a full cycle is four times that (ie the full 32-bit cycle).
//
// Calling that (2**32)/SAMPLES_PER_SEC "F_STEP", we get
//
// T = F_STEP / lfo_step
// freq = lfo_step / F_STEP
// => lfo_step = freq * F_STEP
// ms = 1000 * T = 1000 * F_STEP / lfo_step
// => lfo_step = 1000 * F_STEP / ms
//
#define F_STEP (TWO_POW_32/SAMPLES_PER_SEC)
enum lfo_type {
lfo_sinewave,
lfo_triangle,
lfo_sawtooth,
};
struct lfo_state {
u32 idx, step;
};
// Use this for LFO initializers.
#define LFO_FREQ(x) .step = (x)*F_STEP
static inline void set_lfo_step(struct lfo_state *lfo, float step)
{
lfo->step = (u32) rintf(step);
}
void set_lfo_freq(struct lfo_state *lfo, float freq)
{
set_lfo_step(lfo, freq * F_STEP);
}
void set_lfo_ms(struct lfo_state *lfo, float ms)
{
// Max 10kHz
if (ms < 0.1)
ms = 0.1;
set_lfo_step(lfo, 1000 * F_STEP / ms);
}
float lfo_step(struct lfo_state *lfo, enum lfo_type type)
{
u32 now = lfo->idx;
u32 next = now + lfo->step;
lfo->idx = next;
if (type == lfo_sawtooth)
return u32_to_fraction(now);
float val;
u32 quarter = now >> 30;
now <<= 2;
// Second and fourth quarter reverses direction
if (quarter & 1)
now = ~now;
if (type == lfo_sinewave) {
u32 idx = now >> (32-QUARTER_SINE_STEP_SHIFT);
float a = quarter_sin[idx];
float b = quarter_sin[idx+1];
now <<= QUARTER_SINE_STEP_SHIFT;
val = a + (b-a)*u32_to_fraction(now);
} else {
val = u32_to_fraction(now);
}
// Last two quarters are negative
if (quarter & 2)
val = -val;
return val;
}