Esempio n. 1
0
void Arpeggio::write(Xml& xml) const
      {
      xml.stag("Arpeggio");
      Element::writeProperties(xml);
      xml.tag("subtype", _subtype);
      if (_userLen1.val() != 0.0)
            xml.sTag("userLen1", _userLen1);
      if (_userLen2.val() != 0.0)
            xml.sTag("userLen2", _userLen2);
      if (_span != 1)
            xml.tag("span", _span);
      xml.etag();
      }
Esempio n. 2
0
void Trill::write(Xml& xml) const
{
    if (!xml.canWrite(this))
        return;
    xml.stag(QString("%1 id=\"%2\"").arg(name()).arg(xml.spannerId(this)));
    xml.tag("subtype", trillTypeName());
    writeProperty(xml, P_ID::PLAY);
    writeProperty(xml, P_ID::ORNAMENT_STYLE);
    SLine::writeProperties(xml);
    if (_accidental)
        _accidental->write(xml);
    xml.etag();
}
Esempio n. 3
0
void Lyrics::write(Xml& xml) const
      {
      if(!xml.canWrite(this)) return;
      xml.stag("Lyrics");
      if (_no)
            xml.tag("no", _no);
      if (_syllabic != Syllabic::SINGLE) {
            static const char* sl[] = {
                  "single", "begin", "end", "middle"
                  };
            xml.tag("syllabic", sl[int(_syllabic)]);
            }
      if (_ticks)
            xml.tag("ticks", _ticks);
      Text::writeProperties(xml);
      if (_verseNumber) {
            xml.stag("Number");
            _verseNumber->writeProperties(xml);
            xml.etag();
            }
      xml.etag();
      }
Esempio n. 4
0
void Accidental::write(Xml& xml) const
      {
      xml.stag(name());
      if (_hasBracket)
            xml.tag("bracket", _hasBracket);
      if (_role != ACC_AUTO)
            xml.tag("role", _role);
      if (_small)
            xml.tag("small", _small);
      xml.tag("subtype", accList[_subtype].tag);
      Element::writeProperties(xml);
      xml.etag();
      }
Esempio n. 5
0
void Arpeggio::write(Xml& xml) const
      {
      xml.stag("Arpeggio");
      Element::writeProperties(xml);
      xml.tag("subtype", int(_subtype));
      if (_userLen1 != 0.0)
            xml.tag("userLen1", _userLen1 / spatium());
      if (_userLen2 != 0.0)
            xml.tag("userLen2", _userLen2 / spatium());
      if (_span != 1)
            xml.tag("span", _span);
      xml.etag();
      }
Esempio n. 6
0
void Glissando::write(Xml& xml) const
      {
      if (!xml.canWrite(this))
            return;
      xml.stag(QString("%1 id=\"%2\"").arg(name()).arg(xml.spannerId(this)));
      if (_showText && !_text.isEmpty())
            xml.tag("text", _text);
      xml.tag("subtype", int(_glissandoType));
      writeProperty(xml, P_ID::PLAY);
      writeProperty(xml, P_ID::GLISSANDO_STYLE);
      SLine::writeProperties(xml);
      xml.etag();
      }
Esempio n. 7
0
void LayoutBreak::write(Xml& xml) const
      {
      xml.stag(name());
      Element::writeProperties(xml);

      WRITE_PROPERTIES(LayoutBreak)

      if (!_startWithLongNames)
            xml.tag("startWithLongNames", _startWithLongNames);
      if (!_startWithMeasureOne)
            xml.tag("startWithMeasureOne", _startWithMeasureOne);
      xml.etag();
      }
Esempio n. 8
0
void MidiInstrument::write(int level, Xml& xml)
{
    xml.header();
    xml.tag(level, "oom version=\"1.0\"");
    level++;
    xml.nput(level, "<MidiInstrument name=\"%s\"", Xml::xmlString(iname()).toLatin1().constData());

    if (_nullvalue != -1)
    {
        QString nv;
        nv.setNum(_nullvalue);
        xml.nput(" nullparam=\"%s\"", nv.toLatin1().constData());
    }
    xml.put(">");

    // -------------
    // What about Init, Reset, State, and InitScript ?
    // -------------

    level++;
    for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g)
    {
        PatchGroup* pgp = *g;
        const PatchList& pl = pgp->patches;
        xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(pgp->name).toLatin1().constData());
        level++;
        for (ciPatch p = pl.begin(); p != pl.end(); ++p)
            (*p)->write(level, xml);
        level--;
        xml.etag(level, "PatchGroup");
    }
    for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic)
        ic->second->write(level, xml);
    level--;
    xml.etag(level, "MidiInstrument");
    level--;
    xml.etag(level, "oom");
}
Esempio n. 9
0
void LayoutBreak::write(Xml& xml) const
      {
      xml.stag(name());
      Element::writeProperties(xml);

      writeProperty(xml, P_ID::LAYOUT_BREAK);
      writeProperty(xml, P_ID::PAUSE);

      if (!_startWithLongNames)
            xml.tag("startWithLongNames", _startWithLongNames);
      if (!_startWithMeasureOne)
            xml.tag("startWithMeasureOne", _startWithMeasureOne);
      xml.etag();
      }
Esempio n. 10
0
void Articulation::write(Xml& xml) const
      {
      xml.stag("Articulation");
      if (!_channelName.isEmpty())
            xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
      writeProperty(xml, P_DIRECTION);
      xml.tag("subtype", subtypeName());
      if (_timeStretch != 1.0)
            xml.tag("timeStretch", _timeStretch);
      Element::writeProperties(xml);
      if (anchorStyle == PropertyStyle::UNSTYLED)
            xml.tag("anchor", int(_anchor));
      xml.etag();
      }
Esempio n. 11
0
void LayoutBreak::write(Xml& xml) const
      {
      xml.stag(name());
      Element::writeProperties(xml);
      for (int i = 0; i < PROPERTIES; ++i) {
            const Property<LayoutBreak>& p = propertyList[i];
            xml.tag(p.name, p.type, ((*(LayoutBreak*)this).*(p.data))(), propertyList[i].defaultVal);
            }
      if (!_startWithLongNames)
            xml.tag("startWithLongNames", _startWithLongNames);
      if (!_startWithMeasureOne)
            xml.tag("startWithMeasureOne", _startWithMeasureOne);
      xml.etag();
      }
Esempio n. 12
0
void MidiInstrument::writeDrummaps(int level, Xml& xml) const
{
  xml.tag(level++, "Drummaps");

  for (std::list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin();
       it!=patch_drummap_mapping.end(); it++)
  {
    xml.tag(level++, "entry");

    const patch_collection_t* ap = &it->affected_patches;
    QString tmp="<patch_collection ";
    if (ap->first_program==ap->last_program)
      tmp+="prog=\""+QString::number(ap->first_program)+"\" ";
    else if (! (ap->first_program==0 && ap->last_program>=127))
      tmp+="prog=\""+QString::number(ap->first_program)+"-"+QString::number(ap->last_program)+"\" ";

    if (ap->first_lbank==ap->last_lbank)
      tmp+="lbank=\""+QString::number(ap->first_lbank)+"\" ";
    else if (! (ap->first_lbank==0 && ap->last_lbank>=127))
      tmp+="lbank=\""+QString::number(ap->first_lbank)+"-"+QString::number(ap->last_lbank)+"\" ";

    if (ap->first_hbank==ap->last_hbank)
      tmp+="hbank=\""+QString::number(ap->first_hbank)+"\" ";
    else if (! (ap->first_hbank==0 && ap->last_hbank>=127))
      tmp+="hbank=\""+QString::number(ap->first_hbank)+"-"+QString::number(ap->last_hbank)+"\" ";

    tmp+="/>\n";

    xml.nput(level, tmp.toLatin1().data());

    write_new_style_drummap(level, xml, "drummap", it->drummap);

    xml.etag(--level, "entry");
  }

  xml.etag(--level, "Drummaps");
}
Esempio n. 13
0
void InstrumentTemplate::write(Xml& xml) const
      {
      xml.stag("Instrument");
      foreach(StaffName sn, longNames)
            xml.tag(QString("longName pos=\"%1\"").arg(sn.pos), sn.name);
      foreach(StaffName sn, shortNames)
            xml.tag(QString("shortName pos=\"%1\"").arg(sn.pos), sn.name);
      xml.tag("description", trackName);
      xml.tag("extended", extended);
      if (tablature)
            tablature->write(xml);
      if (staves == 1) {
            xml.tag("clef", clefTable[clefIdx[0]].tag);
            if (staffLines[0] != 5)
                  xml.tag("stafflines", staffLines[0]);
            if (smallStaff[0])
                  xml.tag("smallStaff", smallStaff[0]);
            }
      else {
            xml.tag("staves", staves);
            for (int i = 0; i < staves; ++i) {
                  xml.tag(QString("clef staff=\"%1\"").arg(i), clefTable[clefIdx[i]].tag);
                  if (staffLines[i] != 5)
                        xml.tag(QString("stafflines staff=\"%1\"").arg(i), staffLines[i]);
                  if (smallStaff[i])
                        xml.tag(QString("smallStaff staff=\"%1\"").arg(i), smallStaff[i]);
                  xml.tag(QString("bracket staff=\"%1\"").arg(i), bracket[i]);
                  xml.tag(QString("bracketSpan staff=\"%1\"").arg(i), bracketSpan[i]);
                  xml.tag(QString("barlineSpan staff=\"%1\"").arg(i), barlineSpan[i]);
                  }
            }
      if (minPitchA != 0 || maxPitchA != 127)
            xml.tag("aPitchRange", QString("%1-%2").arg(minPitchA).arg(maxPitchA));
      if (minPitchP != 0 || maxPitchP != 127)
            xml.tag("pPitchRange", QString("%1-%2").arg(minPitchP).arg(maxPitchP));
      if (transpose.diatonic)
            xml.tag("transposeDiatonic", transpose.diatonic);
      if (transpose.chromatic)
            xml.tag("transposeChromatic", transpose.chromatic);
      if (useDrumset) {
            xml.tag("drumset", useDrumset);
            drumset->save(xml);
            }
      foreach(const NamedEventList& a, midiActions)
            a.write(xml, "MidiAction");
      foreach(const Channel& a, channel)
            a.write(xml);
      xml.etag();
      }
Esempio n. 14
0
void Hairpin::write(Xml& xml) const
      {
      if (!xml.canWrite(this))
            return;
      int id = xml.spannerId(this);
      xml.stag(QString("%1 id=\"%2\"").arg(name()).arg(id));
      xml.tag("subtype", int(_hairpinType));
      writeProperty(xml, P_ID::VELO_CHANGE);
      writeProperty(xml, P_ID::HAIRPIN_CIRCLEDTIP);
      writeProperty(xml, P_ID::DYNAMIC_RANGE);
      writeProperty(xml, P_ID::PLACEMENT);
      writeProperty(xml, P_ID::HAIRPIN_HEIGHT);
      writeProperty(xml, P_ID::HAIRPIN_CONT_HEIGHT);
      TextLine::writeProperties(xml);
      xml.etag();
      }
Esempio n. 15
0
void Articulation::write(Xml& xml) const
      {
      if (!xml.canWrite(this))
            return;
      xml.stag("Articulation");
      if (!_channelName.isEmpty())
            xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
      writeProperty(xml, P_ID::DIRECTION);
      xml.tag("subtype", Sym::id2name(_symId));
      writeProperty(xml, P_ID::TIME_STRETCH);
      writeProperty(xml, P_ID::PLAY);
      writeProperty(xml, P_ID::ORNAMENT_STYLE);
      Element::writeProperties(xml);
      writeProperty(xml, P_ID::ARTICULATION_ANCHOR);
      xml.etag();
      }
Esempio n. 16
0
void SLine::writeProperties(Xml& xml, const SLine* proto) const
      {
      Element::writeProperties(xml);
      if (_diagonal && (proto == 0 || proto->diagonal() != _diagonal))
            xml.tag("diagonal", _diagonal);
      if (anchor() != ANCHOR_SEGMENT && (proto == 0 || proto->anchor() != anchor()))
            xml.tag("anchor", anchor());
      if (score() == gscore) {
            // when used as icon
            if (!spannerSegments().isEmpty()) {
                  LineSegment* s = frontSegment();
                  xml.tag("length", s->pos2().x());
                  }
            else
                  xml.tag("length", spatium() * 4);
            return;
            }
      //
      // check if user has modified the default layout
      //
      bool modified = false;
      int n = spannerSegments().size();
      for (int i = 0; i < n; ++i) {
            const LineSegment* seg = segmentAt(i);
            if (!seg->userOff().isNull()
               || !seg->userOff2().isNull()
               || !seg->visible()) {
                  modified = true;
                  break;
                  }
            }
      if (!modified)
            return;

      //
      // write user modified layout
      //
      qreal _spatium = spatium();
      for (int i = 0; i < n; ++i) {
            const LineSegment* seg = segmentAt(i);
            xml.stag("Segment");
            xml.tag("subtype", seg->subtype());
            xml.tag("off2", seg->userOff2() / _spatium);
            seg->Element::writeProperties(xml);
            xml.etag();
            }
      }
Esempio n. 17
0
void Harmony::write(Xml& xml) const
      {
      if (!xml.canWrite(this)) return;
      xml.stag("Harmony");
      if (_leftParen)
            xml.tagE("leftParen");
      if (_rootTpc != Tpc::TPC_INVALID || _baseTpc != Tpc::TPC_INVALID) {
            int rRootTpc = _rootTpc;
            int rBaseTpc = _baseTpc;
            if (staff()) {
                  const Interval& interval = staff()->part()->instr()->transpose();
                  if (xml.clipboardmode && !score()->styleB(StyleIdx::concertPitch) && interval.chromatic) {
                        rRootTpc = transposeTpc(_rootTpc, interval, false);
                        rBaseTpc = transposeTpc(_baseTpc, interval, false);
                        }
                  }
            if (rRootTpc != Tpc::TPC_INVALID)
                  xml.tag("root", rRootTpc);
            if (_id > 0)
                  xml.tag("extension", _id);
            if (_textName != "")
                  xml.tag("name", _textName);
            if (rBaseTpc != Tpc::TPC_INVALID)
                  xml.tag("base", rBaseTpc);
            foreach(const HDegree& hd, _degreeList) {
                  HDegreeType tp = hd.type();
                  if (tp == HDegreeType::ADD || tp == HDegreeType::ALTER || tp == HDegreeType::SUBTRACT) {
                        xml.stag("degree");
                        xml.tag("degree-value", hd.value());
                        xml.tag("degree-alter", hd.alter());
                        switch (tp) {
                              case HDegreeType::ADD:
                                    xml.tag("degree-type", "add");
                                    break;
                              case HDegreeType::ALTER:
                                    xml.tag("degree-type", "alter");
                                    break;
                              case HDegreeType::SUBTRACT:
                                    xml.tag("degree-type", "subtract");
                                    break;
                              default:
                                    break;
                              }
                        xml.etag();
                        }
                  }
Esempio n. 18
0
void Text::writeProperties(Xml& xml, bool writeText) const
      {
      Element::writeProperties(xml);
      if (xml.clipboardmode || styled())
            xml.tag("style", textStyle().name());
      if (xml.clipboardmode || !styled())
            _textStyle.writeProperties(xml);
      if (writeText) {
            if (styled())
                  xml.tag("text", getText());
            else {
                  xml.stag("html-data");
                  xml.writeHtml(_doc->toHtml("utf-8"));
                  xml.etag();
                  }
            }
      }
Esempio n. 19
0
void Bracket::write(Xml& xml) const
      {
      switch(subtype()) {
            case BRACKET_AKKOLADE:
                  xml.stag("Bracket type=\"Akkolade\"");
                  break;
            case BRACKET_NORMAL:
                  xml.stag("Bracket");
                  break;
            case NO_BRACKET:
                  break;
            }
      if (_column)
            xml.tag("level", _column);
      Element::writeProperties(xml);
      xml.etag();
      }
Esempio n. 20
0
void Box::write(Xml& xml) const
      {
      xml.stag(name());
      writeProperty(xml, P_BOX_HEIGHT);
      writeProperty(xml, P_BOX_WIDTH);
      writeProperty(xml, P_TOP_GAP);
      writeProperty(xml, P_BOTTOM_GAP);
      writeProperty(xml, P_LEFT_MARGIN);
      writeProperty(xml, P_RIGHT_MARGIN);
      writeProperty(xml, P_TOP_MARGIN);
      writeProperty(xml, P_BOTTOM_MARGIN);

      Element::writeProperties(xml);
      foreach (const Element* el, _el)
            el->write(xml);
      xml.etag();
      }
Esempio n. 21
0
void Lyrics::write(Xml& xml) const
      {
      if (!xml.canWrite(this))
            return;
      xml.stag("Lyrics");
      if (_no)
            xml.tag("no", _no);
      if (_syllabic != Syllabic::SINGLE) {
            static const char* sl[] = {
                  "single", "begin", "end", "middle"
                  };
            xml.tag("syllabic", sl[int(_syllabic)]);
            }
      writeProperty(xml, P_ID::LYRIC_TICKS);

      Text::writeProperties(xml);
      xml.etag();
      }
Esempio n. 22
0
void Articulation::write(Xml& xml) const
      {
      if (!xml.canWrite(this))
            return;
      xml.stag("Articulation");
      if (!_channelName.isEmpty())
            xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
      writeProperty(xml, P_ID::DIRECTION);
      xml.tag("subtype", subtypeName());
      if (_timeStretch != 1.0)
            xml.tag("timeStretch", _timeStretch);
      writeProperty(xml, P_ID::PLAY_ARTICULATION);
      writeProperty(xml, P_ID::ORNAMENT_STYLE);
      Element::writeProperties(xml);
      if (anchorStyle == PropertyStyle::UNSTYLED)
            xml.tag("anchor", int(_anchor));
      xml.etag();
      }
Esempio n. 23
0
void Lyrics::write(Xml& xml) const
      {
      xml.stag("Lyrics");
      if (_no)
            xml.tag("no", _no);
      if (_syllabic != SINGLE) {
            static const char* sl[] = {
                  "single", "begin", "end", "middle"
                  };
            xml.tag("syllabic", sl[_syllabic]);
            }
      if (_ticks)
            xml.tag("ticks", _ticks);
      Text::writeProperties(xml);
      if (_verseNumber)
            _verseNumber->write(xml, "Number");
      xml.etag();
      }
Esempio n. 24
0
void StaffTypeTablature::write(Xml& xml, int idx) const
      {
      xml.stag(QString("StaffType idx=\"%1\" group=\"%2\"").arg(idx).arg(groupName()));
      StaffType::writeProperties(xml);
      xml.tag("durations",        _genDurations);
      xml.tag("durationFontName", _durationFontName);
      xml.tag("durationFontSize", _durationFontSize);
      xml.tag("durationFontY",    _durationFontUserY);
      xml.tag("fretFontName",     _fretFontName);
      xml.tag("fretFontSize",     _fretFontSize);
      xml.tag("fretFontY",        _fretFontUserY);
      xml.tag("linesThrough",     _linesThrough);
      xml.tag("onLines",          _onLines);
      xml.tag("timesig",          _genTimesig);
      xml.tag("upsideDown",       _upsideDown);
      xml.tag("useNumbers",       _useNumbers);
      xml.etag();
      }
Esempio n. 25
0
void StaffType::write(Xml& xml) const
      {
      xml.stag(QString("StaffType group=\"%1\"").arg(fileGroupNames[(int)_group]));
      if (!_xmlName.isEmpty())
            xml.tag("name", _xmlName);
      if (_lines != 5)
            xml.tag("lines", _lines);
      if (_lineDistance.val() != 1.0)
            xml.tag("lineDistance", _lineDistance.val());
      if (!_genClef)
            xml.tag("clef", _genClef);
      if (_slashStyle)
            xml.tag("slashStyle", _slashStyle);
      if (!_showBarlines)
            xml.tag("barlines", _showBarlines);
      if (!_genTimesig)
            xml.tag("timesig", _genTimesig);
      if (_group == StaffGroup::STANDARD || _group == StaffGroup::PERCUSSION) {
            if (!_genKeysig)
                  xml.tag("keysig", _genKeysig);
            if (!_showLedgerLines)
                  xml.tag("ledgerlines", _showLedgerLines);
            }
      else {
            xml.tag("durations",        _genDurations);
            xml.tag("durationFontName", _durationFonts[_durationFontIdx].displayName);
            xml.tag("durationFontSize", _durationFontSize);
            xml.tag("durationFontY",    _durationFontUserY);
            xml.tag("fretFontName",     _fretFonts[_fretFontIdx].displayName);
            xml.tag("fretFontSize",     _fretFontSize);
            xml.tag("fretFontY",        _fretFontUserY);
            if (_symRepeat != TablatureSymbolRepeat::NEVER)
                  xml.tag("symbolRepeat",     int(_symRepeat));
            xml.tag("linesThrough",     _linesThrough);
            xml.tag("minimStyle",       int(_minimStyle));
            xml.tag("onLines",          _onLines);
            xml.tag("showRests",        _showRests);
            xml.tag("stemsDown",        _stemsDown);
            xml.tag("stemsThrough",     _stemsThrough);
            xml.tag("upsideDown",       _upsideDown);
            xml.tag("useNumbers",       _useNumbers);
            }
      xml.etag();
      }
Esempio n. 26
0
void Box::write(Xml& xml) const
{
    xml.stag(name());

    for (int i = 0;; ++i) {
        const Property<Box>& p = propertyList[i];
        P_ID id = p.id;
        if (id == P_END)
            break;
        QVariant val        = getVariant(id, ((*(Box*)this).*(p.data))());
        QVariant defaultVal = getVariant(id, p.defaultVal);
        if (val != defaultVal)
            xml.tag(propertyName(id), val);
    }

    Element::writeProperties(xml);
    foreach (const Element* el, _el)
        el->write(xml);
    xml.etag();
}
Esempio n. 27
0
void Bracket::write(Xml& xml) const
      {
      switch(bracketType()) {
            case BRACKET_BRACE:
                  xml.stag("Bracket type=\"Brace\"");
                  break;
            case BRACKET_NORMAL:
                  xml.stag("Bracket");
                  break;
            case BRACKET_SQUARE:
                  xml.stag("Bracket type=\"Square\"");
                  break;
            case NO_BRACKET:
                  break;
            }
      if (_column)
            xml.tag("level", _column);
      Element::writeProperties(xml);
      xml.etag();
      }
Esempio n. 28
0
void StaffTypeTablature::write(Xml& xml, int idx) const
      {
      xml.stag(QString("StaffType idx=\"%1\" group=\"%2\"").arg(idx).arg(groupName()));
      StaffType::writeProperties(xml);
      xml.tag("durations",          _genDurations);
      xml.tag("durationFontName",   _durationFonts[_durationFontIdx].displayName);
      xml.tag("durationFontSize",   _durationFontSize);
      xml.tag("durationFontY",      _durationFontUserY);
      xml.tag("fretFontName",       _fretFonts[_fretFontIdx].displayName);
      xml.tag("fretFontSize",       _fretFontSize);
      xml.tag("fretFontY",          _fretFontUserY);
      xml.tag("linesThrough",       _linesThrough);
      xml.tag("minimStyle",         _minimStyle);
      xml.tag("onLines",            _onLines);
      xml.tag("showRests",          _showRests);
      xml.tag("stemsDown",          _stemsDown);
      xml.tag("stemsThrough",       _stemsThrough);
      xml.tag("upsideDown",         _upsideDown);
      xml.tag("useNumbers",         _useNumbers);
      xml.etag();
      }
Esempio n. 29
0
void Articulation::write(Xml& xml) const
      {
      xml.stag("Articulation");
      if (!_channelName.isEmpty())
            xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
      switch(_direction) {
            case MScore::UP:
                  xml.tag("direction", QVariant("up"));
                  break;
            case MScore::DOWN:
                  xml.tag("direction", QVariant("down"));
                  break;
            case MScore::AUTO:
                  break;
            }
      xml.tag("subtype", subtypeName());
      Element::writeProperties(xml);
      if (_anchor != score()->style()->articulationAnchor(subtype()))
            xml.tag("anchor", int(_anchor));
      xml.etag();
      }
Esempio n. 30
0
void MidiAudioCtrlMap::write(int level, Xml& xml) const
{
  for(ciMidiAudioCtrlMap imacm = begin(); imacm != end();  ++imacm)
  {
      int port, chan, mctrl;
      hash_values(imacm->first, &port, &chan, &mctrl);
      int actrl = imacm->second.audioCtrlId();
      QString s= QString("midiMapper port=\"%1\" ch=\"%2\" mctrl=\"%3\" actrl=\"%4\"")
                          .arg(port)
                          .arg(chan)
                          .arg(mctrl)
                          .arg(actrl);
      xml.tag(level++, s.toAscii().constData());
      
      // TODO
      //const MidiAudioCtrlStruct& macs = imacs->second;
      //xml.intTag(level, "macs ???", macs.);
      
      xml.etag(level--, "midiMapper");
  }
}