見出し画像

AIスタックチャンメモ(2)

今日の目標は
「SDカード上の音声ファイルを鳴らすこと」

M5Unifiedを使った例が見つからない

ChatGPTに聞いても、エラーばっかりで全然進まない(私に基礎知識が無いからなんだけど)ので、自力でWeb検索してみることにしました。

「M5stack 音を鳴らす」
「M5Stack Core2 音楽再生」
などなど見るが、今回は「M5Core2.h」のライブラリで書かれたものばかりが見つかります。

本当はChatGPTさんに
「これをM5Unifiedのライブラリで使える形に書きかえて」
と頼めば良いのでしょうが、このスタックチャン工作に関しては、
私はGPTさんをいまいち信用できません。

今日のコード

なので、とりあえず今日は「M5Core2」のライブラリを使ったコードで、とりあえず用意したファイルを再生してもらうことにしました。
前回までのコードは一旦全破棄です。スタックチャンの顔は出ません。


「aisatsu.wav」という名前の短いあいさつの入った音声ファイルをSDのルートに置いて、以下のようなコードを書きました。
(ライブラリは)「M5Core2」と「ESP8266Audio」

※先に注意:ボタンAを押したら、ゆっくりとつぶれたような気持ち悪い音声が再生されます(どんなWAVファイルを用意するかにもよりますが)。再生速度や音量などの設定が悪いのか、スピーカーの限界なのか?

次回は改良を目指します。

#include <M5Core2.h>
#include <driver/i2s.h>
#include "AudioFileSourceSD.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"

AudioGeneratorWAV *wav = NULL;
AudioFileSourceSD *file;
AudioOutputI2S *out;

#define BCLK_PIN 12
#define LRCK_PIN 0
#define SADTA_PIN 2
#define EXTERNAL_I2S 0
#define OUTPUT_GAIN 50 // ボリュームを50%に設定

void playAudio(const char *path)
{
  // 再生中の場合は、停止する
  if (wav != NULL)
  {
    wav->stop();
    delete wav;
    delete file;
    delete out;
    wav = NULL;
    file = NULL;
    out = NULL;
  }

  file = new AudioFileSourceSD(path);
  out = new AudioOutputI2S(0, 1); // 出力チャンネルとボリュームの設定
  out->SetPinout(BCLK_PIN, LRCK_PIN, SADTA_PIN);
  out->SetOutputModeMono(true); // モノラル出力に設定
  out->SetGain((float)OUTPUT_GAIN / 100.0);
  wav = new AudioGeneratorWAV();
  wav->begin(file, out);
}

void setup()
{
  M5.begin();
  M5.Lcd.setBrightness(255);
  M5.Lcd.fillScreen(WHITE);
  // スピーカーの初期化
  M5.Axp.SetSpkEnable(true);
}

void loop()
{
  M5.update();

  if (M5.BtnA.wasPressed())
  {
    if (wav != NULL && wav->isRunning())
    {
      wav->stop();
      delete wav;
      delete file;
      delete out;
      wav = NULL;
      file = NULL;
      out = NULL;
    }
    else
    {
      playAudio("/aisatsu.wav");
    }
  }

  if (wav != NULL)
  {
    if (wav->isRunning())
    {
      if (!wav->loop())
      {
        wav->stop();
        delete wav;
        delete file;
        delete out;
        wav = NULL;
        file = NULL;
        out = NULL;
      }
    }
    else
    {
      Serial.printf("WAV done\n");
      delay(1000);
    }
  }
}

次回は改良を目指します。(大事なことなので2回・・・。)

この記事が気に入ったらサポートをしてみませんか?