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


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

https://qiita.com/n0bisuke/items/88b3d274263b9d4f6dc7

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

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

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">再生行けたと思ってたコード、次の再生にいかず… うーむ。<br><br> <a href="https://twitter.com/hashtag/%E3%83%AA%E3%83%86%E3%83%BC%E3%83%AB%E3%83%86%E3%83%83%E3%82%AF%E3%83%8F%E3%83%83%E3%82%AB%E3%82%BD%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#リテールテックハッカソン</a> <a href="https://twitter.com/hashtag/%E5%91%BC%E3%81%B3%E8%BE%BC%E3%81%BF%E5%90%9B?src=hash&amp;ref_src=twsrc%5Etfw">#呼び込み君</a> <a href="https://t.co/nMEgX3cQE3">pic.twitter.com/nMEgX3cQE3</a></p>&mdash; 菅原のびすけ （プロトアウト9期募集中) (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1667412971981774848?ref_src=twsrc%5Etfw">June 10, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

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

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

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

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">それっぽい挙動にアップデート<br><br> <a href="https://twitter.com/hashtag/%E3%83%AA%E3%83%86%E3%83%BC%E3%83%AB%E3%83%86%E3%83%83%E3%82%AF%E3%83%8F%E3%83%83%E3%82%AB%E3%82%BD%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#リテールテックハッカソン</a> <a href="https://t.co/v1FZVfQZXq">pic.twitter.com/v1FZVfQZXq</a></p>&mdash; 菅原のびすけ （プロトアウト9期募集中) (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1667417844299206661?ref_src=twsrc%5Etfw">June 10, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

```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番目のコードでココがすごいを再生できました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">商品のどこがすごいのかを教えてくれる呼び込み君が出来た！<br><br> <a href="https://twitter.com/hashtag/%E3%83%AA%E3%83%86%E3%83%BC%E3%83%AB%E3%83%86%E3%83%83%E3%82%AF%E3%83%8F%E3%83%83%E3%82%AB%E3%82%BD%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#リテールテックハッカソン</a> <a href="https://twitter.com/hashtag/%E3%82%B3%E3%82%B3%E3%81%8C%E3%81%99%E3%81%94%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#ココがすごい</a> <a href="https://twitter.com/hashtag/%E5%B8%9D%E4%BA%AC%E5%B9%B3%E6%88%90%E5%A4%A7%E5%AD%A6?src=hash&amp;ref_src=twsrc%5Etfw">#帝京平成大学</a> <a href="https://twitter.com/hashtag/%E5%91%BC%E3%81%B3%E8%BE%BC%E3%81%BF%E5%90%9B?src=hash&amp;ref_src=twsrc%5Etfw">#呼び込み君</a> <a href="https://t.co/FzP7rdp7hr">pic.twitter.com/FzP7rdp7hr</a></p>&mdash; 菅原のびすけ （プロトアウト9期募集中) (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1667424325975281665?ref_src=twsrc%5Etfw">June 10, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>