wav,mp3の再生
効果音のサンプルはありましたが、データを直接定義しているので面倒そう! wavファイルなどが再生できれば....と思ったのですが果たしてできるか? できたとしても音質は?結果の動画です。

パソコンで聞くのと同じくらいの音質です。wavやmp3のファイルが再生できるので、 人感センサーが人を検出をしたらパトカーのサイレンを鳴らす。(防犯用)などいろいろ 活用できそうです。
今後、これを使うことが多くなりそうなので、クラスにして使いやすくしました。
本体のソースです。
/*
*******************************************************************************
* M5Stack prototype
* date:2022/8/15
* Author Sadajejeje
*******************************************************************************
*/

#include <M5Core2.h>
#include "myAudio.h"

myAudio g_myAudio;

void setup() {
    M5.begin();
    // スピーカーの初期化
    M5.Axp.SetSpkEnable(true); 
    M5.Lcd.setTextSize(2);
    M5.Lcd.println("ButtonA play wav");
    M5.Lcd.println("ButtonB play mp3");
    M5.Lcd.println("ButtonC play stop");
}


void loop() {
    M5.update();
    if(g_myAudio.getStatus() != IDLE)
    {
        if (M5.BtnC.wasPressed()) {
            g_myAudio.stop();
        } 
        else
        {
            g_myAudio.loop();
        }
    }
    else
    {
        if (M5.BtnA.wasPressed()) {
            //ボタンAが押された
            g_myAudio.playWav("/restra.wav");
        }
        else if (M5.BtnB.wasPressed()) {
            //ボタンBが押された
            g_myAudio.playMp3("/cat.mp3");
        } 
    }

}

ボタンAが押されたらwavファイルをボタンBが押されたらmp3ファイルを再生します。 ボタンCが押せれたら再生を中止します。
クラスmyAudioを使うと本体のコードは簡潔になります。

次はクラスです。
myAudio.h
#ifndef _MyAudio_H
#define _MyAudio_H

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

#pragma once

#define BCLK_PIN 12
#define LRCK_PIN 0
#define SADTA_PIN 2
#define EXTERNAL_I2S 0
#define OUTPUT_GAIN 80

enum {IDLE, WAV, MP3};

class myAudio
{
public:   
    myAudio(void);
    void playWav(const char* fileName);
    void playMp3(const char* fileName);
    void stop();
    void loop();
    
    uint8_t m_status;
    uint8_t getStatus();
    //uint8_t getStatus():
    AudioGeneratorWAV *m_pWav;
    AudioGeneratorMP3 *m_pMp3;

    AudioFileSourceSD *m_pAudioFile;
    AudioOutputI2S *m_pAudioOut;
};


#endif
    
    
必要なインクロードファイルとポートの定義そして関数の定義をしています。
再生は本体側でファイル名を指定できるように、
void playWav(const char* fileName);
void playMp3(const char* fileName);

としています。
次はクラスの実装です。
myAudio.h
#include <M5Core2.h>
#include "myAudio.h"

myAudio::myAudio(void)
{
    m_pAudioFile = NULL;
    m_status = IDLE;
    m_pWav = new AudioGeneratorWAV();
    m_pMp3 = new AudioGeneratorMP3();

    m_pAudioOut = new AudioOutputI2S(I2S_NUM_0, EXTERNAL_I2S); 
    m_pAudioOut->SetPinout(BCLK_PIN, LRCK_PIN, SADTA_PIN);
    m_pAudioOut->SetOutputModeMono(false);
    m_pAudioOut->SetGain((float)OUTPUT_GAIN/100.0);

}

void myAudio::playWav(const char* fileName)
{
    if(m_status != IDLE)
    {
        return;
    }

    if(m_pAudioFile)
    {
        delete m_pAudioFile;
    }
    m_pAudioFile = new AudioFileSourceSD(fileName);
    if(m_pWav->begin(m_pAudioFile, m_pAudioOut) == true)
    {
        // M5.Lcd.print("wav OK");
    }
    m_status = WAV;
}

void myAudio::playMp3(const char* fileName)
{
    if(m_status != IDLE)
    {
        return;
    }

    if(m_pAudioFile)
    {
        delete m_pAudioFile;
    }
    m_pAudioFile = new AudioFileSourceSD(fileName);
    m_pMp3->begin(m_pAudioFile, m_pAudioOut);
    m_status = MP3;
}

void myAudio::stop()
{
    if(m_status == WAV)
    {
        if(m_pWav->isRunning() )
        {
            if(m_pWav->loop())
            {
                m_pWav->stop();
            }
        }
    }
    else if(m_status == MP3)
    {
        if(m_pMp3->isRunning() )
        {
            if(m_pMp3->loop())
            {
                m_pMp3->stop();
            }
        }
    }
    m_status = IDLE;
}


uint8_t myAudio::getStatus()
{
    return  m_status;
}


void myAudio::loop()
{
    if(m_status == WAV)
    {
        if (m_pWav->isRunning()) {
            if (!m_pWav->loop()){
                m_status = IDLE;
            } 
        }
    }
    else if(m_status == MP3)
    {
        if (m_pMp3->isRunning()) {
            if (!m_pMp3->loop()){
                m_status = IDLE;
            } 
        }
    }
}

ちょっと曲者なのがvoid myAudio::loop()です。これを再生中に実行しないと音がでません。 本体のloop()から必要に応じて呼び出されます。
コンストラクタで必要な設定をまとめでやっているので、あとはスッキリとなってます。