Files
cardboy/Firmware/main/include/buzzer.hpp
2025-10-07 22:50:45 +02:00

55 lines
1.5 KiB
C++

// Simple piezo buzzer helper using LEDC (PWM) for square wave tones.
// Provides a tiny queued pattern player for short game SFX without blocking.
#pragma once
#include <cstdint>
class Buzzer {
public:
static Buzzer &get();
void init(); // call once from app_main
// Queue a tone. freq=0 => silence. gap_ms is silence after tone before next.
void tone(uint32_t freq, uint32_t duration_ms, uint32_t gap_ms = 0);
// Convenience SFX
void beepRotate();
void beepMove();
void beepLock();
void beepLines(int lines); // 1..4 lines
void beepLevelUp(int level); // after increment
void beepGameOver();
// Mute controls
void setMuted(bool m);
void toggleMuted();
bool isMuted() const { return _muted; }
// Persistence
void loadState();
void saveState();
private:
struct Step { uint32_t freq; uint32_t dur_ms; uint32_t gap_ms; };
static constexpr int MAX_QUEUE = 16;
Step _queue[MAX_QUEUE]{};
int _q_head = 0; // inclusive
int _q_tail = 0; // exclusive
bool _running = false;
bool _in_gap = false;
void *_timer = nullptr; // esp_timer_handle_t (opaque here)
bool _muted = false;
Buzzer() = default;
void enqueue(const Step &s);
bool empty() const { return _q_head == _q_tail; }
Step &front() { return _queue[_q_head]; }
void popFront();
void startNext();
void schedule(uint32_t ms, bool gapPhase);
void applyFreq(uint32_t freq);
static void timerCb(void *arg);
void clearQueue() { _q_head = _q_tail = 0; }
};