예제 #1
0
bool ZInstrument::loadSfz(const QString& s)
      {
      _program = 0;
      QFile f(s);
      if (!f.open(QIODevice::ReadOnly)) {
            qDebug("ZInstrument: cannot load %s", qPrintable(s));
            return false;
            }
      QFileInfo fi(f);
      QString path = fi.absolutePath();
      qint64 total = fi.size();

      QString sample;

      SfzRegion r;
      SfzRegion g;      // group
      r.init(path);
      g.init(path);

      bool groupMode = false;
      zerberus->setLoadProgress(0);

      while (!f.atEnd()) {
            QByteArray ba = f.readLine();
            zerberus->setLoadProgress(((qreal)f.pos() * 100) / total);
            ba = ba.simplified();

            if (ba.isEmpty() || ba.startsWith("//"))
                  continue;
            if (zerberus->loadWasCanceled())
                  return false;
            if (ba.startsWith("<group>")) {
                  if (!groupMode && !r.isEmpty())
                        addRegion(r);
                  g.init(path);
                  r.init(path);
                  groupMode = true;
                  ba = ba.mid(7);
                  }
            else if (ba.startsWith("<region>")) {
                  if (groupMode) {
                        g = r;
                        groupMode = false;
                        }
                  else {
                        if (!r.isEmpty())
                              addRegion(r);
                        r = g;  // initialize next region with group values
                        }
                  ba = ba.mid(8);
                  }
            QRegularExpression re("\\s?(\\w+)=");
            QRegularExpressionMatchIterator i = re.globalMatch(ba);

            while (i.hasNext()) {
                  QRegularExpressionMatch match = i.next();
                  int si = match.capturedEnd();
                  int ei;
                  if (i.hasNext()) {
                        QRegularExpressionMatch nextMatch = i.peekNext();
                        ei = nextMatch.capturedStart();
                        }
                  else
                        ei = ba.size();
                  QString s = ba.mid(si, ei-si);
                  r.readOp(match.captured(1), s);
                  }
            }
      zerberus->setLoadProgress(100);
      if (!groupMode && !r.isEmpty())
            addRegion(r);
      return true;
      }
예제 #2
0
bool ZInstrument::loadSfz(const QString& s)
      {
      _program = 0;
      QFileInfo fi(s);
      QString path = fi.absolutePath();

      QStringList fileContents = readFile(s);

      if (fileContents.empty()) {
            return false;
            }

      SfzControl c;
      c.init();
      c.defines.clear();
      for (int i = 0;i < 128; i++)
            c.set_cc[i] = -1;

      int idx = 0;
      bool inBlockComment = false;
      // preprocessor
      while(idx < fileContents.size()) {
            QRegularExpression findWithSpaces("\"(.+)\"");
            QRegularExpression comment("//.*$");
            QRegularExpression trailingSpacesOrTab("^[\\s\\t]*");
            QRegularExpressionMatch foundWithSpaces;
            QString curLine = fileContents[idx];
            QString curLineCopy = curLine;
            bool nextIsImportant = false;
            int idxBlockComment = 0;
            int from = 0;

            for (QChar chr : curLineCopy) {
                  bool terminated = false;

                  if (nextIsImportant) {
                        nextIsImportant = false;
                        if (inBlockComment && chr == '/') { // found block end
                              inBlockComment = false;
                              terminated = true;
                              curLine.remove(from, idxBlockComment - from + 1);
                              idxBlockComment = from - 1;
                              }
                        else if (!inBlockComment && chr == '*') { // found block start
                              inBlockComment = true;
                              terminated = true;
                              from = idxBlockComment - 1;
                              }
                        }

                  if (!terminated && inBlockComment && chr == '*')
                        nextIsImportant = true;
                  else if (!terminated && !inBlockComment && chr == '/')
                        nextIsImportant = true;

                  idxBlockComment++;
                  }

            if (inBlockComment)
                  curLine.remove(from, curLine.size() - from);

            curLine = curLine.remove(comment);
            curLine.remove(trailingSpacesOrTab);
            fileContents[idx] = curLine;

            if (curLine.startsWith("#define")) {
                  QStringList define = curLine.split(" ");
                  foundWithSpaces = findWithSpaces.match(curLine);
                  if (define.size() == 3)
                        c.defines.insert(std::pair<QString, QString>(define[1], define[2]));
                  else if(foundWithSpaces.hasMatch())
                        c.defines.insert(std::pair<QString, QString>(define[1], foundWithSpaces.captured(1)));
                  fileContents.removeAt(idx);
                  }
            else if (curLine.startsWith("#include")) {
                  foundWithSpaces = findWithSpaces.match(curLine);
                  if (foundWithSpaces.hasMatch()) {
                        QString newFilename = foundWithSpaces.captured(1);

                        for(auto define : c.defines) {
                              newFilename.replace(define.first, define.second);
                              }

                        QStringList newFileContents = readFile(path + "/" + newFilename);
                        if (newFileContents.empty())
                              return false;

                        int offset = 1;
                        for (QString newFileLine : newFileContents) {
                              fileContents.insert(idx+offset, newFileLine);
                              offset++;
                              }

                        fileContents.removeAt(idx);
                        }
                  }
            else if (curLine.isEmpty())
                  fileContents.removeAt(idx);
            else
                  idx++;
            }

      int total = fileContents.size();
      SfzRegion r;
      SfzRegion g;      // group
      SfzRegion glob;
      r.init(path);
      g.init(path);
      glob.init(path);

      bool groupMode = false;
      bool globMode = false;
      zerberus->setLoadProgress(0);

      for (int idx = 0; idx < fileContents.size(); idx++) {
            QString curLine = fileContents[idx];
            zerberus->setLoadProgress(((qreal) idx * 100) /  (qreal) total);

            if (zerberus->loadWasCanceled())
                  return false;
            if (curLine.startsWith("<global>")) {
                  if (!globMode && !groupMode && !r.isEmpty())
                        addRegion(r);
                  glob.init(path);
                  g.init(path); // global also resets group
                  r.init(path);
                  globMode = true;
                  }
            if (curLine.startsWith("<group>")) {
                  if (!groupMode && !globMode && !r.isEmpty())
                        addRegion(r);
                  g.init(path);
                  if (globMode) {
                        glob = r;
                        globMode = false;
                        }
                  else {
                        r = glob; // initialize group with global values
                        }
                  groupMode = true;
                  curLine = curLine.mid(7);
                  }
            else if (curLine.startsWith("<region>")) {
                  if (groupMode) {
                        g = r;
                        groupMode = false;
                        }
                  else if (globMode) {
                        glob = r;
                        g = glob;
                        globMode = false;
                        }
                  else {
                        if (!r.isEmpty())
                              addRegion(r);
                        r = g;  // initialize next region with group values
                        }
                  curLine = curLine.mid(8);
                  }
            else if (curLine.startsWith("<control>"))
                  c.init();

            QRegularExpression re("\\s?([\\w\\$]+)="); // defines often use the $-sign
            QRegularExpressionMatchIterator i = re.globalMatch(curLine);

            while (i.hasNext()) {
                  QRegularExpressionMatch match = i.next();
                  int si = match.capturedEnd();
                  int ei;
                  if (i.hasNext()) {
                        QRegularExpressionMatch nextMatch = i.peekNext();
                        ei = nextMatch.capturedStart();
                        }
                  else
                        ei = curLine.size();
                  QString s = curLine.mid(si, ei-si);
                  r.readOp(match.captured(1), s, c);
                  }
            }

      for (int i = 0; i < 128; i++)
            _setcc[i] = c.set_cc[i];

      zerberus->setLoadProgress(100);
      if (!groupMode && !globMode && !r.isEmpty())
            addRegion(r);
      return true;
      }