Skip to content

Commit

Permalink
Merge pull request #3797 from rism-digital/develop-cmme
Browse files Browse the repository at this point in the history
Add support for CMME import
  • Loading branch information
ahankinson authored Oct 17, 2024
2 parents 2062300 + 1911f3d commit 8ebb1c8
Show file tree
Hide file tree
Showing 24 changed files with 1,442 additions and 47 deletions.
16 changes: 16 additions & 0 deletions Verovio.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,12 @@
4D64137E2035F68600BB630E /* mdiv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64137D2035F68600BB630E /* mdiv.cpp */; };
4D64137F2035F68600BB630E /* mdiv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64137D2035F68600BB630E /* mdiv.cpp */; };
4D6413802035F68600BB630E /* mdiv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64137D2035F68600BB630E /* mdiv.cpp */; };
4D6479372C9881B800CD9539 /* iocmme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D6479362C9881B800CD9539 /* iocmme.cpp */; };
4D6479392C98825900CD9539 /* iocmme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D6479362C9881B800CD9539 /* iocmme.cpp */; };
4D64793A2C98825A00CD9539 /* iocmme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D6479362C9881B800CD9539 /* iocmme.cpp */; };
4D64793B2C98825A00CD9539 /* iocmme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D6479362C9881B800CD9539 /* iocmme.cpp */; };
4D64793C2C98826600CD9539 /* iocmme.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D6479382C9881DB00CD9539 /* iocmme.h */; };
4D64793D2C98826600CD9539 /* iocmme.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D6479382C9881DB00CD9539 /* iocmme.h */; settings = {ATTRIBUTES = (Public, ); }; };
4D64793F2C9C0F1C00CD9539 /* genericlayerelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64793E2C9C0F1C00CD9539 /* genericlayerelement.cpp */; };
4D6479412C9C0F4200CD9539 /* genericlayerelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64793E2C9C0F1C00CD9539 /* genericlayerelement.cpp */; };
4D6479422C9C0F4300CD9539 /* genericlayerelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D64793E2C9C0F1C00CD9539 /* genericlayerelement.cpp */; };
Expand Down Expand Up @@ -1885,6 +1891,8 @@
4D6413772035F58200BB630E /* pages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pages.cpp; path = src/pages.cpp; sourceTree = "<group>"; };
4D64137B2035F67C00BB630E /* mdiv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdiv.h; path = include/vrv/mdiv.h; sourceTree = "<group>"; };
4D64137D2035F68600BB630E /* mdiv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mdiv.cpp; path = src/mdiv.cpp; sourceTree = "<group>"; };
4D6479362C9881B800CD9539 /* iocmme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iocmme.cpp; path = src/iocmme.cpp; sourceTree = "<group>"; };
4D6479382C9881DB00CD9539 /* iocmme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iocmme.h; path = include/vrv/iocmme.h; sourceTree = "<group>"; };
4D64793E2C9C0F1C00CD9539 /* genericlayerelement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = genericlayerelement.cpp; path = src/genericlayerelement.cpp; sourceTree = "<group>"; };
4D6479402C9C0F2D00CD9539 /* genericlayerelement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = genericlayerelement.h; path = include/vrv/genericlayerelement.h; sourceTree = "<group>"; };
4D674B3E255F40AC008AEF4C /* plica.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plica.h; path = include/vrv/plica.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2895,6 +2903,8 @@
8F59291718854BF800FE51AD /* iobase.h */,
402197931F2E09DA00182DF1 /* ioabc.cpp */,
402197921F2E09CB00182DF1 /* ioabc.h */,
4D6479382C9881DB00CD9539 /* iocmme.h */,
4D6479362C9881B800CD9539 /* iocmme.cpp */,
8F086EC1188539540037FD8E /* iodarms.cpp */,
8F59291818854BF800FE51AD /* iodarms.h */,
4DA20ED01D0F151900706C4A /* iohumdrum.cpp */,
Expand Down Expand Up @@ -3461,6 +3471,7 @@
E7901659298BCA97008FDB4E /* calcalignmentxposfunctor.h in Headers */,
BDEF9ECC26725248008A3A47 /* caesura.h in Headers */,
E7ADB3AB29D1921300825D5D /* adjustarticfunctor.h in Headers */,
4D64793C2C98826600CD9539 /* iocmme.h in Headers */,
E73E86252A069C640089DF74 /* transposefunctor.h in Headers */,
4DEC4DD921C8295700D1D273 /* rdg.h in Headers */,
4DB3D8D01F83D11800B5FC2B /* mordent.h in Headers */,
Expand Down Expand Up @@ -3584,6 +3595,7 @@
4D4CDEA82C079026005621E9 /* adjustneumexfunctor.h in Headers */,
BB4C4B5222A932D7001F6AF0 /* ftrem.h in Headers */,
E7E9C11329B0A1E200CFCE2F /* adjustaccidxfunctor.h in Headers */,
4D64793D2C98826600CD9539 /* iocmme.h in Headers */,
4D88AD0B289673F50006D7DA /* symbol.h in Headers */,
4D1EB6A72A2A40CB00AF2F98 /* textlayoutelement.h in Headers */,
4D2E759022BC2B71004C51F0 /* course.h in Headers */,
Expand Down Expand Up @@ -4110,6 +4122,7 @@
40C2E4222052A6F60003625F /* pb.cpp in Sources */,
4DA0EAF322BB77C300A7EBEB /* facsimileinterface.cpp in Sources */,
4D1694241E3A44F300569BF4 /* positioninterface.cpp in Sources */,
4D6479392C98825900CD9539 /* iocmme.cpp in Sources */,
4D1694251E3A44F300569BF4 /* timestamp.cpp in Sources */,
4D1694261E3A44F300569BF4 /* MidiEventList.cpp in Sources */,
4DA0EAC822BB779400A7EBEB /* facsimile.cpp in Sources */,
Expand Down Expand Up @@ -4449,6 +4462,7 @@
4D79642126C167100026288B /* pagemilestone.cpp in Sources */,
4D2073FB22A3BCE000E0765F /* tabgrp.cpp in Sources */,
4DEC4DBA21C8288900D1D273 /* choice.cpp in Sources */,
4D6479372C9881B800CD9539 /* iocmme.cpp in Sources */,
4DACC9882990F29A00B55913 /* atts_mei.cpp in Sources */,
4D2073F522A3BCE000E0765F /* tuning.cpp in Sources */,
8F086F06188539540037FD8E /* view_beam.cpp in Sources */,
Expand Down Expand Up @@ -4691,6 +4705,7 @@
8F3DD35418854B2E0051330C /* slur.cpp in Sources */,
40C2E4232052A6F70003625F /* pb.cpp in Sources */,
4D64137A2035F58200BB630E /* pages.cpp in Sources */,
4D64793A2C98825A00CD9539 /* iocmme.cpp in Sources */,
4D1694741E3A455200569BF4 /* humlib.cpp in Sources */,
4DB3D8C31F83D0EF00B5FC2B /* anchoredtext.cpp in Sources */,
4DB3D8E71F83D16A00B5FC2B /* ftrem.cpp in Sources */,
Expand Down Expand Up @@ -4982,6 +4997,7 @@
BB4C4B6122A932D7001F6AF0 /* mrpt.cpp in Sources */,
BB4C4AE722A932BC001F6AF0 /* damage.cpp in Sources */,
4DA0EACA22BB779400A7EBEB /* facsimile.cpp in Sources */,
4D64793B2C98825A00CD9539 /* iocmme.cpp in Sources */,
BB4C4B4B22A932D7001F6AF0 /* custos.cpp in Sources */,
BB4C4BB822A932FC001F6AF0 /* Binasc.cpp in Sources */,
BB4C4B7B22A932D7001F6AF0 /* tuplet.cpp in Sources */,
Expand Down
9 changes: 4 additions & 5 deletions include/vrv/alignfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@

namespace vrv {

class Mensur;
class MeterSig;

//----------------------------------------------------------------------------
// AlignMeterParams
//----------------------------------------------------------------------------
/**
* Regroup pointers to meterSig, mensur and proport objects
*/
struct AlignMeterParams {
const MeterSig *meterSig;
const Mensur *mensur;
const MeterSig *meterSig = NULL;
const Mensur *mensur = NULL;
// Not const since we are cumulating proportion
Proport *proport = NULL;
};

//----------------------------------------------------------------------------
Expand Down
8 changes: 7 additions & 1 deletion include/vrv/drawinginterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "mensur.h"
#include "metersig.h"
#include "metersiggrp.h"
#include "proport.h"
#include "vrvdef.h"

namespace vrv {
Expand Down Expand Up @@ -239,7 +240,7 @@ class StaffDefDrawingInterface {
void SetDrawClef(bool drawClef) { m_drawClef = drawClef; }
bool DrawKeySig() const { return (m_drawKeySig); }
void SetDrawKeySig(bool drawKeySig) { m_drawKeySig = drawKeySig; }
bool DrawMensur() const { return (m_drawMensur && m_currentMensur.HasSign()); }
bool DrawMensur() const { return (m_drawMensur && (m_currentMensur.HasSign() || m_currentMensur.HasNum())); }
void SetDrawMensur(bool drawMensur) { m_drawMensur = drawMensur; }
bool DrawMeterSig() const
{
Expand All @@ -260,6 +261,7 @@ class StaffDefDrawingInterface {
void SetCurrentMeterSig(const MeterSig *meterSig);
void SetCurrentMeterSigGrp(const MeterSigGrp *meterSigGrp);
void AlternateCurrentMeterSig(const Measure *measure);
void SetCurrentProport(const Proport *proport);
///@}

/**
Expand All @@ -277,6 +279,8 @@ class StaffDefDrawingInterface {
const MeterSig *GetCurrentMeterSig() const { return &m_currentMeterSig; }
MeterSigGrp *GetCurrentMeterSigGrp() { return &m_currentMeterSigGrp; }
const MeterSigGrp *GetCurrentMeterSigGrp() const { return &m_currentMeterSigGrp; }
Proport *GetCurrentProport() { return &m_currentProport; }
const Proport *GetCurrentProport() const { return &m_currentProport; }
///@}

private:
Expand All @@ -290,6 +294,8 @@ class StaffDefDrawingInterface {
MeterSig m_currentMeterSig;
/** The meter signature group */
MeterSigGrp m_currentMeterSigGrp;
/** The proport */
Proport m_currentProport;

/**
* @name Flags for indicating whether the clef, keysig and mensur needs to be drawn or not
Expand Down
8 changes: 8 additions & 0 deletions include/vrv/genericlayerelement.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ class GenericLayerElement : public LayerElement {
*/
std::string GetMEIName() const { return m_meiName; }

/**
* Return the MEI element original name
*/
std::string GetContent() { return m_content; }
void SetContent(std::string content) { m_content = content; }

//----------//
// Functors //
//----------//
Expand All @@ -58,6 +64,8 @@ class GenericLayerElement : public LayerElement {
std::string m_className;
/** The MEI element name */
std::string m_meiName;
/** The MEI element content */
std::string m_content;

public:
//
Expand Down
2 changes: 2 additions & 0 deletions include/vrv/horizontalaligner.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ enum AlignmentType {
ALIGNMENT_KEYSIG,
ALIGNMENT_MENSUR,
ALIGNMENT_METERSIG,
ALIGNMENT_PROPORT,
ALIGNMENT_DOT,
ALIGNMENT_CUSTOS,
ALIGNMENT_ACCID,
ALIGNMENT_GRACENOTE,
ALIGNMENT_BARLINE,
Expand Down
125 changes: 125 additions & 0 deletions include/vrv/iocmme.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/////////////////////////////////////////////////////////////////////////////
// Name: iocmme.h
// Author: Laurent Pugin
// Created: 2024
// Copyright (c) Authors and others. All rights reserved.
/////////////////////////////////////////////////////////////////////////////

#ifndef __VRV_IOCMME_H__
#define __VRV_IOCMME_H__

#include <string>
#include <utility>
#include <vector>

//----------------------------------------------------------------------------

#include "iobase.h"
#include "pugixml.hpp"
#include "vrvdef.h"

namespace vrv {

class Chord;
class Clef;
class KeySig;
class Layer;
class Measure;
class Note;
class Score;

namespace cmme {

struct mensInfo {
int prolatio = 2;
int tempus = 2;
int modusminor = 2;
int modusmaior = 2;
int proportNum = 1;
int proportDen = 1;
};

} // namespace cmme

//----------------------------------------------------------------------------
// CmmeInput
//----------------------------------------------------------------------------

class CmmeInput : public Input {
public:
// constructors and destructors
CmmeInput(Doc *doc);
virtual ~CmmeInput();

bool Import(const std::string &cmme) override;

private:
void CreateSection(pugi::xml_node musicSectionNode);
void CreateStaff(pugi::xml_node voiceNode);
void CreateApp(pugi::xml_node appNode);
void CreateLemOrRdg(pugi::xml_node lemOrRdgNode, bool isFirst);

void ReadEvents(pugi::xml_node eventsNode);
void ReadEditorialCommentary(pugi::xml_node evenNode, Object *object);

void CreateAccid(pugi::xml_node accidNode);
void CreateBarline(pugi::xml_node barlineNode);
void CreateBreak(pugi::xml_node breakNode);
void CreateChord(pugi::xml_node chordNode);
void CreateClef(pugi::xml_node clefNode);
void CreateCustos(pugi::xml_node custosNode);
void CreateDot(pugi::xml_node dotNode);
void CreateEllipsis();
void CreateKeySig(pugi::xml_node keyNode);
void CreateLacuna(pugi::xml_node lacunaNode);
void CreateMensuration(pugi::xml_node mensurationNode);
void CreateOriginalText(pugi::xml_node originalTextNode);
void CreateProport(pugi::xml_node proportNode);
void CreateNote(pugi::xml_node noteNode);
void CreateRest(pugi::xml_node restNode);

void CreateVerse(pugi::xml_node verseNode);

data_DURATION ReadDuration(pugi::xml_node durationNode, int &num, int &numbase) const;
bool IsClef(pugi::xml_node clefNode) const;

/**
* Helper methods for accessing and converting text in elements.
* Return "" or VRV_UNSET if the node is NULL or the node or the text not found
*/
///@{
std::string AsString(const pugi::xml_node node) const;
std::string ChildAsString(const pugi::xml_node node, const std::string &child) const;
int AsInt(const pugi::xml_node node) const;
int ChildAsInt(const pugi::xml_node node, const std::string &child) const;
///@}

public:
//
private:
/** The current score (only one) */
Score *m_score;
/** The current un-measured measure acting a a MEI section */
Measure *m_currentSection;
/** The current layer (or container) to which the layer elements have to be added */
Object *m_currentContainer;
/** The current key signature to which extra flats might be added */
KeySig *m_currentSignature;
/** The current note */
Note *m_currentNote;
/** The syllable is not the first */
bool m_isInSyllable;
/** The mensural infos for all voices */
std::vector<cmme::mensInfo> m_mensInfos;
/** The mensural info for the current voice */
cmme::mensInfo *m_mensInfo;

/** The number of voices as given in the general data */
int m_numVoices;
/** The name of the voices - if any */
std::vector<std::string> m_voices;
};

} // namespace vrv

#endif
2 changes: 2 additions & 0 deletions include/vrv/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class Layer : public Object,
const Mensur *GetCurrentMensur() const;
MeterSig *GetCurrentMeterSig();
const MeterSig *GetCurrentMeterSig() const;
Proport *GetCurrentProport();
const Proport *GetCurrentProport() const;
///@}

void ResetStaffDefObjects();
Expand Down
8 changes: 8 additions & 0 deletions include/vrv/proport.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class Proport : public LayerElement, public AttDurationRatio {
std::string GetClassName() const override { return "Proport"; }
///@}

int GetCumulatedNum() const;
int GetCumulatedNumbase() const;

void Cumulate(const Proport *proport);

/** Override the method since alignment is required */
bool HasToBeAligned() const override { return true; }

Expand All @@ -52,6 +57,9 @@ class Proport : public LayerElement, public AttDurationRatio {
public:
//
private:
/** the cumulated num and numbase */
int m_cumulatedNum;
int m_cumulatedNumbase;
};

} // namespace vrv
Expand Down
1 change: 1 addition & 0 deletions include/vrv/setscoredeffunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class ScoreDefSetCurrentFunctor : public DocFunctor {
FunctorCode VisitMeasure(Measure *measure) override;
FunctorCode VisitMensur(Mensur *mensur) override;
FunctorCode VisitPage(Page *page) override;
FunctorCode VisitProport(Proport *proport) override;
FunctorCode VisitScore(Score *score) override;
FunctorCode VisitScoreDef(ScoreDef *scoreDef) override;
FunctorCode VisitStaff(Staff *staff) override;
Expand Down
1 change: 1 addition & 0 deletions include/vrv/toolkitdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum FileFormat {
HUMMIDI,
PAE,
ABC,
CMME,
DARMS,
VOLPIANO,
MUSICXML,
Expand Down
3 changes: 3 additions & 0 deletions src/adjustaccidxfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ FunctorCode AdjustAccidXFunctor::VisitAlignmentReference(AlignmentReference *ali
for (Accid *accid : accids) {
// Skip any accid that was already adjusted
if (m_adjustedAccids.count(accid) > 0) continue;
// Skip accid not descendant of a note (e.g., mensural)
if (!accid->GetFirstAncestor(NOTE)) continue;

auto range = octaveEquivalence.equal_range(accid);
// Handle at least two octave accids without unisons
int octaveAccidCount = 0;
Expand Down
Loading

0 comments on commit 8ebb1c8

Please sign in to comment.