Skip to content

Commit

Permalink
Merge pull request #277 from docsteer/243-feature-request-transmit-vi…
Browse files Browse the repository at this point in the history
…ew-manually-set-fps-hz

243 Feature Request - Transmit View - Manually Set FPS Hz
  • Loading branch information
docsteer authored Mar 8, 2023
2 parents a184e5a + bf67571 commit cf09754
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 117 deletions.
93 changes: 92 additions & 1 deletion src/sacn/ACNShare/tock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,102 @@ bool Tock_StartLib()
//Gets a tock representing the current time
tock Tock_GetTock()
{
return tock(timer.elapsed());
return tock(std::chrono::nanoseconds(timer.nsecsElapsed()));
}

//Shuts down the tock layer.
void Tock_StopLib()
{

}

tock::tock():v(0) {}

template <typename Rep, typename Period>
tock::tock(std::chrono::duration<Rep, Period> duration)
{
v = duration;
}

tock::resolution_t tock::Get() const
{
return v;
}

void tock::Set(tock::resolution_t time)
{
v = time;
}

bool operator>(const tock& t1, const tock& t2)
{
return t1.v.count() - t2.v.count() > 0;
}

bool operator>=(const tock& t1, const tock& t2)
{
return t1.v.count() - t2.v.count() >= 0;
}

bool operator==(const tock& t1, const tock& t2)
{
return t1.v.count() - t2.v.count() == 0;
}

bool operator!=(const tock& t1, const tock& t2)
{
return t1.v.count() - t2.v.count() != 0;
}

bool operator<(const tock& t1, const tock& t2)
{
return t2.v.count() - t1.v.count() > 0;
}

bool operator<=(const tock& t1, const tock& t2)
{
return t2.v.count() - t1.v.count() >= 0;
}

ttimer::ttimer():interval(0)
{
Reset();
}

template <typename Rep, typename Period>
ttimer::ttimer(std::chrono::duration<Rep, Period> interval) :
interval(interval)
{
Reset();
}

void ttimer::SetInterval(tock::resolution_t interval)
{
this->interval = interval;
Reset();
}

tock::resolution_t ttimer::GetInterval() const
{
return interval;
}

void ttimer::Reset()
{
tockout.Set(Tock_GetTock().Get() + interval);
}

bool ttimer::Expired() const
{
return (Tock_GetTock().Get()) >= tockout.Get();
}

bool operator==(const ttimer& t1, const ttimer& t2)
{
return ((t1.tockout == t2.tockout) && (t1.interval == t2.interval));
}

bool operator!=(const ttimer& t1, const ttimer& t2)
{
return !(t1 == t2);
}
81 changes: 32 additions & 49 deletions src/sacn/ACNShare/tock.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
Provides a standard definition of a tock and a ttimer.
A tock is the number of milliseconds since a platform-specific date.
A tock is the number of nanoseconds since a platform-specific date.
Tocks are never used directly, rather the difference between two tocks
(latest - previous) are used to determine the passage of time. It is
assumed that tocks always move forward, and that the base date is not
different for any instance of the compiled tock, nor does the base date change.
Tocks are guaranteed to have a millisecond granularity.
Tocks are guaranteed to have a nanosecond granularity.
Tock comparisons correctly handle clock rollover.
A ttimer is a simple abstraction for typical timer usage, which is
Expand All @@ -40,6 +40,7 @@
#define _TOCK_H_

#include <QtGlobal>
#include <chrono>

class tock;
class ttimer;
Expand All @@ -57,20 +58,26 @@ void Tock_StopLib(); //Shuts down the tock layer.
class tock
{
public:
typedef std::chrono::nanoseconds resolution_t;

//construction and copying
tock();
tock(quint32 ms);
tock(const tock& t);
tock& operator=(const tock& t);
tock(const tock&) = default;
tock(tock&&) = default;
tock& operator=(const tock&) = default;
tock& operator=(tock&&) = default;

template <typename Rep, typename Period>
tock(std::chrono::duration<Rep, Period> duration);

//Returns the number of milliseconds that this tock represents
quint32 Getms();
//Returns the number of nanoseconds that this tock represents
resolution_t Get() const;

//Used sparingly, but sets the number of milliseconds that this tock represents
void Setms(quint32 ms);
//Used sparingly, but sets the number of nanoseconds that this tock represents
void Set(resolution_t time);

protected:
qint32 v; //Signed, so the wraparound calculations will work
resolution_t v;

friend bool operator>(const tock& t1, const tock& t2);
friend bool operator>=(const tock& t1, const tock& t2);
Expand All @@ -87,52 +94,28 @@ class ttimer
public:
//construction/setup
ttimer(); //Will immediately time out if timeout isn't set
ttimer(qint32 ms); //The number of milliseconds before the timer will time out
void SetInterval(qint32 ms); //Sets a new timeout interval (in ms) and resets the timer
qint32 GetInterval(); //Returns the current timeout interval (in ms)
ttimer(const ttimer&) = default;
ttimer(ttimer&&) = default;
ttimer& operator=(const ttimer&) = default;
ttimer& operator=(ttimer&&) = default;
template <typename Rep, typename Period>
ttimer(std::chrono::duration<Rep, Period> interval); //The duration before the timer will time out

void SetInterval(tock::resolution_t interval); //Sets a new timeout interval and resets the timer

tock::resolution_t GetInterval() const; //Returns the current timeout interval

void Reset(); //Resets the timer, using the current timeout interval
bool Expired() const; //Returns true if the timer has expired.
//Call Reset() to use this timer again for a new interval.

//Returns true if the timer has expired
//Call Reset() to use this timer again for a new interval.
bool Expired() const;

friend bool operator==(const ttimer& t1, const ttimer& t2);
friend bool operator!=(const ttimer& t1, const ttimer& t2);

protected:
qint32 interval;
tock::resolution_t interval;
tock tockout;
};


//---------------------------------------------------------------------------------
// Implementation

/*ttimer implementation*/
inline ttimer::ttimer():interval(0) {Reset();}
inline ttimer::ttimer(qint32 ms):interval(ms) {Reset();}
inline void ttimer::SetInterval(qint32 ms) {interval = ms; Reset();}
inline qint32 ttimer::GetInterval() {return interval;}
inline void ttimer::Reset() {tockout.Setms(Tock_GetTock().Getms() + interval);}
inline bool ttimer::Expired() const {return Tock_GetTock() > tockout;}
inline bool operator==(const ttimer& t1, const ttimer& t2) { return ((t1.tockout == t2.tockout) && (t1.interval == t2.interval)); }
inline bool operator!=(const ttimer& t1, const ttimer& t2) { return !(t1 == t2); }

/*tock implementation*/
inline tock::tock():v(0) {}
inline tock::tock(quint32 ms):v(ms) {}
inline tock::tock(const tock& t) {v = t.v;}
inline tock& tock::operator=(const tock& t) {v = t.v; return *this;}

inline quint32 tock::Getms() {return v;}
inline void tock::Setms(quint32 ms) {v = ms;}

inline bool operator>(const tock& t1, const tock& t2) {return t1.v - t2.v > 0;}
inline bool operator>=(const tock& t1, const tock& t2) {return t1.v - t2.v >= 0;}
inline bool operator==(const tock& t1, const tock& t2) {return t1.v - t2.v == 0;}
inline bool operator!=(const tock& t1, const tock& t2) {return t1.v - t2.v != 0;}
inline bool operator<(const tock& t1, const tock& t2) {return t2.v - t1.v > 0;}
inline bool operator<=(const tock& t1, const tock& t2) {return t2.v - t1.v >= 0;}
inline quint32 operator-(const tock& t1, const tock& t2) {return t1.v - t2.v;}


#endif /*_TOCK_H*/
1 change: 1 addition & 0 deletions src/sacn/e1_11.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define E1_11_H

namespace E1_11 {
static const unsigned int MIN_REFRESH_RATE_HZ = 1; // E1.11:2008 Table 6
static const unsigned int MAX_REFRESH_RATE_HZ = 44; // E1.11:2008 Table 6
}

Expand Down
2 changes: 1 addition & 1 deletion src/sacn/sacndiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void sACNDiscoveryRX::processPacket(quint8* pbuf, uint buflen)
qDebug() << "DiscoveryRX : New universe - CID" << CID::CIDIntoQString(cid) << ", universe" << universe;
emit newUniverse(CID::CIDIntoQString(cid), universe);
}
m_discoveryList[cid]->Universe[universe].SetInterval(E131_UNIVERSE_DISCOVERY_INTERVAL);
m_discoveryList[cid]->Universe[universe].SetInterval(std::chrono::milliseconds(E131_UNIVERSE_DISCOVERY_INTERVAL));
}
}
else
Expand Down
20 changes: 10 additions & 10 deletions src/sacn/sacnlistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,14 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
{
// This is a source which is coming back online, so we need to repeat the steps
// for initial source aquisition
ps->active.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL);
ps->active.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL));
ps->lastseq = sequence;
ps->src_cid = source_cid;
ps->src_valid = true;
ps->doing_dmx = (start_code == STARTCODE_DMX);
ps->doing_per_channel = ps->waited_for_dd = false;
newsourcenotify = false;
ps->priority_wait.SetInterval(WAIT_PRIORITY);
ps->priority_wait.SetInterval(std::chrono::milliseconds(WAIT_PRIORITY));
}

if(
Expand All @@ -358,10 +358,10 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
//to a value of 1, a receiver shall enter network
//data loss condition. Any property values in
//these packets shall be ignored"
(*it)->active.SetInterval(m_ssHLL); //We factor in the hold last look time here, rather than 0
(*it)->active.SetInterval(std::chrono::milliseconds(m_ssHLL)); //We factor in the hold last look time here, rather than 0

if((*it)->doing_per_channel)
(*it)->priority_wait.SetInterval(m_ssHLL); //We factor in the hold last look time here, rather than 0
(*it)->priority_wait.SetInterval(std::chrono::milliseconds(m_ssHLL)); //We factor in the hold last look time here, rather than 0

validpacket = false;
break;
Expand All @@ -372,7 +372,7 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
{
//No matter how valid, we got something -- but we'll tweak the interval for any hll change
(*it)->doing_dmx = true;
(*it)->active.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL);
(*it)->active.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL));
}
else if(start_code == STARTCODE_PRIORITY && (*it)->waited_for_dd)
{
Expand Down Expand Up @@ -414,14 +414,14 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
{
(*it)->waited_for_dd = true;
(*it)->doing_per_channel = true;
(*it)->priority_wait.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL);
(*it)->priority_wait.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL));
newsourcenotify = true;
}
else if((*it)->priority_wait.Expired())
{
(*it)->waited_for_dd = true;
(*it)->doing_per_channel = false;
(*it)->priority_wait.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL); //In case the source later decides to sent 0xdd packets
(*it)->priority_wait.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL)); //In case the source later decides to sent 0xdd packets
newsourcenotify = true;
}
else
Expand All @@ -448,7 +448,7 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
ps->ip = sender;
ps->universe = universe;
ps->synchronization = synchronization;
ps->active.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL);
ps->active.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL));
ps->lastseq = sequence;
ps->src_cid = source_cid;
ps->src_valid = true;
Expand All @@ -460,14 +460,14 @@ void sACNListener::processDatagram(const QByteArray &data, const QHostAddress &d
ps->waited_for_dd = true;
ps->doing_per_channel = (start_code == STARTCODE_PRIORITY);
newsourcenotify = true;
ps->priority_wait.SetInterval(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL);
ps->priority_wait.SetInterval(std::chrono::milliseconds(E131_NETWORK_DATA_LOSS_TIMEOUT + m_ssHLL));
}
else
{
//If we aren't sampling, we want the earlier logic to set the state
ps->doing_per_channel = ps->waited_for_dd = false;
newsourcenotify = false;
ps->priority_wait.SetInterval(WAIT_PRIORITY);
ps->priority_wait.SetInterval(std::chrono::milliseconds(WAIT_PRIORITY));
}

validpacket = newsourcenotify;
Expand Down
Loading

0 comments on commit cf09754

Please sign in to comment.