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
CI / platformio (push) Failing after 3m57s
This commit was merged in pull request #19.
This commit is contained in:
+17
-1
@@ -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. */
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user