static QPair<int, QString> readMidiPortPreset(Xml& xml)/*{{{*/ { int id = 0; QString sysex; for (;;) { Xml::Token token = xml.parse(); QString tag = xml.s1(); switch (token) { case Xml::TagStart: xml.unknown("midiPreset"); break; case Xml::Attribut: if (tag == "id") id = xml.s2().toInt(); else if (tag == "sysex") { sysex = xml.s2(); } break; case Xml::TagEnd: return qMakePair(id, sysex); default: break; } } }/*}}}*/
void PosLen::read(Xml& xml, const char* name) { sn = -1; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown(name); break; case Xml::Attribut: if (tag == "tick") { setType(TICKS); setTick(xml.s2().toInt()); } else if (tag == "sample") { setType(FRAMES); setFrame(xml.s2().toInt()); } else if (tag == "len") { int n = xml.s2().toInt(); switch (type()) { case TICKS: setLenTick(n); break; case FRAMES: setLenFrame(n); break; } } else xml.unknown(name); break; case Xml::TagEnd: if (tag == name) return; default: break; } } }
QColor readColor(Xml& xml) { int val, r = 0, g = 0, b = 0; for (;;) { Xml::Token token = xml.parse(); if (token != Xml::Attribut) break; QString tag = xml.s1(); switch (token) { case Xml::Attribut: val = xml.s2().toInt(); if (tag == "r") r = val; else if (tag == "g") g = val; else if (tag == "b") b = val; break; default: break; } } return QColor(r, g, b); }
int SigEvent::read(Xml& xml) { int at = 0; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return 0; case Xml::TagStart: if (tag == "tick") tick = xml.parseInt(); else if (tag == "nom") z = xml.parseInt(); else if (tag == "denom") n = xml.parseInt(); else xml.unknown("SigEvent"); break; case Xml::Attribut: if (tag == "at") at = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "sig") return at; default: break; } } return 0; }
void PatchGroup::read(Xml& xml) { for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "Patch") { Patch* patch = new Patch; patch->read(xml); patches.push_back(patch); } else xml.unknown("PatchGroup"); break; case Xml::Attribut: if (tag == "name") name = xml.s2(); break; case Xml::TagEnd: if (tag == "PatchGroup") return; default: break; } } }
int TEvent::read(Xml& xml) { int at = 0; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return 0; case Xml::TagStart: if (tag == "tick") tick = xml.parseInt(); else if (tag == "val") tempo = xml.parseInt(); else xml.unknown("TEvent"); break; case Xml::Attribut: if (tag == "at") at = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "tempo") { return at; } default: break; } } return 0; }
static void readPortChannel(Xml& xml, int midiPort) { int idx = 0; //torbenh for (;;) { Xml::Token token = xml.parse(); if (token == Xml::Error || token == Xml::End) break; QString tag = xml.s1(); switch (token) { case Xml::TagStart: if (tag == "controller") { readController(xml, midiPort, idx); } else xml.skip(tag); break; case Xml::Attribut: if (tag == "idx") idx = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "channel") return; default: break; } } }
void AudioTrack::readAuxSend(Xml& xml) { qint64 idx; double val; bool pre = true; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: { if (tag == "idx") {//Backwards compatible idx = xml.s2().toLongLong(); gUpdateAuxes = true; } else if(tag == "trackId") {//New style trackId based idx = xml.s2().toLongLong(); } else if(tag == "pre") { pre = xml.s2().toInt(); } break; } case Xml::Text: val = tag.toDouble(); break; case Xml::TagEnd: if (xml.s1() == "auxSend") { AuxInfo info(pre, val); _auxSend[idx] = info; return; } default: break; } } }
void Pos::read(Xml& xml, const char* name) { sn = -1; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown(name); break; case Xml::Attribut: if (tag == "tick") { _tick = xml.s2().toInt(); _type = TICKS; } else if (tag == "frame") { _frame = xml.s2().toInt(); _type = FRAMES; } else if (tag == "sample") { // obsolete _frame = xml.s2().toInt(); _type = FRAMES; } else xml.unknown(name); break; case Xml::TagEnd: if (tag == name) return; default: break; } } }
void MidiEventBase::read(Xml& xml) { setType(Note); a = 0; b = 0; c = 0; int dataLen = 0; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown("Event"); break; case Xml::Text: { QByteArray ba = tag.toLatin1(); const char*s = ba.constData(); edata.data = new unsigned char[dataLen]; edata.dataLen = dataLen; unsigned char* d = edata.data; for (int i = 0; i < dataLen; ++i) { char* endp; *d++ = strtol(s, &endp, 16); s = endp; } } break; case Xml::Attribut: if (tag == "tick") setTick(xml.s2().toInt()); else if (tag == "type") setType(EventType(xml.s2().toInt())); else if (tag == "len") setLenTick(xml.s2().toInt()); else if (tag == "a") a = xml.s2().toInt(); else if (tag == "b") b = xml.s2().toInt(); else if (tag == "c") c = xml.s2().toInt(); else if (tag == "datalen") dataLen = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "event") return; default: break; } } }
patch_collection_t MidiInstrument::readDrummapsEntryPatchCollection(Xml& xml) { int first_prog=0, last_prog=256; // this means: int first_lbank=0, last_lbank=256; // "does not matter" int first_hbank=0, last_hbank=256; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return patch_collection_t(-1,-1,-1,-1,-1,-1); // an invalid collection case Xml::TagStart: xml.unknown("MidiInstrument::readDrummapsEntryPatchCollection"); break; case Xml::Attribut: if (tag == "prog") parse_range(xml.s2(), &first_prog, &last_prog); else if (tag == "lbank") parse_range(xml.s2(), &first_lbank, &last_lbank); else if (tag == "hbank") parse_range(xml.s2(), &first_hbank, &last_hbank); break; case Xml::TagEnd: if (tag == "patch_collection") return patch_collection_t(first_prog, last_prog, first_lbank, last_lbank, first_hbank, last_hbank); default: break; } } printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummapsEntryPatchCollection()!\n" " not returning anything. expect undefined behaviour or even crashes.\n"); }
void KeyMap::read(Xml& xml)/*{{{*/ { program = -1; pname = ""; comment = ""; key = -1; hasProgram = false; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown("KeyMap"); break; case Xml::Attribut: if (tag == "comment") comment = xml.s2(); else if (tag == "program") program = xml.s2().toInt(); else if (tag == "key") key = xml.s2().toInt(); else if (tag == "pname") pname = xml.s2(); else if(tag == "hasProgram") hasProgram = (bool)xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "KeyMap") return; default: break; } } }/*}}}*/
void readGlobalInput(Xml& xml)/*{{{*/ { QString name; int type; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: break; case Xml::Attribut: if(tag == "deviceType") { type = xml.s2().toInt(); } else if(tag == "deviceName") { name = xml.s2(); } break; case Xml::TagEnd: if(tag == "globalInput") { if(debugMsg) qDebug("readGlobalInput: Adding My Input to list: Type: %d, Name: %s", type, name.toUtf8().constData()); gInputList.append(qMakePair(type, name)); return; } default: break; } } }/*}}}*/
bool SysEx::read(Xml& xml) { for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return false; case Xml::TagStart: if (tag == "comment") comment = xml.parse1(); else if (tag == "data") { unsigned char*d; int len = string2sysex(xml.parse1(), &d); // Was the conversion succesful, even if empty? if(len != -1) { // Delete existing. if(dataLen != 0 && data) delete[] data; dataLen = len; data = d; } } else xml.unknown("SysEx"); break; case Xml::Attribut: if (tag == "name") name = xml.s2(); break; case Xml::TagEnd: if (tag == "SysEx") { return !name.isEmpty(); } default: break; } } return false; }
void TempoList::read(Xml& xml) { for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "tempo") { TEvent* t = new TEvent(); unsigned tick = t->read(xml); iTEvent pos = find(tick); if (pos != end()) erase(pos); insert(std::pair<const int, TEvent*> (tick, t)); } else if (tag == "globalTempo") _globalTempo = xml.parseInt(); else xml.unknown("TempoList"); break; case Xml::Attribut: if (tag == "fix") _tempo = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "tempolist") { normalize(); ++_tempoSN; return; } default: break; } } }
void MidiInstrument::readMidiState(Xml& xml) { // A kludge to support old midistates by wrapping them in the proper header. _tmpMidiStateVersion = 1; // Assume old (unmarked) first version 1. for (;;) { Xml::Token token = xml.parse(); const QString tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "event") { Event e(Note); e.read(xml); _midiState->add(e); } else xml.unknown("midistate"); break; case Xml::Attribut: if(tag == "version") _tmpMidiStateVersion = xml.s2().toInt(); else xml.unknown("MidiInstrument"); break; case Xml::TagEnd: if(tag == "midistate") return; default: break; } } }
QRect readGeometry(Xml& xml, const QString& name) { QRect r(0, 0, 50, 50); int val; for (;;) { Xml::Token token = xml.parse(); if (token == Xml::Error || token == Xml::End) break; QString tag = xml.s1(); switch (token) { case Xml::TagStart: xml.parse1(); break; case Xml::Attribut: val = xml.s2().toInt(); if (tag == "x") r.setX(val); else if (tag == "y") r.setY(val); else if (tag == "w") r.setWidth(val); else if (tag == "h") r.setHeight(val); break; case Xml::TagEnd: if (tag == name) return r; default: break; } } return r; }
static void readController(Xml& xml, int midiPort, int channel) { int id = 0; int val = CTRL_VAL_UNKNOWN; for (;;) { Xml::Token token = xml.parse(); QString tag = xml.s1(); switch (token) { case Xml::TagStart: if (tag == "val") val = xml.parseInt(); else xml.skip(tag); break; case Xml::Attribut: if (tag == "id") id = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "controller") { MidiPort* port = &midiPorts[midiPort]; //port->addManagedController(channel, id); val = port->limitValToInstrCtlRange(id, val); // The value here will actually be sent to the device LATER, in MidiPort::setMidiDevice() port->setHwCtrlState(channel, id, val); return; } default: return; } } }
void Patch::read(Xml& xml) { //typ = -1; hbank = -1; lbank = -1; prog = 0; drum = false; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown("Patch"); break; case Xml::Attribut: if (tag == "name") name = xml.s2(); else if (tag == "mode") // Obsolete { //typ = xml.s2().toInt(); xml.s2().toInt(); } else if (tag == "hbank") hbank = xml.s2().toInt(); else if (tag == "lbank") lbank = xml.s2().toInt(); else if (tag == "prog") prog = xml.s2().toInt(); else if (tag == "drum") drum = xml.s2().toInt(); break; case Xml::TagEnd: if (tag == "Patch") return; default: break; } } }
void CtrlList::read(Xml& xml) { QLocale loc = QLocale::c(); bool ok; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: if (tag == "id") { _id = loc.toInt(xml.s2(), &ok); if (!ok) { printf("CtrlList::read failed reading _id string: %s\n", xml.s2().toLatin1().constData()); initColor(0); //Set the default color if we have an error } else { initColor(_id); } } else if (tag == "cur") { _curVal = loc.toDouble(xml.s2(), &ok); if (!ok) printf("CtrlList::read failed reading _curVal string: %s\n", xml.s2().toLatin1().constData()); } else if(tag == "visible") { _visible = (bool)xml.s2().toInt(); } else if(tag == "color") { ;//xml.skip(tag); } else printf("unknown tag %s\n", tag.toLatin1().constData()); break; case Xml::Text: { int len = tag.length(); int frame; double val; int i = 0; for (;;) { while (i < len && (tag[i] == ',' || tag[i] == ' ' || tag[i] == '\n')) ++i; if (i == len) break; QString fs; while (i < len && tag[i] != ' ') { fs.append(tag[i]); ++i; } if (i == len) break; // Works OK, but only because if current locale fails it falls back on 'C' locale. // So, let's skip the fallback and force use of 'C' locale. frame = loc.toInt(fs, &ok); if (!ok) { printf("CtrlList::read failed reading frame string: %s\n", fs.toLatin1().constData()); break; } while (i < len && (tag[i] == ' ' || tag[i] == '\n')) ++i; if (i == len) break; QString vs; while (i < len && tag[i] != ' ' && tag[i] != ',') { vs.append(tag[i]); ++i; } // Works OK, but only because if current locale fails it falls back on 'C' locale. // So, let's skip the fallback and force use of 'C' locale. //val = vs.toDouble(&ok); val = loc.toDouble(vs, &ok); if (!ok) { printf("CtrlList::read failed reading value string: %s\n", vs.toLatin1().constData()); break; } //printf("CtrlList::read i:%d len:%d fs:%s frame %d: vs:%s val %f \n", i, len, fs.toLatin1().constData(), frame, vs.toLatin1().constData(), val); add(frame, val); if (i == len) break; } } break; case Xml::TagEnd: if (xml.s1() == "controller") { return; } default: break; } } }
void MidiController::read(Xml& xml) { ControllerType t = Controller7; _initVal = CTRL_VAL_UNKNOWN; static const int NOT_SET = 0x100000; _minVal = NOT_SET; _maxVal = NOT_SET; int h = 0; int l = 0; bool ok; int base = 10; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: { QString s = xml.s2(); if (s.left(2) == "0x") base = 16; if (tag == "name") _name = xml.s2(); else if (tag == "type") t = ctrlType2Int(xml.s2()); else if (tag == "h") h = xml.s2().toInt(&ok, base); else if (tag == "l") { // Support instrument files with '*' or 'pitch' as wildcard. if ((xml.s2() == "*") || (xml.s2() == "pitch")) l = 0xff; else l = xml.s2().toInt(&ok, base); } else if (tag == "min") _minVal = xml.s2().toInt(&ok, base); else if (tag == "max") _maxVal = xml.s2().toInt(&ok, base); else if (tag == "init") _initVal = xml.s2().toInt(&ok, base); else if (tag == "showType") _showInTracks = xml.s2().toInt(&ok, base); } break; case Xml::TagStart: xml.unknown("MidiController"); break; case Xml::TagEnd: if (tag == "Controller") { _num = (h << 8) + l; switch (t) { case RPN: if (_maxVal == NOT_SET) _maxVal = 127; _num |= CTRL_RPN_OFFSET; break; case NRPN: if (_maxVal == NOT_SET) _maxVal = 127; _num |= CTRL_NRPN_OFFSET; break; case Controller7: if (_maxVal == NOT_SET) _maxVal = 127; break; case Controller14: _num |= CTRL_14_OFFSET; if (_maxVal == NOT_SET) _maxVal = 16383; break; case RPN14: if (_maxVal == NOT_SET) _maxVal = 16383; _num |= CTRL_RPN14_OFFSET; break; case NRPN14: if (_maxVal == NOT_SET) _maxVal = 16383; _num |= CTRL_NRPN14_OFFSET; break; case Pitch: if (_maxVal == NOT_SET) _maxVal = 8191; if (_minVal == NOT_SET) _minVal = -8192; _num = CTRL_PITCH; break; case Program: if (_maxVal == NOT_SET) _maxVal = 0xffffff; _num = CTRL_PROGRAM; break; case PolyAftertouch: if (_maxVal == NOT_SET) _maxVal = 127; if (_minVal == NOT_SET) _minVal = 0; _num = CTRL_POLYAFTER; break; case Aftertouch: if (_maxVal == NOT_SET) _maxVal = 127; if (_minVal == NOT_SET) _minVal = 0; _num = CTRL_AFTERTOUCH; break; case Velo: // cannot happen break; } if (_minVal == NOT_SET) _minVal = 0; updateBias(); return; } default: break; } } }
void MidiAudioCtrlMap::read(Xml& xml) { int port = -1, chan = -1, midi_ctrl = -1; MidiAudioCtrlStruct macs(-1); QLocale loc = QLocale::c(); bool ok; int errcount = 0; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: if (tag == "port") { port = loc.toInt(xml.s2(), &ok); if(!ok) { ++errcount; printf("MidiAudioCtrlPortMap::read failed reading port string: %s\n", xml.s2().toLatin1().constData()); } } else if (tag == "ch") { chan = loc.toInt(xml.s2(), &ok); if(!ok) { ++errcount; printf("MidiAudioCtrlPortMap::read failed reading ch string: %s\n", xml.s2().toLatin1().constData()); } } else if (tag == "mctrl") { midi_ctrl = loc.toInt(xml.s2(), &ok); if(!ok) { ++errcount; printf("MidiAudioCtrlPortMap::read failed reading mctrl string: %s\n", xml.s2().toLatin1().constData()); } } else if (tag == "actrl") { macs.setAudioCtrlId(loc.toInt(xml.s2(), &ok)); if(!ok) { ++errcount; printf("MidiAudioCtrlPortMap::read failed reading actrl string: %s\n", xml.s2().toLatin1().constData()); } } else printf("unknown tag %s\n", tag.toLatin1().constData()); break; case Xml::TagStart: // TODO //if (tag == "???") { // } //else xml.unknown("midiMapper"); break; case Xml::TagEnd: if (xml.s1() == "midiMapper") { if(errcount == 0 && port != -1 && chan != -1 && midi_ctrl != -1 && macs.audioCtrlId() != -1) add_ctrl_struct(port, chan, midi_ctrl, macs); return; } default: break; } } }
void CtrlList::read(Xml& xml) { QLocale loc = QLocale::c(); bool ok; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: if (tag == "id") { _id = loc.toInt(xml.s2(), &ok); if(!ok) printf("CtrlList::read failed reading _id string: %s\n", xml.s2().toLatin1().constData()); } else if (tag == "cur") { _curVal = loc.toDouble(xml.s2(), &ok); if(!ok) printf("CtrlList::read failed reading _curVal string: %s\n", xml.s2().toLatin1().constData()); } else if (tag == "visible") { _visible = loc.toInt(xml.s2(), &ok); if(!ok) printf("CtrlList::read failed reading _visible string: %s\n", xml.s2().toLatin1().constData()); } else if (tag == "color") { #if QT_VERSION >= 0x040700 ok = _displayColor.isValidColor(xml.s2()); if (!ok) { printf("CtrlList::read failed reading color string: %s\n", xml.s2().toLatin1().constData()); break; } #endif _displayColor.setNamedColor(xml.s2()); } else printf("unknown tag %s\n", tag.toLatin1().constData()); break; case Xml::Text: { int len = tag.length(); int frame; double val; int i = 0; for(;;) { while(i < len && (tag[i] == ',' || tag[i] == ' ' || tag[i] == '\n')) ++i; if(i == len) break; QString fs; while(i < len && tag[i] != ' ') { fs.append(tag[i]); ++i; } if(i == len) break; frame = loc.toInt(fs, &ok); if(!ok) { printf("CtrlList::read failed reading frame string: %s\n", fs.toLatin1().constData()); break; } while(i < len && (tag[i] == ' ' || tag[i] == '\n')) ++i; if(i == len) break; QString vs; while(i < len && tag[i] != ' ' && tag[i] != ',') { vs.append(tag[i]); ++i; } val = loc.toDouble(vs, &ok); if(!ok) { printf("CtrlList::read failed reading value string: %s\n", vs.toLatin1().constData()); break; } add(frame, val); if(i == len) break; } } break; case Xml::TagEnd: if (xml.s1() == "controller") return; default: break; } } }
void Song::readRoute(Xml& xml)/*{{{*/ { QString src; QString dst; int ch = -1; int chs = -1; int remch = -1; Route sroute, droute; for (;;) { const QString& tag = xml.s1(); Xml::Token token = xml.parse(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "source") { sroute.read(xml); sroute.channel = ch; sroute.channels = chs; sroute.remoteChannel = remch; } else if (tag == "dest") { droute.read(xml); droute.channel = ch; droute.channels = chs; droute.remoteChannel = remch; } else xml.unknown("readRoute"); break; case Xml::Attribut: #ifdef ROUTE_DEBUG printf("Song::readRoute(): attribute:%s\n", tag.toLatin1().constData()); #endif if (tag == "channel") ch = xml.s2().toInt(); else if (tag == "channels") chs = xml.s2().toInt(); else if (tag == "remch") remch = xml.s2().toInt(); else if (tag == "channelMask") // p3.3.50 New channel mask for midi port-track routes. ch = xml.s2().toInt(); else printf("Song::readRoute(): unknown attribute:%s\n", tag.toLatin1().constData()); break; case Xml::TagEnd: if (xml.s1() == "Route") { if (sroute.isValid() && droute.isValid())// Support new routes. { // p3.3.49 Support pre- 1.1-RC2 midi-device-to-track routes. Obsolete. Replaced with midi port routes. if (sroute.type == Route::MIDI_DEVICE_ROUTE && droute.type == Route::TRACK_ROUTE) { if (sroute.device->midiPort() >= 0 && sroute.device->midiPort() < MIDI_PORTS && ch >= 0 && ch < MIDI_CHANNELS) { sroute.midiPort = sroute.device->midiPort(); sroute.device = 0; sroute.type = Route::MIDI_PORT_ROUTE; sroute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask. droute.channel = sroute.channel; addRoute(sroute, droute); } else printf(" Warning - device:%s to track route, no device midi port or chan:%d out of range. Ignoring route!\n", sroute.device->name().toLatin1().constData(), ch); } else if (sroute.type == Route::TRACK_ROUTE && droute.type == Route::MIDI_DEVICE_ROUTE) { if (droute.device->midiPort() >= 0 && droute.device->midiPort() < MIDI_PORTS && ch >= 0 && ch < MIDI_CHANNELS) // p3.3.50 { droute.midiPort = droute.device->midiPort(); droute.device = 0; droute.type = Route::MIDI_PORT_ROUTE; droute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask. sroute.channel = droute.channel; addRoute(sroute, droute); } else printf(" Warning - track to device:%s route, no device midi port or chan:%d out of range. Ignoring route!\n", droute.device->name().toLatin1().constData(), ch); } else { //printf("adding new route...\n"); addRoute(sroute, droute); } } else printf(" Warning - route invalid. Ignoring route! srcValid: %d, destValid: %d\n", sroute.isValid(), droute.isValid()); return; } default: break; } } }/*}}}*/
void Patch::read(Xml& xml)/*{{{*/ { typ = -1; hbank = -1; lbank = -1; prog = 0; drum = false; keys.clear(); keyswitches.clear(); loadmode = -1; index = -1; volume = 1.0; for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: xml.unknown("Patch"); break; case Xml::Attribut: if (tag == "name") name = xml.s2(); else if (tag == "mode") typ = xml.s2().toInt(); else if (tag == "hbank") hbank = xml.s2().toInt(); else if (tag == "lbank") lbank = xml.s2().toInt(); else if (tag == "prog") prog = xml.s2().toInt(); else if (tag == "drum") drum = xml.s2().toInt(); else if(tag == "keys") { QStringList klist = ((QString)xml.s2()).split(QString(" "), QString::SkipEmptyParts); for (QStringList::Iterator it = klist.begin(); it != klist.end(); ++it) { int val = (*it).toInt(); keys.append(val); } } else if(tag == "keyswitches") { QStringList klist = ((QString)xml.s2()).split(QString(" "), QString::SkipEmptyParts); for (QStringList::Iterator it = klist.begin(); it != klist.end(); ++it) { int val = (*it).toInt(); keyswitches.append(val); } } else if(tag == "comments") { QStringList clist = ((QString)xml.s2()).split(QString(" "), QString::SkipEmptyParts); for (QStringList::Iterator it = clist.begin(); it != clist.end(); ++it) { QStringList hashlist = ((*it)).split(QString("@@:@@"), QString::SkipEmptyParts); if(hashlist.size() == 2) { int k = hashlist.at(0).toInt(); comments[k] = hashlist.at(1); } } } else if(tag == "engine") { engine = xml.s2(); } else if(tag == "filename") { filename = xml.s2(); } else if(tag == "loadmode") { loadmode = xml.s2().toInt(); } else if(tag == "volume") { volume = xml.s2().toFloat(); } else if(tag == "index") { index = xml.s2().toInt(); } break; case Xml::TagEnd: if (tag == "Patch") return; default: break; } } }/*}}}*/
void MidiInstrument::read(Xml& xml) { bool ok; int base = 10; _nullvalue = -1; m_keymaps.clear(); for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "Patch") { Patch* patch = new Patch; patch->read(xml); if (pg.empty()) { PatchGroup* p = new PatchGroup; p->patches.push_back(patch); pg.push_back(p); } else pg[0]->patches.push_back(patch); } else if (tag == "PatchGroup") { PatchGroup* p = new PatchGroup; p->read(xml); pg.push_back(p); } else if (tag == "Controller") { MidiController* mc = new MidiController(); mc->read(xml); // Added by Tim. Copied from los 2. // // HACK: make predefined "Program" controller overloadable // if (mc->name() == "Program") { for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) { if (i->second->name() == mc->name()) { delete i->second; _controller->erase(i); break; } } } _controller->add(mc); } else if (tag == "Init") readEventList(xml, _midiInit, "Init"); else if (tag == "Reset") readEventList(xml, _midiReset, "Reset"); else if (tag == "State") readEventList(xml, _midiState, "State"); else if (tag == "InitScript") { if (_initScript) delete _initScript; QByteArray ba = xml.parse1().toLatin1(); const char* istr = ba.constData(); int len = strlen(istr) + 1; if (len > 1) { _initScript = new char[len]; memcpy(_initScript, istr, len); } } else if(tag == "KeyMap") { KeyMap *km = new KeyMap; km->read(xml); m_keymaps.insert(km->key, km); } else xml.unknown("MidiInstrument"); break; case Xml::Attribut: if (tag == "name") setIName(xml.s2()); else if (tag == "nullparam") { _nullvalue = xml.s2().toInt(&ok, base); } else if(tag == "panValue") m_panValue = xml.s2().toDouble(); break; case Xml::TagEnd: if (tag == "MidiInstrument") return; default: break; } } }
void Route::read(Xml& xml)/*{{{*/ { QString s; int dtype = MidiDevice::ALSA_MIDI; int port = -1; unsigned char rtype = Route::TRACK_ROUTE; for (;;) { const QString& tag = xml.s1(); Xml::Token token = xml.parse(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: #ifdef ROUTE_DEBUG printf("Route::read(): attribute:%s\n", tag.toLatin1().constData()); #endif if (tag == "type") rtype = xml.s2().toInt(); else if (tag == "devtype") { dtype = xml.s2().toInt(); rtype = Route::MIDI_DEVICE_ROUTE; } else if (tag == "name") s = xml.s2(); else if(tag == "trackId") { trackId = xml.s2().toLongLong(); rtype = Route::TRACK_ROUTE; } else if (tag == "mport") // p3.3.49 { port = xml.s2().toInt(); rtype = Route::MIDI_PORT_ROUTE; } else if(tag == "mportId") { midiPortId = xml.s2().toLongLong(); rtype = Route::MIDI_PORT_ROUTE; } else printf("Route::read(): unknown attribute:%s\n", tag.toLatin1().constData()); break; case Xml::TagEnd: #ifdef ROUTE_DEBUG printf("Route::read(): tag end type:%d channel:%d name:%s\n", rtype, channel, s.toLatin1().constData()); #endif if (rtype == MIDI_PORT_ROUTE) { if(midiPortId > 0) { //qDebug("Route::read(): MIDI_PORT_ROUTE Finding midiport from id"); type = rtype; MidiPort *mp = oomMidiPorts.value(midiPortId); if(mp) { midiPort = mp->portno(); //qDebug("Route::read(): Found midiport from id: %d", midiPort); } } else if (port >= 0 && port < MIDI_PORTS) { type = rtype; midiPort = port; MidiPort *mp = &midiPorts[midiPort]; midiPortId = mp->id(); } else printf("Route::read(): midi port <%d> out of range\n", port); } else if (!s.isEmpty()) { if (rtype == TRACK_ROUTE) { if(trackId > 0) { track = song->findTrackById(trackId); type = rtype; } else { TrackList* tl = song->tracks(); iTrack i = tl->begin(); for (; i != tl->end(); ++i) { Track* t = *i; if (t->name() == s) { track = t; type = rtype; trackId = t->id(); break; } } if (i == tl->end()) printf("Route::read(): track <%s> not found\n", s.toLatin1().constData()); } } else if (rtype == JACK_ROUTE) { void* jport = 0; if (audioDevice) //Fix from Robert at muse jport = audioDevice->findPort(s.toLatin1().constData()); if (jport == 0) printf("Route::read(): jack port <%s> not found audioDevice(%p)\n", s.toLatin1().constData(), audioDevice); else { jackPort = jport; type = rtype; } } else if (rtype == MIDI_DEVICE_ROUTE) { iMidiDevice imd = midiDevices.begin(); for (; imd != midiDevices.end(); ++imd) { MidiDevice* md = *imd; if (md->name() == s && md->deviceType() == dtype) { // We found a device, but if it is not in use by the song (port is -1), ignore it. // This prevents loading and propagation of bogus routes in the oom file. if (md->midiPort() == -1) break; device = md; type = rtype; break; } } if (imd == midiDevices.end()) printf("Route::read(): midi device <%s> not found\n", s.toLatin1().constData()); } } return; default: break; } } }/*}}}*/
static void readConfigMidiPort(Xml& xml)/*{{{*/ { int idx = 0; qint64 id = -1; QString device; bool isGlobal = false; QString instrument("GM"); QList<PatchSequence*> patchSequences; QList<QPair<int, QString> > presets; int openFlags = 1; int dic = 0; int doc = 0; int type = MidiDevice::ALSA_MIDI; bool cachenrpn = false; MidiDevice* dev = 0; for (;;) { Xml::Token token = xml.parse(); if (token == Xml::Error || token == Xml::End) break; QString tag = xml.s1(); switch (token) { case Xml::TagStart: if (tag == "name") { device = xml.parse1(); if (!dev)//Look for it as an alsa or already created device dev = midiDevices.find(device); } else if (tag == "type") { type = xml.parseInt(); } else if (tag == "record") { // old bool f = xml.parseInt(); if (f) openFlags |= 2; } else if (tag == "openFlags") openFlags = xml.parseInt(); else if (tag == "defaultInChans") dic = xml.parseInt(); else if (tag == "defaultOutChans") doc = xml.parseInt(); else if (tag == "instrument") { instrument = xml.parse1(); } else if (tag == "channel") { readPortChannel(xml, idx); } else if (tag == "preset" || tag == "patchSequence") { PatchSequence* p = readMidiPortPatchSequences(xml); if (p) patchSequences.append(p); } else if(tag == "midiPreset") { presets.append(readMidiPortPreset(xml)); } else if(tag == "cacheNRPN") { cachenrpn = xml.parseInt(); } else xml.skip(tag); break; case Xml::Attribut: if (tag == "idx") {//Check to see if this port is already used, and bump if so idx = xml.s2().toInt(); int freePort = getFreeMidiPort(); if(freePort != idx) {//Set a flag here so we know when loading tracks later that we are dealing with an old file or global inputs changed idx = freePort; } } else if(tag == "portId") {//New style id = xml.s2().toLongLong(); idx = getFreeMidiPort(); } else if(tag == "isGlobalInput") {//Find the matching input if posible and set our index to it isGlobal = xml.s2().toInt(); } break; case Xml::TagEnd: if (tag == "midiport") { if(isGlobal) {//Find the global input that matches // if(gInputListPorts.size()) { int myport = -1; for(int i = 0; i < gInputListPorts.size(); ++i) { myport = gInputListPorts.at(i); MidiPort* inport = &midiPorts[i]; if(inport && inport->device() && inport->device()->name() == device) { idx = myport; break; } } } } if (idx < 0 || idx >= MIDI_PORTS) { fprintf(stderr, "bad midi port %d (>%d)\n", idx, MIDI_PORTS); idx = 0; } if (!dev) { if (type == MidiDevice::JACK_MIDI) { dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55 if (debugMsg) fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.toLatin1().constData()); } else dev = midiDevices.find(device); } if (debugMsg && !dev) fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.toLatin1().constData()); MidiPort* mp = &midiPorts[idx]; if(id) mp->setPortId(id); mp->setInstrument(registerMidiInstrument(instrument)); mp->setDefaultInChannels(dic); mp->setDefaultOutChannels(doc); //Indicate the port was found in the song file, even if no device is assigned to it. mp->setFoundInSongFile(true); if (!patchSequences.isEmpty()) { for (int i = 0; i < patchSequences.size(); ++i) { mp->appendPatchSequence(patchSequences.at(i)); } } if(!presets.isEmpty()) { for(int i = 0; i < presets.size(); ++i) { QPair<int, QString> pair = presets.at(i); mp->addPreset(pair.first, pair.second); } } if (dev) { dev->setOpenFlags(openFlags); midiSeq->msgSetMidiDevice(mp, dev); dev->setCacheNRPN(cachenrpn); } losMidiPorts.insert(mp->id(), mp); return; } default: break; } } }/*}}}*/
void MidiInstrument::read(Xml& xml) { for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "Patch") { Patch* patch = new Patch; patch->read(xml); if (pg.empty()) { PatchGroup* p = new PatchGroup; p->patches.push_back(patch); pg.push_back(p); } else pg[0]->patches.push_back(patch); } else if (tag == "PatchGroup") { PatchGroup* p = new PatchGroup; p->read(xml); pg.push_back(p); } else if (tag == "Controller") { MidiController* mc = new MidiController(); mc->read(xml); // // HACK: make predefined "Program" controller overloadable // if (mc->name() == "Program") { for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) { if (i->second->name() == mc->name()) { delete i->second; _controller->del(i); break; } } } _controller->add(mc); } else if (tag == "Drummaps") { readDrummaps(xml); } else if (tag == "Init") readEventList(xml, _midiInit, "Init"); else if (tag == "Reset") readEventList(xml, _midiReset, "Reset"); else if (tag == "State") readEventList(xml, _midiState, "State"); else if (tag == "InitScript") { if (_initScript) delete _initScript; QByteArray ba = xml.parse1().toLatin1(); const char* istr = ba.constData(); int len = ba.length() +1; if (len > 1) { _initScript = new char[len]; memcpy(_initScript, istr, len); } } else if (tag == "SysEx") { SysEx* se = new SysEx; if(!se->read(xml)) { delete se; printf("MidiInstrument::read():SysEx: reading sysex failed\n"); } else _sysex.append(se); } else xml.unknown("MidiInstrument"); break; case Xml::Attribut: if (tag == "name") setIName(xml.s2()); else if(tag == "nullparam") { } // Obsolete. else if(tag == "NoteOffMode") _noteOffMode = (NoteOffMode)xml.s2().toInt(); // Default is NoteOffAll. break; case Xml::TagEnd: if (tag == "MidiInstrument") return; default: break; } } }
void readConfiguration(Xml& xml, bool readOnlySequencer)/*{{{*/ { for (;;) { Xml::Token token = xml.parse(); if (token == Xml::Error || token == Xml::End) break; QString tag = xml.s1(); switch (token) { case Xml::TagStart: /* the reading of configuration is split in two; read "sequencer" and read ALL. The reason is that it is possible to load a song without configuration. In this case the <configuration> chapter in the song file should be skipped. However the sub part <sequencer> contains elements that are necessary to preserve composition consistency. Mainly midiport configuration and VOLUME. */ if (tag == "sequencer") { readSeqConfiguration(xml); break; } else if (readOnlySequencer) { xml.skip(tag); break; } if (tag == "theme") config.style = xml.parse1(); else if (tag == "styleSheetFile") config.styleSheetFile = xml.parse1(); else if (tag == "useOldStyleStopShortCut") config.useOldStyleStopShortCut = xml.parseInt(); else if (tag == "moveArmedCheckBox") config.moveArmedCheckBox = xml.parseInt(); else if (tag == "externalWavEditor") config.externalWavEditor = xml.parse1(); else if (tag == "font0") config.fonts[0].fromString(xml.parse1()); else if (tag == "font1") config.fonts[1].fromString(xml.parse1()); else if (tag == "font2") config.fonts[2].fromString(xml.parse1()); else if (tag == "font3") config.fonts[3].fromString(xml.parse1()); else if (tag == "font4") config.fonts[4].fromString(xml.parse1()); else if (tag == "font5") config.fonts[5].fromString(xml.parse1()); else if (tag == "font6") config.fonts[6].fromString(xml.parse1()); else if (tag == "globalAlphaBlend") config.globalAlphaBlend = xml.parseInt(); else if (tag == "palette0") config.palette[0] = readColor(xml); else if (tag == "palette1") config.palette[1] = readColor(xml); else if (tag == "palette2") config.palette[2] = readColor(xml); else if (tag == "palette3") config.palette[3] = readColor(xml); else if (tag == "palette4") config.palette[4] = readColor(xml); else if (tag == "palette5") config.palette[5] = readColor(xml); else if (tag == "palette6") config.palette[6] = readColor(xml); else if (tag == "palette7") config.palette[7] = readColor(xml); else if (tag == "palette8") config.palette[8] = readColor(xml); else if (tag == "palette9") config.palette[9] = readColor(xml); else if (tag == "palette10") config.palette[10] = readColor(xml); else if (tag == "palette11") config.palette[11] = readColor(xml); else if (tag == "palette12") config.palette[12] = readColor(xml); else if (tag == "palette13") config.palette[13] = readColor(xml); else if (tag == "palette14") config.palette[14] = readColor(xml); else if (tag == "palette15") config.palette[15] = readColor(xml); else if (tag == "palette16") config.palette[16] = readColor(xml); else if (tag == "ctrlGraphFg") config.ctrlGraphFg = readColor(xml); else if (tag == "extendedMidi") config.extendedMidi = xml.parseInt(); else if (tag == "midiExportDivision") config.midiDivision = xml.parseInt(); else if (tag == "smfFormat") config.smfFormat = xml.parseInt(); else if (tag == "exp2ByteTimeSigs") config.exp2ByteTimeSigs = xml.parseInt(); else if (tag == "expOptimNoteOffs") config.expOptimNoteOffs = xml.parseInt(); else if (tag == "importMidiSplitParts") config.importMidiSplitParts = xml.parseInt(); else if (tag == "midiInputDevice") midiInputPorts = xml.parseInt(); else if (tag == "midiInputChannel") midiInputChannel = xml.parseInt(); else if (tag == "midiRecordType") midiRecordType = xml.parseInt(); else if (tag == "midiThruType") midiThruType = xml.parseInt(); else if (tag == "midiFilterCtrl1") midiFilterCtrl1 = xml.parseInt(); else if (tag == "midiFilterCtrl2") midiFilterCtrl2 = xml.parseInt(); else if (tag == "midiFilterCtrl3") midiFilterCtrl3 = xml.parseInt(); else if (tag == "midiFilterCtrl4") midiFilterCtrl4 = xml.parseInt(); else if (tag == "canvasShowPartType") config.canvasShowPartType = xml.parseInt(); else if (tag == "canvasShowPartEvent") config.canvasShowPartEvent = xml.parseInt(); else if (tag == "canvasShowGrid") config.canvasShowGrid = xml.parseInt(); else if (tag == "canvasBgPixmap") config.canvasBgPixmap = xml.parse1(); else if (tag == "canvasCustomBgList") config.canvasCustomBgList = xml.parse1().split(";", QString::SkipEmptyParts); else if(tag == "vuColorStrip") { vuColorStrip = xml.parseInt(); } else if(tag == "nextTrackPartColor") { lastTrackPartColorIndex = xml.parseInt(); } else if (tag == "mtctype") AL::mtcType = xml.parseInt(); else if (tag == "jackTransportMaster") { // XXX FIXME bool jackTransportMaster = xml.parseInt(); if (audioDevice) audioDevice->setMaster(jackTransportMaster); } else if (tag == "shortcuts") readShortCuts(xml); else if (tag == "division") config.division = xml.parseInt(); else if (tag == "guiDivision") config.guiDivision = xml.parseInt(); else if (tag == "rtcTicks") config.rtcTicks = xml.parseInt(); else if (tag == "minMeter") config.minMeter = xml.parseInt(); else if (tag == "minSlider") config.minSlider = xml.parseDouble(); else if (tag == "freewheelMode") config.freewheelMode = xml.parseInt(); else if (tag == "denormalProtection") config.useDenormalBias = xml.parseInt(); else if (tag == "outputLimiter") config.useOutputLimiter = xml.parseInt(); else if (tag == "dummyAudioSampleRate") config.dummyAudioSampleRate = xml.parseInt(); else if (tag == "dummyAudioBufSize") config.dummyAudioBufSize = xml.parseInt(); else if (tag == "guiRefresh") config.guiRefresh = xml.parseInt(); else if (tag == "userInstrumentsDir") config.userInstrumentsDir = xml.parse1(); else if (tag == "midiTransform") readMidiTransform(xml); else if (tag == "midiInputTransform") readMidiInputTransform(xml); else if (tag == "startMode") config.startMode = xml.parseInt(); else if (tag == "startSong") config.startSong = xml.parse1(); else if (tag == "projectBaseFolder") config.projectBaseFolder = xml.parse1(); else if (tag == "projectStoreInFolder") config.projectStoreInFolder = xml.parseInt(); else if (tag == "useProjectSaveDialog") config.useProjectSaveDialog = xml.parseInt(); else if (tag == "useAutoCrossFades") config.useAutoCrossFades = xml.parseInt(); else if(tag == "globalInputList") readGlobalInputList(xml); else xml.skip(tag); break; case Xml::Text: printf("text <%s>\n", xml.s1().toLatin1().constData()); break; case Xml::Attribut: if (readOnlySequencer) break; if (tag == "version") { int major = xml.s2().section('.', 0, 0).toInt(); int minor = xml.s2().section('.', 1, 1).toInt(); xml.setVersion(major, minor); } break; case Xml::TagEnd: if (tag == "configuration") { return; } break; case Xml::Proc: default: break; } } }/*}}}*/