M5Unified
Speaker_Class.cpp
Go to the documentation of this file.
1 // Copyright (c) M5Stack. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 
4 #include "Speaker_Class.hpp"
5 
6 #include "../M5Unified.hpp"
7 
8 #if !defined (SDL_h_)
9 
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]];
14  #endif
15 #endif
16 
17 #ifndef NON_BREAK
18 #define NON_BREAK ;
19 #endif
20 
21 #include <sdkconfig.h>
22 #include <esp_log.h>
23 
24 #endif
25 
26 #include <math.h>
27 
28 namespace m5
29 {
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)
34  #endif
35  #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 3)
36  #define SAMPLE_RATE_TYPE uint32_t
37  #endif
38  #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
39  #define I2S_DRIVER_VERSION 2
40  #endif
41 #endif
42 #ifndef I2S_DRIVER_VERSION
43 #define I2S_DRIVER_VERSION 1
44 #endif
45 
46 #ifndef COMM_FORMAT_I2S
47 #define COMM_FORMAT_I2S (I2S_COMM_FORMAT_I2S)
48 #define COMM_FORMAT_MSB (I2S_COMM_FORMAT_I2S_MSB)
49 #endif
50 
51 #ifndef SAMPLE_RATE_TYPE
52 #define SAMPLE_RATE_TYPE int
53 #endif
54 
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 }; // sin wave data
56 
57 #if defined (SDL_h_)
58  esp_err_t Speaker_Class::_setup_i2s(void)
59  {
60  return ESP_OK;
61  }
62 #else
63  esp_err_t Speaker_Class::_setup_i2s(void)
64  {
65  if (_cfg.pin_data_out < 0) { return ESP_FAIL; }
66 
67 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
69  if (_cfg.use_dac && _cfg.i2s_port != I2S_NUM_0) { return ESP_FAIL; }
70 #endif
71 
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; // dummy setting
76  i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
77  i2s_config.channel_format = _cfg.stereo || _cfg.buzzer
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
83  i2s_config.dma_desc_num = _cfg.dma_buf_count;
84  i2s_config.dma_frame_num = _cfg.dma_buf_len;
85 #else
86  i2s_config.dma_buf_count = _cfg.dma_buf_count;
87  i2s_config.dma_buf_len = _cfg.dma_buf_len;
88 #endif
89  i2s_pin_config_t pin_config;
90  memset(&pin_config, ~0u, sizeof(i2s_pin_config_t));
91  pin_config.bck_io_num = _cfg.pin_bck;
92  pin_config.ws_io_num = _cfg.pin_ws;
93  pin_config.data_out_num = _cfg.pin_data_out;
94 
95  esp_err_t err;
96  if (ESP_OK != (err = i2s_driver_install(_cfg.i2s_port, &i2s_config, 0, nullptr)))
97  {
98  i2s_driver_uninstall(_cfg.i2s_port);
99  err = i2s_driver_install(_cfg.i2s_port, &i2s_config, 0, nullptr);
100  }
101  if (err != ESP_OK) { return err; }
102 
103 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
104  if (_cfg.use_dac)
105  {
106  i2s_dac_mode_t dac_mode = i2s_dac_mode_t::I2S_DAC_CHANNEL_BOTH_EN;
107  if (!_cfg.stereo)
108  {
109  dac_mode = (_cfg.pin_data_out == GPIO_NUM_25)
110  ? i2s_dac_mode_t::I2S_DAC_CHANNEL_RIGHT_EN // for GPIO 25
111  : i2s_dac_mode_t::I2S_DAC_CHANNEL_LEFT_EN; // for GPIO 26
112  }
113  err = i2s_set_dac_mode(dac_mode);
114  if (_cfg.i2s_port == I2S_NUM_0)
115  {
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;
120  }
121  }
122  else
123 #endif
124  {
125  err = i2s_set_pin(_cfg.i2s_port, &pin_config);
126  }
127 
128  return err;
129  }
130 #endif
131 
132  static void calcClockDiv(uint32_t* div_a, uint32_t* div_b, uint32_t* div_n, uint32_t baseClock, uint32_t targetFreq)
133  {
134  if (baseClock <= targetFreq << 1)
135  {
136  *div_n = 2;
137  *div_a = 1;
138  *div_b = 0;
139  return;
140  }
141  uint32_t save_n = 255;
142  uint32_t save_a = 63;
143  uint32_t save_b = 62;
144  if (targetFreq)
145  {
146  float fdiv = (float)baseClock / targetFreq;
147  uint32_t n = (uint32_t)fdiv;
148  if (n < 256)
149  {
150  fdiv -= n;
151 
152  float check_base = baseClock;
153 // 探索時の誤差を少なくするため、値を大きくしておく;
154  while ((int32_t)targetFreq >= 0) { targetFreq <<= 1; check_base *= 2; }
155  float check_target = targetFreq;
156 
157  uint32_t save_diff = UINT32_MAX;
158  if (n < 255)
159  {
160  save_a = 1;
161  save_b = 0;
162  save_n = n + 1;
163  save_diff = abs((int)(check_target - check_base / (float)save_n));
164  }
165 
166  for (uint32_t a = 1; a < 64; ++a)
167  {
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; }
172  save_diff = diff;
173  save_a = a;
174  save_b = b;
175  save_n = n;
176  if (!diff) { break; }
177  }
178  }
179  }
180  *div_n = save_n;
181  *div_a = save_a;
182  *div_b = save_b;
183  }
184 
186  #define SAMPLERATE_MUL 256
187 
188  void Speaker_Class::spk_task(void* args)
189  {
190  auto self = (Speaker_Class*)args;
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;
194 
195 #if defined (SDL_h_)
196 
197  SDL_Init(SDL_INIT_AUDIO);
198  SDL_AudioSpec fmt;
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);
205  if (res == 0)
206  {
207  SDL_PauseAudio(0);
208  }
209  const int32_t spk_sample_rate_x256 = self->_cfg.sample_rate * SAMPLERATE_MUL;
210 
211 #else
212  i2s_stop(i2s_port);
213 
214  static constexpr uint32_t PLL_D2_CLK = 80*1000*1000; // 80 MHz
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;
218  // MCLKを使用するデバイスに対応する場合には、div_mを使用してBCKとMCKの比率を調整する;
219 
220  calcClockDiv(&div_a, &div_b, &div_n, PLL_D2_CLK, div_m * bits * self->_cfg.sample_rate);
221 
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));
224 // ESP_EARLY_LOGW("Speaker_Class", "sample rate:%d Hz = %d MHz/(%d+(%d/%d))/%d/%d = %d Hz", self->_cfg.sample_rate, PLL_D2_CLK / 1000000, div_n, div_b, div_a, div_m, bits, spk_sample_rate_x256 / SAMPLERATE_MUL);
225 
226 #if defined ( I2S1I_BCK_OUT_IDX )
227  auto dev = (i2s_port == i2s_port_t::I2S_NUM_1) ? &I2S1 : &I2S0;
228 #else
229  auto dev = &I2S0;
230 #endif
231 
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;
235 
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;
240  }
241  int div_y = 1;
242  int div_x = 0;
243  if (div_b)
244  {
245  div_x = div_a / div_b - 1;
246  div_y = div_a % div_b;
247 
248  if (div_y == 0)
249  { // div_yが0になる場合、分数成分が無視される不具合があり、
250  // 指定よりクロックが速くなってしまう。
251  // 回避策として、誤差が少なくなる設定値を導入する。
252  // これにより、誤差をクロック周期512回に1回程度のズレに抑える。;
253  div_y = 1;
254  div_b = 511;
255  }
256  }
257 
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;
261 
262  dev->tx_clkm_conf.tx_clk_sel = 2; // PLL_160M_CLK
263  dev->tx_clkm_conf.clk_en = 1;
264  dev->tx_clkm_conf.tx_clk_active = 1;
265 
266 #else
267 
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; // APLL disable : PLL_160M
273 
274  // If TX is not reset here, BCK polarity may be inverted.
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;
279 
280 #endif
281  i2s_zero_dma_buffer(i2s_port);
282 #endif
283  // ステレオ出力の場合は倍率を2倍する
284  const float magnification = (float)(self->_cfg.magnification << out_stereo) / spk_sample_rate_x256 / (1 << 28);
285 
286  int32_t dac_offset = std::min(INT16_MAX-255, self->_cfg.dac_zero_level << 8);
287 
288  bool flg_nodata = false;
289 
290  enum spk_i2s_state
291  {
292  spk_i2s_stop,
293  spk_i2s_mute,
294  spk_i2s_run,
295  };
296  spk_i2s_state flg_i2s_started = spk_i2s_stop;
297 
298 
299  union
300  {
301  int16_t surplus16 = 0;
302  uint8_t surplus[2];
303  };
304 
305  int32_t* sound_buf32 = (int32_t*)alloca(dma_buf_len * sizeof(int32_t));
306 
307 
308  while (self->_task_running)
309  {
310 #if defined (SDL_h_)
311  if (flg_nodata)
312  {
313  SDL_Delay(1);
314  if (0 == (self->_play_channel_bits.load())) { continue; }
315  }
316 #else
317  if (flg_nodata)
318  {
319  if (self->_cfg.use_dac && dac_offset)
320  { // Gradual transition of DAC output to 0;
321  flg_i2s_started = spk_i2s_mute;
322  size_t idx = 0;
323  do
324  {
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);
328  size_t write_bytes;
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)
331  {
332  dac_offset = 0;
333  }
334  }
335 
336  // バッファ全てゼロになるまで出力を繰返す;
337  memset(sound_buf32, 0, dma_buf_len * sizeof(uint32_t));
338  // DAC使用時は長めに設定する
339  size_t retry = (self->_cfg.dma_buf_count << self->_cfg.use_dac) + 1;
340  while (!ulTaskNotifyTake( pdTRUE, 0 ) && --retry)
341  {
342  size_t write_bytes;
343  i2s_write(i2s_port, sound_buf32, dma_buf_len * sizeof(int32_t), &write_bytes, portMAX_DELAY);
344  }
345 
346  if (!retry)
347  {
348 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
349  if (self->_cfg.use_dac)
350  {
351  flg_i2s_started = spk_i2s_stop;
352  i2s_stop(i2s_port);
353  i2s_set_dac_mode(i2s_dac_mode_t::I2S_DAC_CHANNEL_DISABLE);
354  }
355 #endif
356  // 新しいデータが届くまで待機;
357  ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
358  }
359  }
360  ulTaskNotifyTake( pdTRUE, 0 );
361 
362 #endif
363 
364  flg_nodata = true;
365 
366 #if defined (SDL_h_)
367  auto border = std::max<int>(2048, self->_cfg.sample_rate >> 3);
368  while (SDL_GetQueuedAudioSize(1) > border) { SDL_Delay(1); }
369 #else
370  if (flg_i2s_started != spk_i2s_run)
371  {
372  if (flg_i2s_started == spk_i2s_stop)
373  {
374 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
375  if (self->_cfg.use_dac)
376  {
377  i2s_dac_mode_t dac_mode = i2s_dac_mode_t::I2S_DAC_CHANNEL_BOTH_EN;
378  if (!out_stereo)
379  {
380  dac_mode = (self->_cfg.pin_data_out == GPIO_NUM_25)
381  ? i2s_dac_mode_t::I2S_DAC_CHANNEL_RIGHT_EN // for GPIO 25
382  : i2s_dac_mode_t::I2S_DAC_CHANNEL_LEFT_EN; // for GPIO 26
383  }
384  i2s_set_dac_mode(dac_mode);
385  }
386 #endif
387  i2s_start(i2s_port);
388  }
389 
390  if (self->_cfg.use_dac && self->_cfg.dac_zero_level != 0)
391  {
392  size_t idx = 0;
393  do
394  {
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);
398  size_t write_bytes;
399  i2s_write(i2s_port, sound_buf32, dma_buf_len * sizeof(int32_t), &write_bytes, portMAX_DELAY);
400  }
401  flg_i2s_started = spk_i2s_run;
402  }
403 #endif
404  memset(sound_buf32, 0, dma_buf_len * sizeof(int32_t));
405 
406  float volume = magnification * (self->_master_volume * self->_master_volume);
407 
408  for (size_t ch = 0; ch < sound_channel_max; ++ch)
409  {
410  if (0 == (self->_play_channel_bits.load() & (1 << ch))) { continue; }
411  flg_nodata = false;
412 
413  auto ch_info = &(self->_ch_info[ch]);
414  int ch_diff = ch_info->diff;
415  size_t ch_index = ch_info->index;
416 
417  wav_info_t* current_wav = &(ch_info->wavinfo[!ch_info->flip]);
418  wav_info_t* next_wav = &(ch_info->wavinfo[ ch_info->flip]);
419 
420  size_t idx = 0;
421 
422  if (current_wav->repeat == 0 || next_wav->stop_current)
423  {
424 label_next_wav:
425  bool clear_idx = (next_wav->repeat == 0
426  || !next_wav->no_clear_index
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);
432 #endif
433  std::swap(current_wav, next_wav);
434 
435  if (clear_idx)
436  {
437  ch_index = 0;
438  if (current_wav->repeat == 0)
439  {
440  self->_play_channel_bits.fetch_and(~(1 << ch));
441  if (current_wav->repeat == 0)
442  {
443  ch_info->diff = 0;
444  ch_info->index = 0;
445  continue;
446  }
447  self->_play_channel_bits.fetch_or(1 << ch);
448  }
449  }
450  }
451  auto data = (const uint8_t*)current_wav->data;
452  const bool in_stereo = current_wav->is_stereo;
453  const int32_t in_rate = current_wav->sample_rate_x256;
454  int32_t tmp = ch_info->volume;
455  tmp *= tmp;
456  // 8bitのデータの場合は倍率を256倍する
457  if (!current_wav->is_16bit) { tmp <<= 8; }
458  const float ch_v = volume * tmp;
459 
460  auto liner_base = ch_info->liner_buf[0];
461  auto liner_prev = ch_info->liner_buf[1];
462 
463  if (ch_diff < 0) { goto label_continue_sample; }
464 
465  if (ch_index >= current_wav->length)
466  {
467 label_wav_end:
468  ch_index -= current_wav->length;
469  auto repeat = current_wav->repeat;
470  if (repeat != ~0u)
471  {
472  current_wav->repeat = --repeat;
473  if (repeat == 0)
474  {
475  goto label_next_wav;
476  }
477  }
478  }
479 
480  do
481  {
482  do
483  {
484  if (ch_index >= current_wav->length)
485  {
486  goto label_wav_end;
487  }
488 
489  int32_t l, r;
490  if (current_wav->is_16bit)
491  {
492  auto wav = (const int16_t*)data;
493  l = wav[ch_index];
494  r = wav[ch_index += in_stereo];
495  ch_index++;
496  if (!current_wav->is_signed)
497  {
498  l = (l & 0xFFFF) + INT16_MIN;
499  r = (r & 0xFFFF) + INT16_MIN;
500  }
501  }
502  else
503  {
504  l = data[ch_index];
505  r = data[ch_index += in_stereo];
506  ch_index++;
507  if (current_wav->is_signed)
508  {
509  l = (int8_t)l;
510  r = (int8_t)r;
511  }
512  else
513  {
514  l += INT8_MIN;
515  r += INT8_MIN;
516  }
517  }
518 
519  liner_prev[0] = liner_base[0];
520  if (out_stereo)
521  {
522  liner_prev[1] = liner_base[1];
523  liner_base[1] = r * ch_v;
524  }
525  else
526  {
527  l += r;
528  }
529  liner_base[0] = l * ch_v;
530 
531  ch_diff -= spk_sample_rate_x256;
532  } while (ch_diff >= 0);
533 
534 label_continue_sample:
535 
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;
541  step_l *= in_rate;
542  int32_t b_l = base_l;
543  int32_t s_l = step_l;
544  if (out_stereo)
545  {
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;
550  step_r *= in_rate;
551  int32_t b_r = base_r;
552  int32_t s_r = step_r;
553  do
554  {
555  sound_buf32[ idx] += b_l;
556  sound_buf32[++idx] += b_r;
557  b_l += s_l;
558  b_r += s_r;
559  ch_diff += in_rate;
560  } while (++idx < dma_buf_len && ch_diff < 0);
561  }
562  else
563  {
564  do
565  {
566  sound_buf32[idx] += b_l;
567  b_l += s_l;
568  ch_diff += in_rate;
569  } while (++idx < dma_buf_len && ch_diff < 0);
570  }
571  } while (idx < dma_buf_len);
572  ch_info->diff = ch_diff;
573  ch_info->index = ch_index;
574  }
575 
576  if (!flg_nodata)
577  {
578  if (self->_cfg.use_dac)
579  {
582  const bool zero_bias = (self->_cfg.dac_zero_level == 0);
583  bool biasing = zero_bias;
584  size_t idx = 0;
585  do
586  {
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)
591  {
592  if (zero_bias)
593  {
594  dac_offset = (INT16_MAX-255 < vabs) ? INT16_MAX-255 : vabs;
595  biasing = false;
596  }
597  v1 += dac_offset;
598  v2 += dac_offset;
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; }
603  }
604  else
605  {
606  v1 += dac_offset + surplus[0];
607  surplus[0] = v1;
608  v2 += dac_offset + surplus[out_stereo];
609  surplus[out_stereo] = v2;
610  }
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; }
614  }
615  else if (self->_cfg.buzzer)
616  {
620  int32_t tmp = (uint16_t)surplus16;
621  size_t idx = 0;
622  do
623  {
624  int32_t v = sound_buf32[idx] >> 8;
625  v = INT16_MIN - v;
626  uint32_t bitdata = 0;
627  uint32_t bit = 0x80000000;
628  do
629  {
630  if ((tmp += v) < 0)
631  {
632  tmp += 0x10000;
633  bitdata |= bit;
634  }
635  } while (bit >>= 1);
636  sound_buf32[idx] = bitdata;
637  } while (++idx < dma_buf_len);
638  surplus16 = flg_nodata ? 0x8000 : tmp;
639  }
640  else
641  {
642  size_t idx = 0;
643  do
644  {
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; }
648 
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; }
652 
653  sound_buf32[idx >> 1] = v1 << 16 | (uint16_t)v2;
654  } while (++idx < dma_buf_len);
655  }
656 
657 #if defined (SDL_h_)
658  SDL_QueueAudio(1, sound_buf32, dma_buf_len * sizeof(int16_t));
659 #else
660  size_t write_bytes;
661  i2s_write(i2s_port, sound_buf32, dma_buf_len * sizeof(int16_t) << self->_cfg.buzzer, &write_bytes, portMAX_DELAY);
662 #endif
663  }
664  }
665 #if defined ( SDL_h_ )
666  SDL_CloseAudioDevice(1);
667  SDL_CloseAudio();
668 #else
669  i2s_stop(i2s_port);
670 #if !defined (CONFIG_IDF_TARGET) || defined (CONFIG_IDF_TARGET_ESP32)
671  if (self->_cfg.use_dac)
672  {
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);
676  }
677 #endif
678  self->_task_handle = nullptr;
679  vTaskDelete(nullptr);
680 #endif
681  }
682 
684  {
685  if (_task_running) { return true; }
686 
687 #if !defined (SDL_h_)
688  if (_task_semaphore == nullptr) { _task_semaphore = xSemaphoreCreateBinary(); }
689 #endif
690 
691  bool res = true;
693 
694  res = (ESP_OK == _setup_i2s()) && res;
695  if (res)
696  {
697  size_t stack_size = 1280 + (_cfg.dma_buf_len * sizeof(uint32_t));
698  _task_running = true;
699 #if defined (SDL_h_)
700  _task_handle = SDL_CreateThread((SDL_ThreadFunction)spk_task, "spk_task", this);
701 #else
702 
703 #if portNUM_PROCESSORS > 1
704  if (_cfg.task_pinned_core < portNUM_PROCESSORS)
705  {
706  xTaskCreatePinnedToCore(spk_task, "spk_task", stack_size, this, _cfg.task_priority, &_task_handle, _cfg.task_pinned_core);
707  }
708  else
709 #endif
710  {
711  xTaskCreate(spk_task, "spk_task", stack_size, this, _cfg.task_priority, &_task_handle);
712  }
713 #endif
714  }
715 
716  return res;
717  }
718 
720  {
722  if (!_task_running) { return; }
723  _task_running = false;
724  stop();
725  if (_task_handle)
726  {
727 #if defined (SDL_h_)
728  SDL_WaitThread(_task_handle, nullptr);
729  _task_handle = nullptr;
730 #else
731  xTaskNotifyGive(_task_handle);
732  do { vTaskDelay(1); } while (_task_handle);
733 #endif
734  }
735  _play_channel_bits.store(0);
736  }
737 
739  {
740  wav_info_t tmp;
741  tmp.stop_current = 1;
742  for (size_t ch = 0; ch < sound_channel_max; ++ch)
743  {
744  auto chinfo = &_ch_info[ch];
745  chinfo->wavinfo[chinfo->flip] = tmp;
746  }
747  }
748 
749  void Speaker_Class::stop(uint8_t ch)
750  {
751  if ((size_t)ch >= sound_channel_max)
752  {
753  stop();
754  }
755  else
756  {
757  wav_info_t tmp;
758  tmp.stop_current = 1;
759  auto chinfo = &_ch_info[ch];
760  chinfo->wavinfo[chinfo->flip] = tmp;
761  }
762  }
763 
765  {
766  length = 0;
767  data = nullptr;
768  sample_rate_x256 = 0;
769  flg = 0;
770  repeat = 0;
771  }
772 
773  bool Speaker_Class::_set_next_wav(size_t ch, const wav_info_t& wav)
774  {
775  auto chinfo = &_ch_info[ch];
776  uint8_t chmask = 1 << ch;
777  if (!wav.stop_current)
778  {
779  while ((_play_channel_bits.load() & chmask) && (chinfo->wavinfo[chinfo->flip].repeat))
780  {
781  if (chinfo->wavinfo[!chinfo->flip].repeat == ~0u) { return false; }
782 #if !defined (SDL_h_)
783  xSemaphoreTake(_task_semaphore, 1);
784 #else
785  SDL_Delay(1);
786 #endif
787  }
788  }
789  chinfo->wavinfo[chinfo->flip] = wav;
790  _play_channel_bits.fetch_or(chmask);
791 
792 #if !defined (SDL_h_)
793  xTaskNotifyGive(_task_handle);
794 #endif
795  return true;
796  }
797 
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)
799  {
800  if (!begin() || (_task_handle == nullptr)) { return true; }
801  if (array_len == 0 || data == nullptr) { return true; }
802  size_t ch = (size_t)channel;
803  if (ch >= sound_channel_max)
804  {
805  size_t bits = _play_channel_bits.load();
806  for (ch = sound_channel_max - 1; ch < sound_channel_max; --ch)
807  {
808  if (0 == ((bits >> ch) & 1)) { break; }
809  }
810  if (ch >= sound_channel_max) { return false; }
811  }
812  wav_info_t info;
813  info.data = data;
814  info.length = array_len;
815  info.repeat = repeat_count ? repeat_count : ~0u;
816  info.sample_rate_x256 = sample_rate * SAMPLERATE_MUL;
817  info.is_stereo = flg_stereo;
818  info.is_16bit = flg_16bit;
819  info.is_signed = flg_signed;
820  info.stop_current = stop_current_sound;
821  info.no_clear_index = no_clear_index;
822 
823  return _set_next_wav(ch, info);
824  }
825 
826  bool Speaker_Class::playWav(const uint8_t* wav_data, size_t data_len, uint32_t repeat, int channel, bool stop_current_sound)
827  {
828  struct __attribute__((packed)) wav_header_t
829  {
830  char RIFF[4];
831  uint32_t chunk_size;
832  char WAVEfmt[8];
833  uint32_t fmt_chunk_size;
834  uint16_t audiofmt;
835  uint16_t channel;
836  uint32_t sample_rate;
837  uint32_t byte_per_sec;
838  uint16_t block_size;
839  uint16_t bit_per_sample;
840  };
841  struct __attribute__((packed)) sub_chunk_t
842  {
843  char identifier[4];
844  uint32_t chunk_size;
845  uint8_t data[1];
846  };
847 
848  auto wav = (wav_header_t*)wav_data;
849  /*
850  ESP_LOGD("wav", "RIFF : %.4s" , wav->RIFF );
851  ESP_LOGD("wav", "chunk_size : %d" , wav->chunk_size );
852  ESP_LOGD("wav", "WAVEfmt : %.8s" , wav->WAVEfmt );
853  ESP_LOGD("wav", "fmt_chunk_size : %d" , wav->fmt_chunk_size);
854  ESP_LOGD("wav", "audiofmt : %d" , wav->audiofmt );
855  ESP_LOGD("wav", "channel : %d" , wav->channel );
856  ESP_LOGD("wav", "sample_rate : %d" , wav->sample_rate );
857  ESP_LOGD("wav", "byte_per_sec : %d" , wav->byte_per_sec );
858  ESP_LOGD("wav", "block_size : %d" , wav->block_size );
859  ESP_LOGD("wav", "bit_per_sample : %d" , wav->bit_per_sample);
860  */
861  if ( !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
867  || wav->channel == 0
868  || wav->channel > 2
869  )
870  {
871  return false;
872  }
873 
874  sub_chunk_t* sub = (sub_chunk_t*)(wav_data + offsetof(wav_header_t, audiofmt) + wav->fmt_chunk_size);
875  /*
876  ESP_LOGD("wav", "sub id : %.4s" , sub->identifier);
877  ESP_LOGD("wav", "sub chunk_size : %d" , sub->chunk_size);
878  */
879  while(memcmp(sub->identifier, "data", 4) && (uint8_t*)sub < wav_data + wav->chunk_size + 8)
880  {
881  sub = (sub_chunk_t*)((uint8_t*)sub + offsetof(sub_chunk_t, data) + sub->chunk_size);
882  /*
883  ESP_LOGD("wav", "sub id : %.4s" , sub->identifier);
884  ESP_LOGD("wav", "sub chunk_size : %d" , sub->chunk_size);
885  */
886  }
887  if (memcmp(sub->identifier, "data", 4))
888  {
889  return false;
890  }
891 
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);
895  return _play_raw( sub->data
896  , data_len >> flg_16bit
897  , flg_16bit
898  , flg_16bit
899  , wav->sample_rate
900  , wav->channel > 1
901  , repeat
902  , channel
903  , stop_current_sound
904  , false
905  );
906  }
907 
908 }
#define SAMPLERATE_MUL
レート変換係数 (実際に設定されるレートが浮動小数になる場合があるため、入力と出力の両方のサンプリングレートに係数を掛け、誤差を減らす);
#define COMM_FORMAT_I2S
bool(* _cb_set_enabled)(void *args, bool enabled)
volatile bool _task_running
void stop(void)
stop sound output.
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
speaker_config_t _cfg
Definition: M5Unified.cpp:48
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_ws
i2s_ws (lrck)
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)