00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackFrameTimer.h"
00022 #include "JackError.h"
00023 #include <math.h>
00024 #include <stdio.h>
00025
00026 namespace Jack
00027 {
00028
00029 #if defined(WIN32) && !defined(__MINGW32__)
00030
00031 inline double rint(double nr)
00032 {
00033 double f = floor(nr);
00034 double c = ceil(nr);
00035 return (((c -nr) >= (nr - f)) ? f : c);
00036 }
00037 #endif
00038
00039 JackTimer::JackTimer()
00040 {
00041 fInitialized = false;
00042 fFrames = 0;
00043 fCurrentWakeup = 0;
00044 fCurrentCallback = 0;
00045 fNextWakeUp = 0;
00046 fFilterCoefficient = 0.01f;
00047 fSecondOrderIntegrator = 0.0f;
00048 }
00049
00050 jack_nframes_t JackTimer::Time2Frames(jack_time_t time, jack_nframes_t buffer_size)
00051 {
00052 if (fInitialized) {
00053 return fFrames + (long)rint(((double) ((long long)(time - fCurrentWakeup)) / ((long long)(fNextWakeUp - fCurrentWakeup))) * buffer_size);
00054 } else {
00055 return 0;
00056 }
00057 }
00058
00059 jack_time_t JackTimer::Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size)
00060 {
00061 if (fInitialized) {
00062 return fCurrentWakeup + (long)rint(((double) ((long long)(frames - fFrames)) * ((long long)(fNextWakeUp - fCurrentWakeup))) / buffer_size);
00063 } else {
00064 return 0;
00065 }
00066 }
00067
00068 jack_nframes_t JackTimer::FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate)
00069 {
00070 return (jack_nframes_t) floor((((float)frames_rate) / 1000000.0f) * (cur_time - fCurrentCallback));
00071 }
00072
00073 void JackFrameTimer::InitFrameTime()
00074 {
00075 fFirstWakeUp = true;
00076 }
00077
00078 void JackFrameTimer::IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs)
00079 {
00080 if (fFirstWakeUp) {
00081 InitFrameTimeAux(callback_usecs, period_usecs);
00082 fFirstWakeUp = false;
00083 } else {
00084 IncFrameTimeAux(buffer_size, callback_usecs, period_usecs);
00085 }
00086 }
00087
00088 void JackFrameTimer::ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs)
00089 {
00090 if (!fFirstWakeUp) {
00091 JackTimer* timer = WriteNextStateStart();
00092 jack_nframes_t period_size_guess = (jack_nframes_t)(frames_rate * ((timer->fNextWakeUp - timer->fCurrentWakeup) / 1000000.0));
00093 timer->fFrames += ((callback_usecs - timer->fNextWakeUp) / period_size_guess) * period_size_guess;
00094 timer->fCurrentWakeup = callback_usecs;
00095 timer->fCurrentCallback = callback_usecs;
00096 timer->fNextWakeUp = callback_usecs + period_usecs;
00097 WriteNextStateStop();
00098 TrySwitchState();
00099 }
00100 }
00101
00102
00103
00104
00105
00106
00107 void JackFrameTimer::ReadFrameTime(JackTimer* timer)
00108 {
00109 UInt16 next_index = GetCurrentIndex();
00110 UInt16 cur_index;
00111 do {
00112 cur_index = next_index;
00113 memcpy(timer, ReadCurrentState(), sizeof(JackTimer));
00114 next_index = GetCurrentIndex();
00115 } while (cur_index != next_index);
00116 }
00117
00118
00119
00120 void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs)
00121 {
00122 JackTimer* timer = WriteNextStateStart();
00123 timer->fSecondOrderIntegrator = 0.0f;
00124 timer->fCurrentCallback = callback_usecs;
00125 timer->fNextWakeUp = callback_usecs + period_usecs;
00126 WriteNextStateStop();
00127 TrySwitchState();
00128 }
00129
00130 void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs)
00131 {
00132 JackTimer* timer = WriteNextStateStart();
00133 float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp;
00134 timer->fCurrentWakeup = timer->fNextWakeUp;
00135 timer->fCurrentCallback = callback_usecs;
00136 timer->fFrames += buffer_size;
00137 timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta;
00138 timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator)));
00139 timer->fInitialized = true;
00140 WriteNextStateStop();
00141 TrySwitchState();
00142 }
00143
00144 }
00145