Files
ESP32_ZACUS/plip_voice/main/dtmf.h
T
clement aa7ae277ed
CI / platformio (pull_request) Failing after 4m0s
CI / platformio (push) Failing after 14m58s
feat(plip): voice loop + DTMF + ring cadence
- hook polarity active-HIGH + auto-resync (was LOW)
- ring cadence FT 1.5s ON / 3.5s OFF
- DTMF Goertzel decoder (dtmf.c/h) + rotary debounce
- LISTEN half-duplex: capture → /v1/voice/reply → play
- WAV playback buffered PSRAM + mono→stereo upmix
- SPIFFS mount at boot for pre-loaded greetings
- ES8388: DAC digital vol + mic PGA + GPIO INPUT_OUTPUT
- turn_client multipart + 90s timeout + fixed routing
- debug endpoints: vol/dacvol/offhook/getfile/hookmon
2026-06-15 21:12:33 +02:00

58 lines
1.6 KiB
C

#pragma once
/*
* dtmf.h — DTMF (touch-tone) detector via Goertzel algorithm.
*
* API:
* dtmf_detect_frame() — pure signal processing, no I/O, testable standalone
* dtmf_start() / dtmf_stop() — arm/disarm the background capture task
*
* The capture task reads 20 ms frames from audio_capture_read_frame() and calls
* dialer_push_digit() for confirmed digit presses (digits 0-9 only).
*
* Guard: all declarations and the task body are compiled only when
* CONFIG_PLIP_DIAL_DTMF is set (see Kconfig.projbuild).
*/
#include "sdkconfig.h"
#if CONFIG_PLIP_DIAL_DTMF
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Analyse one 20 ms frame (320 samples at 16 kHz) for a DTMF tone.
*
* Returns the detected character ('0'-'9', '*', '#') once per confirmed press,
* or '\0' when nothing is detected or debounce is still pending.
*
* Debounce rules (internal static state):
* - A symbol must appear in ≥ DTMF_CONFIRM_FRAMES consecutive frames to be
* reported.
* - After a report, at least DTMF_RELEASE_FRAMES of "no tone" must be seen
* before the same (or another) symbol can be reported again.
*/
char dtmf_detect_frame(const int16_t *mono, int n);
/*
* Start the DTMF background task (created once; idempotent re-arm).
* The task reads microphone frames and pushes confirmed 0-9 digits to the
* dialer. Must be called after audio_init().
*/
void dtmf_start(void);
/*
* Disarm the DTMF task. The task suspends itself; the RX stream continues
* for the benefit of the voice capture path (full-duplex architecture).
*/
void dtmf_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_PLIP_DIAL_DTMF */