M5Core2とM5Atom EchoでMP3再生


M5Core2とM5Atomには、スピーカがすでについていますので、MP3再生してみます。
いずれも、ESP32に搭載しているI2Sで再生します。
ファイルソースは、HTTP GetによるURL指定と、SDに格納したファイルパス指定の2種類を用意しました。

ESP32におけるオーディオ再生

以下のライブラリを利用させていただきました。PlatformIOのライブラリでも検索にヒットします。
サンプルコードがたくさんあるので助かりました。

earlephilhower/ESP8266Audio

〇宣言

module_audio.cpp
#include <driver/i2s.h>
#include "AudioFileSourceHTTPStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
#include "AudioFileSourceSD.h"

static AudioOutputI2S *out;

static AudioGeneratorMP3 *mp3 = NULL;
static AudioFileSourceSD *file_sd = NULL;
static AudioFileSourceHTTPStream *file_http = NULL;
static AudioFileSourceBuffer *buff = NULL;

ソースがSDの場合は、AudioFileSourceSDを利用し、HTTPの場合は AudioFileSourceHTTPStream AudioFileSourceBufferを利用します。後者は、ネットワークを介した通信のため、安定化のためにバッファを使っています。
また、WAVEファイルなどでも利用可能ですが、単純化のため今回はMP3ファイル限定にしました。

〇準備

module_audio.cpp
  out = new AudioOutputI2S(I2S_NUM_0);
  out->SetOutputModeMono(true);
  out->SetGain(audio_gain / 100.0);

音量は、audio_gainで指定します。0から100の間です。

〇PIN設定

module_audio.cpp
  out->SetPinout(bclk, lrck, dout);

3つのPINを使います。BCLK、LRCK、DataOutです。
M5Core2では、以下の通りです。

BCLK:12
LRCK:0
DataOut:2

M5Atom Echoでは、以下の通りです。

BCLK:19
LRCK:33
DataOut:22

〇URLから再生
ネットワークに左右されるため、バッファを挟んでいます。

module_audio.cpp
  file_http = new AudioFileSourceHTTPStream(url);
  buff = new AudioFileSourceBuffer(file_http, bufsize);
  mp3 = new AudioGeneratorMP3();
  mp3->begin(buff, out);

〇SDからの再生

module_audio.cpp
  file_sd = new AudioFileSourceSD(path);
  if( !file_sd->isOpen() ){
    delete file_sd;
    file_sd = NULL;
    return JS_EXCEPTION;
  }
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file_sd, out);

上記呼び出して、勝手に再生してくれるわけではなく、上記、URLからの場合とSDKからの場合と、いずれも定期的に音声データの汲み上げが必要です。
以下の処理を、loop()などで定期的に呼び出す必要があります。

module_audio.cpp
  if( mp3 != NULL ){
    if (mp3->isRunning()) {
      if (!mp3->loop())
        mp3->stop();
    }
  }

以上で、MP3ファイルの音声が再生されるかと思います。

Javascriptでの呼び出し

先ほど示した処理をライブラリ等にまとめてESP32でのC言語で実装するだけです。
今回は、以下の技術書で紹介している、ESP32内部で動作するJavascript環境で動作させる場合のJavascriptコード例を示します。

M5StackとJavascriptではじめるIoTデバイス制御

Javascriptでの実装例です。

import * as audio from "Audio";

//audio.begin(12, 0, 2); // for M5Core2
audio.begin(19, 33, 22); // for M5Atom Echo
audio.playUrl("http://192.168.1.16:20080/g_07.mp3"); // URLから再生の場合
//audio.playSd("/g_07.mp3"); // SDから再生の場合

function loop(){
	audio.update(); // 定期的に音声データの汲み上げ
}

実装はこれだけです。細かな処理はC言語で実装済みなので。
(Javascriptで実装すると非常に楽ちんなのでおすすめです。)

以上