Example #1
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;
  }