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); | |||
| }; | |||