M5Stack Core2 for AWSを使って録音・再生を行います。

録音・再生のハードウェア

M5Stack Core2 for AWSでは、I2Sで接続されるSPM1423マイクを使用して録音します。

M5Stack Core2 for AWSでは、外付けのDACを利用してI2Sで接続されたI2Sパワーアンプ「NS4168」使用して再生します。

録音・再生アプリの作成

M5Core2/examples/Basics/record」を参考にして、録音・再生アプリアプリ「mictest.ino」を次のように作成します。

  • 25行目の「InitI2SSpeakOrMic」メソッドで、スピーカーとマイクを初期化します。
  • 66行目の「event_btn_record」メソッドで「Record」ボタンが押されると制御が移ります。録音・再生を行います。
  • 87行目の「event_btn_play」メソッドで「Play」ボタンが押されると制御が移ります。再生を行います。

mictest.ino

#include <M5Core2.h>
#include <driver/i2s.h>

ButtonColors cl_on  = {CYAN, WHITE, WHITE};// タップした時の色 (背景, 文字列, ボーダー)
ButtonColors cl_off = {DARKCYAN, WHITE, WHITE};// 指を離した時の色 (背景, 文字列, ボーダー)
// ボタン定義名( X軸, Y軸, 横幅, 高さ, 回転, ボタンのラベル, 指を離した時の色指定, タッチした時の色指定)
Button btn_record(80, 50, 150, 50, false , "Record", cl_off, cl_on);
Button btn_play(80, 120, 150, 50, false , "Play", cl_off, cl_on);


#define CONFIG_I2S_BCK_PIN     12
#define CONFIG_I2S_LRCK_PIN    0
#define CONFIG_I2S_DATA_PIN    2
#define CONFIG_I2S_DATA_IN_PIN 34

#define Speak_I2S_NUMBER I2S_NUM_0

#define MODE_MIC  0
#define MODE_SPK  1
#define DATA_SIZE 1024

uint8_t microphonedata0[1024 * 100];
int data_offset = 0;

bool InitI2SSpeakOrMic(int mode) {
  esp_err_t err = ESP_OK;

  i2s_driver_uninstall(
    Speak_I2S_NUMBER);
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER),
    .sample_rate = 44100,
    .bits_per_sample =    I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format =    I2S_CHANNEL_FMT_ONLY_RIGHT,
    .communication_format =    I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags =    ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 2,
    .dma_buf_len   = 128,
  };
  if (mode == MODE_MIC) {
    i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM);
  } else {
    i2s_config.mode  = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
    i2s_config.use_apll = false;
    i2s_config.tx_desc_auto_clear =  true;
  }

  err += i2s_driver_install(Speak_I2S_NUMBER, &i2s_config, 0, NULL);

  i2s_pin_config_t tx_pin_config;
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 3, 0))
  tx_pin_config.mck_io_num = I2S_PIN_NO_CHANGE;
#endif
  tx_pin_config.bck_io_num =  CONFIG_I2S_BCK_PIN;

  tx_pin_config.ws_io_num    = CONFIG_I2S_LRCK_PIN;
  tx_pin_config.data_out_num = CONFIG_I2S_DATA_PIN;
  tx_pin_config.data_in_num  = CONFIG_I2S_DATA_IN_PIN;
  err += i2s_set_pin(Speak_I2S_NUMBER,  &tx_pin_config);
  err += i2s_set_clk(
           Speak_I2S_NUMBER, 44100, I2S_BITS_PER_SAMPLE_16BIT,  I2S_CHANNEL_MONO);

  return true;
}

void event_btn_record(Event & e) {
  M5.Axp.SetLDOEnable(3, true);
  delay(100);
  M5.Axp.SetLDOEnable(3, false);
  data_offset = 0;
  InitI2SSpeakOrMic(MODE_MIC);
  size_t byte_read;
  while (1) {
    i2s_read(Speak_I2S_NUMBER,
             (char *)(microphonedata0 + data_offset), DATA_SIZE,
             &byte_read, (100 / portTICK_RATE_MS));
    data_offset += 1024;
    if (data_offset == 1024 * 100 )
      break;
  }
  size_t bytes_written;
  InitI2SSpeakOrMic(MODE_SPK);
  i2s_write(Speak_I2S_NUMBER, microphonedata0, data_offset,
            &bytes_written, portMAX_DELAY);
}

void event_btn_play(Event & e) {
  Serial.println(F("event_btn_play"));
  M5.Axp.SetLed(true);

  size_t bytes_written;
  InitI2SSpeakOrMic(MODE_SPK);
  i2s_write(Speak_I2S_NUMBER, microphonedata0, data_offset,
            &bytes_written, portMAX_DELAY);
  M5.Axp.SetLed(false);
}

void setup() {
  M5.begin();
  M5.Axp.SetSpkEnable(true); 
  // Setup Buttons
  M5.Buttons.setFont(FSSB12);
  btn_record.setFont(FSSB12);
  btn_record.addHandler(event_btn_record, E_RELEASE);
  btn_play.setFont(FSSB12);
  btn_play.addHandler(event_btn_play, E_RELEASE);
  M5.Buttons.draw();

  M5.Axp.SetLed(false);
  delay(100); 
}

void loop() {
  M5.update();
}

録音・再生アプリの実行

録音・再生アプリアプリ「mictest.ino」を実行し、画面の「Recode」ボタンを押すと録音されて再生を行います。画面の「Play」ボタンを押すと録音された音声を再生します。

録音方法:「Recode」ボタンを押して離すときにから録音を開始します。再生時にはノイズが発生しますので、その発生までに発話した音声が録画されます。