Ejemplo n.º 1
0
void
MupExporter::writeClefAndKey(std::ofstream &str, TrackId trackNo)
{
    Composition *c = m_composition;

    for (Composition::iterator i = c->begin(); i != c->end(); ++i) {
        if ((*i)->getTrack() == trackNo) {

            Clef clef((*i)->getClefAtTime((*i)->getStartTime()));
            Rosegarden::Key key((*i)->getKeyAtTime((*i)->getStartTime()));


            str << "staff " << trackNo + 1 << "\n";

            if (clef.getClefType() == Clef::Treble) {
                str << "\tclef=treble\n";
            } else if (clef.getClefType() == Clef::Alto) {
                str << "\tclef=alto\n";
            } else if (clef.getClefType() == Clef::Tenor) {
                str << "\tclef=tenor\n";
            } else if (clef.getClefType() == Clef::Bass) {
                str << "\tclef=bass\n";
            }

            str << "\tkey=" << key.getAccidentalCount()
            << (key.isSharp() ? "#" : "&")
            << (key.isMinor() ? "minor" : "major") << std::endl;

            m_clefKeyMap[trackNo] = ClefKeyPair(clef, key);

            return ;
        }
    }
}
Ejemplo n.º 2
0
QStringList
ProjectPackager::getAudioFiles()
{
    QStringList list;

    // get the Composition from the document, so we can iterate through it
    Composition *comp = &m_doc->getComposition();

    // We don't particularly care about tracks here, so just iterate through the
    // entire Composition to find the audio segments and get the associated
    // file IDs from which to obtain a list of actual files.  This could
    // conceivably pick up audio segments that are residing on MIDI tracks and
    // wouldn't otherwise be functional, but the important thing is to never
    // miss a single file that has any chance of being worth preserving.
    for (Composition::iterator i = comp->begin(); i != comp->end(); ++i) {
        if ((*i)->getType() == Segment::Audio) {

            AudioFileManager *manager = &m_doc->getAudioFileManager();

            unsigned int id = (*i)->getAudioFileId();

            AudioFile *file = manager->getAudioFile(id);

            // some polite sanity checking to avoid possible crashes
            if (!file) continue;

            list << file->getFilename();
        }
    }

    // QStringList::removeDuplicates() would have been easy, but it's only in Qt
    // 4.5.0 and up.  So here's the algorithm from Qt 4.5.0, courtesy of (and
    // originally Copyright 2009) Nokia

    QStringList *that = &list;

    int n = that->size();
    int j = 0;
    QSet<QString> seen;
    seen.reserve(n);
    for (int i = 0; i < n; ++i) {
        const QString &s = that->at(i);
        if (seen.contains(s))
            continue;
        seen.insert(s);
        if (j != i)
            (*that)[j] = s;
        ++j;
    }
    if (n != j)
        that->erase(that->begin() + j, that->end());
//    return n - j;

    return list;
}
Ejemplo n.º 3
0
bool
MupExporter::write()
{
    Composition *c = m_composition;

    std::ofstream str(m_fileName.c_str(), std::ios::out);
    if (!str) {
        std::cerr << "MupExporter::write() - can't write file " << m_fileName
        << std::endl;
        return false;
    }

    str << "score\n";
    str << "\tstaffs=" << c->getNbTracks() << "\n";

    int ts = c->getTimeSignatureCount();
    std::pair<timeT, TimeSignature> tspair;
    if (ts > 0)
        tspair = c->getTimeSignatureChange(0);
    str << "\ttime="
    << tspair.second.getNumerator() << "/"
    << tspair.second.getDenominator() << "\n";

    for (int barNo = -1; barNo < c->getNbBars(); ++barNo) {

        for (TrackId trackNo = c->getMinTrackId();
                trackNo <= c->getMaxTrackId(); ++trackNo) {

            if (barNo < 0) {
                writeClefAndKey(str, trackNo);
                continue;
            }

            if (barNo == 0 && trackNo == 0) {
                str << "\nmusic\n";
            }

            str << "\t" << trackNo + 1 << ":";

            Segment *s = 0;
            timeT barStart = c->getBarStart(barNo);
            timeT barEnd = c->getBarEnd(barNo);

            for (Composition::iterator ci = c->begin(); ci != c->end(); ++ci) {
                if ((*ci)->getTrack() == trackNo &&
                        (*ci)->getStartTime() < barEnd &&
                        (*ci)->getEndMarkerTime() > barStart) {
                    s = *ci;
                    break;
                }
            }

            TimeSignature timeSig(c->getTimeSignatureAt(barStart));

            if (!s) {
                // write empty bar
                writeInventedRests(str, timeSig, 0, barEnd - barStart);
                continue;
            }

            if (s->getStartTime() > barStart) {
                writeInventedRests(str, timeSig,
                                   0, s->getStartTime() - barStart);
            }

            // Mup insists that every bar has the correct duration, and won't
            // recover if one goes wrong.  Keep careful tabs on this: it means
            // that for example we have to round chord durations down where
            // the next chord starts too soon
            //!!! we _really_ can't cope with time sig changes yet!

            timeT writtenDuration = writeBar(str, c, s, barStart, barEnd,
                                             timeSig, trackNo);

            if (writtenDuration < timeSig.getBarDuration()) {
                RG_DEBUG << "writtenDuration: " << writtenDuration
                << ", bar duration " << timeSig.getBarDuration()
                << endl;
                writeInventedRests(str, timeSig, writtenDuration,
                                   timeSig.getBarDuration() - writtenDuration);

            } else if (writtenDuration > timeSig.getBarDuration()) {
                std::cerr << "WARNING: overfull bar in Mup export: duration " << writtenDuration
                << " into bar of duration " << timeSig.getBarDuration()
                << std::endl;
                //!!! warn user
            }

            str << "\n";
        }

        if (barNo >= 0)
            str << "bar" << std::endl;
    }

    str << "\n" << std::endl;
    str.close();
    return true;
}