|
| 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()から必要に応じて呼び出されます。コンストラクタで必要な設定をまとめでやっているので、あとはスッキリとなってます。 |