voxforge.org
VoxForge Dev
Show
Ignore:
Timestamp:
05/29/08 23:01:55 (6 months ago)
Author:
kmaclean
Message:

AudioSegmentation scripts - Sequitor G2P pronunciation alternatives validation to Audio using HVite Forced Alignment - snapshot

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Trunk/Scripts/Audio_scripts/AudioSegmentation/AudioBook/Dictionary.pm

    r2594 r2597  
    1717my $command; 
    1818 
    19 =head1 METHODS (not user accessible) 
     19=head1 CLASS METHODS  
    2020 
    2121=cut 
     
    3737}     
    3838 
     39=head1 INSTANCE METHODS (not user accessible) 
     40 
    3941=head2 findOutOfVocabularyWords  
    4042 
     
    4446 
    4547sub findOutOfVocabularyWords { # public  
    46         my ($self,$voxforgeDict, $missing_words)= @_;  
     48        my ($self,$pronDict, $missing_words)= @_;      
    4749        my $debug = $self->{"debug"};    
    4850        my $htk_files = $self->{'htk_files'}; 
    4951         
    50         $self->{"voxforgeDict"} =  $voxforgeDict; 
     52        $self->{"pronDict"} =  $pronDict; 
    5153        $self->{"missing_words"} = $missing_words; 
    5254          
    53         $command = ("HDMan -A -D -T 1 -g $htk_files/global.ded -m -w AudioBook/interim_files/wlist -i -l AudioBook/interim_files/dlog AudioBook/interim_files/dict $voxforgeDict"); system($command) == 0 or confess "fullrun $command failed: $?"; 
     55        $command = ("HDMan -A -D -T 1 -g $htk_files/global.ded -m -w AudioBook/interim_files/wlist -i -l AudioBook/interim_files/dlog AudioBook/interim_files/dict $pronDict"); system($command) == 0 or confess "fullrun $command failed: $?"; 
    5456        my $dlog1 = "AudioBook/interim_files/logs/dlog1"; 
    5557        $command = ("mv AudioBook/interim_files/dlog $dlog1"); print "cmd:$command\n" if $debug; system($command); 
     
    8183} 
    8284 
    83 =head2 getPronunciations  
     85=head2 getRecommendedPronunciations  
    8486 
    8587Use the Sequitor g2p script (Python) to generate pronunications for out-of-vocabulary words 
     
    8789=cut 
    8890 
    89 sub getPronunciations { # public  
     91sub getRecommendedPronunciations { # public  
    9092        my ($self,$missing_words_out)= @_; 
    9193        my $debug = $self->{'debug'}; 
     
    134136} 
    135137 
     138=head2 getAlternatePronunciations  
     139 
     140Use the Sequitor g2p script (Python) to generate many *alternate* pronunications for out-of-vocabulary words. 
     141These will be later used by HTK's HVite to try to determine the actual pronunication used by the speech in the audio file. 
     142 
     143Creates $missing_words_alt file, which contains the top x pronunication alternatives for each missing word. 
     144 
     145=cut 
     146 
     147sub getAlternatePronunciations { # public  
     148        my ($self,$missing_words_alt, $numberOfPronunciations)= @_; 
     149        my $debug = $self->{'debug'}; 
     150        my $model = $self->{'g2p_model'}; 
     151        my $missing_words = $self->{'missing_words'}; 
     152        my $log = $self->{'log'}; 
     153         
     154        $self->{"missing_words_alt"} = $missing_words_alt; 
     155         
     156        my @missingwords = `export PYTHONPATH=/usr/local/lib64/python2.4/site-packages && 
     157                            g2p.py --model $model --apply $missing_words --variants-number=$numberOfPronunciations`; 
     158        if ($?) { 
     159            confess "g2p.py $command failed: $?"; 
     160        } 
     161        open(MISSINGWORDSALT,">$missing_words_alt") or confess ("cannot open $missing_words_alt file"); 
     162        my ($word, $seqnum, $prob, $phonemes); 
     163        format MISSINGWORDSALT = 
     164@<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
     165$word,"[" . $word ."]",$phonemes 
     166. 
     167        foreach my $line (@missingwords) { 
     168                chomp $line; 
     169                print MISSINGWORDSALT "$line\n"; 
     170        } 
     171        close MISSINGWORDSALT; 
     172        return 1; 
     173} 
     174 
     175=head2 validateAlternatePronunciations  
     176 
     177Todo: This might need to go in a new Prompts class 
     178 
     179=cut 
     180 
     181sub validateAlternatePronunciations { # public  
     182        my ($self,$originalDict,$altDict,$prompts)= @_; 
     183        my $debug = $self->{'debug'}; 
     184        my $missing_words = $self->{'missing_words'};    
     185         
     186        $self->_createAltDict($originalDict,$altDict); 
     187        my $missingWordList = $self->_getMissingWordList($missing_words); 
     188        my %prompts; 
     189        open(PROMPTS,"$prompts") or confess ("cannot open $prompts file"); 
     190        open(MISSINGWORDPROMPTS,"AudioBook/interim_files/missingWordsFolder/missingWordPrompts") or confess ("cannot open AudioBook/interim_files/wav/missingWordPrompts file");                 
     191        open(MISSINGWORDSVAL,"AudioBook/interim_files/missingWords_val") or confess ("cannot open AudioBook/interim_files/wav/missingWordPrompts file");                 
     192        while (my $line = <PROMPTS>) {  
     193                chomp $line;     
     194                my @line = split(/\s/, $line); 
     195                my $promptID = shift @line; 
     196                foreach my $word (@line) { 
     197                        if ($missingWordList->{$word}) { 
     198                                my $wavfilename = $promptID . "\.wav"; 
     199                                copy("AudioBook/interim_files/wav/$wavfilename","AudioBook/interim_files/missingWordsFolder/$wavfilename");                              
     200                                print MISSINGWORDPROMPTS "$word:$promptID,@line\n"; 
     201                                my @phoneList = _forceAlignPromptLine($word,$promptID,@line); 
     202                                print MISSINGWORDSVAL "$word [$word] @phoneList\n"; 
     203                        } 
     204                } 
     205        } 
     206        close PROMPTS; 
     207        close MISSINGWORDPROMPTS; 
     208} 
     209 
     210=head2 _forceAlignPromptLine  
     211 
     212HVite looks at the audio, and tries to find a matching phone sequence in $altdict (which contains many alternate pronunications generated by  
     213Sequitor G2P), in doing so, it picks the most likely pronunciation, thereby validating a Sequitor G2P with real audio. 
     214 
     215=cut 
     216 
     217sub _forceAlignPromptLine { # private  
     218        my ($self,$word,$promptID,$promptLine)= @_; 
     219        my $altDict = $self->{"altDict"};        
     220        my ($aligned_out, $log) = AudioBook::Audio::forceAlign($self, $promptID, $promptLine, $altDict); 
     221        open(ALIGNED_OUT,"$aligned_out") or confess ("cannot open $prompts file"); 
     222        my @phoneList; 
     223        while (my $line = <ALIGNED_OUT>) { 
     224                my @line = split(/\s/, $line); 
     225                my($startTime,$stopTime, $phone, $probability, $recword) = @line; 
     226                if (defined($recword)) { 
     227                        if ($recword eq $word) { 
     228                                $gatherPhones=1; 
     229                        } else { 
     230                                $gatherPhones=0; 
     231                        } 
     232                } 
     233                if $gatherPhones { 
     234                        push (@phoneList,$phone); 
     235                } 
     236        }  
     237        return @phoneList; 
     238} 
     239 
     240=head2 _getMissingWordList  
     241 
     242=cut 
     243 
     244sub _getMissingWordList { # private  
     245        my ($self,$missing_words)= @_; 
     246        my %missingWordList; 
     247        open(MISSINGWORDS,"$missing_words") or confess ("cannot open $missing_words file");      
     248        while (my $line = <MISSINGWORDS>) {  
     249                chomp $line; 
     250                $missingWordList{$line} = 1; 
     251        } 
     252        close MISSINGWORDS; 
     253        return \%missingWordList; 
     254} 
     255 
     256=head2 createAltDict  
     257 
     258Need to merge the output from Sequitor G2P in getAlternatePronunciations() to the dict for the submission 
     259 
     260(todo: may need to create individual dict files for each out-of-vocabulary word to speed things up) 
     261 
     262=cut 
     263 
     264sub _createAltDict { # private  
     265        my ($self,$originalDict,$altDict)= @_; 
     266        my $missing_words_alt = $self->{"missing_words_alt"};    
     267         
     268        $self->{"altDict"} = $altDict;   
     269 
     270        open(MISSINGWORDSALT,"$missing_words_alt") or confess ("cannot open $missing_words_alt file"); 
     271        my @missingWordAlt; 
     272        while (my $line = <MISSINGWORDSALT>) { # reformat MISSINGWORDSALT so that it can be merged with dict. 
     273                chomp $line; 
     274                my @line = split(/\t/, $line); 
     275                my ($word, $seqnum, $prob, $phonemes) = @line; 
     276                push (@missingWordAlt, "$word [$word] $phonemes\n"); 
     277        } 
     278        open(DICT,$originalDict) or confess ("cannot open $originalDict file"); 
     279        my @dict = <DICT>; # slurp in entire file into an array 
     280        my @altdict = sort(@missingWordAlt,@dict); # merge and sort 
     281 
     282        open(ALTDICT,">$altDict") or confess ("cannot open $altDict file");              
     283        foreach my $line (@altdict) { 
     284                print ALTDICT $line; 
     285        } 
     286         
     287        close MISSINGWORDSALT; 
     288        close DICT; 
     289        close ALTDICT; 
     290} 
     291 
    136292=head2 updatePronDict  
    137293 
     
    147303 
    148304sub updatePronDict { # public  
    149         my ($self)= @_;                 
     305        my ($self, $pronDictionary)= @_; 
    150306        my $debug = $self->{"debug"};            
    151         my $voxforgeDict = $self->{"voxforgeDict"}; 
    152         my $missing_words_out = $self->{"missing_words_out"};    
     307        my $missing_words_out = $self->{"missing_words_out"}; 
     308                 
     309        $self->{"pronDictionary"} = $pronDictionary; 
    153310          
    154         open(DICTIONARY,">>$voxforgeDict") or confess ("cannot open $voxforgeDict file"); 
     311        open(DICTIONARY,">>$pronDictionary") or confess ("cannot open $pronDictionary file"); 
    155312        open(MISSINGWORDSOUT,"<$missing_words_out") or confess ("cannot open $missing_words_out file"); 
    156313        print "adding the following words to VoxForge Pronunciation Dictionary\n"; 
     
    165322        close DICTIONARY; 
    166323         
    167         open(DICTIONARY,"$voxforgeDict") or confess ("cannot open $voxforgeDict file"); 
     324        open(DICTIONARY,"$pronDictionary") or confess ("cannot open $pronDictionary file"); 
    168325        my(@lines) = <DICTIONARY>;         # read file into list 
    169326        close(DICTIONARY); 
    170327         
    171         open(DICTIONARY,">$voxforgeDict") or confess ("cannot open $voxforgeDict file"); 
     328        open(DICTIONARY,">$pronDictionary") or confess ("cannot open $pronDictionary file"); 
    172329        @lines = sort(@lines);              # sort the list 
    173330        my($line);