がいよー
M5Stackでなんか音を出してみようと思ってMozziライブラリというのが便利そうだぞ、と。とりあえず音を鳴らすところまでやりたい。
Mozziライブラリは以下。Arduino IDEのライブラリから検索するとサクッとインストールできる。
サンプルコードを眺める
いっぱいある。まずはBASICあたりのSineWaveをば。
初期化
void setup(){
startMozzi(CONTROL_RATE); // :)
aSin.setFreq(440); // set the frequency
}
Mozziを初期化してサイン波の周波数をセットしている。それだけ。
音を鳴らすとこ
AudioOutput_t updateAudio(){
return MonoOutput::from8Bit(aSin.next()); // return an int signal centred around 0
}
オーディオを出力するタイミングでupdateAudio()が呼ばれるらしい。サイン波のテーブルを順繰りに読み込んでるんだろうな。とりあえずこれビルドしてポーってなったら優勝。
鳴らないのでいろいろ調べる
M5Stack用にsetup()を修正してみたけれど鳴らない。
修正後の初期化
#include <M5Core2.h>
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
void setup(){
M5.begin();
M5.Axp.SetSpkEnable(true);
M5.Lcd.println("Hello Mozzi");
startMozzi(MOZZI_CONTROL_RATE); // :)
aSin.setFreq(440); // set the frequency
}
ChatGPTに聞いてみたら、どうもピン番号がおかしいのではないかと。あとMozziのバージョンによって対応が変わってくるそうで、2.x系はピン番号なんかを上書きでセットできるらしいが、ひとまずMozzi 1.1.2まで戻す。
とりあえず鳴るパターン。
- Mozziライブラリは1.1.2にダウングレード
- MozziライブラリのAudioConfigESP32.hのdefineを手で書き換える
AudioConfigESP32.h
// Set output mode
// #define ESP32_AUDIO_OUT_MODE INTERNAL_DAC
#define ESP32_AUDIO_OUT_MODE PT8211_DAC
// For external I2S output, only: I2S_PINS
// #define ESP32_I2S_BCK_PIN 26
// #define ESP32_I2S_WS_PIN 25
// #define ESP32_I2S_DATA_PIN 33
#define ESP32_I2S_BCK_PIN 12
#define ESP32_I2S_WS_PIN 0
#define ESP32_I2S_DATA_PIN 2
サイン波を鳴らすコード
#include <M5Core2.h>
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#define MOZZI_CONTROL_RATE 256
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table included above
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
bool isPlaying = false;
void setup(){
M5.begin();
M5.Axp.SetSpkEnable(true);
M5.Lcd.println("Hello Mozzi");
startMozzi(MOZZI_CONTROL_RATE); // :)
aSin.setFreq(440); // set the frequency
}
void updateControl(){
M5.update();
// ボタン A が押されたら音を再生
if (M5.BtnA.wasPressed()) {
isPlaying = true;
M5.Lcd.println("Play");
}
// ボタン B が押されたら音を停止
if (M5.BtnB.wasPressed()) {
isPlaying = false;
M5.Lcd.println("Stop");
}
}
AudioOutput_t updateAudio(){
if (isPlaying) {
return MonoOutput::from8Bit(aSin.next() / 4);
} else {
return MonoOutput::from8Bit(128);
}
}
void loop(){
audioHook(); // required here for Mozzi
}
ボタンAを押すとポーって鳴る。ボタンBで止まる。ちなみにM5Unified版だとうまくならない。I2Cを食い合ってるんじゃないかとGPT曰く。