スタックチャン風呼び出しマシン作製の続き。(これから書く)
音声の出し方はこちらでしらべて手を付けられそうになった。
まずは出し方で調べた音声用のAudioOutputM5Speakerを別ファイルに切り出し。サンプルソースほぼそのまんま。ただ、他の人とクラス名かぶりそうなのでネームスペースだけ切っておいた。
#ifndef EPEA__AUDIOOUTPUT_M5SPEAKER_H
#define EPEA__AUDIOOUTPUT_M5SPEAKER_H
#include <AudioOutput.h>
namespace epea {
class AudioOutputM5Speaker : public AudioOutput {
ファイル名指定したらファイル流す、止める関数追加
void stopVoice() {
if (mp3.isRunning()) mp3.stop();
}
void startVoice(const char *filename) {
file.open(filename);
mp3.begin(&file, &out);
}
セットアップの中でavater.initしてループの中でボタン押されたらストップ&スタートでとりあえず音楽は流れる。が、途切れがち。CPUコア1にだいぶ頑張らせているからかな?
avater.initの中から呼ばれる描画タスクはどちらもcore1で動いている。音声もcore1。今のところ使ってないけどcore0はwifiで結構使うみたいなので開けておきたい。
CPU負荷が原因ならmp3からcpuに優しいwavにしたらいいじゃないと試してみたけど状況は悪化。ファイル形式変更の道もつらそうなのでやはりmp3で頑張ってみる。
試しにスピーカーで使うCPUをcore0に変えても状況は変わらず。もしかしてCPUのせいじゃない??
auto spk_cfg = M5.Speaker.config();
spk_cfg.task_pinned_core = PRO_CPU_NUM;
M5.Speaker.config(spk_cfg);
M5.Speaker.begin();
タカヲさんからサンプルを教えてもらったので一旦こちらを試す。
このあとは調べ中。タカヲさんの調べながら(おわったら?)書き足す->試したときのメモこちら
EpeaAudioOutputM5Speaker.h)
#ifndef EPEA__AUDIOOUTPUT_M5SPEAKER_H
#define EPEA__AUDIOOUTPUT_M5SPEAKER_H
#include <AudioOutput.h>
namespace epea {
class AudioOutputM5Speaker : public AudioOutput {
public:
AudioOutputM5Speaker(m5::Speaker_Class* m5sound, uint8_t virtual_sound_channel = 0) {
_m5sound = m5sound;
_virtual_ch = virtual_sound_channel;
}
virtual ~AudioOutputM5Speaker(void){};
virtual bool begin(void) override {
return true;
}
virtual bool ConsumeSample(int16_t sample[2]) override {
if (_tri_buffer_index < tri_buf_size) {
_tri_buffer[_tri_index][_tri_buffer_index] = sample[0];
_tri_buffer[_tri_index][_tri_buffer_index + 1] = sample[1];
_tri_buffer_index += 2;
return true;
}
flush();
return false;
}
virtual void flush(void) override {
if (_tri_buffer_index) {
_m5sound->playRaw(_tri_buffer[_tri_index], _tri_buffer_index, hertz, true, 1, _virtual_ch);
_tri_index = _tri_index < 2 ? _tri_index + 1 : 0;
_tri_buffer_index = 0;
}
}
virtual bool stop(void) override {
flush();
_m5sound->stop(_virtual_ch);
return true;
}
const int16_t* getBuffer(void) const {
return _tri_buffer[(_tri_index + 2) % 3];
}
protected:
m5::Speaker_Class* _m5sound;
uint8_t _virtual_ch;
static constexpr size_t tri_buf_size = 1536;
int16_t _tri_buffer[3][tri_buf_size];
size_t _tri_buffer_index = 0;
size_t _tri_index = 0;
};
} // end namespace epea
#endif /* EPEA__AUDIOOUTPUT_M5SPEAKER_H */
#ifndef EPEA__AUDIOOUTPUT_M5SPEAKER_H
#define EPEA__AUDIOOUTPUT_M5SPEAKER_H
#include <AudioOutput.h>
namespace epea {
class AudioOutputM5Speaker : public AudioOutput {
public:
AudioOutputM5Speaker(m5::Speaker_Class* m5sound, uint8_t virtual_sound_channel = 0) {
_m5sound = m5sound;
_virtual_ch = virtual_sound_channel;
}
virtual ~AudioOutputM5Speaker(void){};
virtual bool begin(void) override {
return true;
}
virtual bool ConsumeSample(int16_t sample[2]) override {
if (_tri_buffer_index < tri_buf_size) {
_tri_buffer[_tri_index][_tri_buffer_index] = sample[0];
_tri_buffer[_tri_index][_tri_buffer_index + 1] = sample[1];
_tri_buffer_index += 2;
return true;
}
flush();
return false;
}
virtual void flush(void) override {
if (_tri_buffer_index) {
_m5sound->playRaw(_tri_buffer[_tri_index], _tri_buffer_index, hertz, true, 1, _virtual_ch);
_tri_index = _tri_index < 2 ? _tri_index + 1 : 0;
_tri_buffer_index = 0;
}
}
virtual bool stop(void) override {
flush();
_m5sound->stop(_virtual_ch);
return true;
}
const int16_t* getBuffer(void) const {
return _tri_buffer[(_tri_index + 2) % 3];
}
protected:
m5::Speaker_Class* _m5sound;
uint8_t _virtual_ch;
static constexpr size_t tri_buf_size = 1536;
int16_t _tri_buffer[3][tri_buf_size];
size_t _tri_buffer_index = 0;
size_t _tri_index = 0;
};
} // end namespace epea
#endif /* EPEA__AUDIOOUTPUT_M5SPEAKER_H */