[dasher] Fix framerate changing!
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher] Fix framerate changing!
- Date: Tue, 18 Jan 2011 17:15:39 +0000 (UTC)
commit a9d64488415bc84671d83ee102c2c40d64a53785
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Tue Oct 12 16:36:37 2010 +0100
Fix framerate changing!
LP_FRAMERATE stores decaying average of framerate; used to
compute m_iSteps & m_dRXMax immediately upon bitrate change.
Removed GetFramerate() etc. methods (use LP_FRAMERATE!)
Src/DasherCore/AutoSpeedControl.cpp | 16 +++----
Src/DasherCore/AutoSpeedControl.h | 2 +-
Src/DasherCore/DasherGameMode.cpp | 5 +-
Src/DasherCore/DasherInterfaceBase.cpp | 7 ---
Src/DasherCore/DasherInterfaceBase.h | 2 -
Src/DasherCore/DefaultFilter.cpp | 2 +-
Src/DasherCore/FrameRate.cpp | 64 ++++++++++++++++++--------------
Src/DasherCore/FrameRate.h | 30 +++++++--------
Src/DasherCore/Parameters.h | 2 +-
Src/Gtk2/GtkDasherControl.cpp | 6 ---
Src/Gtk2/GtkDasherControl.h | 1 -
11 files changed, 62 insertions(+), 75 deletions(-)
---
diff --git a/Src/DasherCore/AutoSpeedControl.cpp b/Src/DasherCore/AutoSpeedControl.cpp
index be487e2..afafc18 100644
--- a/Src/DasherCore/AutoSpeedControl.cpp
+++ b/Src/DasherCore/AutoSpeedControl.cpp
@@ -129,13 +129,11 @@ inline double CAutoSpeedControl::Variance()
inline int CAutoSpeedControl::UpdateSampleSize(double dFrameRate)
{
- double dFramerate = dFrameRate;
- double dSpeedSamples = 0.0;
- double dBitrate = m_dBitrate;
- if(dBitrate < 1.0)// for the purposes of this function
- dBitrate = 1.0; // we don't care exactly how slow we're going
- // *really* low speeds are ~ equivalent?
- dSpeedSamples = dFramerate * (m_dSampleScale / dBitrate + m_dSampleOffset);
+ // for the purposes of this function
+ // we don't care exactly how slow we're going
+ // *really* low speeds are ~ equivalent?
+ double dBitrate = std::max(1.0,m_dBitrate);
+ double dSpeedSamples = dFrameRate * (m_dSampleScale / dBitrate + m_dSampleOffset);
m_nSpeedSamples = int(round(dSpeedSamples));
@@ -180,7 +178,7 @@ inline void CAutoSpeedControl::UpdateSigmas(double r, double dFrameRate)
////////////////////////////////////////////////////////////////
-void CAutoSpeedControl::SpeedControl(myint iDasherX, myint iDasherY, double dFrameRate, CDasherView *pView) {
+void CAutoSpeedControl::SpeedControl(myint iDasherX, myint iDasherY, CDasherView *pView) {
if(GetBoolParameter(BP_AUTO_SPEEDCONTROL)) {
// Coordinate transforms:
@@ -188,7 +186,7 @@ void CAutoSpeedControl::SpeedControl(myint iDasherX, myint iDasherY, double dFra
pView->Dasher2Polar(iDasherX, iDasherY, r, theta);
m_dBitrate = GetLongParameter(LP_MAX_BITRATE) / 100.0; // stored as long(round(true bitrate * 100))
-
+ double dFrameRate = GetLongParameter(LP_FRAMERATE) / 100.0;
UpdateSigmas(r, dFrameRate);
// Data collection:
diff --git a/Src/DasherCore/AutoSpeedControl.h b/Src/DasherCore/AutoSpeedControl.h
index 2a184ff..e41143b 100644
--- a/Src/DasherCore/AutoSpeedControl.h
+++ b/Src/DasherCore/AutoSpeedControl.h
@@ -22,7 +22,7 @@ class CAutoSpeedControl : public Dasher::CDasherComponent {
/// \param dFrameRate The current frame rate
/// \param pView The current Dasher view class
///
- void SpeedControl(myint iDasherX, myint iDasherY, double dFrameRate, CDasherView *pView);
+ void SpeedControl(myint iDasherX, myint iDasherY, CDasherView *pView);
virtual void HandleEvent(Dasher::CEvent *pEvent) {
};
diff --git a/Src/DasherCore/DasherGameMode.cpp b/Src/DasherCore/DasherGameMode.cpp
index 40e0793..aa9bcd9 100644
--- a/Src/DasherCore/DasherGameMode.cpp
+++ b/Src/DasherCore/DasherGameMode.cpp
@@ -438,13 +438,12 @@ void CDasherGameMode::SetTargetY(const std::vector<std::pair<Dasher::myint,bool>
void CDasherGameMode::CalculateDemoParameters()
{
+ if(GetLongParameter(LP_FRAMERATE) <= 0) return;
// Recalculates the parameters used in the demo following a change in framerate or speed.
double spring = GetLongParameter(LP_DEMO_SPRING)/100.0;
double noisemem = GetLongParameter(LP_DEMO_NOISE_MEM)/100.0;
- double lambda = 0.7*double(GetLongParameter(LP_MAX_BITRATE))/(100.0*m_pModel->Framerate());
+ double lambda = 0.7*double(GetLongParameter(LP_MAX_BITRATE))/(100.0*GetLongParameter(LP_FRAMERATE));
- if(m_pModel->Framerate() <= 0) return;
-
m_DemoCfg.dSpring = (1-exp(-spring*lambda));
m_DemoCfg.dNoiseNew = noisemem*(1-exp(-lambda));
m_DemoCfg.dNoiseOld = sqrt(1.0-m_DemoCfg.dNoiseNew*m_DemoCfg.dNoiseNew);
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index 52f224c..5a6b008 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -1052,13 +1052,6 @@ void CDasherInterfaceBase::ExecuteCommand(const std::string &strName) {
delete pEvent;
}
-double CDasherInterfaceBase::GetFramerate() {
- if(m_pDasherModel)
- return(m_pDasherModel->Framerate());
- else
- return 0.0;
-}
-
void CDasherInterfaceBase::AddActionButton(const std::string &strName) {
m_vRightButtons.push_back(new CActionButton(this, strName, false));
}
diff --git a/Src/DasherCore/DasherInterfaceBase.h b/Src/DasherCore/DasherInterfaceBase.h
index d621194..40bfc96 100644
--- a/Src/DasherCore/DasherInterfaceBase.h
+++ b/Src/DasherCore/DasherInterfaceBase.h
@@ -325,8 +325,6 @@ public:
void ResetNats();
- double GetFramerate();
-
/// @}
/// @name Control hierarchy and action buttons
diff --git a/Src/DasherCore/DefaultFilter.cpp b/Src/DasherCore/DefaultFilter.cpp
index a66336d..c8e9276 100644
--- a/Src/DasherCore/DefaultFilter.cpp
+++ b/Src/DasherCore/DefaultFilter.cpp
@@ -70,7 +70,7 @@ bool CDefaultFilter::Timer(int Time, CDasherView *m_pDasherView, CDasherModel *m
m_pDasherModel->OneStepTowards(iDasherX,iDasherY, Time, pAdded, pNumDeleted);
bDidSomething = true;
- m_pAutoSpeedControl->SpeedControl(iDasherX, iDasherY, m_pDasherModel->Framerate(), m_pDasherView);
+ m_pAutoSpeedControl->SpeedControl(iDasherX, iDasherY, m_pDasherView);
}
if(m_pStartHandler)
diff --git a/Src/DasherCore/FrameRate.cpp b/Src/DasherCore/FrameRate.cpp
index 2712d02..ff69c24 100644
--- a/Src/DasherCore/FrameRate.cpp
+++ b/Src/DasherCore/FrameRate.cpp
@@ -1,21 +1,20 @@
#include "FrameRate.h"
-namespace Dasher {
+
+using namespace Dasher;
+
CFrameRate::CFrameRate(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore) :
CDasherComponent(pEventHandler, pSettingsStore) {
- //what follows was once the Initialise() method, but
- // (ACL 21/05/09) is no longer called from elsewhere, hence inlining
- m_dRXmax = 2; // only a transient effect
+ //Sampling parameters...
m_iFrames = 0;
m_iSamples = 1;
-
- // start off very slow until we have sampled framerate adequately
- m_iSteps = 2000;
m_iTime = 0; // Hmmm, User must reset framerate before starting.
- //Set bitrate and framerate
- m_dFr = GetLongParameter(LP_FRAMERATE) / 100.0;
- m_dMaxbitrate = GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR) / 10000.0;
+ //try and carry on from where we left off at last run
+ CParameterNotificationEvent evt(LP_FRAMERATE);
+ HandleEvent(&evt);
+ evt.m_iParameter = LP_MAX_BITRATE;
+ HandleEvent(&evt); //calls UpdateSteps(), which sets m_dRXMax and m_iSteps
}
void CFrameRate::RecordFrame(unsigned long Time)
@@ -24,7 +23,7 @@ void CFrameRate::RecordFrame(unsigned long Time)
// Update values once enough samples have been collected
if(m_iFrames == m_iSamples) {
- m_iTime2 = Time;
+ int m_iTime2 = Time;
// If samples are collected in < 50ms, collect more
if(m_iTime2 - m_iTime < 50)
@@ -39,25 +38,19 @@ void CFrameRate::RecordFrame(unsigned long Time)
// Calculate the framerate and reset framerate statistics for next
// sampling period
+ double dFrNow;
if(m_iTime2 - m_iTime > 0) {
- SetLongParameter(LP_FRAMERATE, m_iFrames * 100000.0 / (m_iTime2 - m_iTime));
+ dFrNow = m_iFrames * 1000.0 / (m_iTime2 - m_iTime);
+ SetLongParameter(LP_FRAMERATE, long(GetLongParameter(LP_FRAMERATE) + (dFrNow*100))/2);
m_iTime = m_iTime2;
m_iFrames = 0;
- }
+ } else //best guess: use decaying average
+ dFrNow = GetLongParameter(LP_FRAMERATE) / 100.0;
- // Update auxiliary variables - even if we didn't recalc the framerate
- // (means we reach sensible values more quickly after first loading)
- m_dRXmax = exp(m_dMaxbitrate * LN2 / m_dFr);
-
- // Note that m_iSteps is smoothed here - 50:50 interpolation with
- // previous value
- m_iSteps = m_iSteps / 2 + (int)(-log(0.2) * m_dFr / LN2 / m_dMaxbitrate) / 2;
+ UpdateSteps(dFrNow);
- // If the framerate slows to < 4 then we end up with steps < 1 !
- if(m_iSteps == 0)
- m_iSteps = 1;
+ DASHER_TRACEOUTPUT("Fr %f Steps %d Samples %d Time2 %d rxmax %f\n", dFrNow, m_iSteps, m_iSamples, m_iTime2, m_dRXmax);
- DASHER_TRACEOUTPUT("Fr %f Steps %d Samples %d Time2 %d rxmax %f\n", m_dFr, m_iSteps, m_iSamples, m_iTime2, m_dRXmax);
}
}
@@ -69,14 +62,29 @@ void CFrameRate::HandleEvent(Dasher::CEvent *pEvent) {
switch (pEvt->m_iParameter) {
case LP_MAX_BITRATE: // Delibarate fallthrough
case LP_BOOSTFACTOR:
- BitrateChanged(GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR) / 10000.0);
- //Apply the bit rate fully straightaway (no 50:50 interpolation with previous):
- m_iSteps = (int)(-log(0.2) * m_dFr / LN2 / m_dMaxbitrate);
+ m_dMaxbitrate=(GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR)) / 10000.0;
+ UpdateSteps(GetLongParameter(LP_FRAMERATE) / 100.0); //use the decaying average as current
break;
case LP_FRAMERATE:
- FramerateChanged(GetLongParameter(LP_FRAMERATE) / 100.0);
+ m_dFrDecay = GetLongParameter(LP_FRAMERATE) / 100.0;
}
}
}
+const double LN2 = log(2.0);
+const double STEPS_COEFF = -log(0.2) / LN2;
+
+void CFrameRate::UpdateSteps(double dFrNow) {
+ // Update auxiliary variables - even if we didn't recalc the framerate
+ // (means we reach sensible values more quickly after first loading)
+ m_dRXmax = exp(m_dMaxbitrate * LN2 / dFrNow);
+
+ // Note that m_iSteps is smoothed here - 50:50 interpolation with
+ // previous value
+ m_iSteps = std::max(1,(int)(STEPS_COEFF * m_dFrDecay / m_dMaxbitrate));
+
+ // If the framerate slows to < 4 then we end up with steps < 1 !
+ if(m_iSteps == 0)
+ m_iSteps = 1;
+
}
diff --git a/Src/DasherCore/FrameRate.h b/Src/DasherCore/FrameRate.h
index 11cd288..8e13a80 100644
--- a/Src/DasherCore/FrameRate.h
+++ b/Src/DasherCore/FrameRate.h
@@ -15,14 +15,12 @@
#include "Parameters.h"
#include "DasherComponent.h"
-const double LN2 = log(2.0);
-
namespace Dasher {
/// \ingroup Model
/// \{
-/// keeps track of framerate
-/// computes the Steps parameter
+/// keeps the framerate (LP_FRAMERATE / 100.0) up-to-date,
+/// computes the Steps parameter,
/// computes RXmax - which controls the maximum rate of zooming in
class CFrameRate : public CDasherComponent {
public:
@@ -46,19 +44,10 @@ public:
return m_iSteps;
};
- ///
- /// Get the current framerate
- ///
- double Framerate() const {
- return m_dFr;
- };
-
double Bitrate() const {
return m_dMaxbitrate;
}
- virtual void BitrateChanged(double dMaxbitrate) {m_dMaxbitrate = dMaxbitrate;}
- virtual void FramerateChanged(double dFr) {m_dFr = dFr;}
///
/// Reset the framerate class
/// TODO: Need to check semantics here
@@ -69,15 +58,24 @@ public:
m_iTime = Time;
}
-
void RecordFrame(unsigned long Time);
private:
- double m_dFr; // current frame rate (cache of LP_FRAMERATE/100.0)
+ double m_dFrDecay; // current frame rate (cache of LP_FRAMERATE/100.0)
double m_dMaxbitrate; // the maximum rate of entering information (cache)
double m_dRXmax; // the maximum zoomin per frame
- int m_iFrames, m_iTime, m_iTime2, m_iSamples;
+ ///number of frames that have been sampled
+ int m_iFrames;
+ ///time at which first sampled frame was rendered
+ int m_iTime;
+ ///number of frames over which we will compute average framerate
+ int m_iSamples;
+
int m_iSteps; // the 'Steps' parameter. See djw thesis.
+
+ ///updates m_dRXMax and m_iSteps
+ /// \param dFrNow current (non-decaying-average) framerate (if available!)
+ void UpdateSteps(double dFrNow);
};
/// \}
}
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index dd95cfa..64df3f3 100644
--- a/Src/DasherCore/Parameters.h
+++ b/Src/DasherCore/Parameters.h
@@ -190,7 +190,7 @@ static lp_table longparamtable[] = {
{LP_ORIENTATION, "ScreenOrientation", PERS, -2, "Screen Orientation"},
{LP_REAL_ORIENTATION, "RealOrientation", !PERS, 0, "Actual screen orientation (allowing for alphabet default)"},
{LP_MAX_BITRATE, "MaxBitRateTimes100", PERS, 80, "Max Bit Rate Times 100"},
- {LP_FRAMERATE, "FrameRate", PERS, 3200, "Last known frame rate, times 100"},
+ {LP_FRAMERATE, "FrameRate", PERS, 3200, "Decaying average of last known frame rates, *100"},
{LP_VIEW_ID, "ViewID", PERS, 1, "ViewID"},
{LP_LANGUAGE_MODEL_ID, "LanguageModelID", PERS, 0, "LanguageModelID"},
{LP_DASHER_FONTSIZE, "DasherFontSize", PERS, 2, "DasherFontSize"},
diff --git a/Src/Gtk2/GtkDasherControl.cpp b/Src/Gtk2/GtkDasherControl.cpp
index e2ea47c..94778e1 100644
--- a/Src/Gtk2/GtkDasherControl.cpp
+++ b/Src/Gtk2/GtkDasherControl.cpp
@@ -289,12 +289,6 @@ gtk_dasher_control_force_pause(GtkDasherControl *pControl) {
pPrivate->pControl->Stop();
}
-double
-gtk_dasher_control_get_framerate(GtkDasherControl *pControl) {
- GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
- return pPrivate->pControl->GetFramerate();
-}
-
void
gtk_dasher_control_add_action_button(GtkDasherControl *pControl, const gchar *szCommand) {
GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
diff --git a/Src/Gtk2/GtkDasherControl.h b/Src/Gtk2/GtkDasherControl.h
index 1ff3ab1..3856c79 100644
--- a/Src/Gtk2/GtkDasherControl.h
+++ b/Src/Gtk2/GtkDasherControl.h
@@ -87,7 +87,6 @@ void gtk_dasher_control_game_helperreg(GtkDasherControl *pControl, void* gameHel
void gtk_dasher_control_game_messageout(GtkDasherControl *pControl, int message, const void* messagedata);
void gtk_dasher_control_force_pause(GtkDasherControl *pControl);
-double gtk_dasher_control_get_framerate(GtkDasherControl *pControl);
void gtk_dasher_control_add_action_button(GtkDasherControl *pControl, const gchar *szCommand);
void gtk_dasher_user_log_new_trial(GtkDasherControl * pControl);
void gtk_dasher_control_set_focus(GtkDasherControl * pControl);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]