<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Hay un increíble archivo de palabras e información de pronunciación en Universidad de Carnegie mellon .Más de 100 mil palabras y variaciones.De su sitio web: " Sus entradas son particularmente útiles para el reconocimiento y la síntesis de voz, ya que tiene asignaciones de palabras a sus pronunciaciones en el conjunto de fonemas ARPAbet, un estándar para la pronunciación en inglés. El conjunto de fonemas actual contiene 39 fonemas, las vocales llevan un marcador de estrés léxico ".Una línea típica en el archivo se ve así
RUNAROUND R AH1 N AH0 R AW2 ND
Es fácil trabajar con el archivo; cada línea termina con un solo carácter de nueva línea y la palabra está separada de los datos con dos espacios y cada elemento de datos está separado por un solo espacio.Los elementos de datos se describen en otro archivo que tiene entradas como esta
Phoneme Example Translation ------- ------- ----------- AA odd AA D AE at AE T AH hut HH AH T AO ought AO Tfor 39 phonemes.
Aquí hay algo de JSL para cargar las más de 100 000 palabras en una matriz asociativa.
source = Load Text File( "$DESKTOP/grammar/cmudict-0.7b",charset("windows-1252") );symbols = Load Text File( "$DESKTOP/grammar/cmudict-0.7b.symbols" );symlist = Words( symbols, "\!n" );symPat = symlist; // make a copySubstitute Into( symPat, Expr( {} ), Expr( Pat Altern() ) ); // convert list to alternation patternsympat = Eval( sympat ); // build the pattern, oncelineEnding = "\!n";commentLine = ";" + Pat Break( lineEnding ) + lineEnding;dataLine = Pat Break( " " ) >> word + " " + Pat Repeat( " " + symPat ) >> pronounce[word] + lineEnding;pronounce = Associative Array();rc = Pat Match( source, Pat Pos( 0 ) + Pat Repeat( (dataLine | commentLine) + Pat Fence() ) + Pat R Pos( 0 ) );if( rc, Show( pronounce["ELEPHANTS"] ), print("failed"));pronuncia["ELEFANTES"] = "EH1 L AH0 F AH0 NT S";
Las líneas 1 y 2 cargan los archivos descargados desde una carpeta en el escritorio en cadenas JSL.El enorme archivo tiene entradas como el ejemplo de RUNAROUND anterior.El pequeño archivo tiene un solo fonema en cada línea.Estos símbolos se cargan en una lista en la línea 3.La función words() usa la nueva línea para dividir el texto en una lista de palabras individuales.symlist contiene las palabras, y en la línea 4 se hace una copia en sympat.
En la línea 5, SubstituteInto() manipula la expresión de lista JSL de cadenas separadas por comas, convirtiéndola en una llamada de función JSL a Pat Altern() con una lista de cadenas separadas por comas.La línea 6 evalúa la función Pat Altern(), produciendo un valor de patrón real.Esto es más o menos equivalente a construir de alguna manera este JSL y evaluarlo:
sympat = "AA" | "AA0" | ... | "Z" | "ZH"; // 39 phonemes in all
La manipulación de expresiones es un tema avanzado y puede ser muy útil.
La línea 7 está asignando una cadena de nueva línea simple a una variable JSL.Es más fácil leer el nombre de la variable que la secuencia de escape.La línea 8 describe cómo se ve una línea de comentario en el archivo enorme.Aquí está el bloque de comentarios que Line 8 se saltará:
;;; # CMUdict -- Major Version: 0.07;;; # ========================================================================;;; # Copyright (C) 1993-2015 Carnegie Mellon University. All rights reserved.;;; # Redistribution and use in source and binary forms, with or without;;; # modification, are permitted provided that the following conditions;;; # are met:;;; # 1. Redistributions of source code must retain the above copyright;;; # notice, this list of conditions and the following disclaimer.;;; # The contents of this file are deemed to be source code.;;; # 2. Redistributions in binary form must reproduce the above copyright;;; # notice, this list of conditions and the following disclaimer in;;; # the documentation and/or other materials provided with the;;; # distribution.;;; # This work was supported in part by funding from the Defense Advanced;;; # Research Projects Agency, the Office of Naval Research and the National;;; # Science Foundation of the United States of America, and by member;;; # companies of the Carnegie Mellon Sphinx Speech Consortium. We acknowledge;;; # the contributions of many volunteers to the expansion and improvement of;;; # this dictionary.;;; # THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND;;; # ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,;;; # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR;;; # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY;;; # NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,;;; # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT;;; # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,;;; # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY;;; # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT;;; # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE;;; # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
La línea 9 describe las líneas de datos en el archivo enorme.La línea 9 hace mucho trabajo, aquí está de nuevo
dataLine = Pat Break( " " ) >> palabra + " " + Pat Repeat( " " + symPat ) >> pronunciar[palabra] + lineEnding;
PatBreak() coincide con el texto hasta un espacio en blanco y almacena el texto en palabra .Hay dos espacios en blanco después de la palabra; uno de ellos coincide antes de patRepeat y uno de ellos coincide con la primera vez que patRepeat ejecuta su patrón.El patrón patRepeat usa symPat para validar cada fonema; si hubiera un fonema incorrecto, PatMatch fallaría y solo se cargaría una parte del diccionario de matrices asociativas.
patRepeat es CODICIOSO y va tan lejos como puede, engullendo espacios en blanco y simpatizantes.Cuando llega al final de línea, no puede ir más allá y el >> operador de asignación inmediata almacena la coincidencia repetida en pronunciar[palabra].¡MAGIA! ¡el valor de la palabra utilizada para indexar la pronunciación es el valor que acaba de coincidir!¡Se acaba de crear una entrada de diccionario!
La línea 10 crea el diccionario, una matriz asociativa.Está bien crearlo después de definir el patrón en la Línea 9; el patrón no se ejecutará hasta la siguiente línea.
pronunciar = matriz asociativa ();
Línea 11:
rc = Pat Match( source, Pat Pos( 0 ) + Pat Repeat( (dataLine | commentLine) + Pat Fence() ) + Pat R Pos( 0 ) );
utiliza PatPos y PatRpos para asegurarse de que coincida toda la cadena.En el medio hay otro PatRepeat que analiza una línea de datos o una línea de comentarios, una y otra vez, más de 100 000 veces.PatFence es una optimización que le dice al comparador de patrones que no guarde la información de retroceso.Si el patrón fallaba, cerca del final, retroceder le permitiría al comparador retroceder y probar diferentes opciones.Para este archivo, eso no tendría sentido, y la memoria requerida para almacenar toda la información de rastreo sería grande.La sugerencia de PatFence lo acelera.
pronunciar["CEBRA"]
" Z IY1 BR AH0"
pronunciar["AARDVARK"]
"AA1 RDV AA2 R K"
pronuncia["SUPERCALIFRAGILISTICEXPEALIDOSHUS"]
" S UW2 P ER0 K AE2 L AH0 FR AE1 JH AH0 L IH2 ST IH0 K EH2 KSP IY0 AE2 L AH0 D OW1 SH AH0 S"
Dependiendo de dónde descargue los datos de CMU, los finales de línea y el espaciado pueden ser confusos. Lo siguiente debería manejarlo mejor.
source = Load Text File( "z:/cmudict-0.7b.txt",charset("windows-1252") );
symbols = Load Text File( "z:/cmudict-0.7b.symbols.txt" );
symlist = Words( symbols, "\!n" );
symPat = symlist; // make a copy
Substitute Into( symPat, Expr( {} ), Expr( Pat Altern() ) ); // convert list to alternation pattern
sympat = Eval( sympat ); // build the pattern, once
lineEnding = "\!n\!r";
commentLine = ";;;" + Pat Break( lineEnding ) + patspan(lineEnding);
dataLine = Pat Break( " " ) >> word + " " + Pat Repeat( patspan(" ") + symPat ) >> pronounce[word] + patspan(lineEnding);
pronounce = Associative Array();
rc = Pat Match( source, Pat Pos( 0 ) + Pat Repeat( (dataLine | commentLine ) + Pat Fence() ) + Pat R Pos( 0 ) );
if( rc, Show( pronounce["ELEPHANTS"] ), print("failed"));Debería ser un poco más robusto porque manejará muchas combinaciones de CR y LF al final de las líneas (no solo LF) y manejará más de dos espacios ocasionales entre una palabra y la pronunciación.