LoginSignup
0
0

ATOM EchoでMP3音源の再生色々 #リテールテックハッカソン

Posted at

以前ATOM EchoでMP3再生をするところまでの記事を書きましたが、細かい挙動ごとでコピペで使えるようにまとめておきます。

1. 1回ボタンを押して曲を流すと消える

1回だけ再生です。ボタンを押しても二度目はない。苦笑

狙った挙動ではないけどエラーでこうなっているみたいでした。

2. 1回ボタンを押すと曲が最後まで流れ、終了後にボタンを押すと再生できる

1回再生すると最後まで曲が再生され、途中でボタンを押しても止まりません。
これはすごく良さそう

main.cpp
#include <M5Atom.h>
#include "SPIFFS.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;
#define CONFIG_I2S_BCK_PIN      19
#define CONFIG_I2S_LRCK_PIN     33
#define CONFIG_I2S_DATA_PIN     22

void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
  (void)cbData;
  Serial.printf("ID3 callback for: %s = '", type);

  if (isUnicode) {
    string += 2;
  }
  
  while (*string) {
    char a = *(string++);
    if (isUnicode) {
      string++;
    }
    Serial.printf("%c", a);
  }
  Serial.printf("'\n");
  Serial.flush();
}

void mp3begin(){
  file = new AudioFileSourceSPIFFS("/popopo.mp3");
  id3 = new AudioFileSourceID3(file);
  id3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");  
  out = new AudioOutputI2S();
  out->SetPinout(CONFIG_I2S_BCK_PIN, CONFIG_I2S_LRCK_PIN, CONFIG_I2S_DATA_PIN);
  out->SetChannels(1);
  out->SetGain(0.8);

  mp3 = new AudioGeneratorMP3();
  mp3->begin(id3, out);
}

void setup(){
  M5.begin(true, false, true);
  delay(50);
  Serial.println();
  SPIFFS.begin();
  Serial.printf("MP3 playback begins...\n");
  audioLogger = &Serial;
  Serial.printf("Sample MP3 playback begins...\n");
  mp3begin();
}

int flag = 0;

void loop(){
  M5.update();

  if (M5.Btn.isPressed()){
    flag = 1;    
  }

  if(flag == 1){
    if (mp3->isRunning()) {
      if (!mp3->loop()) {
        mp3->stop();
        flag = 0;
      }
    } else {
      Serial.printf("MP3 done\n");
      delay(500);
      mp3begin();
    }
  }

  delay(1);
}

フラグ管理なしでできないのかなこれ...

3. ボタンを押している間音楽が再生され、もう一度押すと続きから再生される

2番目のコードをベースにloop関数内を変えました。

main.cpp
(省略)
void loop(){
  M5.update();

  if (M5.Btn.isPressed()){
    if (mp3->isRunning()) {
      if (!mp3->loop()) mp3->stop();
    } else {
      Serial.printf("MP3 done\n");
      delay(500);
      mp3begin();
    }
  }
  delay(1);
}

続きから再生されるのは挙動として欲しい時あるかも...?

4. 連続再生

二つ目のコードとほぼ一緒ですがloop関数の中だけちょっと変えました。

main.cpp
//省略

void loop(){
  M5.update();

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    Serial.printf("MP3 done\n");
    delay(500);
    mp3begin();
  }

  delay(1);
}

まとめ

2~4番目の挙動は用途によってそれぞれ使えそうですね。

2番目のコードでココがすごいを再生できました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0