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 63 static 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,
84 SineWaveformGenerator::SineWaveformGenerator()
94 if (m_frequency != value) {
96 m_phaseInc = (((uint32_t)m_frequency * 256) << 11) /
sampleRate();
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;
139 SquareWaveformGenerator::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;
198 TriangleWaveformGenerator::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;
250 SawtoothWaveformGenerator::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;
302 NoiseWaveformGenerator::NoiseWaveformGenerator()
320 m_noise = (m_noise >> 1) ^ (-(m_noise & 1) & 0xB400u);
321 int sample = 127 - (m_noise >> 8);
324 sample = sample *
volume() / 127;
343 VICNoiseGenerator::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;
417 SamplesGenerator::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();
475 SoundGenerator::~SoundGenerator()
478 vTaskDelete(m_waveGenTaskHandle);
479 heap_caps_free(m_sampleBuffer);
480 vSemaphoreDelete(m_mutex);
486 AutoSemaphore autoSemaphore(m_mutex);
488 m_channels =
nullptr;
492 void 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 );
548 bool 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)
573 bool 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())
624 void 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;
685 void 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);
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
int getSample()
Gets next sample.
void setFrequency(int value)
Sets output frequency.
void attach(WaveformGenerator *value)
Attaches a waveform generator.
int getSample()
Gets next sample.
int volume()
Determines current overall volume.
void clear()
Stops playing and removes all attached waveform generators.
void detach(WaveformGenerator *value)
Detaches a waveform generator.
bool play(bool value)
Starts or stops playing.
void setFrequency(int value)
Sets output frequency.
This file contains all classes related to FabGL Sound System.
SoundGenerator(int sampleRate=16000)
Creates an instance of the sound generator. Only one instance is allowed.