29template <
class T =
int16_t>
59 virtual void end(
bool allow_rampdown) {
62 LOGD(
"end() immediate");
83 virtual size_t readBytes(uint8_t* data,
size_t len) {
84 LOGD(
"readBytes: %d", (
int)len);
87 int frame_size =
sizeof(T) * channels;
88 int frames = len / frame_size;
89 if (len >= frame_size) {
100 int frames = len / channels;
101 if (frames == 0)
return 0;
116 LOGE(
"setFrequency not supported");
134 LOGI(
"setPlayTime: playMs=%d, upPercent=%d, downPercent=%d",
playMs,
194 LOGE(
"Only use either: setPlayTime() or setRampTimes(), not both. up%% %u down%% %u upMs: %u downMs: %u",
196 LOGE(
"Reset the other to zero if switching back and forth.")
238 T* result_buffer = (T*)buffer;
239 int frames_written = 0;
245 for (
int j = 0; j < frames; j++) {
254 for (
int ch = 0; ch < channels; ch++) {
255 *result_buffer++ = sample;
265 return frames_written *
sizeof(T) * channels;
288 return (T)(
factor * sample);
292 int frame_size,
int channels) {
295 uint8_t tmp[frame_size];
316template <
class T =
int16_t>
321 float phase = 0.0f) {
322 LOGD(
"FloatSineGenerator");
335 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"FloatSineGenerator",
343 LOGI(
"%s::begin(channels=%d, sample_rate=%d, frequency=%.2f)",
348 if (frequency > 0.0f) {
354 bool begin(
int channels,
int sample_rate,
float frequency) {
372 LOGI(
"setFrequency: %.2f", frequency);
404 LOGI(
"amplitude: %f", this->m_amplitude);
416template <
class T =
int16_t>
421 LOGD(
"FastSineGenerator");
439 float p = (t - (int)t) - 0.5f;
441 return (p - 6.283211f * pp * p + 9.132843f * pp * pp * p) * -6.221086f;
461template <
class T =
int16_t>
465 float phase = 0.0f) {
466 LOGD(
"FastIntSineGenerator");
479 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"FastIntSineGenerator",
488 if (frequency > 0.0f) {
494 bool begin(
int channels,
int sample_rate,
float frequency) {
507 LOGI(
"setFrequency: %.2f", frequency);
514 double turns = phase / (2.0 *
PI);
548 if (sample_rate > 0) {
550 (uint32_t)((
double)
m_frequency / sample_rate * 4294967296.0);
556 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179,
557 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279, 14010, 14732,
558 15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403,
559 22005, 22594, 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790,
560 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956, 30273, 30571,
561 30852, 31113, 31356, 31580, 31785, 31971, 32137, 32285, 32412, 32521,
562 32609, 32678, 32728, 32757, 32767, 32757, 32728, 32678, 32609, 32521,
563 32412, 32285, 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571,
564 30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790,
565 26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005, 21403,
566 20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151, 15446, 14732,
567 14010, 13279, 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179,
568 6393, 5602, 4808, 4011, 3212, 2410, 1608, 804, 0, -804,
569 -1608, -2410, -3212, -4011, -4808, -5602, -6393, -7179, -7962, -8739,
570 -9512, -10278,-11039,-11793,-12539,-13279,-14010,-14732,-15446,-16151,
571 -16846,-17530,-18204,-18868,-19519,-20159,-20787,-21403,-22005,-22594,
572 -23170,-23731,-24279,-24811,-25329,-25832,-26319,-26790,-27245,-27683,
573 -28105,-28510,-28898,-29268,-29621,-29956,-30273,-30571,-30852,-31113,
574 -31356,-31580,-31785,-31971,-32137,-32285,-32412,-32521,-32609,-32678,
575 -32728,-32757,-32767,-32757,-32728,-32678,-32609,-32521,-32412,-32285,
576 -32137,-31971,-31785,-31580,-31356,-31113,-30852,-30571,-30273,-29956,
577 -29621,-29268,-28898,-28510,-28105,-27683,-27245,-26790,-26319,-25832,
578 -25329,-24811,-24279,-23731,-23170,-22594,-22005,-21403,-20787,-20159,
579 -19519,-18868,-18204,-17530,-16846,-16151,-15446,-14732,-14010,-13279,
580 -12539,-11793,-11039,-10278,-9512, -8739, -7962, -7179, -6393, -5602,
581 -4808, -4011, -3212, -2410, -1608, -804};
591template <
class T =
int16_t>
594template <
class T =
int16_t>
599template <
class T =
int16_t>
616template <
class T =
int16_t>
620 float phase = 0.0f) {
621 LOGD(
"SquareWaveGenerator");
634 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"SquareWaveGenerator",
643 if (frequency > 0.0f) {
649 bool begin(
int channels,
int sample_rate,
float frequency) {
662 LOGI(
"setFrequency: %.2f", frequency);
669 double turns = phase / (2.0 *
PI);
698 if (sample_rate > 0) {
700 (uint32_t)((
double)
m_frequency / sample_rate * 4294967296.0);
720template <
class T =
int16_t>
724 float phase = 0.0f) {
725 LOGD(
"SawToothGenerator");
738 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"SawToothGenerator",
747 if (frequency > 0.0f) {
753 bool begin(
int channels,
int sample_rate,
float frequency) {
766 LOGI(
"setFrequency: %.2f", frequency);
773 double turns = phase / (2.0 *
PI);
788 int32_t ramp = (int32_t)phase;
804 if (sample_rate > 0) {
806 (uint32_t)((
double)
m_frequency / sample_rate * 4294967296.0);
818template <
class T =
int16_t>
830 int random(
int min,
int max) {
return min + rand() % ((max + 1) - min); }
840template <
class T =
int16_t>
860 int diff = last_key ^
key;
862 for (
int i = 0; i < 5; i++) {
887template <
class T =
int16_t>
909template <
class T =
int16_t>
942 for (
int j = 0; j <
channels; j++) {
973template <
class T =
int16_t>
989 template <
size_t arrayLen>
991 bool setInactiveAtEnd =
false,
size_t startIndex = 0) {
999 template <
int arrayLen>
1007 for (
int j = 0; j < size; j++) {
1008 table[j] = array[j];
1010 LOGI(
"table_length: %d", (
int)size);
1039 if (
table.size() == 0) {
1047 const float table_size =
static_cast<float>(
table.size());
1069 int idx1 = idx0 + 1;
1070 if (idx1 >=
static_cast<int>(
table.size())) {
1073 float frac =
sound_index -
static_cast<float>(idx0);
1074 float sample =
static_cast<float>(
table[idx0]) * (1.0f - frac) +
1075 static_cast<float>(
table[idx1]) * frac;
1076 result =
static_cast<T
>(sample);
1092 LOGE(
"setFrequency failed: sample_rate=%d table_size=%d",
1106 int setupSine(
int sampleRate,
float reqFrequency,
float amplitude = 1.0) {
1108 static_cast<float>(sampleRate) /
1110 float angle = 2.0 *
PI / sample_count;
1111 table.resize(sample_count);
1112 for (
int j = 0; j < sample_count; j++) {
1113 table[j] = sinf(j * angle) * amplitude;
1116 return sampleRate / sample_count;
1141template <
class T =
int16_t>
1178template <
class T =
int16_t>
1196 if (
angle >= 360.0f) {
1197 while (
angle >= 360.0f) {
1225 bool begin(
int channels,
int sample_rate, uint16_t frequency = 0) {
1251 0, 0.0174524, 0.0348995, 0.052336, 0.0697565, 0.0871557,
1252 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809,
1253 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372,
1254 0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731,
1255 0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481,
1256 0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576,
1257 0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059,
1258 0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354,
1259 0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636,
1260 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167,
1261 0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308,
1262 0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519,
1263 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437,
1264 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546,
1265 0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848,
1266 1, 0.999848, 0.999391, 0.99863, 0.997564, 0.996195,
1267 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627,
1268 0.978148, 0.97437, 0.970296, 0.965926, 0.961262, 0.956305,
1269 0.951057, 0.945519, 0.939693, 0.93358, 0.927184, 0.920505,
1270 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.87462,
1271 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152,
1272 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.75471,
1273 0.743145, 0.731354, 0.71934, 0.707107, 0.694658, 0.681998,
1274 0.669131, 0.656059, 0.642788, 0.62932, 0.615661, 0.601815,
1275 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038,
1276 0.5, 0.48481, 0.469472, 0.45399, 0.438371, 0.422618,
1277 0.406737, 0.390731, 0.374607, 0.358368, 0.34202, 0.325568,
1278 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951,
1279 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869,
1280 0.104528, 0.0871557, 0.0697565, 0.052336, 0.0348995, 0.0174524,
1284 bool positive = (
angle <= 180.0f);
1285 float angle_positive = positive ?
angle :
angle - 180.0f;
1286 int angle_int1 = angle_positive;
1287 int angle_int2 = angle_int1 + 1;
1290 T result = v1 < v2 ?
map(angle_positive, angle_int1, angle_int2, v1, v2)
1291 :
map(angle_positive, angle_int1, angle_int2, v2, v1);
1293 return positive ? result : -result;
1296 T
map(T x, T in_min, T in_max, T out_min, T out_max) {
1297 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
1305 if (abs(diff) >= 1.0f) {
1319template <
class T =
int16_t>
1332 for (
auto& generator :
vector) {
1333 if (generator->isActive()) {
1334 T sample = generator->readSample();
1339 return count > 0.0f ? total / count : 0;
1355template <
class T =
int16_t>
1383template <
class T =
int16_t>
1386 virtual bool begin(uint16_t queue_size=256) {
1396 virtual size_t readBytes(uint8_t *buffer,
size_t buf_len)
override {
1397 LOGD(
"readBytes: %d", (
int)buf_len);
1399 if (
queue.available() == 0)
return 0;
1401 size_t bytes_read = 0;
1405 while (bytes_read < buf_len) {
1408 ret = current_generator->
readBytes(buffer+bytes_read, buf_len-bytes_read);
1414 if (
queue.available() == 0)
break;
1423 if (
readBytes((uint8_t *)&buf,
sizeof(T)) !=
sizeof(T))
return (T)0;
1428 return (
readBytes((uint8_t *)data, len*
sizeof(T)) /
sizeof(T));
1439 const void *cb_data =
nullptr
1441 LOGD(
"pushGenerator()");
1442 if (
queue.availableForWrite() == 0)
return false;
1444 QNode *node =
new QNode(gen, start_cb, end_cb, cb_data);
1445 if (node ==
nullptr)
return false;
1447 if (!
queue.write(node)) {
1456 virtual inline void setPlayTime(uint32_t p, uint8_t u = 20, uint8_t d = 30)
override {
1457 LOGW(
"GeneratorQueue::setPlayTime() does nothing.");
1460 LOGW(
"GeneratorQueue::setFrequency() does nothing.");
1465 if (!
queue.peek(node))
return nullptr;
1471 return queue.available() == 0;
1495 if (
queue.available() == 0)
return nullptr;
1497 QNode *node =
nullptr;
1498 if (!
queue.peek(node) || node ==
nullptr)
return nullptr;
1512 if (
queue.available() == 0)
return false;
1514 QNode *node =
nullptr;
1515 bool ret =
queue.read(node);
1516 if (node !=
nullptr) {
#define PI
Definition AudioEffectsSuite.h:28
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140