2024-08-19 22:43:24 +10:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
2024-10-01 13:39:28 +10:00
|
|
|
#include "util.hpp"
|
2024-08-19 22:43:24 +10:00
|
|
|
|
|
|
|
struct Tone {
|
2024-10-03 02:27:58 +10:00
|
|
|
|
|
|
|
enum Type {
|
|
|
|
tt_sine = 0,
|
|
|
|
tt_saw = 1,
|
|
|
|
tt_square = 2,
|
|
|
|
tt_triangle = 3,
|
|
|
|
};
|
|
|
|
|
2024-08-19 22:43:24 +10:00
|
|
|
uint32_t phase;
|
|
|
|
uint16_t frequency;
|
2024-08-26 13:02:17 +10:00
|
|
|
uint8_t amplitude;
|
2024-10-03 02:27:58 +10:00
|
|
|
Type mode;
|
2024-08-26 13:02:17 +10:00
|
|
|
|
|
|
|
inline static int8_t sin_lookup[256];
|
|
|
|
|
|
|
|
static void init();
|
2024-08-19 22:43:24 +10:00
|
|
|
|
2024-10-01 13:39:28 +10:00
|
|
|
inline bool active() const AW_IN {
|
2024-08-19 22:43:24 +10:00
|
|
|
return amplitude > 0;
|
|
|
|
}
|
|
|
|
|
2024-10-01 13:39:28 +10:00
|
|
|
inline void update(uint32_t t) AW_IN {
|
2024-08-19 22:43:24 +10:00
|
|
|
phase += t * frequency;
|
|
|
|
}
|
|
|
|
|
2024-10-01 13:39:28 +10:00
|
|
|
inline int get() const AW_IN {
|
2024-10-03 02:27:58 +10:00
|
|
|
int v;
|
|
|
|
switch(mode) {
|
|
|
|
case tt_sine:
|
|
|
|
v = sin_lookup[(phase >> 12) & 255];
|
|
|
|
break;
|
|
|
|
case tt_saw:
|
|
|
|
v = (int8_t)((phase >> 12) & 255);
|
|
|
|
break;
|
|
|
|
case tt_square:
|
|
|
|
v = phase & 0x80000 ? -127 : 127;
|
|
|
|
break;
|
|
|
|
case tt_triangle:
|
|
|
|
v = (phase >> 11) & 0x1ff;
|
|
|
|
v = (v > 0xff ? 1 : -1) * (int8_t)phase;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return v * amplitude;
|
2024-08-19 22:43:24 +10:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|