/**
   * Changes the pronunciation of "the" from 'd ax' to 'd iy' if the following word starts with a
   * vowel. "The every" is a good example.
   *
   * @param utterance the utterance to process
   */
  private void fixTheIy(Utterance utterance) {
    Voice voice = utterance.getVoice();
    for (Item item = utterance.getRelation(Relation.SEGMENT).getHead();
        item != null;
        item = item.getNext()) {

      if ("ax".equals(item.toString())) {
        String word = wordPath.findFeature(item).toString();
        if ("the".equals(word) && ("+".equals(N_PH_VC.findFeature(item)))) {
          item.getFeatures().setString("name", "iy");
        }
      }
    }
  }
  /**
   * Fixes apostrophe s segments.
   *
   * @param utterance the utterance to fix
   */
  private void fixApostrophe(Utterance utterance) {
    Voice voice = utterance.getVoice();
    for (Item item = utterance.getRelation(Relation.SEGMENT).getHead();
        item != null;
        item = item.getNext()) {
      String word = wordPath.findFeature(item).toString();

      if (word.equals("'s")) {

        String pname = item.getPrevious().toString();

        if (("fa".indexOf(voice.getPhoneFeature(pname, "ctype")) != -1)
            && ("dbg".indexOf(voice.getPhoneFeature(pname, "cplace")) == -1)) {
          prependSchwa(item);
        } else if (voice.getPhoneFeature(pname, "cvox").equals("-")) {
          item.getFeatures().setString("name", "s");
        }
      } else if (word.equals("'ve") || word.equals("'ll") || word.equals("'d")) {
        if ("-".equals(P_PH_VC.findFeature(item))) {
          prependSchwa(item);
        }
      }
    }
  }
Exemple #3
0
  public MaryData process(MaryData d) throws Exception {
    Document doc = MaryXML.newDocument();
    Element root = doc.getDocumentElement();
    Locale locale = d.getLocale();
    if (locale != null) {
      root.setAttribute("xml:lang", MaryUtils.locale2xmllang(locale));
    }
    Element paragraph = MaryXML.appendChildElement(root, MaryXML.PARAGRAPH);

    List<Utterance> utterances = d.getUtterances();
    Iterator<Utterance> it = utterances.iterator();
    while (it.hasNext()) {
      Utterance utterance = it.next();
      Element insertHere = paragraph;

      if (logger.getEffectiveLevel().equals(Level.DEBUG)) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        utterance.dump(pw, 2, name(), true); // padding, justRelations
        logger.debug("Converting the following Utterance to XML:\n" + sw.toString());
      }

      // Make sure we have the correct voice:
      Voice maryVoice = null;
      if (utterance.getVoice() != null) {
        maryVoice = FreeTTSVoices.getMaryVoice(utterance.getVoice());
      }
      if (maryVoice != null) {
        if (insertHere.getTagName().equals(MaryXML.VOICE)) {
          // Are utterance voice and voiceElement voice the same?
          if (maryVoice.hasName(insertHere.getAttribute("name"))) {
            // then insertHere is set OK, leave it like it is
          } else {
            // get one higher up, create new voice element after this
            // one, and make insertHere point to the new voice element
            Element parent = (Element) insertHere.getParentNode();
            Element newVoice = MaryXML.createElement(doc, MaryXML.VOICE);
            parent.appendChild(newVoice);
            newVoice.setAttribute("name", maryVoice.getName());
            insertHere = newVoice;
          }
        } else {
          // Check if the last child of insertHere is a voice with the right name
          Element lastChild = MaryDomUtils.getLastChildElement(insertHere);
          if (lastChild != null
              && lastChild.getTagName().equals(MaryXML.VOICE)
              && maryVoice.hasName(lastChild.getAttribute("name"))) {
            insertHere = lastChild;
          } else {
            // create a new voice element, insert it as a child of this
            // node, and let insertHere point to it
            Element newVoice = MaryXML.createElement(doc, MaryXML.VOICE);
            insertHere.appendChild(newVoice);
            newVoice.setAttribute("name", maryVoice.getName());
            insertHere = newVoice;
          }
        }
        // Now insertHere is the correct <voice> element.

        // Any prosodic settings to insert?
        Element prosody = insertProsodySettings(insertHere, utterance);
        if (prosody != null) insertHere = prosody;
      }
      // Create a sentence element <s> for this utterance:
      Element sentence = MaryXML.createElement(doc, MaryXML.SENTENCE);
      insertHere.appendChild(sentence);

      fillSentence(sentence, utterance);
    }

    if (logger.getEffectiveLevel().equals(Level.DEBUG)) {
      logger.debug("Constructed the following XML structure:");
      MaryNormalisedWriter mnw = new MaryNormalisedWriter();
      ByteArrayOutputStream debugOut = new ByteArrayOutputStream();
      mnw.output(doc, debugOut);
      logger.debug(debugOut.toString());
    }

    MaryData output = new MaryData(outputType(), d.getLocale());
    output.setDocument(doc);
    return output;
  }
Exemple #4
0
 /**
  * Depending on the data type, find the right information in the utterance and insert it into the
  * sentence.
  */
 protected final void fillSentence(Element sentence, Utterance utterance) {
   Document doc = sentence.getOwnerDocument();
   Relation tokenRelation = utterance.getRelation(Relation.TOKEN);
   if (tokenRelation == null) return;
   Item tokenItem = tokenRelation.getHead();
   Relation phraseRelation = utterance.getRelation(Relation.PHRASE);
   Item phraseItem = null;
   if (phraseRelation != null) {
     phraseItem = phraseRelation.getHead();
     // Challenge: Bring token and phrase relations together. They have
     // common children, which can be interpreted as Word or SylStructure
     // items. Algorithm: For a given phrase, look at tokens. If a token's
     // first child, interpreted in the phrase relation, has the phrase as
     // its parent, then insert the token and all its children, and move to
     // the next token. If not, move to the next phrase.
     while (phraseItem != null) {
       // The phrases:
       Element phrase = MaryXML.createElement(doc, MaryXML.PHRASE);
       sentence.appendChild(phrase);
       Element insertHere = phrase;
       // Is this token part of this phrase?
       while (tokenItem != null
           && tokenItem.getDaughter().findItem("R:Phrase.parent").equals(phraseItem)) {
         FeatureSet tokenFeatures = tokenItem.getFeatures();
         if (tokenFeatures.isPresent(XML2UttBase.PROSODY_START)) {
           Element prosody = insertProsodySettings(insertHere, tokenFeatures);
           if (prosody != null) {
             insertHere = prosody;
           }
         }
         insertToken(tokenItem, phrase, true); // create deep structure
         if (tokenFeatures.isPresent(XML2UttBase.PROSODY_END)) {
           assert insertHere.getTagName().equals(MaryXML.PROSODY);
           insertHere = (Element) insertHere.getParentNode();
         }
         tokenItem = tokenItem.getNext();
       }
       phraseItem = phraseItem.getNext();
     }
   } else {
     // No phrase relation, simply create tokens.
     Element insertHere = sentence;
     while (tokenItem != null) {
       FeatureSet tokenFeatures = tokenItem.getFeatures();
       if (tokenFeatures.isPresent(XML2UttBase.PROSODY_START)) {
         Element prosody = insertProsodySettings(insertHere, tokenFeatures);
         if (prosody != null) {
           insertHere = prosody;
         }
       }
       insertToken(tokenItem, insertHere);
       if (tokenFeatures.isPresent(XML2UttBase.PROSODY_END)) {
         if (insertHere.getTagName().equals(MaryXML.PROSODY)) {
           insertHere = (Element) insertHere.getParentNode();
         } // else, we are looking at an empty prosody tag with no arguments, which is being
         // deleted right now.
       }
       tokenItem = tokenItem.getNext();
     }
   }
 }