// Initialize intervals, one for each unique attribute value void initialize_intervals(int dimIndex) { g_intervals.clear(); IntervalSet interval; TupleVec::iterator it = g_data.begin(), end = g_data.end(), next; int index = 0; for ( ; it != end; ++it, ++index) { next = it+1; // Add element (index) to interval interval.insert(index); bool insertInterval = (next == end) || ( (next->first)[dimIndex] != (it->first)[dimIndex] ); if (insertInterval) { // Insert interval into list if // (a) end of sequence or // (b) next element is not the same as current element g_intervals.push_back(interval); interval.clear(); } } // Debug print_all_intervals(); }
std::vector<Tuning*> *Tuning::getTunings() { // if already have tunings, return them // TODO: It would be polite to check the mtime on the tunings file // and to re-read it if it's been changed. For now, you need // to restart Rosegarden. if (!m_tunings.empty()) return &m_tunings; QString tuningsPath = ResourceFinder().getResourcePath("pitches", "tunings.xml"); if (tuningsPath == "") return NULL; # if (TUNING_DEBUG > 1) qDebug() << "Path to tunings file:" << tuningsPath; # endif QFile infile(tuningsPath); IntervalList *intervals = new IntervalList; SpellingList *spellings = new SpellingList; if (infile.open(QIODevice::ReadOnly) ) { QXmlStreamReader stream(&infile); QString tuningName, intervalRatio; stream.readNextStartElement(); if (stream.name() != "rosegarden_scales") { qDebug() << "Tunings configuration file " << tuningsPath << " is not a valid rosegarden scales file. " << "(Root element is " << stream.name() << ")"; return NULL; } enum {needTuning, needName, needInterval, needSpellings} state; # if (TUNING_DEBUG > 2) static const char * stateNames[] = { "expecting <tuning>", "expecting <name>", "expecting <interval>", "expecting <spelling>" }; # endif state = needTuning; while(!stream.atEnd()) { // Read to the next element delimiter do { stream.readNext(); } while(!stream.isStartElement() && !stream.isEndElement() && !stream.atEnd()); if (stream.atEnd()) break; // Perform state transistions at end elements if (stream.isEndElement()) { if (stream.name() == "tuning") { // Save the tuning and prepare for a new one saveTuning(tuningName, intervals, spellings); intervals = new IntervalList; spellings = new SpellingList; state = needTuning; } else if (stream.name() == "name") { // End of tuning name: expect intervals state = needInterval; } else if (stream.name() == "interval") { // After an </interval>, we're expecting another interval state = needInterval; } else if (stream.name() == "rosegarden_scales") { // XML's fininshed. Don't need the current tuning // or spelling lists created when the last tuning ended // so let's not leak memory. delete intervals; delete spellings; // Don't bother reading any more of the file break; } # if (TUNING_DEBUG > 2) qDebug() << "End of XML element " << stream.name() << "New state: " << state << " (" << stateNames[state] << ")"; # endif continue; } // So it's a start element. Parse it. // If we are in the needSpellings state but hit a new interval, // we need to process that. So force a state-change here. if (state == needSpellings && stream.name() == "interval") { state = needInterval; } # if (TUNING_DEBUG > 2) qDebug() << "XML Element: " << stream.name() << " Current XML parser state: " << state << " (" << stateNames[state] << ")"; # endif switch (state) { case needTuning: if (stream.name() != "tuning") { qDebug() << "Reading Tunings. Expected tuning element, " << "found " << stream.name(); stream.skipCurrentElement(); } else { // Require a name element state = needName; } break; case needName: if (stream.name() != "name") { qDebug() << "Tuning must start with a <name> element, " << "found <" << stream.name() << ">"; stream.skipCurrentElement(); } else { tuningName = stream.readElementText(); state = needInterval; # if (TUNING_DEBUG > 1) qDebug() << "\nNew Tuning: " << tuningName; # endif } break; case needInterval: if (stream.name() != "interval") { qDebug() << "Expecting an <interval> element, " << "found <" << stream.name() << ">"; // Bail out stream.skipCurrentElement(); } else { intervalRatio = stream.attributes().value("ratio").toString(); # if (TUNING_DEBUG > 1) qDebug() << "New Ratio: " << intervalRatio; # endif const double cents = scalaIntervalToCents(intervalRatio, stream.lineNumber()); intervals->push_back(cents); state = needSpellings; } break; case needSpellings: if (stream.name() != "spelling") { qDebug() << "Intervals may contain only spellings. " << "Found <" << stream.name() << ">"; // Keep looking for spellings stream.skipCurrentElement(); } else { // Parse this spelling parseSpelling(stream.readElementText(), intervals, spellings); } break; default: // Illegal state (can't happen: it's an enumerated type!) qDebug() << "Something nasty happened reading tunings. " "Illegal state at line " << stream.lineNumber(); stream.skipCurrentElement(); break; } // end switch(state) } // end while(!stream.atEnd()) # if (TUNING_DEBUG > 1) qDebug() << "Closing tunings file"; # endif infile.close(); } // end if (m_infile.open(... return &m_tunings; }
/** * 2DO extend to support non default references * If no tuning present, will default to 12ET */ Tuning *PMLDocument::getTuning(){ DOMElement *perf = getSingleElement(m_doc->getDocumentElement(), "performance"); if( !perf ){ //cerr << "No performance element! Defaulting to 12ET\n"; } else{ DOMElement *tuningEl = getSingleElement(perf, "tuning"); if( !tuningEl ){ cout << "No tuning element! Defaulting to 12ET\n"; } else{ string tuningName = XS( tuningEl->getAttribute(XS("name")) ); IntervalList *intervals = new IntervalList; SpellingList *spellingList = new SpellingList; /* Get intervals */ DOMElement* intList = getSingleElement(tuningEl,"intervallist"); DOMNodeList *intervalEls = intList->getElementsByTagName(XS("interval")); for( int i=0; i<intervalEls->getLength(); i++ ){ string is = getText((DOMElement*)intervalEls->item(i)); //cout << "Interval " << is << endl; intervals->push_back( atof(is.c_str()) ); } /* Get enharmonic equivalent spellings */ DOMElement *spellingListEl = getSingleElement( tuningEl, "spellinglist" ); DOMNodeList *equivs = spellingListEl->getElementsByTagName(XS("enharmequiv")); for( int e=0; e<equivs->getLength(); e++ ){ DOMElement *equiv = (DOMElement*)equivs->item(e); DOMNodeList *spellings = equiv->getElementsByTagName(XS("spelling")); for( int i=0; i<spellings->getLength(); i++ ){ DOMElement* spEl = (DOMElement*)spellings->item(i); Accidental acc; if( spEl->getAttributeNode(XS("acc")) == NULL ) acc = Accidentals::NoAccidental; else acc = XS( spEl->getAttribute(XS("acc")) ); //cout << "Acc " << acc << endl; string notest = XS(spEl->getAttribute(XS("note"))); char note = notest[0]; PitchSpelling ps(note,acc); SpellingListItem spi( e, ps ); spellingList->insert( spi); } } Tuning *tuning = new Tuning( tuningName, intervals, spellingList); return tuning; } } std::vector<Tuning*>* tunings = Tuning::getTunings( "/usr/local/lib/tunings" ); Tuning *tuning = tunings->at(0); return tuning; }