6 #include "../M5Unified.hpp"
10 #if __has_include (<esp_idf_version.h>)
11 #include <esp_idf_version.h>
12 #if ESP_IDF_VERSION_MAJOR >= 4
13 #define NON_BREAK ;[[fallthrough]];
21 #include <sdkconfig.h>
30 #if defined (ESP_IDF_VERSION_VAL)
31 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
32 #define COMM_FORMAT_I2S (I2S_COMM_FORMAT_STAND_I2S)
33 #define COMM_FORMAT_MSB (I2S_COMM_FORMAT_STAND_MSB)
35 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 3)
36 #define SAMPLE_RATE_TYPE uint32_t
38 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
39 #define I2S_DRIVER_VERSION 2
42 #ifndef I2S_DRIVER_VERSION
43 #define I2S_DRIVER_VERSION 1
46 #ifndef COMM_FORMAT_I2S
47 #define COMM_FORMAT_I2S (I2S_COMM_FORMAT_I2S)
48 #define COMM_FORMAT_MSB (I2S_COMM_FORMAT_I2S_MSB)
51 #ifndef SAMPLE_RATE_TYPE
52 #define SAMPLE_RATE_TYPE int
55 const uint8_t
Speaker_Class::_default_tone_wav[16] = { 177, 219, 246, 255, 246, 219, 177, 128, 79, 37, 10, 1, 10, 37, 79, 128 };
67 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
72 i2s_config_t i2s_config;
73 memset(&i2s_config, 0,
sizeof(i2s_config_t));
74 i2s_config.mode = (i2s_mode_t)( I2S_MODE_MASTER | I2S_MODE_TX );
75 i2s_config.sample_rate = 48000;
76 i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
78 ? I2S_CHANNEL_FMT_RIGHT_LEFT
79 : I2S_CHANNEL_FMT_ONLY_RIGHT;
80 i2s_config.communication_format = (i2s_comm_format_t)(
COMM_FORMAT_I2S );
81 i2s_config.tx_desc_auto_clear =
true;
82 #if I2S_DRIVER_VERSION > 1
89 i2s_pin_config_t pin_config;
90 memset(&pin_config, ~0u,
sizeof(i2s_pin_config_t));
96 if (ESP_OK != (err = i2s_driver_install(
_cfg.
i2s_port, &i2s_config, 0,
nullptr)))
99 err = i2s_driver_install(
_cfg.
i2s_port, &i2s_config, 0,
nullptr);
101 if (err != ESP_OK) {
return err; }
103 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
106 i2s_dac_mode_t dac_mode = i2s_dac_mode_t::I2S_DAC_CHANNEL_BOTH_EN;
110 ? i2s_dac_mode_t::I2S_DAC_CHANNEL_RIGHT_EN
111 : i2s_dac_mode_t::I2S_DAC_CHANNEL_LEFT_EN;
113 err = i2s_set_dac_mode(dac_mode);
116 I2S0.conf2.lcd_en =
true;
117 I2S0.conf.tx_right_first =
false;
118 I2S0.conf.tx_msb_shift = 0;
119 I2S0.conf.tx_short_sync = 0;
132 static void calcClockDiv(uint32_t* div_a, uint32_t* div_b, uint32_t* div_n, uint32_t baseClock, uint32_t targetFreq)
134 if (baseClock <= targetFreq << 1)
141 uint32_t save_n = 255;
142 uint32_t save_a = 63;
143 uint32_t save_b = 62;
146 float fdiv = (float)baseClock / targetFreq;
147 uint32_t n = (uint32_t)fdiv;
152 float check_base = baseClock;
154 while ((int32_t)targetFreq >= 0) { targetFreq <<= 1; check_base *= 2; }
155 float check_target = targetFreq;
157 uint32_t save_diff = UINT32_MAX;
163 save_diff = abs((
int)(check_target - check_base / (
float)save_n));
166 for (uint32_t a = 1; a < 64; ++a)
168 uint32_t b = roundf(a * fdiv);
169 if (a <= b) {
continue; }
170 uint32_t diff = abs((
int)(check_target - ((check_base * a) / (n * a + b))));
171 if (save_diff <= diff) {
continue; }
176 if (!diff) {
break; }
186 #define SAMPLERATE_MUL 256
191 const i2s_port_t i2s_port =
self->_cfg.i2s_port;
192 const bool out_stereo =
self->_cfg.stereo;
193 const size_t dma_buf_len =
self->_cfg.dma_buf_len & ~1;
197 SDL_Init(SDL_INIT_AUDIO);
199 fmt.freq =
self->_cfg.sample_rate;
200 fmt.format = AUDIO_S16LSB;
201 fmt.channels =
self->_cfg.stereo ? 2 : 1;
202 fmt.samples = dma_buf_len;
203 fmt.callback =
nullptr;
204 auto res = SDL_OpenAudio(&fmt,
nullptr);
209 const int32_t spk_sample_rate_x256 =
self->_cfg.sample_rate *
SAMPLERATE_MUL;
214 static constexpr uint32_t PLL_D2_CLK = 80*1000*1000;
215 uint32_t bits = (
self->_cfg.use_dac) ? 1 : 16;
216 uint32_t div_a, div_b, div_n;
217 uint32_t div_m = 32 / bits;
220 calcClockDiv(&div_a, &div_b, &div_n, PLL_D2_CLK, div_m * bits * self->_cfg.sample_rate);
223 const int32_t spk_sample_rate_x256 = (float)PLL_D2_CLK *
SAMPLERATE_MUL / ((
float)(div_b * div_m * bits) / (
float)div_a + (div_n * div_m * bits));
226 #if defined ( I2S1I_BCK_OUT_IDX )
227 auto dev = (i2s_port == i2s_port_t::I2S_NUM_1) ? &I2S1 : &I2S0;
232 #if defined ( CONFIG_IDF_TARGET_ESP32C3 ) || defined ( CONFIG_IDF_TARGET_ESP32S3 )
233 dev->tx_conf1.tx_bck_div_num = div_m - 1;
234 dev->tx_clkm_conf.tx_clkm_div_num = div_n;
236 dev->tx_clkm_div_conf.val = 0;
237 if (div_b > (div_a >> 1)) {
238 dev->tx_clkm_div_conf.tx_clkm_div_yn1 = 1;
239 div_b = div_a - div_b;
245 div_x = div_a / div_b - 1;
246 div_y = div_a % div_b;
258 dev->tx_clkm_div_conf.tx_clkm_div_x = div_x;
259 dev->tx_clkm_div_conf.tx_clkm_div_y = div_y;
260 dev->tx_clkm_div_conf.tx_clkm_div_z = div_b;
262 dev->tx_clkm_conf.tx_clk_sel = 2;
263 dev->tx_clkm_conf.clk_en = 1;
264 dev->tx_clkm_conf.tx_clk_active = 1;
268 dev->sample_rate_conf.tx_bck_div_num = div_m;
269 dev->clkm_conf.clkm_div_a = div_a;
270 dev->clkm_conf.clkm_div_b = div_b;
271 dev->clkm_conf.clkm_div_num = div_n;
272 dev->clkm_conf.clka_en = 0;
275 dev->conf.tx_reset = 1;
276 dev->conf.tx_fifo_reset = 1;
277 dev->conf.tx_reset = 0;
278 dev->conf.tx_fifo_reset = 0;
281 i2s_zero_dma_buffer(i2s_port);
284 const float magnification = (float)(self->_cfg.magnification << out_stereo) / spk_sample_rate_x256 / (1 << 28);
286 int32_t dac_offset = std::min(INT16_MAX-255, self->_cfg.dac_zero_level << 8);
288 bool flg_nodata =
false;
296 spk_i2s_state flg_i2s_started = spk_i2s_stop;
301 int16_t surplus16 = 0;
305 int32_t* sound_buf32 = (int32_t*)alloca(dma_buf_len *
sizeof(int32_t));
308 while (self->_task_running)
314 if (0 == (self->_play_channel_bits.load())) {
continue; }
319 if (self->_cfg.use_dac && dac_offset)
321 flg_i2s_started = spk_i2s_mute;
325 auto tmp = (uint32_t)((1.0f + cosf(idx * M_PI / dma_buf_len)) * (dac_offset >> 1));
326 sound_buf32[idx] = tmp | tmp << 16;
327 }
while (++idx < dma_buf_len);
329 i2s_write(i2s_port, sound_buf32, dma_buf_len *
sizeof(int32_t), &write_bytes, portMAX_DELAY);
330 if (self->_cfg.dac_zero_level == 0)
337 memset(sound_buf32, 0, dma_buf_len *
sizeof(uint32_t));
339 size_t retry = (
self->_cfg.dma_buf_count <<
self->_cfg.use_dac) + 1;
340 while (!ulTaskNotifyTake( pdTRUE, 0 ) && --retry)
343 i2s_write(i2s_port, sound_buf32, dma_buf_len *
sizeof(int32_t), &write_bytes, portMAX_DELAY);
348 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
349 if (self->_cfg.use_dac)
351 flg_i2s_started = spk_i2s_stop;
353 i2s_set_dac_mode(i2s_dac_mode_t::I2S_DAC_CHANNEL_DISABLE);
357 ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
360 ulTaskNotifyTake( pdTRUE, 0 );
367 auto border = std::max<int>(2048, self->_cfg.sample_rate >> 3);
368 while (SDL_GetQueuedAudioSize(1) > border) { SDL_Delay(1); }
370 if (flg_i2s_started != spk_i2s_run)
372 if (flg_i2s_started == spk_i2s_stop)
374 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
375 if (self->_cfg.use_dac)
377 i2s_dac_mode_t dac_mode = i2s_dac_mode_t::I2S_DAC_CHANNEL_BOTH_EN;
380 dac_mode = (
self->_cfg.pin_data_out == GPIO_NUM_25)
381 ? i2s_dac_mode_t::I2S_DAC_CHANNEL_RIGHT_EN
382 : i2s_dac_mode_t::I2S_DAC_CHANNEL_LEFT_EN;
384 i2s_set_dac_mode(dac_mode);
390 if (self->_cfg.use_dac && self->_cfg.dac_zero_level != 0)
395 auto tmp = (uint32_t)((1.0f - cosf(idx * M_PI / dma_buf_len)) * (dac_offset >> 1));
396 sound_buf32[idx] = tmp | tmp << 16;
397 }
while (++idx < dma_buf_len);
399 i2s_write(i2s_port, sound_buf32, dma_buf_len *
sizeof(int32_t), &write_bytes, portMAX_DELAY);
401 flg_i2s_started = spk_i2s_run;
404 memset(sound_buf32, 0, dma_buf_len *
sizeof(int32_t));
406 float volume = magnification * (
self->_master_volume *
self->_master_volume);
410 if (0 == (self->_play_channel_bits.load() & (1 << ch))) {
continue; }
413 auto ch_info = &(
self->_ch_info[ch]);
414 int ch_diff = ch_info->diff;
415 size_t ch_index = ch_info->index;
417 wav_info_t* current_wav = &(ch_info->wavinfo[!ch_info->flip]);
418 wav_info_t* next_wav = &(ch_info->wavinfo[ ch_info->flip]);
425 bool clear_idx = (next_wav->
repeat == 0
427 || (next_wav->
data != current_wav->
data));
428 current_wav->
clear();
429 ch_info->flip = !ch_info->flip;
430 #if !defined (SDL_h_)
431 xSemaphoreGive(self->_task_semaphore);
433 std::swap(current_wav, next_wav);
438 if (current_wav->
repeat == 0)
440 self->_play_channel_bits.fetch_and(~(1 << ch));
441 if (current_wav->
repeat == 0)
447 self->_play_channel_bits.fetch_or(1 << ch);
451 auto data = (
const uint8_t*)current_wav->
data;
452 const bool in_stereo = current_wav->
is_stereo;
454 int32_t tmp = ch_info->volume;
457 if (!current_wav->
is_16bit) { tmp <<= 8; }
458 const float ch_v = volume * tmp;
460 auto liner_base = ch_info->liner_buf[0];
461 auto liner_prev = ch_info->liner_buf[1];
463 if (ch_diff < 0) {
goto label_continue_sample; }
465 if (ch_index >= current_wav->
length)
468 ch_index -= current_wav->
length;
469 auto repeat = current_wav->
repeat;
472 current_wav->
repeat = --repeat;
484 if (ch_index >= current_wav->
length)
492 auto wav = (
const int16_t*)data;
494 r = wav[ch_index += in_stereo];
498 l = (l & 0xFFFF) + INT16_MIN;
499 r = (r & 0xFFFF) + INT16_MIN;
505 r = data[ch_index += in_stereo];
519 liner_prev[0] = liner_base[0];
522 liner_prev[1] = liner_base[1];
523 liner_base[1] = r * ch_v;
529 liner_base[0] = l * ch_v;
531 ch_diff -= spk_sample_rate_x256;
532 }
while (ch_diff >= 0);
534 label_continue_sample:
537 float base_l = liner_base[0];
538 float step_l = base_l - liner_prev[0];
539 base_l *= spk_sample_rate_x256;
540 base_l += step_l * ch_diff;
542 int32_t b_l = base_l;
543 int32_t s_l = step_l;
546 float base_r = liner_base[1];
547 float step_r = base_r - liner_prev[1];
548 base_r *= spk_sample_rate_x256;
549 base_r += step_r * ch_diff;
551 int32_t b_r = base_r;
552 int32_t s_r = step_r;
555 sound_buf32[ idx] += b_l;
556 sound_buf32[++idx] += b_r;
560 }
while (++idx < dma_buf_len && ch_diff < 0);
566 sound_buf32[idx] += b_l;
569 }
while (++idx < dma_buf_len && ch_diff < 0);
571 }
while (idx < dma_buf_len);
572 ch_info->diff = ch_diff;
573 ch_info->index = ch_index;
578 if (self->_cfg.use_dac)
582 const bool zero_bias = (
self->_cfg.dac_zero_level == 0);
583 bool biasing = zero_bias;
587 int32_t v1 = sound_buf32[ idx] >> 8;
588 int32_t v2 = sound_buf32[++idx] >> 8;
589 int32_t vabs = std::max(abs(v1), abs(v2));
590 if (dac_offset <= vabs)
594 dac_offset = (INT16_MAX-255 < vabs) ? INT16_MAX-255 : vabs;
599 if (v1 < 0) { v1 = 0; }
600 else if (v1 > UINT16_MAX) { v1 = UINT16_MAX; }
601 if (v2 < 0) { v2 = 0; }
602 else if (v2 > UINT16_MAX) { v2 = UINT16_MAX; }
606 v1 += dac_offset + surplus[0];
608 v2 += dac_offset + surplus[out_stereo];
609 surplus[out_stereo] = v2;
611 sound_buf32[idx >> 1] = v1 << 16 | v2;
612 }
while (++idx < dma_buf_len);
613 if (biasing) { dac_offset -= (dac_offset * dma_buf_len) >> 15; }
615 else if (self->_cfg.buzzer)
620 int32_t tmp = (uint16_t)surplus16;
624 int32_t v = sound_buf32[idx] >> 8;
626 uint32_t bitdata = 0;
627 uint32_t bit = 0x80000000;
636 sound_buf32[idx] = bitdata;
637 }
while (++idx < dma_buf_len);
638 surplus16 = flg_nodata ? 0x8000 : tmp;
645 int32_t v1 = sound_buf32[idx] >> 8;
646 if (v1 < INT16_MIN) { v1 = INT16_MIN; }
647 else if (v1 > INT16_MAX) { v1 = INT16_MAX; }
649 int32_t v2 = sound_buf32[++idx] >> 8;
650 if (v2 < INT16_MIN) { v2 = INT16_MIN; }
651 else if (v2 > INT16_MAX) { v2 = INT16_MAX; }
653 sound_buf32[idx >> 1] = v1 << 16 | (uint16_t)v2;
654 }
while (++idx < dma_buf_len);
658 SDL_QueueAudio(1, sound_buf32, dma_buf_len *
sizeof(int16_t));
661 i2s_write(i2s_port, sound_buf32, dma_buf_len *
sizeof(int16_t) << self->_cfg.buzzer, &write_bytes, portMAX_DELAY);
665 #if defined ( SDL_h_ )
666 SDL_CloseAudioDevice(1);
670 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
671 if (self->_cfg.use_dac)
673 i2s_set_dac_mode(i2s_dac_mode_t::I2S_DAC_CHANNEL_DISABLE);
674 m5gfx::gpio_lo(self->_cfg.pin_data_out);
675 m5gfx::pinMode(self->_cfg.pin_data_out, m5gfx::pin_mode_t::output);
678 self->_task_handle =
nullptr;
679 vTaskDelete(
nullptr);
687 #if !defined (SDL_h_)
703 #if portNUM_PROCESSORS > 1
745 chinfo->
wavinfo[chinfo->flip] = tmp;
760 chinfo->
wavinfo[chinfo->flip] = tmp;
776 uint8_t chmask = 1 << ch;
779 while ((
_play_channel_bits.load() & chmask) && (chinfo->wavinfo[chinfo->flip].repeat))
781 if (chinfo->wavinfo[!chinfo->flip].repeat == ~0u) {
return false; }
782 #if !defined (SDL_h_)
789 chinfo->wavinfo[chinfo->flip] = wav;
792 #if !defined (SDL_h_)
798 bool Speaker_Class::_play_raw(
const void* data,
size_t array_len,
bool flg_16bit,
bool flg_signed,
float sample_rate,
bool flg_stereo, uint32_t repeat_count,
int channel,
bool stop_current_sound,
bool no_clear_index)
801 if (array_len == 0 || data ==
nullptr) {
return true; }
802 size_t ch = (size_t)channel;
808 if (0 == ((bits >> ch) & 1)) {
break; }
815 info.
repeat = repeat_count ? repeat_count : ~0u;
826 bool Speaker_Class::playWav(
const uint8_t* wav_data,
size_t data_len, uint32_t repeat,
int channel,
bool stop_current_sound)
833 uint32_t fmt_chunk_size;
836 uint32_t sample_rate;
837 uint32_t byte_per_sec;
839 uint16_t bit_per_sample;
848 auto wav = (wav_header_t*)wav_data;
862 || memcmp(wav->RIFF,
"RIFF", 4)
863 || memcmp(wav->WAVEfmt,
"WAVEfmt ", 8)
864 || wav->audiofmt != 1
865 || wav->bit_per_sample < 8
866 || wav->bit_per_sample > 16
874 sub_chunk_t* sub = (sub_chunk_t*)(wav_data + offsetof(wav_header_t, audiofmt) + wav->fmt_chunk_size);
879 while(memcmp(sub->identifier,
"data", 4) && (uint8_t*)sub < wav_data + wav->chunk_size + 8)
881 sub = (sub_chunk_t*)((uint8_t*)sub + offsetof(sub_chunk_t, data) + sub->chunk_size);
887 if (memcmp(sub->identifier,
"data", 4))
892 data_len = data_len >
sizeof(wav_header_t) ? data_len -
sizeof(wav_header_t) : 0;
893 if (data_len > sub->chunk_size) { data_len = sub->chunk_size; }
894 bool flg_16bit = (wav->bit_per_sample >> 4);
896 , data_len >> flg_16bit
#define SAMPLERATE_MUL
レート変換係数 (実際に設定されるレートが浮動小数になる場合があるため、入力と出力の両方のサンプリングレートに係数を掛け、誤差を減らす);
bool(* _cb_set_enabled)(void *args, bool enabled)
volatile bool _task_running
void stop(void)
stop sound output.
void * _cb_set_enabled_args
bool _set_next_wav(size_t ch, const wav_info_t &wav)
TaskHandle_t _task_handle
channel_info_t _ch_info[sound_channel_max]
bool playWav(const uint8_t *wav_data, size_t data_len=~0u, uint32_t repeat=1, int channel=-1, bool stop_current_sound=false)
bool _play_raw(const void *wav, size_t array_len, bool flg_16bit, bool flg_signed, float sample_rate, bool flg_stereo, uint32_t repeat_count, int channel, bool stop_current_sound, bool no_clear_index)
esp_err_t _setup_i2s(void)
static void spk_task(void *args)
static const uint8_t _default_tone_wav[16]
std::atomic< uint16_t > _play_channel_bits
static constexpr const size_t sound_channel_max
volatile SemaphoreHandle_t _task_semaphore
struct __attribute__((packed)) rtc_time_t
uint32_t sample_rate_x256
-1 mean infinity repeat
uint8_t task_pinned_core
background task pinned core
bool buzzer
use single gpio buzzer, ( need only pin_data_out )
bool stereo
use stereo output
int pin_data_out
i2s_data_out (for spk)
uint8_t task_priority
background task priority
i2s_port_t i2s_port
I2S port.
size_t dma_buf_count
for I2S dma_buf_count
size_t dma_buf_len
for I2S dma_buf_len (max 1024)