概要
前回は小さめのWaveファイルをプログラムのフラッシュに埋め込みました。今回はもう少し大きなファイルを保存できるSPIFFSにmp3ファイルを保存してみたいと思います。
注意点
mp3再生はちょっと間違えると雑音が鳴ります。そしてATOM Echoの初期ロットは音声のアンプに比べてスピーカーが弱いです。その結果大きな音を鳴らすとスピーカーが壊れる報告がでています。私のATOM Echoも低音で音が割れるようになってしまいました。
症状が進むと発熱して、ケースが溶けてしまうので現時点ではこの作業はおすすめしません!
おそらくハードウエア的に何らかの対策が今後取られると思います、、、
保存容量について
Partition Scheme | プログラム | SPIFFS |
初期値 | 1.3M | 1.5M |
No OTA | 2M | 2M |
Minimal SPIFFS | 2M | 0.2M |
ざっくりですが、上記の関係になっています。ATOM Echoはフラッシュが4M搭載しています。その4Mをどの割合で使うのかを設定することができます。初期値はプログラムをネット経由で更新できるOTAが利用できるようにプログラム領域が2つあり、プログラムだけで2.6Mも専有しています。
OTAを利用しない場合には、プログラムの書き換え用の領域である1.3Mが利用できない領域となり無駄になります。No OTAを選択することでその1.3M相当を他の用途で利用できるようになります。
- Partition Table – M5StickC非公式日本語リファレンス
上記にすこし詳しい説明があります。
SPIFFSとは?
フラッシュ領域に擬似的なファイルシステムを再現した仕組みです。SDカードなどと同じようなイメージでファイルを扱うことができます。
一般的には上記のようなツールを使って、SPIFFSにファイルをアップロードします。ちょっとツールを入れるのが面倒なんですよね。。。
そこで、今回はArduino IDEのスケッチからファイルを保存してみました。
SPIFFSファイル保存スケッチ例(GitHub)
#include "FS.h" #include "SPIFFS.h" #include "file.h" #define FILENAME "/trumpet2.mp3" void setup() { Serial.begin(115200); SPIFFS.begin(); delay(50); Serial.println("SPIFFS FILE SAVE"); // フォーマット Serial.println("SPIFFS FORMAT START"); SPIFFS.format(); Serial.println("SPIFFS FORMAT END"); // ファイルを開く Serial.println("SPIFFS FILE OPEN"); File fp = SPIFFS.open(FILENAME, FILE_WRITE); // 書き込み Serial.println("SPIFFS FILE WRITE START"); fp.write(file, sizeof(file)); fp.close(); Serial.println("SPIFFS FILE WRITE END"); // 保存できているか確認 fp = SPIFFS.open(FILENAME, FILE_READ); size_t size = fp.size(); Serial.printf("SPIFFS FILE SIZE = %d\n", size); } void loop() { }
ファイルをスケッチの中に埋め込んで、スケッチからSPIFFSに保存するスケッチです。やっていることは単純なので理解しやすいと思います。ファイル名はスラッシュから書く必要があるので注意してください。
今回も効果音ラボさんのデータを利用させていただきました。音声はどんなものでも構いません。ただし、プログラムに埋め込んだものを保存するので、初期値では1M程度のものが上限となります。No OTAにすることで2M近くのファイルを保存可能です。
内部でSPIFFSをフォーマットして初期化していますので、初期化せずにファイル保存をすることで複数のファイルを保存することも可能です。
ただし、複数のファイルを頻繁に更新する場合には、上記で紹介した転送ツールを使ったほうが便利だと思います。
mp3のデータ化はこのブログのTOOLS以下にある「ファイルデータ変換」のページで行うことができます。画像や音声とは違いファイル全体をそのまま16進数に変換しています。
再生スケッチ例(GitHub)
#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 #define FILENAME "/trumpet2.mp3" void setup() { M5.begin(true, false, true); delay(50); Serial.println(); SPIFFS.begin(); Serial.printf("MP3 playback begins...\n"); audioLogger = &Serial; file = new AudioFileSourceSPIFFS(FILENAME); id3 = new AudioFileSourceID3(file); out = new AudioOutputI2S(); out->SetPinout(CONFIG_I2S_BCK_PIN, CONFIG_I2S_LRCK_PIN, CONFIG_I2S_DATA_PIN); out->SetChannels(1); out->SetGain(0.3); mp3 = new AudioGeneratorMP3(); } void loop() { M5.update(); if (M5.Btn.isPressed()) { if (!mp3->isRunning()) { Serial.println("Play"); mp3->begin(id3, out); } } if (mp3->isRunning()) { if (!mp3->loop()){ mp3->stop(); } } delay(1); }
上記ライブラリを使わせてもらっています。ライブラリの中にいろいろサンプルが入っているのですが、I2Sの他にDACなどを利用しているサンプルがあるので間違えて実行しないように注意してください。
間違えて実行するとATOM Echo壊れる可能性があります。。。まあ、間違えて実行していなくても私のATOM Echoはこわれたので、このライブラリ自体がちょっと現在のATOM Echoには負荷を与えてしまっている気がします。
※追記
本家のライブラリに手を入れてしまっているみたいなので、上記のファイルを使わないとだめみたいです。。。
out->SetPinout(CONFIG_I2S_BCK_PIN, CONFIG_I2S_LRCK_PIN, CONFIG_I2S_DATA_PIN); out->SetChannels(1); out->SetGain(0.3);
上記の3行は設定しなくても動かすことができます。しかしながらピンなどは明示的に設定したほうがいいと思いますので設定を追加しています。
SetGain()がボリュームになります。0.3なので元の30%の音量に減らしています。1のまま再生するとちょっとスピーカーに負荷を与えてしまう可能性があります。ただ(以下略)
雑音がなった場合
音声の試験としていると、意図しない再生が発生する場合があります。この場合には素早くUSBを抜いてください。ATOMなので電源が抜かれることで音も止まるはずです。基本的に電源を入れた状態ですぐに音がなる設定になっているとスピーカーに負荷を与えるので、ボタンを押したら再生などにしたほうが安全です。
再起動して音がならない状態であれば、電源を抜くのではなくリセットボタンを押すのでも大丈夫だと思います。万が一起動したら音がなるスケッチを入れてしまった場合には、音がならない安全なスケッチを上書きします。このときリセットボタンを押しながらパソコンに接続し、書き込み待ちのときにリセットボタンを離すことで、安全にスケッチの上書きが可能になります。
まとめ
現状のATOM Echoはスピーカーに問題があるので、利用をおすすめしません。Waveなどは比較的トラブルになりにくいですがmp3は負荷が高い気がします。
スピーカーが完全に壊れるとショートした状態になり、熱が発生してケースが溶けてしまいます。発火する可能性や、パソコンに影響を与える可能性があるので必ず目の前で確認しながら使ってください。
連続してATOM Echoの記事を書いてきましたが、壊れてしまったので少しお休みして他のネタを書いていきたいと思います。
SPIFFS自体は汎用的に使えるので、転送ツールを使うか書き込み用のスケッチを使うなどしてぜひ活用してみてください。
コメント