Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 19 additions & 93 deletions src/engraving/dom/tempo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,50 +31,16 @@
using namespace mu;

namespace mu::engraving {
//---------------------------------------------------------
// TEvent
//---------------------------------------------------------

TEvent::TEvent()
{
type = TempoType::INVALID;
tempo = 0.0;
pause = 0.0;
time = 0.0;
}

TEvent::TEvent(const TEvent& e)
{
type = e.type;
tempo = e.tempo;
pause = e.pause;
time = e.time;
}

TEvent::TEvent(BeatsPerSecond t, double p, TempoType tp)
TEvent::TEvent(const BeatsPerSecond t, const double p, const TempoType tp)
: type(tp), tempo(t), pause(p)
{
type = tp;
tempo = t;
pause = p;
time = 0.0;
}

bool TEvent::valid() const
{
return !(!type);
}

//---------------------------------------------------------
// TempoMap
//---------------------------------------------------------

TempoMap::TempoMap()
{
m_tempo = 2.0; // default fixed tempo in beat per second
m_tempoSN = 1;
m_tempoMultiplier = 1.0;
}

//---------------------------------------------------------
// setPause
//---------------------------------------------------------
Expand Down Expand Up @@ -135,7 +101,6 @@ void TempoMap::normalize()
tick = e->first;
tempo = e->second.tempo.val;
}
++m_tempoSN;
}

//---------------------------------------------------------
Expand All @@ -159,7 +124,6 @@ void TempoMap::clear()
{
std::map<int, TEvent>::clear();
m_pauses.clear();
++m_tempoSN;
}

//---------------------------------------------------------
Expand All @@ -183,7 +147,6 @@ void TempoMap::clearRange(int tick1, int tick2)
}

erase(first, last);
++m_tempoSN;
}

//---------------------------------------------------------
Expand Down Expand Up @@ -224,27 +187,6 @@ double TempoMap::pauseSecs(int tick) const
return muse::value(m_pauses, tick, 0.0);
}

//---------------------------------------------------------
// del
//---------------------------------------------------------

void TempoMap::del(int tick)
{
auto e = find(tick);
if (e == end()) {
LOGD("TempoMap::del event at (%d): not found", tick);
// abort();
return;
}
// don't delete event if still being used for pause
if (e->second.type & TempoType::PAUSE) {
e->second.type = TempoType::PAUSE;
} else {
erase(e);
}
normalize();
}

BeatsPerSecond TempoMap::tempoMultiplier() const
{
return m_tempoMultiplier;
Expand Down Expand Up @@ -272,34 +214,22 @@ bool TempoMap::setTempoMultiplier(BeatsPerSecond val)

void TempoMap::delTempo(int tick)
{
del(tick);
++m_tempoSN;
}

//---------------------------------------------------------
// tick2time
//---------------------------------------------------------

double TempoMap::tick2time(int tick, double time, int* sn) const
{
return (*sn == m_tempoSN) ? time : tick2time(tick, sn);
}

//---------------------------------------------------------
// time2tick
// return cached value t if list did not change
//---------------------------------------------------------

int TempoMap::time2tick(double time, int t, int* sn) const
{
return (*sn == m_tempoSN) ? t : time2tick(time, sn);
auto e = find(tick);
if (e == end()) {
LOGD("TempoMap::del event at (%d): not found", tick);
// abort();
return;
}
// don't delete event if still being used for pause
if (e->second.type & TempoType::PAUSE) {
e->second.type = TempoType::PAUSE;
} else {
erase(e);
}
normalize();
}

//---------------------------------------------------------
// tick2time
//---------------------------------------------------------

double TempoMap::tick2time(int tick, int* sn) const
double TempoMap::tick2time(int tick) const
{
double time = 0.0;
double delta = double(tick);
Expand Down Expand Up @@ -329,9 +259,7 @@ double TempoMap::tick2time(int tick, int* sn) const
} else {
LOGD("TempoMap: empty");
}
if (sn) {
*sn = m_tempoSN;
}

time += delta / (Constants::DIVISION * tempo.val * m_tempoMultiplier.val);
return time;
}
Expand All @@ -340,7 +268,7 @@ double TempoMap::tick2time(int tick, int* sn) const
// time2tick
//---------------------------------------------------------

int TempoMap::time2tick(double time, int* sn) const
int TempoMap::time2tick(double time) const
{
int tick = 0;
double delta = time;
Expand All @@ -363,9 +291,7 @@ int TempoMap::time2tick(double time, int* sn) const
}
delta = time - delta;
tick += lrint(delta * m_tempoMultiplier.val * Constants::DIVISION * tempo.val);
if (sn) {
*sn = m_tempoSN;
}

return tick;
}
}
42 changes: 14 additions & 28 deletions src/engraving/dom/tempo.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "../types/bps.h"

namespace mu::engraving {
static constexpr int TEMPO_PRECISION = 6;
inline constexpr int TEMPO_PRECISION = 6;

enum class TempoType : char {
INVALID = 0x0, PAUSE = 0x1, FIX = 0x2, RAMP = 0x4
Expand All @@ -39,19 +39,14 @@ enum class TempoType : char {
typedef muse::Flags<TempoType> TempoTypes;
DECLARE_OPERATORS_FOR_FLAGS(TempoTypes)

//---------------------------------------------------------
// Tempo Event
//---------------------------------------------------------

struct TEvent {
TempoTypes type;
BeatsPerSecond tempo; // beats per second
double pause = 0.0; // pause in seconds
double time = 0.0; // precomputed time for tick in sec

TEvent();
TEvent(const TEvent& e);
TEvent(BeatsPerSecond bps, double seconds, TempoType t);
TempoTypes type = TempoType::INVALID;
BeatsPerSecond tempo = 0.0;
double pause = 0.0; // pause in seconds
double time = 0.0; // precomputed time for tick in sec

TEvent() = default;
TEvent(BeatsPerSecond, double pauseInSeconds, TempoType);
bool valid() const;

bool operator ==(const TEvent& other) const
Expand All @@ -63,16 +58,13 @@ struct TEvent {
}
};

//---------------------------------------------------------
// Tempomap
//---------------------------------------------------------

class TempoMap : public std::map<int, TEvent>
{
OBJECT_ALLOCATOR(engraving, TempoMap)

public:
TempoMap();
TempoMap() = default;

void clear();
void clearRange(int tick1, int tick2);

Expand All @@ -82,11 +74,8 @@ class TempoMap : public std::map<int, TEvent>
BeatsPerSecond multipliedTempo(int tick) const;
double pauseSecs(int tick) const;

double tick2time(int tick, int* sn = 0) const;
double tick2time(int tick, double time, int* sn) const;
int time2tick(double time, int* sn = 0) const;
int time2tick(double time, int tick, int* sn) const;
int tempoSN() const { return m_tempoSN; }
double tick2time(int tick) const;
int time2tick(double time) const;

void setTempo(int t, BeatsPerSecond);
void setPause(int t, double);
Expand All @@ -96,13 +85,10 @@ class TempoMap : public std::map<int, TEvent>
bool setTempoMultiplier(BeatsPerSecond val);

private:

void normalize();
void del(int tick);

int m_tempoSN = 0; // serial no to track tempo changes
BeatsPerSecond m_tempo; // tempo if not using tempo list (beats per second)
BeatsPerSecond m_tempoMultiplier;
BeatsPerSecond m_tempo = 2.0; // tempo if not using tempo list (beats per second)
BeatsPerSecond m_tempoMultiplier = 1.0;

std::unordered_map<int, double> m_pauses;
};
Expand Down
Loading