Skip to content

Commit

Permalink
Merge pull request #3816 from rism-digital/develop-timemap-fractions
Browse files Browse the repository at this point in the history
Add `useFractions` parameter to the timemap rendering
  • Loading branch information
ahankinson authored Oct 10, 2024
2 parents 528bdb9 + 1e60747 commit a2da4dd
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 20 deletions.
2 changes: 1 addition & 1 deletion include/vrv/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class Doc : public Object {
* Extract a timemap from the document to a JSON string.
* Run trough all the layers and fill the timemap file content.
*/
bool ExportTimemap(std::string &output, bool includeRests, bool includeMeasures);
bool ExportTimemap(std::string &output, bool includeRests, bool includeMeasures, bool useFractions);

/**
* Extract expansionMap from the document to JSON string.
Expand Down
3 changes: 2 additions & 1 deletion include/vrv/horizontalaligner.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class Fraction {

public:
// Constructors - make them explicit to avoid type conversion
explicit Fraction(int num = 0, int denom = 1);
explicit Fraction();
explicit Fraction(int num, int denom = 1);
explicit Fraction(data_DURATION duration);

// Enable implicit conversion constructor for `int`
Expand Down
16 changes: 12 additions & 4 deletions include/vrv/timemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@

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

#include "horizontalaligner.h"

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

#include "jsonxx.h"

namespace vrv {

class Object;
Expand All @@ -28,7 +34,7 @@ class Object;
*/
struct TimemapEntry {
double tempo = -1000.0;
double qstamp;
double tstamp;
std::vector<std::string> notesOn;
std::vector<std::string> notesOff;
std::vector<std::string> restsOn;
Expand Down Expand Up @@ -59,20 +65,22 @@ class Timemap {
/**
* Return (and possibly add) an entry for the given time.
*/
TimemapEntry &GetEntry(double time) { return m_map[time]; }
TimemapEntry &GetEntry(const Fraction &time) { return m_map[time]; }

/**
* Write the current timemap to a JSON string
*/
void ToJson(std::string &output, bool includetRests, bool includetMeasures);
void ToJson(std::string &output, bool includeRests, bool includeMeasures, bool useFractions);

static jsonxx::Array ToArray(const Fraction &fraction);

private:
//
public:
//
private:
/** The map with time values as keys */
std::map<double, TimemapEntry> m_map;
std::map<Fraction, TimemapEntry> m_map;

}; // class Timemap

Expand Down
4 changes: 2 additions & 2 deletions src/doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile)
}
}

bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeasures)
bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeasures, bool useFractions)
{
if (!this->HasTimemap()) {
// generate MIDI timemap before progressing
Expand All @@ -558,7 +558,7 @@ bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeas
generateTimemap.SetCueExclusion(this->GetOptions()->m_midiNoCue.GetValue());
this->Process(generateTimemap);

timemap.ToJson(output, includeRests, includeMeasures);
timemap.ToJson(output, includeRests, includeMeasures, useFractions);

return true;
}
Expand Down
6 changes: 6 additions & 0 deletions src/horizontalaligner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ namespace vrv {
// Fraction
//----------------------------------------------------------------------------

Fraction::Fraction()
{
m_numerator = 0;
m_denominator = 1;
}

Fraction::Fraction(int num, int denom) : m_numerator(num), m_denominator(denom)
{
if (denom == 0) {
Expand Down
12 changes: 6 additions & 6 deletions src/midifunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,11 +955,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)

/*********** start values ***********/

TimemapEntry &startEntry = m_timemap->GetEntry(realTimeStart);
TimemapEntry &startEntry = m_timemap->GetEntry(scoreTimeStart);

// Should check if value for realTimeStart already exists and if so, then
// ensure that it is equal to scoreTimeStart:
startEntry.qstamp = scoreTimeStart.ToDouble();
startEntry.tstamp = realTimeStart;

// Store the element ID in list to turn on at given time - note or rest
if (!isRest) startEntry.notesOn.push_back(object->GetID());
Expand All @@ -970,11 +970,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)

/*********** end values ***********/

TimemapEntry &endEntry = m_timemap->GetEntry(realTimeEnd);
TimemapEntry &endEntry = m_timemap->GetEntry(scoreTimeEnd);

// Should check if value for realTimeEnd already exists and if so, then
// ensure that it is equal to scoreTimeEnd:
endEntry.qstamp = scoreTimeEnd.ToDouble();
endEntry.tstamp = realTimeEnd;

// Store the element ID in list to turn off at given time - notes or rest
if (!isRest) endEntry.notesOff.push_back(object->GetID());
Expand All @@ -989,11 +989,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)
Fraction scoreTimeStart = m_scoreTimeOffset;
double realTimeStart = round(m_realTimeOffsetMilliseconds);

TimemapEntry &startEntry = m_timemap->GetEntry(realTimeStart);
TimemapEntry &startEntry = m_timemap->GetEntry(scoreTimeStart);

// Should check if value for realTimeStart already exists and if so, then
// ensure that it is equal to scoreTimeStart:
startEntry.qstamp = scoreTimeStart.ToDouble();
startEntry.tstamp = realTimeStart;

// Add the measureOn
startEntry.measureOn = measure->GetID();
Expand Down
23 changes: 18 additions & 5 deletions src/timemap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,22 @@ void Timemap::Reset()
m_map.clear();
}

void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasures)
void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasures, bool useFractions)
{
double currentTempo = -1000.0;
double newTempo;

jsonxx::Array timemap;

for (auto &[tstamp, entry] : m_map) {
for (auto &[qstamp, entry] : m_map) {
jsonxx::Object o;
o << "tstamp" << tstamp;
o << "qstamp" << entry.qstamp;
if (useFractions) {
o << "qfrac" << Timemap::ToArray(qstamp);
}
else {
o << "qstamp" << qstamp.ToDouble();
}
o << "tstamp" << entry.tstamp;

// on / off
if (!entry.notesOn.empty()) {
Expand Down Expand Up @@ -80,7 +85,7 @@ void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasure
newTempo = entry.tempo;
if (newTempo != currentTempo) {
currentTempo = newTempo;
o << "tempo" << std::to_string(currentTempo);
o << "tempo" << currentTempo;
}
}

Expand All @@ -94,4 +99,12 @@ void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasure
output = timemap.json();
}

jsonxx::Array Timemap::ToArray(const Fraction &fraction)
{
jsonxx::Array array;
array << fraction.GetNumerator();
array << fraction.GetDenominator();
return array;
}

} // namespace vrv
4 changes: 3 additions & 1 deletion src/toolkit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,7 @@ std::string Toolkit::RenderToTimemap(const std::string &jsonOptions)
{
bool includeMeasures = false;
bool includeRests = false;
bool useFractions = false;

jsonxx::Object json;

Expand All @@ -1811,13 +1812,14 @@ std::string Toolkit::RenderToTimemap(const std::string &jsonOptions)
if (json.has<jsonxx::Boolean>("includeMeasures"))
includeMeasures = json.get<jsonxx::Boolean>("includeMeasures");
if (json.has<jsonxx::Boolean>("includeRests")) includeRests = json.get<jsonxx::Boolean>("includeRests");
if (json.has<jsonxx::Boolean>("useFractions")) useFractions = json.get<jsonxx::Boolean>("useFractions");
}
}

this->ResetLogBuffer();

std::string output;
m_doc.ExportTimemap(output, includeRests, includeMeasures);
m_doc.ExportTimemap(output, includeRests, includeMeasures, useFractions);
return output;
}

Expand Down

0 comments on commit a2da4dd

Please sign in to comment.