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