208 lines
8.2 KiB
C++
208 lines
8.2 KiB
C++
//=============================================================================
|
|
// MusE Score
|
|
// Linux Music Score Editor
|
|
// $Id: musicxmlsupport.h 5595 2012-04-29 15:30:32Z lvinken $
|
|
//
|
|
// Copyright (C) 2012 Werner Schweer and others
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//=============================================================================
|
|
|
|
#ifndef __MUSICXMLSUPPORT_H__
|
|
#define __MUSICXMLSUPPORT_H__
|
|
|
|
#include "libmscore/fraction.h"
|
|
#include "libmscore/mscore.h"
|
|
#include "libmscore/note.h"
|
|
|
|
namespace Ms {
|
|
|
|
//---------------------------------------------------------
|
|
// NoteList
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
List of note start/stop times in a voice in a single staff.
|
|
*/
|
|
|
|
typedef QPair<int, int> StartStop;
|
|
typedef QList<StartStop> StartStopList;
|
|
|
|
//---------------------------------------------------------
|
|
// NoteList
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
List of note start/stop times in a voice in all staves.
|
|
*/
|
|
|
|
class NoteList {
|
|
public:
|
|
NoteList();
|
|
void addNote(const int startTick, const int endTick, const int staff);
|
|
void dump(const QString& voice) const;
|
|
bool stavesOverlap(const int staff1, const int staff2) const;
|
|
bool anyStaffOverlaps() const;
|
|
private:
|
|
QList<StartStopList> _staffNoteLists; ///< The note start/stop times in all staves
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// VoiceDesc
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
The description of a single voice in a MusicXML part.
|
|
*/
|
|
|
|
class VoiceDesc {
|
|
public:
|
|
VoiceDesc();
|
|
void incrChordRests(int s);
|
|
int numberChordRests() const;
|
|
int numberChordRests(int s) const { return (s >= 0 && s < MAX_STAVES) ? _chordRests[s] : 0; }
|
|
int preferredStaff() const; ///< Determine preferred staff for this voice
|
|
void setStaff(int s) { if (s >= 0) _staff = s; }
|
|
int staff() const { return _staff; }
|
|
void setVoice(int v) { if (v >= 0) _voice = v; }
|
|
int voice() const { return _voice; }
|
|
void setVoice(int s, int v) { if (s >= 0 && s < MAX_STAVES) _voices[s] = v; }
|
|
int voice(int s) const { return (s >= 0 && s < MAX_STAVES) ? _voices[s] : -1; }
|
|
void setOverlap(bool b) { _overlaps = b; }
|
|
bool overlaps() const { return _overlaps; }
|
|
void setStaffAlloc(int s, int i) { if (s >= 0 && s < MAX_STAVES) _staffAlloc[s] = i; }
|
|
int staffAlloc(int s) const { return (s >= 0 && s < MAX_STAVES) ? _staffAlloc[s] : -1; }
|
|
QString toString() const;
|
|
private:
|
|
int _chordRests[MAX_STAVES]; ///< The number of chordrests on each MusicXML staff
|
|
int _staff; ///< The MuseScore staff allocated
|
|
int _voice; ///< The MuseScore voice allocated
|
|
bool _overlaps; ///< This voice contains active notes in multiple staves at the same time
|
|
int _staffAlloc[MAX_STAVES]; ///< For overlapping voices: voice is allocated on these staves (note: -2=unalloc -1=undef 1=alloc)
|
|
int _voices[MAX_STAVES]; ///< For every voice allocated on the staff, the voice number
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// VoiceOverlapDetector
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
Detect overlap in a voice, which is when a voice has two or more notes
|
|
active at the same time. In theory this should not happen, as voices
|
|
only move forward in time, but Sibelius 7 reuses voice numbers in multi-
|
|
staff parts, which leads to overlap.
|
|
|
|
Current implementation does not detect voice overlap within a staff,
|
|
but only between staves.
|
|
*/
|
|
|
|
class VoiceOverlapDetector {
|
|
public:
|
|
VoiceOverlapDetector();
|
|
void addNote(const int startTick, const int endTick, const QString& voice, const int staff);
|
|
void dump() const;
|
|
void newMeasure();
|
|
bool stavesOverlap(const QString& voice) const;
|
|
private:
|
|
QMap<QString, NoteList> _noteLists; ///< The notelists for all the voices
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// MusicXMLDrumInstrument
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
A single instrument in a MusicXML part.
|
|
Used for both a drum part and a (non-drum) multi-instrument part
|
|
*/
|
|
|
|
struct MusicXMLDrumInstrument {
|
|
int pitch; // pitch read from MusicXML
|
|
QString name; // name read from MusicXML
|
|
QString sound; // sound read from MusicXML
|
|
QString virtLib; // virtual library read from MusicXML
|
|
QString virtName; // virtualname read from MusicXML
|
|
int midiChannel; // channel read from MusicXML
|
|
int midiPort; // port read from MusicXML
|
|
int midiProgram; // program read from MusicXML
|
|
int midiVolume; // volume read from MusicXML
|
|
int midiPan; // pan value read from MusicXML
|
|
NoteHead::Group notehead; ///< notehead symbol set
|
|
int line; ///< place notehead onto this line
|
|
Direction stemDirection;
|
|
|
|
QString toString() const;
|
|
|
|
MusicXMLDrumInstrument()
|
|
: pitch(-1), name(), midiChannel(-1), midiPort(-1), midiProgram(-1), midiVolume(100), midiPan(63),
|
|
notehead(NoteHead::Group::HEAD_INVALID), line(0), stemDirection(Direction::AUTO) {}
|
|
MusicXMLDrumInstrument(QString s)
|
|
: pitch(-1), name(s), midiChannel(-1), midiPort(-1), midiProgram(-1), midiVolume(100), midiPan(63),
|
|
notehead(NoteHead::Group::HEAD_INVALID), line(0), stemDirection(Direction::AUTO) {}
|
|
MusicXMLDrumInstrument(int p, QString s, NoteHead::Group nh, int l, Direction d)
|
|
: pitch(p), name(s), midiChannel(-1), midiPort(-1), midiProgram(-1), midiVolume(100), midiPan(63),
|
|
notehead(nh), line(l), stemDirection(d) {}
|
|
};
|
|
|
|
/**
|
|
A MusicXML drumset or set of instruments in a multi-instrument part.
|
|
*/
|
|
|
|
typedef QMap<QString, MusicXMLDrumInstrument> MusicXMLDrumset;
|
|
typedef QMapIterator<QString, MusicXMLDrumInstrument> MusicXMLDrumsetIterator;
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// MxmlSupport -- MusicXML import support functions
|
|
//---------------------------------------------------------
|
|
|
|
class MxmlSupport {
|
|
public:
|
|
static int stringToInt(const QString& s, bool* ok);
|
|
static Fraction durationAsFraction(const int divisions, const QDomElement e);
|
|
static Fraction noteTypeToFraction(QString type);
|
|
static Fraction calculateFraction(QString type, int dots, int normalNotes, int actualNotes);
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// ValidatorMessageHandler
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
Message handler for the MusicXML schema validator QXmlSchemaValidator.
|
|
*/
|
|
|
|
class ValidatorMessageHandler : public QAbstractMessageHandler
|
|
{
|
|
public:
|
|
ValidatorMessageHandler() : QAbstractMessageHandler(0) {}
|
|
QString getErrors() const { return errors; }
|
|
protected:
|
|
virtual void handleMessage(QtMsgType type, const QString& description,
|
|
const QUrl& identifier, const QSourceLocation& sourceLocation);
|
|
private:
|
|
QString errors;
|
|
};
|
|
|
|
extern void domError(const QDomElement&);
|
|
extern void domNotImplemented(const QDomElement&);
|
|
|
|
|
|
extern QString accSymId2MxmlString(const SymId id);
|
|
extern QString accidentalType2MxmlString(const AccidentalType type);
|
|
extern AccidentalType mxmlString2accidentalType(const QString mxmlName);
|
|
extern SymId mxmlString2accSymId(const QString mxmlName);
|
|
extern AccidentalType microtonalGuess(double val);
|
|
|
|
} // namespace Ms
|
|
#endif
|