コンテンツにスキップ
JA

合成 sine ストリーミング

MCU 上で 16 kHz mono PCM16 の sine を合成して Hapbeat に流します。保存音源は不要で、 周波数・強さをライブに変えられます。

hb.playSine(160.0f, 0.7f, 400); // 160Hz・強さ0.7・400ms

playSinedurationMs の間ブロックします。短い触覚フィードバックに向きます。

押している間ずっと振動させたい、センサ値で周波数を動かしたい、といった用途では beginSine / pumpSine / endSine を使います。pumpSine()loop() から頻繁に呼んで、 デバイスのリングバッファを満たし続けます。

void onPressDown() {
hb.beginSine(160.0f, 0.8f); // 連続 sine を開始
}
void loop() {
// ... 入力処理 ...
if (hb.sineActive()) hb.pumpSine(); // 毎ループ呼ぶ(途切れ防止)
}
void onPressUp() {
hb.endSine(); // 停止
}
  • pumpSine() は 1 回の呼び出しで送るチャンク数が上限つきなので、loop() を 長時間(おおよそ 160ms 以上)ブロックしなければ自動でペース調整されます。
  • 連続中に周波数・強さを変えたい場合は、一度 endSine() してから新しい値で beginSine() し直します。

合成 sine は UDP で送るため、Wi-Fi の状況で途切れることがあります。対策:

  • WiFi.setSleep(false) を WiFi 接続後に呼ぶ(ESP32 の modem-sleep ジッタを排除)。
  • デバイスを見つけておく: discover() 済みなら送信は unicast になり、MAC ACK + 再送が効いて大幅に滑らかになります。1 台も見つかっていないとブロードキャストに なり、ACK / 再送が無いうえ AP の DTIM 保留(100〜300 ms)も受けます (デバイス検出と宛先指定 参照)。loop() から数秒おきに ping() を呼んで宛先表を維持してください。
  • pumpSine()loop() で頻繁に呼ぶ。重い処理で loop() が長く止まると、 デバイス側のリング(約 256ms)が枯渇して途切れます。