git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2655 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -1237,10 +1237,12 @@ EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_cli | |||
#endif | |||
JackTimer timer; | |||
JackEngineControl* control = GetEngineControl(); | |||
if (!control) | |||
if (control) { | |||
control->ReadFrameTime(&timer); | |||
return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate); | |||
} else { | |||
return 0; | |||
control->ReadFrameTime(&timer); | |||
return (jack_nframes_t) floor((((float)control->fSampleRate) / 1000000.0f) * (GetMicroSeconds() - timer.fCurrentCallback)); | |||
} | |||
} | |||
EXPORT jack_time_t jack_get_time() | |||
@@ -1260,13 +1262,9 @@ EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nfr | |||
} else { | |||
JackTimer timer; | |||
JackEngineControl* control = GetEngineControl(); | |||
if (!control) | |||
return 0; | |||
control->ReadFrameTime(&timer); | |||
if (timer.fInitialized) { | |||
return timer.fCurrentWakeup + | |||
(long) rint(((double) ((frames - timer.fFrames)) * | |||
((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) / control->fBufferSize); | |||
if (control) { | |||
control->ReadFrameTime(&timer); | |||
return timer.Frames2Time(frames, control->fBufferSize); | |||
} else { | |||
return 0; | |||
} | |||
@@ -1285,13 +1283,9 @@ EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_ | |||
} else { | |||
JackTimer timer; | |||
JackEngineControl* control = GetEngineControl(); | |||
if (!control) | |||
return 0; | |||
control->ReadFrameTime(&timer); | |||
if (timer.fInitialized) { | |||
return timer.fFrames + | |||
(long) rint(((double) ((time - timer.fCurrentWakeup)) / | |||
((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) * control->fBufferSize); | |||
if (control) { | |||
control->ReadFrameTime(&timer); | |||
return timer.Time2Frames(time, control->fBufferSize); | |||
} else { | |||
return 0; | |||
} | |||
@@ -1312,7 +1306,7 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) | |||
JackEngineControl* control = GetEngineControl(); | |||
if (control) { | |||
control->ReadFrameTime(&timer); | |||
return timer.fFrames; | |||
return timer.CurFrame(); | |||
} else { | |||
return 0; | |||
} | |||
@@ -126,16 +126,16 @@ namespace Jack | |||
return (res < 0) ? 1 : res; | |||
} | |||
jack_time_t CurFrame2Time() | |||
jack_nframes_t CurFrame() | |||
{ | |||
return fCurrentWakeup; | |||
return fFrames; | |||
} | |||
jack_nframes_t CurTime2Frame() | |||
jack_time_t CurTime() | |||
{ | |||
return fFrames; | |||
return fCurrentWakeup; | |||
} | |||
}; | |||
class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop> | |||
@@ -40,18 +40,41 @@ JackTimer::JackTimer() | |||
fSecondOrderIntegrator = 0.0f; | |||
} | |||
jack_nframes_t JackTimer::Time2Frames(jack_time_t time, jack_nframes_t buffer_size) | |||
{ | |||
if (fInitialized) { | |||
return fFrames + (long)rint(((double) ((time - fCurrentWakeup)) / ((jack_time_t)(fNextWakeUp - fCurrentWakeup))) * buffer_size); | |||
} else { | |||
return 0; | |||
} | |||
} | |||
jack_time_t JackTimer::Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size) | |||
{ | |||
if (fInitialized) { | |||
return fCurrentWakeup + (long)rint(((double) ((frames - fFrames)) * ((jack_time_t)(fNextWakeUp - fCurrentWakeup))) / buffer_size); | |||
} else { | |||
return 0; | |||
} | |||
} | |||
jack_nframes_t JackTimer::FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate) | |||
{ | |||
return (jack_nframes_t) floor((((float)frames_rate) / 1000000.0f) * (cur_time - fCurrentCallback)); | |||
} | |||
void JackFrameTimer::InitFrameTime() | |||
{ | |||
fFirstWakeUp = true; | |||
} | |||
void JackFrameTimer::IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | |||
void JackFrameTimer::IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs) | |||
{ | |||
if (fFirstWakeUp) { | |||
InitFrameTimeAux(callback_usecs, period_usecs); | |||
fFirstWakeUp = false; | |||
} else { | |||
IncFrameTimeAux(nframes, callback_usecs, period_usecs); | |||
IncFrameTimeAux(buffer_size, callback_usecs, period_usecs); | |||
} | |||
} | |||
@@ -97,13 +120,13 @@ void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t pe | |||
TrySwitchState(); // always succeed since there is only one writer | |||
} | |||
void JackFrameTimer::IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | |||
void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs) | |||
{ | |||
JackTimer* timer = WriteNextStateStart(); | |||
float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp; | |||
timer->fCurrentWakeup = timer->fNextWakeUp; | |||
timer->fCurrentCallback = callback_usecs; | |||
timer->fFrames += nframes; | |||
timer->fFrames += buffer_size; | |||
timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta; | |||
timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator))); | |||
timer->fInitialized = true; | |||
@@ -32,22 +32,40 @@ namespace Jack | |||
\brief A structure used for time management. | |||
*/ | |||
struct EXPORT JackTimer | |||
class EXPORT JackTimer | |||
{ | |||
jack_nframes_t fFrames; | |||
jack_time_t fCurrentWakeup; | |||
jack_time_t fCurrentCallback; | |||
jack_time_t fNextWakeUp; | |||
float fSecondOrderIntegrator; | |||
bool fInitialized; | |||
/* not accessed by clients */ | |||
float fFilterCoefficient; /* set once, never altered */ | |||
JackTimer(); | |||
~JackTimer() | |||
{} | |||
friend class JackFrameTimer; | |||
private: | |||
jack_nframes_t fFrames; | |||
jack_time_t fCurrentWakeup; | |||
jack_time_t fCurrentCallback; | |||
jack_time_t fNextWakeUp; | |||
float fSecondOrderIntegrator; | |||
bool fInitialized; | |||
float fFilterCoefficient; /* set once, never altered */ | |||
public: | |||
JackTimer(); | |||
~JackTimer() | |||
{} | |||
jack_nframes_t Time2Frames(jack_time_t time, jack_nframes_t buffer_size); | |||
jack_time_t Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size); | |||
jack_nframes_t FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate); | |||
jack_nframes_t CurFrame() | |||
{ | |||
return fFrames; | |||
} | |||
jack_time_t CurTime() | |||
{ | |||
return fCurrentWakeup; | |||
} | |||
}; | |||
@@ -57,10 +75,11 @@ struct EXPORT JackTimer | |||
class JackFrameTimer : public JackAtomicState<JackTimer> | |||
{ | |||
private: | |||
bool fFirstWakeUp; | |||
void IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | |||
void IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); | |||
void InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs); | |||
public: | |||
@@ -72,7 +91,7 @@ class JackFrameTimer : public JackAtomicState<JackTimer> | |||
void InitFrameTime(); | |||
void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); | |||
void IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | |||
void IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); | |||
void ReadFrameTime(JackTimer* timer); | |||
}; | |||