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};
587template <
class T =
int16_t>
590template <
class T =
int16_t>
595template <
class T =
int16_t>
612template <
class T =
int16_t>
616 float phase = 0.0f) {
617 LOGD(
"SquareWaveGenerator");
630 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"SquareWaveGenerator",
639 if (frequency > 0.0f) {
645 bool begin(
int channels,
int sample_rate,
float frequency) {
658 LOGI(
"setFrequency: %.2f", frequency);
665 double turns = phase / (2.0 *
PI);
694 if (sample_rate > 0) {
696 (uint32_t)((
double)
m_frequency / sample_rate * 4294967296.0);
716template <
class T =
int16_t>
720 float phase = 0.0f) {
721 LOGD(
"SawToothGenerator");
734 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"SawToothGenerator",
743 if (frequency > 0.0f) {
749 bool begin(
int channels,
int sample_rate,
float frequency) {
762 LOGI(
"setFrequency: %.2f", frequency);
769 double turns = phase / (2.0 *
PI);
784 int32_t ramp = (int32_t)phase;
800 if (sample_rate > 0) {
802 (uint32_t)((
double)
m_frequency / sample_rate * 4294967296.0);
814template <
class T =
int16_t>
826 int random(
int min,
int max) {
return min + rand() % ((max + 1) - min); }
836template <
class T =
int16_t>
856 int diff = last_key ^
key;
858 for (
int i = 0; i < 5; i++) {
883template <
class T =
int16_t>
905template <
class T =
int16_t>
938 for (
int j = 0; j <
channels; j++) {
969template <
class T =
int16_t>
985 template <
size_t arrayLen>
987 bool setInactiveAtEnd =
false,
size_t startIndex = 0) {
995 template <
int arrayLen>
1003 for (
int j = 0; j < size; j++) {
1004 table[j] = array[j];
1006 LOGI(
"table_length: %d", (
int)size);
1035 if (
table.size() == 0) {
1043 const float table_size =
static_cast<float>(
table.size());
1065 int idx1 = idx0 + 1;
1066 if (idx1 >=
static_cast<int>(
table.size())) {
1069 float frac =
sound_index -
static_cast<float>(idx0);
1070 float sample =
static_cast<float>(
table[idx0]) * (1.0f - frac) +
1071 static_cast<float>(
table[idx1]) * frac;
1072 result =
static_cast<T
>(sample);
1088 LOGE(
"setFrequency failed: sample_rate=%d table_size=%d",
1102 int setupSine(
int sampleRate,
float reqFrequency,
float amplitude = 1.0) {
1104 static_cast<float>(sampleRate) /
1106 float angle = 2.0 *
PI / sample_count;
1107 table.resize(sample_count);
1108 for (
int j = 0; j < sample_count; j++) {
1109 table[j] = sinf(j * angle) * amplitude;
1112 return sampleRate / sample_count;
1137template <
class T =
int16_t>
1174template <
class T =
int16_t>
1192 if (
angle >= 360.0f) {
1193 while (
angle >= 360.0f) {
1221 bool begin(
int channels,
int sample_rate, uint16_t frequency = 0) {
1247 0, 0.0174524, 0.0348995, 0.052336, 0.0697565, 0.0871557,
1248 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809,
1249 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372,
1250 0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731,
1251 0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481,
1252 0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576,
1253 0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059,
1254 0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354,
1255 0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636,
1256 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167,
1257 0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308,
1258 0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519,
1259 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437,
1260 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546,
1261 0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848,
1262 1, 0.999848, 0.999391, 0.99863, 0.997564, 0.996195,
1263 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627,
1264 0.978148, 0.97437, 0.970296, 0.965926, 0.961262, 0.956305,
1265 0.951057, 0.945519, 0.939693, 0.93358, 0.927184, 0.920505,
1266 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.87462,
1267 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152,
1268 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.75471,
1269 0.743145, 0.731354, 0.71934, 0.707107, 0.694658, 0.681998,
1270 0.669131, 0.656059, 0.642788, 0.62932, 0.615661, 0.601815,
1271 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038,
1272 0.5, 0.48481, 0.469472, 0.45399, 0.438371, 0.422618,
1273 0.406737, 0.390731, 0.374607, 0.358368, 0.34202, 0.325568,
1274 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951,
1275 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869,
1276 0.104528, 0.0871557, 0.0697565, 0.052336, 0.0348995, 0.0174524,
1280 bool positive = (
angle <= 180.0f);
1281 float angle_positive = positive ?
angle :
angle - 180.0f;
1282 int angle_int1 = angle_positive;
1283 int angle_int2 = angle_int1 + 1;
1286 T result = v1 < v2 ?
map(angle_positive, angle_int1, angle_int2, v1, v2)
1287 :
map(angle_positive, angle_int1, angle_int2, v2, v1);
1289 return positive ? result : -result;
1292 T
map(T x, T in_min, T in_max, T out_min, T out_max) {
1293 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
1301 if (abs(diff) >= 1.0f) {
1315template <
class T =
int16_t>
1328 for (
auto& generator :
vector) {
1329 if (generator->isActive()) {
1330 T sample = generator->readSample();
1335 return count > 0.0f ? total / count : 0;
1351template <
class T =
int16_t>
1379template <
class T =
int16_t>
1382 virtual bool begin(uint16_t queue_size=256) {
1392 virtual size_t readBytes(uint8_t *buffer,
size_t buf_len)
override {
1393 LOGD(
"readBytes: %d", (
int)buf_len);
1395 if (
queue.available() == 0)
return 0;
1397 size_t bytes_read = 0;
1401 while (bytes_read < buf_len) {
1404 ret = current_generator->
readBytes(buffer+bytes_read, buf_len-bytes_read);
1410 if (
queue.available() == 0)
break;
1419 if (
readBytes((uint8_t *)&buf,
sizeof(T)) !=
sizeof(T))
return (T)0;
1424 return (
readBytes((uint8_t *)data, len*
sizeof(T)) /
sizeof(T));
1435 const void *cb_data =
nullptr
1437 LOGD(
"pushGenerator()");
1438 if (
queue.availableForWrite() == 0)
return false;
1440 QNode *node =
new QNode(gen, start_cb, end_cb, cb_data);
1441 if (node ==
nullptr)
return false;
1443 if (!
queue.write(node)) {
1452 virtual inline void setPlayTime(uint32_t p, uint8_t u = 20, uint8_t d = 30)
override {
1453 LOGW(
"GeneratorQueue::setPlayTime() does nothing.");
1456 LOGW(
"GeneratorQueue::setFrequency() does nothing.");
1461 if (!
queue.peek(node))
return nullptr;
1467 return queue.available() == 0;
1491 if (
queue.available() == 0)
return nullptr;
1493 QNode *node =
nullptr;
1494 if (!
queue.peek(node) || node ==
nullptr)
return nullptr;
1508 if (
queue.available() == 0)
return false;
1510 QNode *node =
nullptr;
1511 bool ret =
queue.read(node);
1512 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