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 | #endif | ||||
| JackTimer timer; | JackTimer timer; | ||||
| JackEngineControl* control = GetEngineControl(); | JackEngineControl* control = GetEngineControl(); | ||||
| if (!control) | |||||
| if (control) { | |||||
| control->ReadFrameTime(&timer); | |||||
| return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate); | |||||
| } else { | |||||
| return 0; | 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() | 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 { | } else { | ||||
| JackTimer timer; | JackTimer timer; | ||||
| JackEngineControl* control = GetEngineControl(); | 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 { | } else { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -1285,13 +1283,9 @@ EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_ | |||||
| } else { | } else { | ||||
| JackTimer timer; | JackTimer timer; | ||||
| JackEngineControl* control = GetEngineControl(); | 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 { | } else { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -1312,7 +1306,7 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) | |||||
| JackEngineControl* control = GetEngineControl(); | JackEngineControl* control = GetEngineControl(); | ||||
| if (control) { | if (control) { | ||||
| control->ReadFrameTime(&timer); | control->ReadFrameTime(&timer); | ||||
| return timer.fFrames; | |||||
| return timer.CurFrame(); | |||||
| } else { | } else { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -126,16 +126,16 @@ namespace Jack | |||||
| return (res < 0) ? 1 : res; | 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> | class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop> | ||||
| @@ -40,18 +40,41 @@ JackTimer::JackTimer() | |||||
| fSecondOrderIntegrator = 0.0f; | 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() | void JackFrameTimer::InitFrameTime() | ||||
| { | { | ||||
| fFirstWakeUp = true; | 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) { | if (fFirstWakeUp) { | ||||
| InitFrameTimeAux(callback_usecs, period_usecs); | InitFrameTimeAux(callback_usecs, period_usecs); | ||||
| fFirstWakeUp = false; | fFirstWakeUp = false; | ||||
| } else { | } 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 | 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(); | JackTimer* timer = WriteNextStateStart(); | ||||
| float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp; | float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp; | ||||
| timer->fCurrentWakeup = timer->fNextWakeUp; | timer->fCurrentWakeup = timer->fNextWakeUp; | ||||
| timer->fCurrentCallback = callback_usecs; | timer->fCurrentCallback = callback_usecs; | ||||
| timer->fFrames += nframes; | |||||
| timer->fFrames += buffer_size; | |||||
| timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta; | timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta; | ||||
| timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator))); | timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator))); | ||||
| timer->fInitialized = true; | timer->fInitialized = true; | ||||
| @@ -32,22 +32,40 @@ namespace Jack | |||||
| \brief A structure used for time management. | \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> | class JackFrameTimer : public JackAtomicState<JackTimer> | ||||
| { | { | ||||
| private: | private: | ||||
| bool fFirstWakeUp; | 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); | void InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs); | ||||
| public: | public: | ||||
| @@ -72,7 +91,7 @@ class JackFrameTimer : public JackAtomicState<JackTimer> | |||||
| void InitFrameTime(); | void InitFrameTime(); | ||||
| void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); | 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); | void ReadFrameTime(JackTimer* timer); | ||||
| }; | }; | ||||