<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
C'è un incredibile file di parole e informazioni sulla pronuncia su Università Carnegie Mellon .Oltre 100 mila parole e variazioni.Dal loro sito web: " Le sue voci sono particolarmente utili per il riconoscimento vocale e la sintesi, poiché ha mappature dalle parole alle loro pronunce nel set di fonemi ARPAbet, uno standard per la pronuncia inglese. L'attuale set di fonemi contiene 39 fonemi, le vocali portano un marcatore di accento lessicale ".Una riga tipica nel file ha questo aspetto
RUNAROUND R AH1 N AH0 R AW2 ND
Il file è facile da lavorare; ogni riga termina con un singolo carattere di nuova riga e la parola è separata dai dati con due spazi e ogni elemento di dati è separato da un singolo spazio.Gli elementi di dati sono descritti in un altro file che contiene voci come questa
Phoneme Example Translation ------- ------- ----------- AA odd AA D AE at AE T AH hut HH AH T AO ought AO Tfor 39 phonemes.
Ecco alcuni JSL per caricare le oltre 100.000 parole in un array associativo.
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["ELEFANTI"] = " EH1 L AH0 F AH0 NT S";
Le righe 1 e 2 caricano i file scaricati da una cartella sul desktop in stringhe JSL.L'enorme file ha voci come l'esempio RUNAROUND sopra.Il minuscolo file ha un singolo fonema su ogni riga.Questi simboli vengono caricati in un elenco alla riga 3.La funzione words() usa il newline per dividere il testo in un elenco di singole parole.symlist contiene le parole, e alla riga 4 ne viene fatta una copia in sympat.
Alla riga 5 SubstituteInto() manipola l'espressione dell'elenco JSL di stringhe separate da virgola, trasformandola in una chiamata di funzione JSL a Pat Altern() con un elenco di stringhe separate da virgola.La riga 6 valuta la funzione Pat Altern(), producendo un valore modello effettivo.Questo è più o meno equivalente a costruire in qualche modo questo JSL e valutarlo:
sympat = "AA" | "AA0" | ... | "Z" | "ZH"; // 39 phonemes in all
La manipolazione delle espressioni è un argomento avanzato e può essere molto utile.
La riga 7 assegna una semplice stringa di nuova riga a una variabile JSL.È più facile leggere il nome della variabile rispetto alla sequenza di escape.La riga 8 descrive l'aspetto di una riga di commento nel file enorme.Ecco il blocco di commenti che Line 8 salterà:
;;; # 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 riga 9 descrive le righe di dati nel file enorme.La riga 9 fa un sacco di lavoro, eccolo di nuovo
dataLine = Pat Break( " " ) >> word + " " + Pat Repeat( " " + symPat ) >> pronuncia[word] + lineEnding;
PatBreak() corrisponde al testo fino a uno spazio vuoto e memorizza il testo in parola .Ci sono due spazi vuoti dopo la parola; uno di essi viene abbinato prima di patRepeat e uno di essi viene abbinato la prima volta che patRepeat esegue il suo pattern.Il modello patRepeat usa symPat per convalidare ogni fonema; se fosse presente un fonema errato, il PatMatch fallirebbe e verrebbe caricata solo una parte del dizionario dell'array associativo.
patRepeat è GREEDY e va il più lontano possibile, divorando spazi vuoti e symPats.Quando raggiunge la rigaFine, non può andare oltre e l'operatore di assegnazione immediata >> memorizza la corrispondenza ripetuta in pronuncia[parola].MAGIA! il valore della parola usata per indicizzare la pronuncia è il valore appena abbinato!È stata appena creata una voce del dizionario!
La riga 10 crea il dizionario, un array associativo.Va bene crearlo dopo aver definito il modello sulla riga 9; il modello non verrà eseguito fino alla riga successiva.
pronuncia = Array Associativo();
Riga 11:
rc = Pat Match( source, Pat Pos( 0 ) + Pat Repeat( (dataLine | commentLine) + Pat Fence() ) + Pat R Pos( 0 ) );
utilizza PatPos e PatRpos per assicurarsi che l'intera stringa corrisponda.Nel mezzo c'è un altro PatRepeat che analizza una riga di dati o una riga di commento, più e più volte, più di 100.000 volte.Il PatFence è un'ottimizzazione che dice al pattern matcher di non salvare le informazioni di backtracking.Se il modello fallisce, verso la fine, il backtracking consentirebbe al matcher di eseguire il backup e provare diverse scelte.Per questo file, sarebbe inutile e la memoria richiesta per contenere tutte le informazioni di backtracking sarebbe grande.Il suggerimento PatFence lo accelera.
pronuncia["ZEBRA"]
" Z IY1 BR AH0"
pronuncia["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"
A seconda di dove scarichi i dati CMU, le terminazioni di riga e la spaziatura potrebbero essere disordinate. Quanto segue dovrebbe gestirlo meglio.
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"));Dovrebbe essere un po' più robusto perché gestirà molte combinazioni di CR e LF alla fine delle righe (non solo LF) e gestirà occasionalmente più di due spazi tra una parola e la pronuncia.