29#include "freertos/FreeRTOS.h"
30#include "freertos/timers.h"
36#include "driver/i2s.h"
37#include "driver/adc.h"
38#include "esp_adc_cal.h"
39#if __has_include("hal/i2s_types.h")
40 #include "hal/i2s_types.h"
48#pragma GCC optimize ("O2")
55#define FABGL_SAMPLE_BUFFER_SIZE 32
63static const int8_t sinTable[257] = {
64 0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46,
65 49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88,
66 90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116,
67 117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127,
68 127, 127, 127, 127, 126, 126, 126, 125, 125, 124, 123, 122, 122, 121, 120, 118,
69 117, 116, 115, 113, 112, 111, 109, 107, 106, 104, 102, 100, 98, 96, 94, 92,
70 90, 88, 85, 83, 81, 78, 76, 73, 71, 68, 65, 63, 60, 57, 54, 51,
71 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 12, 9, 6, 3,
72 0, -3, -6, -9, -12, -16, -19, -22, -25, -28, -31, -34, -37, -40, -43, -46,
73 -49, -51, -54, -57, -60, -63, -65, -68, -71, -73, -76, -78, -81, -83, -85, -88,
74 -90, -92, -94, -96, -98, -100, -102, -104, -106, -107, -109, -111, -112, -113, -115, -116,
75-117, -118, -120, -121, -122, -122, -123, -124, -125, -125, -126, -126, -126, -127, -127, -127,
76-127, -127, -127, -127, -126, -126, -126, -125, -125, -124, -123, -122, -122, -121, -120, -118,
77-117, -116, -115, -113, -112, -111, -109, -107, -106, -104, -102, -100, -98, -96, -94, -92,
78 -90, -88, -85, -83, -81, -78, -76, -73, -71, -68, -65, -63, -60, -57, -54, -51,
79 -49, -46, -43, -40, -37, -34, -31, -28, -25, -22, -19, -16, -12, -9, -6, -3,
84SineWaveformGenerator::SineWaveformGenerator()
93void SineWaveformGenerator::setFrequency(
int value) {
94 if (m_frequency != value) {
96 m_phaseInc = (((uint32_t)m_frequency * 256) << 11) / sampleRate();
101int SineWaveformGenerator::getSample() {
102 if (m_frequency == 0 || duration() == 0) {
103 if (m_lastSample > 0)
105 else if (m_lastSample < 0)
113 uint32_t index = m_phaseAcc >> 11;
114 double fmul = (double)(m_phaseAcc & 0x7ff) / 2048.0;
115 int sample = sinTable[index] + (sinTable[index + 1] - sinTable[index]) * fmul;
118 sample = sample * volume() / 127;
120 m_lastSample = sample;
122 m_phaseAcc = (m_phaseAcc + m_phaseInc) & 0x7ffff;
139SquareWaveformGenerator::SquareWaveformGenerator()
150 if (m_frequency != value) {
152 m_phaseInc = (((uint32_t)m_frequency * 256) << 11) /
sampleRate();
160 m_dutyCycle = dutyCycle;
165 if (m_frequency == 0 ||
duration() == 0) {
166 if (m_lastSample > 0)
168 else if (m_lastSample < 0)
175 uint32_t index = m_phaseAcc >> 11;
176 int sample = (index <= m_dutyCycle ? 127 : -127);
179 sample = sample *
volume() / 127;
181 m_lastSample = sample;
183 m_phaseAcc = (m_phaseAcc + m_phaseInc) & 0x7ffff;
198TriangleWaveformGenerator::TriangleWaveformGenerator()
208 if (m_frequency != value) {
210 m_phaseInc = (((uint32_t)m_frequency * 256) << 11) /
sampleRate();
216 if (m_frequency == 0 ||
duration() == 0) {
217 if (m_lastSample > 0)
219 else if (m_lastSample < 0)
226 uint32_t index = m_phaseAcc >> 11;
227 int sample = (index & 0x80 ? -1 : 1) * ((index & 0x3F) * 2 - (index & 0x40 ? 0 : 127));
230 sample = sample *
volume() / 127;
232 m_lastSample = sample;
234 m_phaseAcc = (m_phaseAcc + m_phaseInc) & 0x7ffff;
250SawtoothWaveformGenerator::SawtoothWaveformGenerator()
260 if (m_frequency != value) {
262 m_phaseInc = (((uint32_t)m_frequency * 256) << 11) /
sampleRate();
268 if (m_frequency == 0 ||
duration() == 0) {
269 if (m_lastSample > 0)
271 else if (m_lastSample < 0)
278 uint32_t index = m_phaseAcc >> 11;
279 int sample = index - 128;
282 sample = sample *
volume() / 127;
284 m_lastSample = sample;
286 m_phaseAcc = (m_phaseAcc + m_phaseInc) & 0x7ffff;
302NoiseWaveformGenerator::NoiseWaveformGenerator()
320 m_noise = (m_noise >> 1) ^ (-(m_noise & 1) & 0xB400u);
321 int sample = 127 - (m_noise >> 8);
324 sample = sample *
volume() / 127;
343VICNoiseGenerator::VICNoiseGenerator()
354 if (m_frequency != value) {
355 m_frequency = value >= 127 ? 0 : value;
373 for (
int i = 0; i < reduc; ++i) {
375 if (m_counter >= 127) {
378 m_counter = m_frequency;
381 m_outSR = ((m_outSR << 1) | ~(m_outSR >> 7));
384 int bit3 = (m_LFSR >> 3) & 1;
385 int bit12 = (m_LFSR >> 12) & 1;
386 int bit14 = (m_LFSR >> 14) & 1;
387 int bit15 = (m_LFSR >> 15) & 1;
388 m_LFSR |= (bit3 ^ bit12) ^ (bit14 ^ bit15);
392 sample += m_outSR & 1 ? 127 : -128;
397 sample = sample / reduc;
400 sample = sample *
volume() / 127;
417SamplesGenerator::SamplesGenerator(int8_t
const *
data,
int length)
436 int sample = m_data[m_index++];
438 if (m_index == m_length)
442 sample = sample *
volume() / 127;
462 : m_waveGenTaskHandle(nullptr),
464 m_sampleBuffer(nullptr),
466 m_sampleRate(sampleRate),
468 m_state(SoundGeneratorState::Stop)
470 m_mutex = xSemaphoreCreateMutex();
475SoundGenerator::~SoundGenerator()
478 vTaskDelete(m_waveGenTaskHandle);
479 heap_caps_free(m_sampleBuffer);
480 vSemaphoreDelete(m_mutex);
486 AutoSemaphore autoSemaphore(m_mutex);
488 m_channels =
nullptr;
492void SoundGenerator::i2s_audio_init()
494 i2s_config_t i2s_config;
495 i2s_config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN);
496 i2s_config.sample_rate = m_sampleRate;
497 i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
498 #if FABGL_ESP_IDF_VERSION <= FABGL_ESP_IDF_VERSION_VAL(4, 1, 1)
499 i2s_config.communication_format = (i2s_comm_format_t) I2S_COMM_FORMAT_I2S_MSB;
501 i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
503 i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
504 i2s_config.intr_alloc_flags = 0;
505 i2s_config.dma_buf_count = 2;
506 i2s_config.dma_buf_len = FABGL_SAMPLE_BUFFER_SIZE *
sizeof(uint16_t);
507 i2s_config.use_apll = 0;
508 i2s_config.tx_desc_auto_clear = 0;
509 i2s_config.fixed_mclk = 0;
511 i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
513 i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
515 m_sampleBuffer = (uint16_t*) heap_caps_malloc(FABGL_SAMPLE_BUFFER_SIZE *
sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
522 AutoSemaphore autoSemaphore(m_mutex);
524 if (actualPlaying() != value) {
525 bool r = forcePlay(value);
538 sgen->setAutoDestroy(
true);
540 sgen->setDuration(durationMS > 0 ? (m_sampleRate / 1000 * durationMS) : length );
548bool SoundGenerator::forcePlay(
bool value)
550 bool isPlaying = actualPlaying();
554 if (!m_waveGenTaskHandle)
555 xTaskCreate(waveGenTask,
"", WAVEGENTASK_STACK_SIZE,
this, 5, &m_waveGenTaskHandle);
556 m_state = SoundGeneratorState::RequestToPlay;
557 xTaskNotifyGive(m_waveGenTaskHandle);
563 m_state = SoundGeneratorState::RequestToStop;
565 while (m_state != SoundGeneratorState::Stop)
573bool SoundGenerator::actualPlaying()
575 return m_waveGenTaskHandle && m_state == SoundGeneratorState::Playing;
582 AutoSemaphore autoSemaphore(m_mutex);
584 bool isPlaying = forcePlay(
false);
586 value->setSampleRate(m_sampleRate);
588 value->next = m_channels;
591 forcePlay(isPlaying || m_play);
600 AutoSemaphore autoSemaphore(m_mutex);
602 bool isPlaying = forcePlay(
false);
603 detachNoSuspend(value);
604 forcePlay(isPlaying);
610 for (
WaveformGenerator * c = m_channels, * prev =
nullptr; c; prev = c, c = c->next) {
613 prev->next = c->next;
615 m_channels = c->next;
616 if (value->autoDestroy())
624void IRAM_ATTR SoundGenerator::waveGenTask(
void * arg)
628 i2s_set_clk(I2S_NUM_0, soundGenerator->m_sampleRate, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
630 uint16_t * buf = soundGenerator->m_sampleBuffer;
633 int muteCyclesCount = 0;
638 if (soundGenerator->m_state == SoundGeneratorState::RequestToStop || soundGenerator->m_state == SoundGeneratorState::Stop) {
639 soundGenerator->m_state = SoundGeneratorState::Stop;
640 while (soundGenerator->m_state == SoundGeneratorState::Stop)
641 ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
645 if (soundGenerator->m_channels ==
nullptr && muteCyclesCount >= 8) {
646 soundGenerator->m_state = SoundGeneratorState::Stop;
647 while (soundGenerator->m_state == SoundGeneratorState::Stop)
648 ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
651 soundGenerator->m_state = SoundGeneratorState::Playing;
653 int mainVolume = soundGenerator->volume();
655 for (
int i = 0; i < FABGL_SAMPLE_BUFFER_SIZE; ++i) {
656 int sample = 0, tvol = 0;
657 for (
auto g = soundGenerator->m_channels; g; ) {
659 sample += g->getSample();
661 }
else if (g->duration() == 0 && g->autoDetach()) {
664 soundGenerator->detachNoSuspend(curr);
670 int avol = tvol ? imin(127, 127 * 127 / tvol) : 127;
671 sample = sample * avol / 127;
672 sample = sample * mainVolume / 127;
674 buf[i + (i & 1 ? -1 : 1)] = (127 + sample) << 8;
677 size_t bytes_written;
678 i2s_write(I2S_NUM_0, buf, FABGL_SAMPLE_BUFFER_SIZE *
sizeof(uint16_t), &bytes_written, portMAX_DELAY);
680 muteCyclesCount = soundGenerator->m_channels ==
nullptr ? muteCyclesCount + 1 : 0;
685void SoundGenerator::mutizeOutput()
687 for (
int i = 0; i < FABGL_SAMPLE_BUFFER_SIZE; ++i)
688 m_sampleBuffer[i] = 127 << 8;
689 size_t bytes_written;
690 for (
int i = 0; i < 4; ++i)
691 i2s_write(I2S_NUM_0, m_sampleBuffer, FABGL_SAMPLE_BUFFER_SIZE *
sizeof(uint16_t), &bytes_written, portMAX_DELAY);
int getSample()
Gets next sample.
void setFrequency(int value)
Sets output frequency.
void attach(WaveformGenerator *value)
Attaches a waveform generator.
void detach(WaveformGenerator *value)
Detaches a waveform generator.
int volume()
Determines current overall volume.
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
SoundGenerator(int sampleRate=16000)
Creates an instance of the sound generator. Only one instance is allowed.
bool play(bool value)
Starts or stops playing.
void clear()
Stops playing and removes all attached waveform generators.
int getSample()
Gets next sample.
void setFrequency(int value)
Sets output frequency.
This file contains all classes related to FabGL Sound System.