# ==========
# en1tobr.pl
# ==========

# quick hack to translate en1 (English) on stdin to use br1 (Brazilian) voice
# Mike Hamilton (mikeh@hamilton.net.au) January 2000

# Map English phonemes to Brazilian

%en1tobr1map=(
  "5"  => "l",
  "p"  => "p",   # pat
  "b"  => "b",   # but
  "t"  => "t",   # ten
  "d"  => "d",   # den
  "k"  => "k",   # can
  "m"  => "m",   # man
  "n"  => "n",   # not
  "l"  => "l",   # like
  "r"  => "r",   # run
  "f"  => "f",   # full
  "v"  => "v",   # very
  "s"  => "s",   # some
  "z"  => "z",   # zeal
  "h"  => "h",   # hat
  "w"  => "w",   # went
  "g"  => "g",   # game
  "tS" => "x" ,  # chain
  "dZ" => "x",   # Jane
  "N"  => "nh",	 # long
  "T" =>  "t",   # thin
  "D" =>  "t",   # then
  "S" =>  "x",   # ship
  "Z" =>  "z",   # measure
  "j" =>  "y",   # yes
  "i:" => "i",   # bean
  "A:" => "a",   # barn
  "O:" => "oo",   # born
  "u:" => "u",   # boon
  "3:" => "@",   # burn
  "I"  => "i",   # pit
  "e"  => "e",   # pet
  "{"  => "a",   # pat
  "V"  => "a",   # putt
  "Q"  => "o",   # pot
  "U"  => "u",   # good
  "@"  => "@",	 # about
  "eI" => "e",   # bay
  "aI" => "i",   # buy
  "OI" => "oo",  # boy
  "\@U"=> "oo",  # no
  "aU" => "u",   # now
  "I\@"=> "@",   # peer
  "e\@"=> "@",   # pair
  "U\@"=> "@"    # poor
);


# ----------------
# BrazilianNoElide
# ----------------
# These Brazilian pairs cannot be elided, but
# can be played if @ is inserted

@BrazilianNoElide=(
  "am", "r2",
  "am", "w",
  "am", "y",
  "b", "b",
  "b", "d",
  "b", "f",
  "b", "g",
  "b", "j",
  "b", "k",
  "b", "m",
  "b", "p",
  "b", "r2",
  "b", "s",
  "b", "s2",
  "b", "t",
  "b", "v",
  "b", "x",
  "b", "z",
  "d", "b",
  "d", "d",
  "d", "f",
  "d", "g",
  "d", "j",
  "d", "k",
  "d", "m",
  "d", "n",
  "d", "p",
  "d", "r2",
  "d", "s",
  "d", "s2",
  "d", "t",
  "d", "v",
  "d", "x",
  "d", "z",
  "em", "r2",
  "em", "w",
  "em", "y",
  "f", "b",
  "f", "d",
  "f", "f",
  "f", "g",
  "f", "j",
  "f", "k",
  "f", "n",
  "f", "p",
  "f", "r2",
  "f", "s",
  "f", "s2",
  "f", "t",
  "f", "v",
  "f", "x",
  "g", "b",
  "g", "d",
  "g", "f",
  "g", "g",
  "g", "j",
  "g", "k",
  "g", "m",
  "g", "n",
  "g", "p",
  "g", "r2",
  "g", "s" ,
  "g", "s2",
  "g", "t",
  "g", "v",
  "g", "x",
  "g", "z",
  "im", "r2",
  "im", "w",
  "im", "y",
  "j", "b",
  "j", "d",
  "j", "f",
  "j", "g",
  "j", "j",
  "j", "k",
  "j", "p",
  "j", "r2",
  "j", "s2",
  "j", "t",
  "j", "v",
  "j", "x",
  "k", "b",
  "k", "d",
  "k", "f",
  "k", "g",
  "k", "j",
  "k", "k",
  "k", "m",
  "k", "n",
  "k", "p",
  "k", "r2",
  "k", "s",
  "k", "s2",
  "k", "t",
  "k", "v",
  "k", "x",
  "l", "b",
  "l", "d",
  "l", "f",
  "l", "g",
  "l", "j",
  "l", "k",
  "l", "l",
  "l", "m",
  "l", "n",
  "l", "p",
  "l", "r",
  "l", "r2",
  "l", "s",
  "l", "s2",
  "l", "t",
  "l", "v",
  "l", "x",
  "l", "z",
  "m", "b",
  "m", "d",
  "m", "f",
  "m", "g",
  "m", "j",
  "m", "k",
  "m", "l",
  "m", "m",
  "m", "n",
  "m", "p",
  "m", "r",
  "m", "r2",
  "m", "s",
  "m", "s2",
  "m", "t",
  "m", "v",
  "m", "x",
  "m", "z",
  "n", "b",
  "n", "d",
  "n", "f",
  "n", "g",
  "n", "j",
  "n", "k",
  "n", "l",
  "n", "m",
  "n", "n",
  "n", "p",
  "n", "r",
  "n", "r2",
  "n", "s",
  "n", "s2",
  "n", "t",
  "n", "v",
  "n", "x",
  "n", "z",
  "nh", "b",
  "nh", "d",
  "nh", "f",
  "nh", "g",
  "nh", "j",
  "nh", "k",
  "nh", "l",
  "nh", "m",
  "nh", "p",
  "nh", "r2",
  "nh", "s",
  "nh", "s2",
  "nh", "t",
  "nh", "v",
  "nh", "x",
  "nh", "z",
  "om", "r2",
  "om", "w",
  "om", "y",
  "p", "b",
  "p", "d",
  "p", "f",
  "p", "g",
  "p", "j",
  "p", "k",
  "p", "p",
  "p", "r2",
  "p", "s",
  "p", "s2",
  "p", "t",
  "p", "v",
  "p", "x",
  "r", "b",
  "r", "d",
  "r", "f",
  "r", "g",
  "r", "j",
  "r", "k",
  "r", "l",
  "r", "m",
  "r", "n",
  "r", "p",
  "r", "r",
  "r", "r2",
  "r", "s",
  "r", "s2",
  "r", "t",
  "r", "v",
  "r", "x",
  "r", "z",
  "rr", "b",
  "rr", "d",
  "rr", "f",
  "rr", "g",
  "rr", "j",
  "rr", "k",
  "rr", "p",
  "rr", "r2",
  "rr", "s2",
  "rr", "t",
  "rr", "v",
  "rr", "x",
  "s", "b",
  "s", "d",
  "s", "f",
  "s", "g",
  "s", "j",
  "s", "k",
  "s", "l",
  "s", "m",
  "s", "n",
  "s", "p",
  "s", "r",
  "s", "r2",
  "s", "s",
  "s", "s2",
  "s", "t",
  "s", "v",
  "s", "x",
  "s", "z",
  "t", "b",
  "t", "d",
  "t", "f",
  "t", "g",
  "t", "j",
  "t", "k",
  "t", "m",
  "t", "n",
  "t", "p",
  "t", "r2",
  "t", "s",
  "t", "s2",
  "t", "t",
  "t", "v",
  "t", "x",
  "t", "z",
  "um", "r2",
  "um", "w",
  "um", "y",
  "v", "b",
  "v", "d",
  "v", "f",
  "v", "g",
  "v", "j",
  "v", "k",
  "v", "n",
  "v", "p",
  "v", "r2",
  "v", "s",
  "v", "s2",
  "v", "t",
  "v", "v",
  "v", "x",
  "v", "z",
  "w", "r2",
  "w", "w",
  "w", "y",
  "x", "b",
  "x", "d",
  "x", "f",
  "x", "g",
  "x", "j",
  "x", "k",
  "x", "l",
  "x", "m",
  "x", "n",
  "x", "p",
  "x", "r",
  "x", "r2",
  "x", "s",
  "x", "s2",
  "x", "t",
  "x", "v",
  "x", "x",
  "x", "z",
  "y", "r2",
  "y", "w",
  "y", "y",
  "z", "b",
  "z", "d",
  "z", "f",
  "z", "g",
  "z", "j",
  "z", "k",
  "z", "l",
  "z", "m",
  "z", "n",
  "z", "p",
  "z", "r",
  "z", "r2",
  "z", "s",
  "z", "s2",
  "z", "t",
  "z", "v",
  "z", "x"
);

# ---------------------
# BrazilianCheckElision
# ---------------------

sub BrazilianCheckElision
{
  local ($phon1,$phon2)=@_;
  local ($ok,$a,$i,$n,$s1,$s2);
  $n=($#BrazilianNoElide+1)/2;


  for ($a=0;$a<$n; ++$a) {
    $i=$a*2;
    $s1=$BrazilianNoElide[$i];
    if ($phon1 eq $s1) {
      $s2=$BrazilianNoElide[$i+1];
      if ($phon2 eq $s2) {
        return 1;
      }
    }
  }

  return 0;
}

# -----------------
# MakeBrazilianLine
# -----------------

sub MakeBrazilianLine
{
  local ($phon,$line)=@_;
  local ($BrazilianLine);

  $BrazilianLine="$phon ";
  @fields=split(" ",$line);
  $nFields=$#fields;

  for ($i=1; $i<=$nFields; ++$i) {
     $BrazilianLine .= "$fields[$i]";
     $BrazilianLine .=" " if ($i !=$nFields);
  }
  return $BrazilianLine;

}

# ----------
# ReadmBrola
# ----------

# read, eating comments

sub ReadmBrola
{
  return -1 if (!($lookAhead=<>));  # eof

  chop ($lookahead);

  while ($lookAhead =~ /^;/) # comment
  {
   print "$lookAhead\n";
    last if (!($lookAhead=<>));  # eof
    chop ($lookAhead);
  }

  $lookAhead =~  s/^\s+|\s+$//g; # strip leading/trailing spaces
}

# -----------
# ProcessLine
# -----------

sub ProcessLine
{
   print "\n", return if ($line eq "");   # empty line

   @fields=split(" ",$lookAhead);
   $nextEnglishPhon=$fields[0];
   $nextBrazilianPhon=$en1tobr1map{$nextEnglishPhon};

   @fields=split(" ",$line);
   $EnglishPhon=$fields[0];


   $BrazilianPhon=$en1tobr1map{$EnglishPhon};

   # make English aI from a-i
   if ($EnglishPhon eq "aI") {
     print "a 40\n";
   }

   # make English e@ from e-@
   if ($EnglishPhon eq "e\@") {
     print "e 40\n";
   }

   # make English U@ from u-@
   if ($EnglishPhon eq "U\@") {
     print "u 40\n";
   }

   # make English aU from a-u
   if ($EnglishPhon eq "aU") {
     print "a 40\n";
   }

   # make English I@ from i-@
   if ($EnglishPhon eq "I\@") {
     print "i 40\n";
   }

   # make English 3: from ee-@
   if ($EnglishPhon eq "3:") {
     print "ee 40\n";
   }

   $InsertPhonAfter="";

   # at end of word
   if ( (
         ($BrazilianPhon eq "l")
         || ($BrazilianPhon eq "s")
         || ($BrazilianPhon eq "m")
         || ($BrazilianPhon eq "n")
         || ($BrazilianPhon eq "nh")
         || ($BrazilianPhon eq "z")
         || ($BrazilianPhon eq "r")
         )

         && ($lookAhead =~ /^[_#]/) ) {
        $InsertPhonAfter="@ 10\n";
      }

    if ($line =~ /^[_#]/) {
      print "$line\n";
      $lastLineOutput=$line;
    }
    else {
      if ( $BrazilianPhon ne "h")  {
        $lastOutputLine=&MakeBrazilianLine($BrazilianPhon,$line);
        print "$lastOutputLine\n";
      }
    }

    if ($InsertPhonAfter ne "") {
      print "$InsertPhonAfter\n";
      $lastOutputLine=$InsertPhonAfter;
    }

    if ( &BrazilianCheckElision($BrazilianPhon,$nextBrazilianPhon)) {
      $s="@ 10";
      print "$s\n";
      $lastOutputLine=$s;
    }

}

# --------
# en1tobr1
# --------

sub en1tobr1
{
  $lastLineOutput="";

  &ReadmBrola;

  while (1) {
    @fields=split(" ",$lastOutputLine);
    $lastOutputPhon=$fields[0];

    $line=$lookAhead;

    last if (&ReadmBrola == -1); # eof
    &ProcessLine;
  }

  &ProcessLine; # deal with the last line

}

&en1tobr1;

1;




