Merge pull request 'feat(plip): mute audio output when handset on-hook' (#19) from feat/plip-mute-onhook into main
CI / platformio (push) Failing after 3m57s

This commit was merged in pull request #19.
This commit is contained in:
2026-06-14 18:45:03 +00:00
4 changed files with 54 additions and 5 deletions
+17 -1
View File
@@ -17,6 +17,7 @@
#include "audio.h"
#include "board_config.h"
#include "es8388.h"
#include "phone.h"
#include <inttypes.h>
#include <math.h>
@@ -24,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include "driver/gpio.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_spiffs.h"
@@ -371,10 +373,18 @@ static void audio_worker_task(void *arg)
ESP_LOGI(TAG, "stop");
break;
case CMD_RING:
ESP_LOGI(TAG, "ring start");
/* Ring must sound on-hook (caller hears it before picking up).
* Force PA on for the duration of the ring regardless of hook state. */
ESP_LOGI(TAG, "ring start — forcing PA on");
audio_pa_set(true);
xTaskCreate(ring_task, "ring", 4096, NULL, 4, NULL);
break;
case CMD_PLAY: {
/* Gate playback on hook state: no sound if handset is on-hook. */
if (!phone_is_offhook()) {
ESP_LOGI(TAG, "play ignored: on-hook (handset down)");
break;
}
const char *p = cmd.path;
if (!p || !*p || strncmp(p, "embedded:", 9) == 0) {
ESP_LOGI(TAG, "play: embedded cue");
@@ -393,6 +403,12 @@ static void audio_worker_task(void *arg)
/* ── Public API ──────────────────────────────────────────────────────────── */
void audio_pa_set(bool enable)
{
gpio_set_level(PLIP_PA_ENABLE, enable ? 1 : 0);
ESP_LOGI(TAG, "PA %s", enable ? "ON" : "OFF");
}
esp_err_t audio_init(void)
{
/* 1. ES8388 I2C init + register sequence. */
+6
View File
@@ -43,6 +43,12 @@ esp_err_t audio_stop(void);
* audio_stop() is called. Non-blocking — spawns an internal task. */
esp_err_t audio_ring_start(void);
/* Enable or disable the power amplifier (GPIO21 PA_ENABLE).
* Call audio_pa_set(true) on off-hook, audio_pa_set(false) on on-hook.
* ring_start forces PA on internally; ring_stop calls audio_pa_set(false)
* only if the handset is on-hook. */
void audio_pa_set(bool enable);
/*
* Capture microphone audio and encode as WAV (16 kHz, mono, S16-LE).
*
+26 -4
View File
@@ -23,6 +23,7 @@
static volatile bool s_edge_pending = false;
static volatile bool s_ringing = false;
static volatile bool s_offhook = false; /* true = handset picked up */
/* IRAM_ATTR: ISR must live in IRAM on original ESP32. */
static void IRAM_ATTR on_hook_isr(void *arg)
@@ -66,8 +67,20 @@ static void phone_task(void *arg)
/* Read and report initial level so master state machine is in sync. */
int last_level = gpio_get_level(hook_gpio);
const char *init_state = (last_level == 0) ? "off" : "on";
s_offhook = (last_level == 0);
ESP_LOGI(TAG, "phone task ready, hook GPIO=%d level=%d (%s)",
hook_gpio, last_level, init_state);
/* Set PA state to match initial hook position.
* On-hook at boot → mute PA so no audio escapes while handset is down. */
if (!s_offhook) {
ESP_LOGI(TAG, "boot: on-hook → PA off (mute)");
audio_pa_set(false);
} else {
ESP_LOGI(TAG, "boot: off-hook → PA on (unmute)");
audio_pa_set(true);
}
hook_client_report(init_state, "boot");
for (;;) {
@@ -78,14 +91,18 @@ static void phone_task(void *arg)
if (level != last_level) {
last_level = level;
if (level == 0) {
/* Off-hook: handset picked up. Stop ringing if active. */
ESP_LOGI(TAG, "off-hook (pickup) detected");
/* Off-hook: handset picked up. Enable PA, stop ringing. */
s_offhook = true;
ESP_LOGI(TAG, "off-hook (pickup) detected — PA on");
audio_pa_set(true);
phone_ring_stop();
hook_client_report("off", "pickup");
} else {
/* On-hook: handset hung up. */
ESP_LOGI(TAG, "on-hook (hangup) detected");
/* On-hook: handset hung up. Stop playback, kill PA. */
s_offhook = false;
ESP_LOGI(TAG, "on-hook (hangup) detected — PA off, stopping audio");
audio_stop();
audio_pa_set(false);
hook_client_report("on", "hangup");
}
}
@@ -101,3 +118,8 @@ esp_err_t phone_init(void)
TASK_PRIO, NULL, 1);
return (ok == pdPASS) ? ESP_OK : ESP_ERR_NO_MEM;
}
bool phone_is_offhook(void)
{
return s_offhook;
}
+5
View File
@@ -10,6 +10,7 @@
* Hook events: forwarded to hook_client_report().
*/
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
@@ -26,6 +27,10 @@ void phone_ring_start(void);
/* Stop ringing. */
void phone_ring_stop(void);
/* Returns true if the handset is currently off-hook (picked up).
* Safe to call from any task; backed by a volatile flag updated in phone_task. */
bool phone_is_offhook(void);
#ifdef __cplusplus
}
#endif