fix(tts): fiabilise la lecture à voix haute des questions en séance mixte - #63
Merged
Conversation
…à voix haute En séance mixte, la lecture TTS d'une question pouvait être silencieusement perdue : le MP3 était décodé à la volée à l'arrivée sur la question, et si l'enfant répondait avant la fin du décodage (typique d'un fait connu, répondu au quart de tour), le stop() de la réponse annulait une lecture jamais démarrée. Les divisions, plus lentes à répondre, s'entendaient ; les tables connues, non. Correctif : - SessionScreen précharge l'audio de toutes les questions dès l'ouverture de la séance (questions + intros). - useTTS expose preload() et démarre la lecture par un chemin synchrone quand le buffer est déjà en cache — plus de fenêtre async annulable par un stop(). Test de régression : un enfant qui répond plus vite que la latence de premier décodage entend bien chaque question.
Contributor
|
Preview supprimée (PR fermée). Les URLs ne sont plus accessibles. |
… vocal) En mode vocal, la reconnaissance (micro) peut suspendre ou « interrompre » (iOS) le contexte audio partagé ; source.start() sur un contexte non `running` est alors silencieux — une question sur deux passait inaperçue. On résume le contexte avant la lecture quand il n'est pas en cours. Le cas `running` (courant) reste sur le chemin synchrone, donc la lecture demeure increvable par un stop() concurrent.
isc
marked this pull request as ready for review
June 12, 2026 06:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptôme
En séance mixte (multiplications + divisions), la lecture TTS de certaines questions ne se déclenchait pas : on entendait les divisions et
2 × 2, mais pas5 × 3,8 × 8« et autres ». L'enfant répondait à la voix (speech-to-text).Diagnostic
Ce n'est pas un problème de fichiers audio. Vérifié : les 355 MP3 attendus sont tous présents, synchro avec
scripts/generate-tts.mjs, décodent sans erreur dans un vrai Chromium (format identique), aucun silencieux ; etSessionScreenappelle bienspeak()avec la bonne clé pour chaque question.Deux mécanismes concourants laissaient une question muette :
speak(key)lance un chargement asynchrone du MP3 avantsource.start(). Si unstopSpeech()survient pendant cette fenêtre (réponse soumise, y compris via le fast-path vocal en lisant la question à l'écran), la lecture, périmée, n'est jamais démarrée. Test déterministe : 0/7 lues.AVAudioSessionen record), elle peut suspendre/« interrompre » le contexte Web Audio ;source.start()sur un contexte nonrunningest alors silencieux.Correctif
SessionScreenprécharge l'audio de toutes les questions dès l'ouverture (questions + intros) →speakdémarre par un chemin synchrone, increvable par unstop()concurrent.useTTSexposepreload(), et réveille l'AudioContext (resume()) avant de jouer quand il n'est pasrunning(cas vocal/iOS). Le casrunningreste sur le chemin synchrone.Tests
src/__tests__/mixedSessionTTS.test.tsx: latence de premier décodage + réponse rapide → 7/7 questions atteignentsource.start()(0/7 sans le fix).tsc -bOK,eslint .propre,BASE=/ npm run buildOK.À vérifier sur le preview
VoiceInput.https://claude.ai/code/session_01VE7EMsCmruBMhycaVX3XYE