3#include <initializer_list>
8#include "SQLiteCpp/SQLiteCpp.h"
9#include "maiacore/chord.h"
10#include "maiacore/constants.h"
11#include "maiacore/key.h"
12#include "maiacore/measure.h"
13#include "maiacore/note.h"
14#include "maiacore/part.h"
15#include "nlohmann/json.hpp"
16#include "pugi/pugixml.hpp"
28 std::string _composerName;
29 std::vector<Part> _part;
30 std::string _filePath;
31 std::string _fileName;
33 pugi::xml_document _doc;
40 std::vector<Chord> _stackedChords;
41 int _lcmDivisionsPerQuarterNote;
42 bool _haveAnacrusisMeasure;
52 const std::string keyName;
56 mutable std::vector<NoteEvent> _cachedNoteEvents;
57 mutable bool _isNoteEventsCached =
false;
62 std::vector<NoteEvent> collectNoteEvents()
const;
64 mutable std::vector<std::vector<NoteEvent>> _cachedNoteEventsPerPart;
65 mutable bool _isNoteEventsPerPartCached =
false;
70 std::vector<std::vector<NoteEvent>> collectNoteEventsPerPart()
const;
77 void removeDuplicatePatterns(std::vector<std::vector<Note>>* patterns)
const;
79 typedef struct noteData_st {
80 float currentTimeValue = 0.0f;
81 const Note* notePtr =
nullptr;
82 float floatBeatStartTime = 0.0f;
83 float floatBeatEndTime = 0.0f;
86 typedef struct chordData_st {
87 std::vector<NoteData> noteData;
88 const Measure* measurePtr =
nullptr;
89 bool isHomophonicChord =
true;
90 float beatEndTimeHigherLimit = 0.0f;
91 float beatStartTimeLowerLimit = 1000.0f;
92 float chordQuarterDuration = 0.0f;
100 void loadXMLFile(
const std::string& filePath);
108 std::vector<std::tuple<int, float, Key, Chord, bool>> getChordsPerEachNoteEvent(
109 SQLite::Database& db,
const bool includeDuplicates);
117 explicit Score(
const std::initializer_list<std::string>& partsName,
const int numMeasures = 20);
124 explicit Score(
const std::vector<std::string>& partsName,
const int numMeasures = 20);
131 explicit Score(
const std::string& filePath);
155 void addPart(
const std::string& partName,
const int numStaves = 1);
245 void setKeySignature(
const int fifthCicle,
const bool isMajorMode =
true,
const int measureId = 0);
269 void setMetronomeMark(
int bpm,
const RhythmFigure duration = RhythmFigure::QUARTER,
int measureStart = 0);
277 const std::string
toXML(
const int identSize = 2)
const;
292 void toFile(std::string fileName,
bool compressedXML =
false,
const int identSize = 2)
const;
309 std::function<
void(
Part* part,
Measure* measure,
int staveId,
Note* note)> callback,
310 int measureStart = 0,
int measureEnd = -1, std::vector<std::string> partNames = {});
352 bool getNote(
const int part,
const int measure,
const int note, std::string& pitch,
353 std::string& step,
int& octave,
int& duration,
int& voice, std::string& type,
354 std::string& steam,
int& staff)
const;
366 bool getNote(
const int part,
const int measure,
const int note, std::string& pitch,
367 std::string& step,
int& octave)
const;
377 bool getNote(
const int part,
const int measure,
const int note, std::string& pitch)
const;
426 std::string& pitch, std::string& pitchClass, std::string& alterSymbol,
427 int& alterValue,
int& octave, std::string& type,
float& duration)
const;
506 _title = other._title;
507 _composerName = other._composerName;
508 _filePath = other._filePath;
509 _fileName = other._fileName;
511 _numParts = other._numParts;
512 _numMeasures = other._numMeasures;
513 _numNotes = other._numNotes;
514 _isValidXML = other._isValidXML;
515 _haveTypeTag = other._haveTypeTag;
516 _isLoadedXML = other._isLoadedXML;
517 _lcmDivisionsPerQuarterNote = other._lcmDivisionsPerQuarterNote;
518 _stackedChords = other._stackedChords;
519 _haveAnacrusisMeasure = other._haveAnacrusisMeasure;
522 _doc.reset(other._doc);
525 _isNoteEventsCached =
false;
526 _isNoteEventsPerPartCached =
false;
527 _cachedNoteEvents.clear();
528 _cachedNoteEventsPerPart.clear();
537 if (
this == &other)
return *
this;
539 _title = other._title;
540 _composerName = other._composerName;
541 _filePath = other._filePath;
542 _fileName = other._fileName;
544 _numParts = other._numParts;
545 _numMeasures = other._numMeasures;
546 _numNotes = other._numNotes;
547 _isValidXML = other._isValidXML;
548 _haveTypeTag = other._haveTypeTag;
549 _isLoadedXML = other._isLoadedXML;
550 _lcmDivisionsPerQuarterNote = other._lcmDivisionsPerQuarterNote;
551 _stackedChords = other._stackedChords;
552 _haveAnacrusisMeasure = other._haveAnacrusisMeasure;
555 _doc.reset(other._doc);
558 _isNoteEventsCached =
false;
559 _isNoteEventsPerPartCached =
false;
560 _cachedNoteEvents.clear();
561 _cachedNoteEventsPerPart.clear();
572 typedef std::tuple<std::string, int, int, std::string, std::string, std::vector<std::string>, std::vector<float>, std::vector<float>,
631 const std::vector<Note>& melodyPattern,
const float totalIntervalsSimilarityThreshold = 0.5,
632 const float totalRhythmSimilarityThreshold = 0.5,
633 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
634 intervalsSimilarityCallback =
nullptr,
635 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
636 rhythmSimilarityCallback =
nullptr,
637 const std::function<
float(
const std::vector<float>&)> totalIntervalSimilarityCallback =
639 const std::function<
float(
const std::vector<float>&)> totalRhythmSimilarityCallback =
641 const std::function<
float(
float,
float)> totalSimilarityCallback =
nullptr)
const;
657 const std::vector<std::vector<Note>>& melodyPatterns,
const float totalIntervalsSimilarityThreshold = 0.5,
658 const float totalRhythmSimilarityThreshold = 0.5,
659 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
660 intervalsSimilarityCallback =
nullptr,
661 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
662 rhythmSimilarityCallback =
nullptr,
663 const std::function<
float(
const std::vector<float>&)> totalIntervalSimilarityCallback =
665 const std::function<
float(
const std::vector<float>&)> totalRhythmSimilarityCallback =
667 const std::function<
float(
float,
float)> totalSimilarityCallback =
nullptr)
const;
683 const float totalIntervalsSimilarityThreshold = 1.0f,
684 const float totalRhythmSimilarityThreshold = 1.0f,
685 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
686 intervalsSimilarityCallback =
nullptr,
687 const std::function<std::vector<float>(
const std::vector<Note>&,
const std::vector<Note>&)>
688 rhythmSimilarityCallback =
nullptr,
689 const std::function<
float(
const std::vector<float>&)> totalIntervalSimilarityCallback =
691 const std::function<
float(
const std::vector<float>&)> totalRhythmSimilarityCallback =
693 const std::function<
float(
float,
float)> totalSimilarityCallback =
nullptr)
const;
755 std::vector<std::tuple<int, float, Key, Chord, bool>>
getChords(nlohmann::json config = {});
Represents a musical measure (bar) within a score, containing notes, staves, key/time signatures,...
Definition: measure.h:23
Represents a musical note, including pitch, duration, articulation, and MusicXML-related attributes.
Definition: note.h:19
Represents a musical part (instrument or voice) in a score, containing measures, staves,...
Definition: part.h:17
Represents a complete musical score, including metadata, parts, measures, and notes.
Definition: score.h:25
void forEachNote(std::function< void(Part *part, Measure *measure, int staveId, Note *note)> callback, int measureStart=0, int measureEnd=-1, std::vector< std::string > partNames={})
Iterates over all notes in the score, applying a callback function.
Score(const std::initializer_list< std::string > &partsName, const int numMeasures=20)
Constructs a new blank Score object with specified part names and initial measure count.
int getNumParts() const
Returns the number of parts (instruments/voices) in the score.
int getNumNotes() const
Returns the total number of notes in the score.
void addPart(const std::string &partName, const int numStaves=1)
Adds a new part (instrument/voice) to the score.
void clear()
Clears all content from the score, removing parts, measures, and metadata.
Part & getPart(const std::string &partName)
Returns a reference to a part by its name.
const std::vector< std::string > getPartsNames() const
Returns a vector with the names of all parts/instruments.
void getNoteNodeData(const pugi::xml_node &node, std::string &partName, int &measure, std::string &pitch, std::string &pitchClass, std::string &alterSymbol, int &alterValue, int &octave, std::string &type, float &duration) const
Retrieves detailed information from a note XML node.
MelodyPatternTable findMelodyPattern(const std::vector< Note > &melodyPattern, const float totalIntervalsSimilarityThreshold=0.5, const float totalRhythmSimilarityThreshold=0.5, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> intervalsSimilarityCallback=nullptr, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> rhythmSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalIntervalSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalRhythmSimilarityCallback=nullptr, const std::function< float(float, float)> totalSimilarityCallback=nullptr) const
Searches for a melodic pattern throughout the score, returning detailed results.
void setTimeSignature(const int timeUpper, const int timeLower, const int measureId=-1)
Sets the time signature for all or part of the measures.
void printPartNames() const
Prints the names of all parts/instruments in the score to the terminal.
bool isValid(void) const
Returns true if the score is valid (MusicXML loaded correctly).
void toFile(std::string fileName, bool compressedXML=false, const int identSize=2) const
Saves the score to a file in XML or compressed MXL format.
Score(const Score &other)
Copy constructor for Score.
Definition: score.h:505
~Score()
Destructor. Releases resources associated with the score.
int getNumMeasures() const
Returns the number of measures in the score.
void removePart(const int partId)
Removes a part from the score by its index.
void info() const
Prints summary information about the score to the log.
Part & getPart(const int partId)
Returns a reference to a part by its index.
std::tuple< std::string, int, int, std::string, std::string, std::vector< std::string >, std::vector< float >, std::vector< float >, float, float, float > MelodyPatternRow
Table row type for melodic pattern search results.
Definition: score.h:573
std::string getTitle() const
Returns the title of the score.
void setRepeat(int measureStart, int measureEnd=-1)
Sets repeat barlines for a range of measures.
std::vector< MelodyPatternTable > findMelodyPattern(const std::vector< std::vector< Note > > &melodyPatterns, const float totalIntervalsSimilarityThreshold=0.5, const float totalRhythmSimilarityThreshold=0.5, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> intervalsSimilarityCallback=nullptr, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> rhythmSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalIntervalSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalRhythmSimilarityCallback=nullptr, const std::function< float(float, float)> totalSimilarityCallback=nullptr) const
Searches for multiple melodic patterns in the score, returning a table for each pattern.
nlohmann::json instrumentFragmentation(nlohmann::json config=nlohmann::json())
Analyzes instrumental fragmentation patterns across the score timeline.
void setKeySignature(const int fifthCicle, const bool isMajorMode=true, const int measureId=0)
Sets the key signature for all parts at a specific measure.
void setKeySignature(const std::string &key, const int measureId=0)
Sets the key signature using the key name (e.g., "C", "Gm").
bool getNote(const int part, const int measure, const int note, std::string &pitch, std::string &step, int &octave, int &duration, int &voice, std::string &type, std::string &steam, int &staff) const
Retrieves detailed information about a specific note in the score.
void removeMeasure(const int measureStart, const int measureEnd)
Removes a range of measures from all parts in the score.
bool getNote(const int part, const int measure, const int note, std::string &pitch, std::string &step, int &octave) const
Retrieves basic information about a specific note (pitch, step, octave).
Score & operator=(const Score &other)
Assignment operator for Score.
Definition: score.h:536
const std::string toJSON() const
Exports the score to JSON format.
std::vector< std::tuple< int, float, Key, Chord, bool > > getChords(nlohmann::json config={})
Extracts vertical chord structures from the score with configurable analysis parameters.
std::vector< MelodyPatternRow > MelodyPatternTable
Table type for melodic pattern search results.
Definition: score.h:577
std::string getFilePath() const
Returns the file path of the loaded MusicXML file.
int xPathCountNodes(const std::string &xPath) const
Counts the number of XML nodes matching a given XPath expression.
bool haveTypeTag(void) const
Returns true if the MusicXML file contains <type> tags for notes.
const std::string toXML(const int identSize=2) const
Exports the score to MusicXML format.
bool haveAnacrusisMeasure() const
Returns true if the score contains an anacrusis (pickup) measure.
bool getPartIndex(const std::string &partName, int *index) const
Gets the index of a part by its name.
Score(Score &&)=default
Move constructor for Score.
Score(const std::vector< std::string > &partsName, const int numMeasures=20)
Constructs a new blank Score object with specified part names and initial measure count.
bool getNote(const int part, const int measure, const int note, std::string &pitch) const
Retrieves only the pitch of a specific note.
std::vector< MelodyPatternTable > findAnyMelodyPattern(const int patternNumNotes=5, const float totalIntervalsSimilarityThreshold=1.0f, const float totalRhythmSimilarityThreshold=1.0f, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> intervalsSimilarityCallback=nullptr, const std::function< std::vector< float >(const std::vector< Note > &, const std::vector< Note > &)> rhythmSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalIntervalSimilarityCallback=nullptr, const std::function< float(const std::vector< float > &)> totalRhythmSimilarityCallback=nullptr, const std::function< float(float, float)> totalSimilarityCallback=nullptr) const
Finds all possible melodic patterns of a given length in the score.
void setTitle(const std::string &scoreTitle)
Sets the title of the score.
void setMetronomeMark(int bpm, const RhythmFigure duration=RhythmFigure::QUARTER, int measureStart=0)
Sets the metronome mark (BPM) for a specific measure.
std::string getComposerName() const
Returns the composer's name.
void addMeasure(const int numMeasures)
Adds a specified number of measures to all parts in the score.
std::string getFileName() const
Returns the file name of the loaded MusicXML file.
const std::string getPartName(const int partId) const
Returns the name of a part by its index.
void setComposerName(const std::string &composerName)
Sets the composer's name.
Score(const std::string &filePath)
Constructs a new Score object by loading a MusicXML file.