PBToolboxAI v3 ← Site

speechout — n_pbt_speechout #

← Referencia de componentes · Índice de la guía

Lectura en voz alta: la aplicación lee un texto frase por frase y le dice por dónde va. Sin servicio de terceros, sin clave de API — la síntesis es la del equipo.

▶ Verlo en vivo — Aplicación de demostración, mosaico Speech out: la vista previa, el código que la produce y esta página, lado a lado.


En resumen #

Objeto no visualn_pbt_speechout
Sirve paraHacer oír un texto: accesibilidad, manos ocupadas, un aviso que nadie mira
PrincipioUsted da el texto; el componente lo corta en frases y le dice cuál está leyendo
DependenciaLa síntesis de voz del equipo — sin servicio de terceros, sin clave de API

Inicio rápido #

// once, when the window opens
inv_voice.of_open()

// then, wherever you need it
inv_voice.is_lang = inv_voice.LANG_FR_FR
inv_voice.of_speak("Bonjour. Votre commande est expediee.")

No visual: el cableado de los eventos #

Una voz no tiene nada que mostrar. El componente no dibuja por tanto nada: ninguna barra de reproducción que colocar, ningún espacio quitado a lo que sirve.

Y para ello no tiene que cablear nada: un objeto no visual no tiene ventana, así que no hay timbre, pero el componente recoge sus propios eventos en el bucle de PowerBuilder mientras la voz está abierta y los lanza en el objeto. Solo escribe los manejadores ue_* (sin receptor, sin temporizador).

// Just speak -- the ue_* events arrive on their own :
inv_voice.of_speak("Good morning. Your order has shipped.")
// the ue_sentence / ue_word / ue_stopped events arrive on their own

Seguir la lectura en SU texto #

ue_sentence lleva el índice y el texto de la frase que se está leyendo. De ahí sale el resaltado — en su mle_, su datawindow o su statictext: usted sabe dónde está su texto, nosotros nunca.

El camino inverso también existe: of_speak_from() retoma en una frase concreta, lo que se conecta al clic sobre un párrafo. Los números vienen de ue_sentence, así que siempre señalan lo que realmente se leyó.

El corte es el del componente, no el suyo: of_sentence_count() devuelve su propia cuenta. No vuelva a contar por su lado, las dos derivarían.


Lo que el equipo sabe decir de verdad #

of_languages() devuelve los idiomas que este equipo sabe pronunciar de verdad, sin duplicados. Es la pregunta que se hace un usuario: no «qué voces existen», sino «está mi idioma».

of_voices() baja un escalón y nombra las voces mismas. Ambas listas vienen de la máquina, no de nosotros: nunca codifique un nombre fijo.

El reconocimiento de voz no tiene equivalente, y no es un olvido: el reconocimiento no lleva ninguna lista de los idiomas que acepta.

Sin ningún componente por su parte, gnv_utils.of_speech_languages(as_tags[]) da la misma lista — la DLL consulta una voz oculta y luego la descarta: es lo que una ventana pregunta antes de que la voz exista, qué idioma ofrecer, en cuál leer. La llamada es síncrona y puede tardar hasta dos segundos la primera vez: la lista de voces llega tarde, y la llamada la espera. Y gnv_utils.of_speech_voices(as_names[], as_langs[]) da las voces mismas con su idioma, para ofrecer «Hortense» o «Julie» en lugar de una etiqueta; gnv_utils.of_locale_name(as_tag) da a una etiqueta su nombre legible — «francés (Francia)» para fr-FR.

string ls_tags[]

if inv_voice.of_languages(ls_tags) > 0 then inv_voice.is_lang = ls_tags[1]

Propiedades #

PropiedadTipoPredeterminadoFunción
is_langstringen-USIdioma leído, en BCP-47 (constantes LANG_*). Decide qué voz se elige — mientras is_voice esté vacía, ya que un nombre de voz fija su propio idioma. Sin voz para ese idioma el equipo lee con la que tiene, y ue_voice_fallback nombra ambas
is_textstring""El texto a leer. El componente lo corta en frases; tres etiquetas dicen CÓMO leer un trozo: [pause=500], [spell]…[/spell], [say-as=digits]…[/say-as] (ver más abajo)
is_voicestring""Nombre de la voz, tomado de of_voices(). Vacío = la primera que habla is_lang
ii_rateinteger100Velocidad, en POR CIENTO de la normal (10 a 400). Cambiada durante la lectura, se aplica a la frase siguiente
ii_pitchinteger100Tono de la voz, en POR CIENTO del tono normal (0 a 200)
ii_volumeinteger100Volumen en porcentaje (0 mudo a 100), la escala del reproductor de vídeo
il_timeout_mslong300000Duración máxima de una lectura SÍNCRONA: cinco minutos. Después, of_speak_sync devuelve -4 y la lectura se corta (is_last_error dice por qué)
is_last_errorstring""Por qué el último of_speak_sync devolvió -4: voz no creada, fallo del motor, tiempo agotado

Métodos #

MétodoFunción
of_open ( )Crea la voz. Opcional — of_speak lo hace — pero llamarlo al abrir la ventana paga el coste una vez, lejos de la primera frase. Devuelve un número positivo cuando la voz existe, 0 o menos si no pudo crearse
of_is_open ( )Verdadero una vez creada la voz
of_speak ( string as_text )Pone el texto y lo lee, desde la primera frase. Sin argumento, relee is_text. Devuelve 0 una vez enviado, -1 si la voz no pudo crearse
of_speak_from ( long al_index )Retoma la lectura en una frase concreta. Devuelve 0 una vez enviado, -1 si la voz no pudo crearse
of_pause ( )Suspende la lectura donde está. Devuelve 0 una vez enviado, -1 si la voz no pudo crearse
of_resume ( )Retoma donde of_pause se detuvo. Devuelve 0 una vez enviado, -1 si la voz no pudo crearse
of_stop ( )Detiene la lectura; of_speak vuelve a empezar por la primera frase
of_is_speaking ( )Verdadero mientras se lee una frase — una lectura en pausa sigue contando. Preguntado al componente, nunca una copia caducada
of_sentence_count ( )Devuelve cuántas frases ha hecho el componente del texto
of_count ( ) → integerCuántas frases ha hecho el componente del texto — el mismo número que devuelve of_sentence_count. La biblioteca hace esta pregunta bajo un solo nombre en todas partes
of_voices ( ref string as_names[] )Rellena la matriz con las voces instaladas en este equipo y devuelve cuántas hay
of_languages ( ref string as_tags[] )Rellena la matriz con los idiomas que este equipo sabe pronunciar, sin duplicados, y devuelve cuántos hay
of_voice_used ( )La voz que el componente entregará realmente al motor — no siempre la que pide is_lang: un equipo lleva las voces que alguien instaló y ninguna otra. Vacío = el componente no impone ninguna, y el motor toma la suya, la del idioma del sistema. Nombrarla sería adivinar. ue_error lo dice al leer; esto se lee antes
of_speak_sync ( { string as_text } )Lee y ESPERA el final: la línea siguiente corre tras la última frase, la ventana sigue pintándose. Devuelve 0 al final, -4 en caso de fallo o tiempo agotado (is_last_error)
of_enqueue ( string as_text )Pone un texto en COLA: leído enseguida si la voz está libre, tras la lectura en curso si no, sin cortarla nunca. Devuelve 0, -1 si la voz no pudo crearse
of_clear_queue ( )Olvida los textos en espera, sin cortar el que se lee. Devuelve 0, -1 si la voz no pudo crearse
of_queue_count ( )Devuelve el número de textos aún en espera (el que se lee no cuenta)
of_add_replacement ( string as_from, string as_to )Una regla de pronunciación: cada palabra ENTERA as_from se lee as_to (PB → PowerBuilder). Aplicada antes de las etiquetas, guardada por el objeto. Devuelve 0, -5 si as_from está vacío
of_clear_replacements ( )Vacía el diccionario. Devuelve 0
of_replacement_count ( )Devuelve el número de reglas del diccionario
of_pick_voice ( string as_lang, string as_gender )Elige una voz INSTALADA para un idioma y, si existe, un género (GENDER_FEMALE, GENDER_MALE, GENDER_ANY): idioma exacto, luego su familia. La pone en is_voice y la devuelve; vacío si ninguna voz habla ese idioma
of_duration ( )Devuelve la duración ESTIMADA de la lectura, en milisegundos (palabras por minuto a la velocidad pedida, pausas incluidas): para una barra de progreso, no para un cronómetro. El ritmo APRENDE la voz: cada frase leída hasta el final mide el real, recordado por voz en este equipo
of_position ( )Devuelve la posición estimada de la lectura, en milisegundos, afinada por las palabras que el motor reporta; 0 cuando nada se lee
of_progress ( )Devuelve el progreso estimado, de 0 a 100
of_spoken_text ( )Las frases TAL COMO la voz las recibe, una por línea (diccionario aplicado, etiquetas resueltas): el texto a mostrar para seguir palabra a palabra
of_process_events ( )Vacía los eventos pendientes y los lanza sobre este objeto. El pump interno del componente lo llama por usted mientras la voz está abierta — usted nunca lo llama
of_close ( )Libera la voz, deteniendo antes lo que estuviera diciendo. El destructor lo llama
of_reset ( )Devuelve todas las propiedades a su valor original

Eventos #

EventoSe dispara cuando
ue_started (string as_lang)La lectura comienza; as_lang recuerda en qué idioma
ue_stopped ( )La última frase ha terminado, o se ha llamado a of_stop
ue_paused ( )La lectura está suspendida
ue_resumed ( )La lectura se reanuda
ue_sentence (long al_index, string as_text)Para cada frase, con su rango y su texto: así se sigue la lectura en otra parte de la ventana
ue_error (string as_message)El equipo no tiene motor ni voz alguna, o la voz falla. Una voz simplemente AUSENTE no es un error: es ue_voice_fallback
ue_voices_ready (long al_count)El motor ha llenado su lista de voces — llega tarde; of_voices, of_languages, of_voice_used y of_pick_voice la esperan por sí mismos (2,5 s como máximo), este evento solo dice CUÁNDO llegó; al_count dice cuántas tiene el equipo
ue_word (long al_index, long al_start, long al_length)La PALABRA en curso en la frase al_index: Mid(frase, al_start, al_length). Cuando el motor reporta las palabras (la mayoría de las voces de Windows)
ue_queue_done ( )El último texto de la cola (of_enqueue) está leído
ue_voice_fallback (string as_wanted, string as_used)La voz o el idioma pedido no está en este equipo; as_used nombra la que lee en su lugar. Una información, no un error: la lectura continúa

Pronunciación: pausas, deletreo, diccionario #

WebView2 no tiene SSML. El texto lleva por tanto tres etiquetas propias, resueltas antes del corte en frases, y un diccionario de palabras enteras aplicado antes. Una etiqueta desconocida se lee tal cual.

EtiquetaEfecto
[pause=500]Un silencio de 500 ms (10 s como máximo). La pausa termina la frase en curso
[spell]ABC12[/spell]Cada carácter dicho uno por uno: «A, B, C, 1, 2»
[say-as=digits]4152[/say-as]Los dígitos uno por uno, no «cuatro mil ciento cincuenta y dos»
[say-as=characters]…[/say-as]Como [spell]
// The dictionary : whole words, in the order added, case-sensitive
inv_voice.of_add_replacement("PB", "PowerBuilder")
inv_voice.of_add_replacement("Mme", "Madame")
inv_voice.of_add_replacement("4152", "[say-as=digits]4152[/say-as]")   // a rule may add a tag

inv_voice.of_speak("Mme Durand, PB order 4152 [pause=600] code [spell]PBT[/spell].")

Cola, lectura síncrona, progreso #


Ejemplos #

Leer una notificación #

inv_voice.of_speak("Order 4152 has been shipped. It arrives on Thursday.")

Resaltar la frase en curso #

// in ue_sentence, on the nonvisual object
st_read.text = as_text

// and a click on a paragraph resumes from it
inv_voice.of_speak_from(2)

Elegir la voz y la velocidad #

string ls_voices[]

if inv_voice.of_voices(ls_voices) > 0 then inv_voice.is_voice = ls_voices[1]
inv_voice.ii_rate = 75
inv_voice.of_speak()

Anunciar sin cortar: la cola #

// Each event of the application is queued : all of them are heard, in order
inv_voice.of_enqueue("Order 4152 has been shipped.")
inv_voice.of_enqueue("Order 4153 is ready.")
// ue_queue_done fires after the last one

Resaltar la palabra en curso #

// in ue_sentence : keep the sentence
is_sentence = as_text

// in ue_word : the word is Mid(is_sentence, al_start, al_length)
st_read.text = Left(is_sentence, al_start - 1) + "[" + Mid(is_sentence, al_start, al_length) + "]" + Mid(is_sentence, al_start + al_length)

Una voz por idioma y género, luego leer esperando el final #

inv_voice.of_pick_voice(n_pbt_speechout.LANG_FR_FR, n_pbt_speechout.GENDER_FEMALE)
if inv_voice.of_speak_sync("Please confirm the order.") = 0 then
	li_answer = MessageBox("Order", "Confirm ?", Question!, YesNo!)
end if

Buenas prácticas #


← Referencia de componentes · Índice de la guía