/[mbrola]/trunk/mbrola.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/mbrola.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1 by dpavlin, Sat Aug 5 10:54:32 2006 UTC revision 5 by dpavlin, Tue Aug 8 15:06:33 2006 UTC
# Line 7  Line 7 
7  use strict;  use strict;
8  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
9  use Term::ReadLine;  use Term::ReadLine;
10    use File::Slurp;
 my $term = new Term::ReadLine 'Simple Perl calc';  
 my $prompt = "Pričaj: ";  
 my $OUT = $term->OUT || \*STDOUT;  
   
11    
12  my $letters = {  my $letters = {
13          'a' => [['a'],          'a' => [['a'],
# Line 194  my $silence = { Line 190  my $silence = {
190  };  };
191    
192  my $recovery;  my $recovery;
193  foreach my $df (qw/ bp oo uks/) {  foreach my $df (qw/bp oo uks/) {
194          $recovery->{$df}++;          $recovery->{$df}++;
195  }  }
196    
# Line 210  sub speak_hr { Line 206  sub speak_hr {
206          # FIXME: lj, nj, dľ          # FIXME: lj, nj, dľ
207          my @chars = split(//, $text);          my @chars = split(//, $text);
208    
209          my @pho = ({ char => '_', dur => [50] });          my @pho = ({ char => '_', dur => [ $silence->{word} ] });
210    
211          my ($g,$f) = ('','');          my ($g,$f) = ('','');
212    
213          foreach my $i ( 0 .. $#chars ) {          my $last_c = '';
214                  my $c = $chars[$i];  
215            my $i = 0;
216            while (@chars) {
217                    my $c = shift @chars;
218    
219                  $g .= $c;                  $g .= $c;
220    
221                  if (defined( $phonemes->{$c} )) {                  if (defined( $phonemes->{ lc($c) } )) {
222                          $c = $phonemes->{$c};                          $c = $phonemes->{ lc($c) };
223                  } elsif (defined( $token_to_grapheme->{$c} )) {                  } elsif (defined( $token_to_grapheme->{ lc($c) } )) {
224                          $c = $token_to_grapheme->{$c};                          my $tmp = $token_to_grapheme->{ lc($c) };
225                  } else {                          if (length($tmp) > 1) {
226                          $pho[ $#pho ]->{dur}->[0] = $silence->{word};                                  my @tmp_c = split(//, $tmp);
227                          next;                                  warn "### $c --> $tmp\n";
228                                    $c = shift @tmp_c;
229                                    unshift @chars, ( @tmp_c );
230                            } else {
231                                    $c = $tmp;
232                            }
233                  }                  }
234    
235                  my $d = $durations->{$c} || $silence->{word};                  my $d = $durations->{$c} || $durations->{ lc($c) };
   
                 my @dur = ( $d );  
   
                 if ($first) {  
                         $first = 0;  
236    
237                          push @dur, ( 10, 120 );                  if (! $d) {
238                  }                          next if ($c =~ m/\s/);
239                            warn "### skipped: $c\n";
240                  if ($zarez) {                          $c = '_';
241                          $zarez = 0;                          $d = $silence->{word};
                         push @dur, ( 10, 100 );  
242                  }                  }
243    
244                    my @dur = ( $d );
245    
246                  if ($c =~ m/[,\.!\? _]/) {                  if ($last_c =~ m/[,\.!\? _]/) {
247    
248                          my $from = $#{ $pho[ $i - 1 ]->{dur} };                          my $from = $#{ $pho[ $i - 1 ]->{dur} };
249                          $from = 3 if ($from > 3);                          $from = 3 if ($from > 3);
# Line 256  sub speak_hr { Line 255  sub speak_hr {
255                                  $tmpr += 30;                                  $tmpr += 30;
256                          }                          }
257    
258                          if ($c =~ m/,/) {                          # begining of sentence
259                                  $zarez = 1;                          push @dur, ( 10, 120 );
260                                  @dur = ( $silence->{comma} );                  }
                         } else {  
                                 @dur = ( $silence->{sentence} );  
                                 $first = 1;  
                         }  
261    
262                    if ($c =~ m/\s/) {
263                            $pho[ $#pho ]->{dur}->[0] += $silence->{word};
264                            $last_c = $c;
265                            next;
266                    } elsif ($c =~ m/[\.!\?]/) {
267                            $pho[ $#pho ]->{dur}->[0] += $silence->{word};
268                            push @pho, {
269                                    char => '_',
270                                    dur => [ $silence->{sent} ],
271                            };
272                            $last_c = $c;
273                            next;
274                    } elsif ($c =~ m/,/) {
275                            push @dur, ( 10, 100 );
276                  }                  }
277    
278                    # same last chars? double duration
279                    if ($last_c eq $c) {
280                            $pho[ $#pho ]->{dur}->[0] *= 2;
281                            next;
282                    }
283    
284                    # fixup sequences that need special handling
285                    if (defined($recovery->{ $last_c . $c })) {
286                            push @pho, {
287                                    char => '_',
288                                    dur => [ $silence->{word} ],
289                            };
290                    }
291    
292                    $last_c = $c;
293                  push @pho, {                  push @pho, {
294                          char => $c,                          char => $c,
295                          dur => \@dur,                          dur => \@dur,
# Line 274  sub speak_hr { Line 298  sub speak_hr {
298                  $f .= $c;                  $f .= $c;
299          }          }
300    
301          push @pho, { char => '_', dur => [50] };          push @pho, { char => '_', dur => [ $silence->{sent} ] };
302    
303          warn "# pho = ",dump(@pho),$/;  #       warn "# pho = ",dump(@pho),$/;
304    
305          my $out;          my $out;
306    
         my $last_c = '';  
   
307          foreach my $p (@pho) {          foreach my $p (@pho) {
                 if (defined($recovery->{ $last_c . $p->{char} })) {  
                         $out .= '_ ' . ( $silence->{word} * $speed ) . "\n";  
                 }  
308                  $out .= $p->{char} . ' ' . join(' ', map { $_ * $speed } @{ $p->{dur} }) . "\n";                  $out .= $p->{char} . ' ' . join(' ', map { $_ * $speed } @{ $p->{dur} }) . "\n";
   
                 $last_c = $p->{char};  
309          }          }
310    
311          return ($out, $g, $f);          return ($out, $g, $f);
# Line 296  sub speak_hr { Line 313  sub speak_hr {
313    
314  my $mbrola = './bin/mbrola-linux-i386 ./cr1/cr1';  my $mbrola = './bin/mbrola-linux-i386 ./cr1/cr1';
315    
316  while ( defined ($_ = $term->readline($prompt)) ) {  my $term = new Term::ReadLine 'Mbrola croatian speaker';
317    my $OUT = $term->OUT || \*STDOUT;
318    
319          $term->addhistory($_);  sub play_speak_hr {
320            my $text = shift || return;
321    
322          my ($out,$g,$f) = speak_hr( $_ );          my ($out,$g,$f) = speak_hr( $text );
323    
324          open(my $fh, "| $mbrola - tmp.wav") || die "can't open $mbrola: $!";          open(my $fh, "| $mbrola - tmp.wav") || die "can't open $mbrola: $!";
325    
326          print $OUT ">>> $g\n>>> $f\n$out\n";          print $OUT ">>> $g\n<<< $f\n";
327    
328          print $fh $out || die "can't pipe to $mbrola";          print $fh $out || die "can't pipe to $mbrola";
329          close($fh) || die "error closing pipe to $mbrola";          close($fh) || die "error closing pipe to $mbrola";
330    
331            $out =~ s/\n/ | /gs;
332            print $OUT "# $out\n";
333    
334          system 'play tmp.wav';          system 'play tmp.wav';
335    }
336    
337    
338    if (my $path = shift @ARGV) {
339            my $text = read_file($path) || die "can't read $path: $!";
340    
341            # strip html
342            $text =~ s!</?[^>]+>! !gs;
343    
344            $text =~ s!\s+! !gs;
345    
346            print "-- $text --";
347    
348            play_speak_hr( $text );
349            exit;
350    }
351    
352    my $prompt = "Pričaj: ";
353    
354    while ( defined ($_ = $term->readline($prompt)) ) {
355            $term->addhistory( $_ );
356            play_speak_hr( $_ );
357  }  }
358    
359    

Legend:
Removed from v.1  
changed lines
  Added in v.5

  ViewVC Help
Powered by ViewVC 1.1.26