Aquí hay unas notas rápidas sobre cómo el nuevo marco de trabajo para la voz implementado en #7599 puede usarse para implementar algunos casos de uso complicados. El hecho de que estén aquí no significa que se hayan completado.
Casos de uso al cambiar de perfil
Cualquier cosa que quiera cambiar la voz, sintetizador, etc. puede implementarse usando ConfigProfileTriggerCommand en secuencias de voz. En vez de tener ajustes específicos y restrictivos (por ejemplo, establecer sintetizador dependiendo del idioma, cambiar velocidad para las matemáticas, etc.), pueden usarse disparadores de perfil. Esto permite mucha más flexibilidad. Por ejemplo, en vez de ser capaz de establecer sólo velocidad para las matemáticas, podrías cambiar la voz si quisieras; es posible modificar cualquier cosa en un perfil. Podríamos querer ofrecer asistentes o cosas similares para ayudar a configurar casos de uso comunes.
Entre los casos relevantes se incluyen:
- Cambiar a sintetizadores específicos cuando cambie el idioma (#279)
- Cambiar velocidad según el idioma (#4738)
- Alias de voz (#4433)
- Introducir un ajuste especial para la velocidad de la voz al leer matemáticas (#7274).
La idea general es:
- Crear un disparador de perfil apropiado; por ejemplo un disparador de perfil de idioma que se use cuando se encuentre un LangChangeCommand.
- Usar speech.ConfigProfileTriggerCommand para entrar y salir de este disparador en una secuencia de voz cuando sea apropiado. Por ejemplo, se añadirían comandos para LanguageProfileTrigger en speech.speak. Para matemáticas, podríamos emitir comandos para MathProfileTrigger en speech._speakTextInfo_addMath.
- Ofrecer interfaz gráfica para los usuarios para configurar este disparador en los diálogos de configuración de perfiles y disparadores. Esto podría ser algo relativamente fácil para matemáticas; se puede hacer de forma similar a verbalizar todo. Sin embargo, podríamos necesitar algún tipo de interfaz de usuario para agregar disparadores adicionales para cosas con muchas opciones, tales como los idiomas.
NVDA Remote
Probablemente seguimos queriendo que NVDA Remote soporte antiguos sintetizadores que no utilicen la nueva api. Desafortunadamente, eso significa que NVDA Remote seguiría utilizando su mecanismo de aplicación de parches al código para esos sintetizadores. Puedes probarlos usando speech.shouldUseCompatCodeForIndexing. Este código existente no funcionará del todo para nuevos sintetizadores que usen el nuevo marco de trabajo.
Con respecto a cómo implementar las cosas en el nuevo marco de trabajo:
- En la mayoría de los casos, el esclavo debe redirigir las secuencias de voz pasadas a speech._SpeechManager.speak al maestro.
- Se necesita añadir un punto de extensión en algún lugar, pero primero hay que averiguar dónde.
- Algunos comandos como BeepCommand, EndUtteranceCommand y WaveFileCommand se pueden serializar fácilmente. Las devoluciones de llamada (callbacks) personalizadas, sin embargo, no.
- Esto significa que NVDA Remote obtendrá indicaciones de que una letra es mayúscula, ya que el deletreo es una secuencia de voz que usa BeepCommand, PitchCommand, etc. Mira NVDARemote/NVDARemote#110.
- Necesitaremos alguna forma de diferenciar llamadas independientes a tones.beep y nvwave.playWaveFile de las que no lo son. Esto puede hacerse fácilmente con un argumento extra.
- ¿Significa esto que no debemos lanzar el punto de extensión en caso de que haya un comando de voz?
- Relacionado: https://github.com/nvaccess/nvda/pull/7594
- Verbalizar todo es un poco más complicado. Queremos sincronizar el cursor con la voz en el maestro, y no el esclavo, ya que el maestro es quien principalmente controla.
- Esto puede hacerse eliminando en el esclavo las devoluciones de llamada a verbalizar todo de la secuencia de voz y almacenándolas en un mapa con un identificador. Necesitaremos un filtro en el núcleo para esto. También necesitaremos una forma de distinguir las devoluciones de llamada de verbalizar todo; actualmente, ahora son simples comandos de devolución de llamada. Probablemente se podría crear una subclase simple llamada SayAllCallbackCommand.
- El esclavo pasaría este identificador al maestro como parte de la secuencia de voz.
- El maestro terminaría la tarea con una devolución de llamada. Al llamarla, la devolución de llamada notificaría al esclavo de que se ha alcanzado este identificador.
- El esclavo cogería entonces la devolución de llamada original del mapa y la llamaría, sincronizando por tanto el cursor, enviando más voz, etc.
Determinar si NVDA está hablando
Tal y como se ha solicitado en: Add the ability to determine if NVDA is speaking in NVDA Controller.dll #5638
Debería ser relativamente sencillo añadir una función que realice esta tarea. Puede comprobar speech._manager._curPriQueue. Si devuelve None, significa que NVDA no está hablando en ese momento.