aissia/plans/PHASE7_COMPILATION_ISSUE.md
StillHammer 3915424d75 feat(wip): Phase 7.1 STT Service Layer - Architecture complète (ne compile pas)
Architecture Phase 7 STT implémentée mais bloquée par conflits de macros
entre GroveEngine (JsonDataNode.h) et spdlog/fmt.

## Nouveau contenu

### Interfaces & Services
- ISTTService.hpp: Interface service STT (modes passive/active, callbacks)
- STTService.{hpp,cpp}: Implémentation service STT avec factory pattern
- VoskSTTEngine.{hpp,cpp}: Engine STT local Vosk (~50MB model)

### Factory Pattern
- STTEngineFactory: Support multi-engines (Vosk, Whisper API, auto-select)
- Fallback automatique Vosk -> Whisper API

### Configuration
- config/voice.json: Config Phase 7 (passive_mode, active_mode, whisper_api)
- Support modèles Vosk locaux + fallback cloud

### Intégration
- VoiceService: Nouvelle méthode configureSTT(json) pour Phase 7
- main.cpp: Chargement config STT depuis voice.json
- CMakeLists.txt: Ajout fichiers + dépendance optionnelle Vosk

## Problème de Compilation

**Bloqué par conflits de macros**:
- JsonDataNode.h (GroveEngine) définit des macros qui polluent 'logger' et 'queue'
- Cause erreurs dans VoiceService.cpp et STTService.cpp
- Voir plans/PHASE7_COMPILATION_ISSUE.md pour diagnostic complet

## Fonctionnalités Implémentées

 Architecture STT complète (service layer + engines)
 Support Vosk local (modèles français)
 Factory pattern avec auto-selection
 Configuration JSON Phase 7
 Callbacks transcription/keywords
 Ne compile pas (macro conflicts)

## Prochaines Étapes

1. Résoudre conflits macros (fixer GroveEngine ou isolation namespace)
2. Phase 7.2: PocketSphinxEngine (keyword spotting "Celuna")
3. Tests intégration STT

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 09:01:26 +08:00

8.6 KiB

Phase 7 - Problème de Compilation (Macro Conflicts)

Date: 2025-11-29 Status: ⚠️ Bloqué - Conflit de macros entre GroveEngine et spdlog


Résumé du Problème

L'implémentation de Phase 7.1 (STT Service Layer) est fonctionnellement complète mais ne compile pas à cause de conflits de macros entre:

  1. GroveEngine (JsonDataNode.h) - définit des macros qui polluent le namespace global
  2. spdlog/fmt - templates de formatting qui entrent en conflit avec les macros
  3. nlohmann::json - interfère avec l'ordre d'inclusion

Symptômes

// Erreurs typiques:
error: request for member 'empty' in 'm_speakQueue', which is of non-class type 'int'
error: no match for 'operator=' (operand types are 'std::shared_ptr<spdlog::logger>' and 'int')
error: 'logger' was not declared in this scope

Cause racine: Les macros dans JsonDataNode.h remplacent logger et queue par int, causant des erreurs de compilation dans tout code qui:

  • Utilise std::queue
  • Utilise spdlog::logger
  • Inclut JsonDataNode.h (via VoiceService.hpp)

Architecture Implémentée (Phase 7.1)

Fichiers Créés

Fichier Lignes Status Description
src/services/ISTTService.hpp 104 Complet Interface du service STT
src/services/STTService.hpp 66 Complet Implémentation service STT
src/services/STTService.cpp 180 ⚠️ Ne compile pas Logic métier STT
src/shared/audio/VoskSTTEngine.hpp 77 Complet Engine STT local Vosk
src/shared/audio/VoskSTTEngine.cpp 201 Complet Implémentation Vosk
config/voice.json 36 Complet Config Phase 7

📝 Fichiers Modifiés

Fichier Modifications Status
src/shared/audio/ISTTEngine.hpp Ajout factory multi-engine OK
src/shared/audio/STTEngineFactory.cpp Support Vosk + auto-selection OK
src/services/VoiceService.hpp Intégration ISTTService OK
src/services/VoiceService.cpp Nouvelle méthode configureSTT ⚠️ Ne compile pas
src/main.cpp Chargement config Phase 7 OK
CMakeLists.txt Ajout fichiers + dépendance Vosk OK

Fonctionnalités Implémentées

Phase 7.1 - Service Layer (MVP)

Interface ISTTService:

  • Modes passive/active (enum STTMode)
  • Callbacks pour transcription et keywords
  • Support multi-engines via factory
  • Méthodes: start(), stop(), setMode(), transcribe(), transcribeFile()

Implémentation STTService:

  • Chargement config JSON (active_mode, whisper_api)
  • Factory pattern pour créer engines (Vosk, Whisper API, auto)
  • Callbacks fonctionnels (non testés)
  • État: mode actif uniquement (passive mode = Phase 7.2)

Engine Vosk:

  • Support modèles locaux (vosk-model-small-fr-0.22)
  • Transcription fichiers WAV
  • Transcription données PCM
  • Compile flag HAS_VOSK pour compilation optionnelle
  • Parse JSON results de Vosk
  • Lecture fichiers WAV (header + PCM data)

Factory Pattern:

STTEngineFactory::create(
    type,      // "vosk", "whisper-api", "auto"
    modelPath, // "./models/vosk-model-small-fr-0.22"
    apiKey     // Fallback Whisper API
)

Configuration:

{
  "stt": {
    "active_mode": {
      "enabled": true,
      "engine": "vosk",
      "model_path": "./models/vosk-model-small-fr-0.22",
      "language": "fr"
    },
    "whisper_api": {
      "api_key_env": "OPENAI_API_KEY"
    }
  }
}

Solutions Tentées (Sans Succès)

1. Ordre des Includes

// Testé: nlohmann/json avant tout
#include <nlohmann/json.hpp>
#include "VoiceService.hpp"
// Résultat: Macros déjà définies par JsonDataNode.h

2. Macros SPDLOG

// Testé: Utiliser SPDLOG_LOGGER_INFO au lieu de m_logger->info
SPDLOG_LOGGER_INFO(m_logger, "message");
// Résultat: Mêmes conflits (macros fmt sous-jacentes)

3. Logs Sans Format ⚠️ Partiel

// Testé: Enlever tous les paramètres de format
m_logger->info("STT service started");  // au lieu de "... {}", var
// Résultat: Réduit les erreurs mais ne résout pas le problème de fond

4. Namespaces Explicites

// Testé: ::std::queue, ::spdlog::logger
// Résultat: Macros s'appliquent avant la résolution du namespace

Solutions Possibles (Non Testées)

Option A: Fixer GroveEngine 🔨

Modifier external/GroveEngine/include/grove/JsonDataNode.h

Problème: JsonDataNode.h définit probablement des macros comme:

#define logger    // quelque chose
#define queue     // quelque chose

Action: Remplacer les macros par des constexpr ou enum class

Avantage: Résout le problème à la racine Inconvénient: Modifie GroveEngine (dépendance externe)

Option B: Isolation de Namespace 🔒

Créer un fichier séparé sans includes GroveEngine:

// stt_impl.cpp - PAS d'include JsonDataNode.h
namespace aissia::stt_impl {
    // Toute la logique STT ici
}

Avantage: Isole le problème Inconvénient: Duplication de code, complexité

Option C: Refactor en Service Séparé 🏗️

// Ne pas intégrer STTService dans VoiceService
// Créer un service indépendant communicant via IIO pub/sub

Avantage: Meilleure séparation des responsabilités Inconvénient: Refonte architecture (temps)

Option D: Compiler en Bibliothèque Statique 📦

# Compiler STTService en lib séparée AVANT VoiceService
add_library(AissiaSTT STATIC src/services/STTService.cpp)
# Avec flags de compilation spécifiques

Avantage: Contrôle fin sur ordre de compilation Inconvénient: Peut ne pas suffire (macros sont au preprocessor)


Recommandation

Option A (Fixer GroveEngine) est la meilleure solution long terme:

  1. Identifier les macros problématiques dans JsonDataNode.h
  2. Les remplacer par:
    // Au lieu de #define logger ...
    static constexpr int LOGGER_SOMETHING = ...;
    
  3. Mettre à jour GroveEngine ou forker

Court terme: Désactiver STTService dans CMakeLists et continuer Phase 7.2 (PocketSphinx) en parallèle.


Impact

Ce qui fonctionne

  • Architecture STT complète (interfaces, factory, engines)
  • Configuration JSON
  • Integration conceptuelle dans VoiceService
  • Tests peuvent être écrits (sans exécution)

Ce qui bloque

  • Compilation de VoiceService.cpp
  • Compilation de STTService.cpp
  • Tests d'intégration
  • Utilisation effective du STT

🔄 Workaround Temporaire

// Dans main.cpp: NE PAS appeler voiceService.configureSTT()
// Le reste de l'application compile et fonctionne

Prochaines Étapes

Court Terme (Déblocage)

  1. Documenter le problème (ce fichier)
  2. ⏭️ Commit le code actuel (architecture valide)
  3. ⏭️ Investiguer GroveEngine/JsonDataNode.h
  4. ⏭️ Tester Option A (fix macros)

Moyen Terme (Phase 7.2)

Si Option A échoue:

  • Implémenter PocketSphinxEngine séparément (compile indépendamment)
  • Tests unitaires des engines (sans VoiceService)
  • Documentation architecture alternative

Long Terme (Phase 7 Complète)

  • Résoudre conflits macros définitivement
  • Intégration complète STT → VoiceService
  • Tests end-to-end avec microphone

Logs de Compilation (Exemple)

/src/services/VoiceService.cpp:84:34: error:
  request for member 'empty' in 'm_speakQueue', which is of non-class type 'int'
   84 |     while (!m_speakQueue.empty()) m_speakQueue.pop();
      |                          ^~~~~

/src/services/VoiceService.cpp:10:42: error:
  no match for 'operator=' (operand types are 'std::shared_ptr<spdlog::logger>' and 'int')
   10 |     m_logger = spdlog::get("VoiceService");
      |                                          ^

/spdlog/sinks/stdout_color_sinks.h:39:17: error:
  'logger' was not declared in this scope; did you mean 'spdlog::logger'?

Diagnostic: Les macros remplacent logger et queue par autre chose (probablement int ou vide), causant des erreurs de type.


Références


Auteur: Claude Code Dernière mise à jour: 2025-11-29 Status: 🔴 Bloqué - Attend résolution conflits macros