mirror of
https://github.com/deunix-educ/voice-assistant.git
synced 2026-10-13 00:11:57 +02:00
Assistant vocal local ESP32 : étapes 1 à 15, et 15b écrite
État du projet au premier commit : - firmware ESP32 : micro I2S, lecture anti-gigue, MQTT (état retenu, testament), mains libres, domotique de démonstration, chien de garde, présence du serveur ; - serveur Python : sessions, VAD, faster-whisper, pyannote, identification, droits par profil, domotique, mot de réveil, Piper ; - broker Mosquitto : configuration, comptes et ACL (non activés en développement) ; - étape 15b écrite, en attente d'essai : agent MQTT pour machines Linux. Étapes 1 à 15 validées. 203 tests, pyright sans erreur. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/stream_buffer.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
/**
|
||||
* @brief File d'attente d'octets PCM entre deux rythmes différents.
|
||||
*
|
||||
* Deux usages, même mécanisme :
|
||||
* - lecture (étape 2) : la réception écrit par à-coups, la tâche audio lit au
|
||||
* rythme régulier du DAC ;
|
||||
* - capture (étape 4) : la tâche de capture écrit au rythme du micro, l'envoi
|
||||
* réseau lit par à-coups, au gré du Wi-Fi.
|
||||
*
|
||||
* C'est un StreamBuffer FreeRTOS, conçu pour exactement un écrivain et un
|
||||
* lecteur. Son stockage est fourni par l'appelant (tableau statique) : aucune
|
||||
* allocation, et chaque FIFO a la taille qui convient à son usage.
|
||||
*
|
||||
* Invariant : on n'écrit que des chunks entiers, jamais un morceau. Un chunk
|
||||
* coupé laisserait un nombre impair d'octets, et tous les échantillons suivants
|
||||
* seraient lus à cheval sur deux valeurs — un bruit assourdissant.
|
||||
*/
|
||||
class AudioFifo {
|
||||
public:
|
||||
AudioFifo() = default;
|
||||
|
||||
/**
|
||||
* @brief Crée le StreamBuffer sur le stockage fourni.
|
||||
* @param storage Tableau d'au moins @p capacity + 1 octets (exigence FreeRTOS).
|
||||
* @param capacity Capacité utile en octets.
|
||||
* @param wakeBytes Nombre d'octets qui réveillent un lecteur en attente.
|
||||
* @return true si la création a réussi.
|
||||
*/
|
||||
bool begin(uint8_t* storage, size_t capacity, size_t wakeBytes);
|
||||
|
||||
/**
|
||||
* @brief Ajoute un chunk, sans jamais attendre.
|
||||
* @return true si le chunk entier a été accepté ; false s'il a été refusé
|
||||
* faute de place (il est alors compté comme perdu, en entier).
|
||||
*/
|
||||
bool write(const uint8_t* data, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Retire au plus @p length octets, en attendant au plus @p timeoutMs.
|
||||
* @return Nombre d'octets lus (pair, tant qu'on ne demande que des tailles paires).
|
||||
*/
|
||||
size_t read(uint8_t* data, size_t length, uint32_t timeoutMs);
|
||||
|
||||
/// Octets actuellement en attente.
|
||||
size_t available() const;
|
||||
|
||||
/// Nombre de chunks refusés faute de place depuis le démarrage.
|
||||
uint32_t overruns() const;
|
||||
|
||||
private:
|
||||
StaticStreamBuffer_t _control = {};
|
||||
StreamBufferHandle_t _handle = nullptr;
|
||||
std::atomic<uint32_t> _overruns{0}; ///< lu par loop(), incrémenté par l'écrivain
|
||||
};
|
||||
Reference in New Issue
Block a user