Wio Terminal本体のみでMP3を鳴らす
2021/11/23公開
概要
Wio Terminal本体のSDカードに保存されたMP3を本体によるデコードで鳴らすTipsです。Wio TerminalでMP3を再生する方法についてググってみたところGrove MP3を制御して鳴らす例はありましたが、
本体のみで完結している例はありませんでしたので、ここに検証した結果を残しておきたいと思います。
解説
MP3のデコードにはAdafruit_MP3を使用していますので先にインストールしておいてください。本来はAdafruit製のARMチップ搭載ボード向けのライブラリなのですが、検証したところ特に変更を加えることなく動作しました。
また、MicroSDにはあらかじめ再生したいMP3ファイルを保存して本体に挿入しておいてください。
このサンプルソースでは下記3種類の出力方法をサポートしています。
使用したい出力先のコメントアウトを外して使ってください。
- 内蔵ブザー
- Groveポート(画面向かって右側)
- DACピン
個人的にはdigitalWriteが好きです。
- digitalWrite:はっきりした音ですが仕組み上、減衰音はうまく鳴りません。
- analogWrite:若干音が小さく不明瞭な音。減衰音は一応ちゃんと出せるっぽい。
接続例
サンプルソース
#include <Seeed_FS.h>
#include <SD/Seeed_SD.h>
#include "Adafruit_MP3.h"
//set this to a value between 0 and 4095 to raise/lower volume
// DACピンから出力する場合
//#define VOLUME_MAX 4095
// 内蔵ブザーまたはGroveポートから出力する場合
#define VOLUME_MAX 512
const char *filename = "music.mp3";
File dataFile;
Adafruit_MP3 player;
void writeDacs(int16_t l, int16_t r){
uint16_t vall = map(l, -32768, 32767, 0, VOLUME_MAX);
uint16_t valr = map(r, -32768, 32767, 0, VOLUME_MAX);
// 内蔵ブザーから鳴らす場合(analogWrite版)
//analogWrite(WIO_BUZZER, vall);
// 内蔵ブザーから鳴らす場合(digitalWrite版)
if(vall > 256) {
digitalWrite(WIO_BUZZER, HIGH);
} else {
digitalWrite(WIO_BUZZER, LOW);
}
// Groveポートから出力する場合(analogWrite版)
//analogWrite(A0, vall);
//analogWrite(A1, valr);
// Groveポートから出力する場合(digitalWrite版)
//if(vall > 256) {
// digitalWrite(D0, HIGH);
//} else {
// digitalWrite(D0, LOW);
//}
//if(valr > 256) {
// digitalWrite(D1, HIGH);
//} else {
// digitalWrite(D1, LOW);
//}
// DACピンから鳴らす場合
//analogWrite(PIN_DAC0, vall);
//analogWrite(PIN_DAC1, valr);
}
int getMoreData(uint8_t *writeHere, int thisManyBytes){
int bytesRead = 0;
int toRead = min(thisManyBytes, 768); //limit the number of bytes we can read at a time so the file isn't interrupted
while(dataFile.available() && bytesRead < toRead){
*writeHere = dataFile.read();
writeHere++;
bytesRead++;
}
return bytesRead;
}
void setup() {
SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 25000000);
// 内蔵ブザーから出力する場合
pinMode(WIO_BUZZER, OUTPUT);
// Groveポートから出力する場合
//pinMode(A0, OUTPUT);
//pinMode(A1, OUTPUT);
// DACピンから出力する場合
//analogWriteResolution(12);
//pinMode(PIN_DAC0, OUTPUT);
//pinMode(PIN_DAC1, OUTPUT);
dataFile = SD.open(filename);
if(!dataFile){
//Serial.println("could not open file!");
while(1);
}
player.begin();
//do this when there are samples ready
player.setSampleReadyCallback(writeDacs);
//do this when more data is required
player.setBufferCallback(getMoreData);
player.play();
}
void loop() {
player.tick();
}
戻る