# ===========
# en1tonl2.pl
# ===========

# quick hack to translate en1 (English) on stdin to use nl2 (Dutch) voice
# Mike Hamilton (mikeh@hamilton.net.au) December 1999

# Map English phonemes to Dutch

%en1tonl2map=(
  "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"  => "w",   # very
  "s"  => "s",   # some
  "z"  => "z",   # zeal
  "h"  => "h",   # hat
  "w"  => "w",   # went
  "g"  => "g",   # game
  "tS" => "tj",  # chain
  "dZ" => "dj",  # Jane
  "N"  => "N",	 # long
  "T" =>  "d",   # thin
  "D" =>  "d",   # then
  "S" =>  "S",   # ship
  "Z" =>  "Z",   # measure
  "j" =>  "j",   # yes
  "i:" => "i",   # bean
  "A:" => "A",   # barn
  "O:" => "O",   # born
  "u:" => "y",   # boon
  "3:" => "A",   # burn
  "I"  => "I",   # pit
  "e"  => "e",   # pet
  "{"  => "A",   # pat
  "V"  => "a",   # putt
  "Q"  => "o",   # pot
  "U"  => "u",   # good
  "@"  => "@",	 # about
  "eI" => "e",   # bay
  "aI" => "Ei",  # buy
  "OI" => "o",   # boy
  "\@U"=> "Au",  # no
  "aU" => "Au",  # now
  "I\@"=> "I:",  # peer
  "e\@"=> "e",   # pair
  "U\@"=> "o"    # poor
);

# -----------
# DutchVowels
# -----------

@DutchVowels= (
               "I",
               "Y",
               "E",
               "@",
               "O",
               "A",
               "i",
  	       "y",
               "u",
               "e",
               "2",
               "o",
               "a",
               "Au",
               "Ei"
              );

# ------------
# IsDutchVowel
# ------------

sub IsDutchVowel
{
  local ($phon)=@_;
  local ($s);

  foreach $s (@DutchVowels) {
    if ($s eq $phon) { return 1; }
  }
  return 0;
}

# ------------
# DutchNoElide
# ------------
# These Dutch pairs cannot be elided

@DutchNoElide=(
  "b", "b",
  "b", "f",
  "b", "k",
  "b", "L",
  "b", "m",
  "b", "n",
  "b", "N",
  "b", "p",
  "b", "S",
  "b", "s",
  "b", "t",
  "b", "w",
  "b", "x",
  "c", "f",
  "c", "k",
  "c", "l",
  "c", "L",
  "c", "m",
  "c", "N",
  "c", "n",
  "c", "p",
  "c", "r",
  "c", "S",
  "c", "s",
  "c", "t",
  "c", "w",
  "c", "x",
  "d", "b",
  "d", "d",
  "d", "f",
  "d", "k",
  "d", "l",
  "d", "L",
  "d", "m",
  "d", "n",
  "d", "N",
  "d", "p",
  "d", "S",
  "d", "s",
  "d", "t",
  "d", "x",
  "d", "z",
  "dj", "b",
  "dj", "d",
  "dj", "dj",
  "dj", "f",
  "dj", "G",
  "dj", "g",
  "dj", "k",
  "dj", "m",
  "dj", "n",
  "dj", "N",
  "dj", "p",
  "dj", "s",
  "dj", "t",
  "dj", "v",
  "dj", "x",
  "dj", "z",
  "f", "f",
  "f", "L",
  "f", "N",
  "G", "f",
  "G", "G",
  "g", "g",
  "G", "k",
  "G", "l",
  "g", "L",
  "G", "L",
  "G", "m",
  "G", "n",
  "G", "N",
  "g", "N",
  "G", "p",
  "G", "r",
  "G", "S",
  "G", "s",
  "G", "t",
  "G", "w",
  "G", "x",
  "h", "f",
  "h", "k",
  "h", "L",
  "h", "l",
  "h", "m",
  "h", "n",
  "h", "N",
  "h", "p",
  "h", "r",
  "h", "S",
  "h", "s",
  "h", "t",
  "h", "w",
  "h", "x",
  "j", "f",
  "j", "k",
  "j", "l",
  "j", "L",
  "j", "m",
  "j", "n",
  "j", "N",
  "j", "p",
  "j", "r",
  "j", "s",
  "j", "S",
  "j", "t",
  "j", "w",
  "j", "x",
  "k", "k",
  "k", "L",
  "k", "N",
  "l", "L",
  "l", "N",
  "m", "L",
  "m", "m",
  "m", "N",
  "n", "L",
  "N", "N",
  "n", "n",
  "n", "N",
  "nj", "b",
  "nj", "d",
  "nj", "f",
  "nj", "G",
  "nj", "g",
  "nj", "k",
  "nj", "m",
  "nj", "n",
  "nj", "N",
  "nj", "nj",
  "nj", "p",
  "nj", "r",
  "nj", "s",
  "nj", "t",
  "nj", "v",
  "nj", "x",
  "nj", "z",
  "p", "L",
  "p", "N",
  "p", "p",
  "r", "L",
  "r", "N",
  "r", "r",
  "s", "L",
  "S", "L",
  "s", "N",
  "S", "N",
  "S", "S",
  "s", "s",
  "t", "L",
  "t", "N",
  "t", "t",
  "tj", "b",
  "tj", "d",
  "tj", "f",
  "tj", "g",
  "tj", "G",
  "tj", "k",
  "tj", "m",
  "tj", "n",
  "tj", "N",
  "tj", "p",
  "tj", "s",
  "tj", "t",
  "tj", "tj",
  "tj", "v",
  "tj", "x",
  "tj", "z",
  "v", "f",
  "v", "k",
  "v", "L",
  "v", "m",
  "v", "n",
  "v", "N",
  "v", "p",
  "v", "S",
  "v", "s",
  "v", "t",
  "v", "v",
  "v", "w",
  "v", "x",
  "w", "L",
  "w", "N",
  "x", "L",
  "x", "N",
  "x", "x",
  "z", "d",
  "Z", "f",
  "z", "f",
  "z", "k",
  "Z", "k",
  "z", "l",
  "Z", "L",
  "z", "L",
  "Z", "l",
  "Z", "m",
  "z", "m",
  "Z", "N",
  "z", "N",
  "z", "n",
  "Z", "n",
  "Z", "p",
  "z", "p",
  "z", "r",
  "Z", "r",
  "Z", "s",
  "z", "S",
  "z", "s",
  "Z", "S",
  "Z", "t",
  "z", "t",
  "Z", "w",
  "z", "x",
  "Z", "x",
  "Z", "Z",
  "z", "z"
  );

# -----------------
# DutchCheckElision
# -----------------

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

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

  return 0;  # doesn't need pause
}

# -------------
# MakeDutchLine
# -------------

sub MakeDutchLine
{
  local ($phon,$line)=@_;
  local ($DutchLine);

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

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

}

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



# read, eating comments and blank lines

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

  chop ($lookahead);

  while ( ($lookAhead =~ /^;/) || ($lookAhead eq "") )
  {
    ++$lineNumber;
    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

   if ($line =~ /^_/) {
     print "$line\n";
     return;
   }

   if ($line =~ /^#/) {
     print "$line\n";
     return;
   }

   # set $nextEnglishPhon, $nextDutchPhon from $lookAhead

   $nextEnglishPhon="";
   $nextDutchPhon="";
   if ( ($lookAhead !~ /^_/) && ($lookAhead !~ /^#/) )
   {
   @fields=split(" ",$lookAhead);

   $nextEnglishPhon=$fields[0];

   if ($nextEnglishPhon eq "") {
     print STDERR "??? [$lookAhead] in line number $lineNumber\n";
     exit;
   }

   $nextDutchPhon=$en1tonl2map{$nextEnglishPhon};

   if ($nextDutchPhon eq "") {
     print STDERR "??? phon for [$nextEnglishPhon] is ??? in line number $lineNumber\n";
     exit;
   }
   }

   @fields=split(" ",$line);
   $EnglishPhon=$fields[0];
   $DutchPhon=$en1tonl2map{$EnglishPhon};

   $InsertPhonAfter="";

   if (&IsDutchVowel($nextDutchPhon)==0) {

     if ($DutchPhon eq "l") {
       # can only change to L if preceded by a vowel
       if (&IsDutchVowel($lastOutputPhon) ) {
         $DutchPhon = "L";
       }
       else {
          print "a 1\n";  # insert a vowel
          $DutchPhon = "L";
       }
     }

     if ($DutchPhon eq "r") {
       # can only change Dutch "r" to R if NOT preceded by [e,2,o]
       if ( ($lastOutputPhon ne "e")
              && ($lastOutputPhon ne "2")
              && ($lastOutputPhon ne "o")
              ) {
                $DutchPhon = "R";
                }
       }

      # Dutch w

      if ($DutchPhon eq "w") {
        if ($lookAhead =~ /^[_#]/) {
          $InsertPhonAfter="a 1";
        }
        else {
          if ( ($lastOutputPhon eq "i")
             || ($lastOutputPhon eq "e")
             || ($lastOutputPhon eq "y")
             )
             {
               $DutchPhon = "W";
             }
             else
             {
               # English "v" in (e.g. "five")
   	       # sounds better as "f" ("five" becomes "fife")
               $DutchPhon="f";
             }
        }
      }

      if ($DutchPhon eq "j") {
        $DutchPhon = "J";
      }

   }

   # "hubert", "juan" (h j, h w )
   # can't say h-j or h-w in nl2
   # so we will add a tiny i before the w
   if ( ($DutchPhon eq "h") &&
          (
	   ($nextDutchPhon eq "j")
           || ($nextDutchPhon eq "w")
	  )
          )
      {
        $InsertPhonAfter="i 1";
      }

   # at end of word
   if ( (
         ($DutchPhon eq "d")
         || ($DutchPhon eq "z")
         )
         && ($lookAhead =~ /^[_#]/) ) {
        $InsertPhonAfter="@ 10\n";
      }

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

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

    if ( &DutchCheckElision($DutchPhon,$nextDutchPhon)) {
      $s   ="@ 10";
      print "$s\n";
      $lastOutputLine=$s;
    }
}

# --------
# en1tonl2
# --------

sub en1tonl2
{
  $lastLineOutput="";

  &ReadmBrola;

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

    $line=$lookAhead; # which we read before
    # read the next line ahead
    last if (&ReadmBrola == -1); # eof
    &ProcessLine;
  }

  &ProcessLine; # deal with the last line

}

&en1tonl2;

1;




