#include <M5Unified.h>
#include <FastLED.h>
#include <arduinoFFT.h>
// --- LEDの設定 ---
#define LED_PIN 26
#define NUM_LEDS 300
#define EMP_LEDS 120
CRGB leds[NUM_LEDS];
// --- マイク & FFTの設定 ---
#define SAMPLES 512
#define SAMPLING_FREQ 40000
ArduinoFFT<double> FFT = ArduinoFFT<double>();
int16_t* audio_buffer = nullptr;
double vReal[SAMPLES];
double vImag[SAMPLES];
// --- 新しいロジックで使う設定値 ---
#define MAX_MAGNITUDE 8000.0 // 反応する音の大きさの最大値。要調整。
#define FFT_BIN_START 0 // 視覚化する周波数範囲の開始点
#define FFT_BIN_END 60 // 視覚化する周波数範囲の終了点
void setup() {
M5.begin();
// シリアル通信の開始 (PIOのモニタ用)
Serial.begin(115200);
M5.Lcd.setRotation(1);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.println("Equalizer Viz (PIO)");
audio_buffer = (int16_t*)malloc(sizeof(int16_t) * SAMPLES);
if (!audio_buffer) {
M5.Lcd.println("Memory failed");
while(1);
}
M5.Mic.begin();
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(60);
FastLED.clear();
FastLED.show();
}
void loop() {
// マイクから音声データを読み込む
M5.Mic.record(audio_buffer, SAMPLES, SAMPLING_FREQ);
// FFTの準備
for (int i = 0; i < SAMPLES; i++) {
vReal[i] = (double)audio_buffer[i];
vImag[i] = 0;
}
// FFT計算
FFT.windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.complexToMagnitude(vReal, vImag, SAMPLES);
// ==================== ここからロジック変更 ====================
for (int i = 0; i < NUM_LEDS; i++) {
// このLED (i番目) が担当するFFTビンの範囲を計算
int start_bin = map(i, 0, NUM_LEDS, FFT_BIN_START, FFT_BIN_END);
int end_bin = map(i + 1, 0, NUM_LEDS, FFT_BIN_START, FFT_BIN_END);
// 担当範囲のFFT結果(音の強さ)の平均を求める
double magnitude_sum = 0;
for (int j = start_bin; j < end_bin; j++) {
magnitude_sum += vReal[j];
}
double magnitude = magnitude_sum / (end_bin - start_bin);
// 音の強さに応じて、色(Hue)と明るさ(Brightness)を決定
magnitude = constrain(magnitude, 0, MAX_MAGNITUDE);
// 色のマッピング: 弱い(0) => 青(160), 強い(MAX) => 赤(0)
byte hue = map(magnitude, 0, MAX_MAGNITUDE, 160, 0);
// 明るさのマッピング: 弱い(0) => 暗い(50), 強い(MAX) => 明るい(255)
byte brightness = map(magnitude, 0, MAX_MAGNITUDE, 9, 255);
// もし音が非常に小さければ、LEDを消灯する
if (magnitude < 100) {
brightness = 0;
}
// 計算した色と明るさをLEDに設定
leds[i + EMP_LEDS] = CHSV(hue, 255, brightness);
}
// ==================== ここまでロジック変更 ====================
FastLED.show();
delay(10);
}
Comments