feat(audio): tonalite via audio_router

Composant audio_router cree : tache FreeRTOS 440 Hz,
machine d'etat DIAL/BUSY/RINGBACK. Cable dans app_main,
tonalite active au boot (PA ON confirme en serie).
This commit is contained in:
clement
2026-06-19 09:25:19 +02:00
parent aea32cfd41
commit 22aca75e57
5 changed files with 152 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
idf_component_register(
SRCS "audio_router.c"
INCLUDE_DIRS "include"
REQUIRES esp_driver_i2s bsp tone_gen hal_i2s
)
+118
View File
@@ -0,0 +1,118 @@
/*
* audio_router.c — aiguillage des tonalités vers l'I2S (écouteur).
* Adapté de plip_voice/main/tones.c : la génération de sinus est déléguée à
* tone_gen ; l'écriture I2S passe par hal_i2s_spk_handle().
* Cadences France Télécom (440 Hz) : DIAL continu, BUSY 500/500, RINGBACK 1500/3500.
*/
#include "audio_router.h"
#include "tone_gen.h"
#include "hal_i2s.h"
#include "board_config.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "esp_log.h"
#include <string.h>
#include <stdbool.h>
#define TAG "audio_router"
typedef enum { TONE_NONE, TONE_DIAL, TONE_BUSY, TONE_RINGBACK } tone_mode_t;
#define SR PLIP_SAMPLE_RATE /* 16000 — doit correspondre à hal_i2s */
#define FRAME 320 /* 20 ms @ 16 kHz */
#define TONE_AMPLITUDE 8000.0f
#define TONE_FREQ_HZ 440.0f
static volatile tone_mode_t s_mode = TONE_NONE;
static volatile bool s_tone_idle = true;
static TaskHandle_t s_task = NULL;
static void tone_task(void *a)
{
(void)a;
int16_t buf[FRAME * 2];
uint32_t ph = 0;
int64_t t = 0; /* ms écoulées dans l'état courant */
for (;;) {
tone_mode_t m = s_mode;
if (m == TONE_NONE) {
s_tone_idle = true;
vTaskDelay(pdMS_TO_TICKS(20));
t = 0;
ph = 0;
continue;
}
bool on = true;
if (m == TONE_BUSY) {
on = (t % 1000) < 500;
} else if (m == TONE_RINGBACK) {
on = (t % 5000) < 1500;
}
/* TONE_DIAL : toujours on */
if (on) {
tone_gen_fill_stereo(buf, FRAME, &ph, TONE_FREQ_HZ, TONE_AMPLITUDE, SR);
} else {
memset(buf, 0, sizeof(buf));
ph += FRAME; /* garder la phase continue */
}
size_t written = 0;
s_tone_idle = false;
i2s_channel_write(hal_i2s_spk_handle(), buf, sizeof(buf), &written,
pdMS_TO_TICKS(50));
t += 20;
}
}
void audio_router_init(void)
{
if (!s_task) {
xTaskCreate(tone_task, "tones", 3072, NULL, 5, &s_task);
ESP_LOGI(TAG, "tone task created");
}
}
void audio_router_dialtone_start(void)
{
ESP_LOGI(TAG, "dial tone start");
hal_audio_pa_set(true);
audio_router_init();
s_mode = TONE_DIAL;
}
void audio_router_busy_start(void)
{
ESP_LOGI(TAG, "busy tone start");
hal_audio_pa_set(true);
audio_router_init();
s_mode = TONE_BUSY;
}
void audio_router_ringback_start(void)
{
ESP_LOGI(TAG, "ringback tone start");
hal_audio_pa_set(true);
audio_router_init();
s_mode = TONE_RINGBACK;
}
void audio_router_tones_stop(void)
{
ESP_LOGI(TAG, "tones stop");
s_mode = TONE_NONE;
const int max_wait_ms = 200;
int waited_ms = 0;
while (!s_tone_idle && waited_ms < max_wait_ms) {
vTaskDelay(pdMS_TO_TICKS(5));
waited_ms += 5;
}
if (waited_ms >= max_wait_ms) {
ESP_LOGW(TAG, "tones_stop: timeout waiting for tone task idle");
}
}
@@ -0,0 +1,24 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Create the tone task (idempotent). Call once after hal_i2s_init(). */
void audio_router_init(void);
/* Start a continuous 440 Hz dial tone (enables PA). */
void audio_router_dialtone_start(void);
/* Start the busy tone: 500 ms on / 500 ms off. */
void audio_router_busy_start(void);
/* Start the ringback tone: 1500 ms on / 3500 ms off (France Télécom). */
void audio_router_ringback_start(void);
/* Stop tones; waits (<=200 ms) until the tone task leaves i2s_channel_write. */
void audio_router_tones_stop(void);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
idf_component_register(
SRCS "app_main.c"
INCLUDE_DIRS "."
REQUIRES nvs_flash config_store hal_es8388 hal_i2s
REQUIRES nvs_flash config_store hal_es8388 hal_i2s audio_router
)
+4
View File
@@ -3,6 +3,7 @@
#include "freertos/task.h"
#include "config_store.h"
#include "hal_i2s.h"
#include "audio_router.h"
static const char *TAG = "rtc_phone";
@@ -11,6 +12,9 @@ void app_main(void)
ESP_LOGI(TAG, "RTC BL PHONE — socle ESP-IDF v5.4 (esp32 classique)");
ESP_ERROR_CHECK(config_store_init());
ESP_ERROR_CHECK(hal_i2s_init());
audio_router_init();
audio_router_dialtone_start();
ESP_LOGI(TAG, "tonalite de numerotation demarree (combine decroche pour ecouter)");
ESP_LOGI(TAG, "boot OK — Phase 2 HAL audio ES8388");
while (true) {
ESP_LOGI(TAG, "heartbeat");