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 fPeriodUsecs = 0.0f;
00047 fFilterOmega = 0.0f;
00048 }
00049
00050 jack_nframes_t JackTimer::Time2Frames(jack_time_t usecs, jack_nframes_t buffer_size)
00051 {
00052 if (fInitialized) {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 int64_t du = usecs - fCurrentWakeup;
00064 int64_t dp = fNextWakeUp - fCurrentWakeup;
00065 return fFrames + (int32_t)rint((double)du / (double)dp * buffer_size);
00066 } else {
00067 return 0;
00068 }
00069 }
00070
00071 jack_time_t JackTimer::Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size)
00072 {
00073 if (fInitialized) {
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 int32_t df = frames - fFrames;
00085 int64_t dp = fNextWakeUp - fCurrentWakeup;
00086 return fCurrentWakeup + (int64_t)rint((double) df * (double) dp / buffer_size);
00087 } else {
00088 return 0;
00089 }
00090 }
00091
00092 int JackTimer::GetCycleTimes(jack_nframes_t* current_frames, jack_time_t* current_usecs, jack_time_t* next_usecs, float* period_usecs)
00093 {
00094 if (fInitialized) {
00095 *current_frames = fFrames;
00096 *current_usecs = fCurrentWakeup;
00097 *next_usecs = fNextWakeUp;
00098 *period_usecs = fPeriodUsecs;
00099 return 0;
00100 } else {
00101 return -1;
00102 }
00103 }
00104
00105 jack_nframes_t JackTimer::FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate)
00106 {
00107 return (jack_nframes_t) floor((((float)frames_rate) / 1000000.0f) * (cur_time - fCurrentCallback));
00108 }
00109
00110 void JackFrameTimer::InitFrameTime()
00111 {
00112 fFirstWakeUp = true;
00113 }
00114
00115 void JackFrameTimer::IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs)
00116 {
00117 if (fFirstWakeUp) {
00118 InitFrameTimeAux(callback_usecs, period_usecs);
00119 fFirstWakeUp = false;
00120 }
00121
00122 IncFrameTimeAux(buffer_size, callback_usecs, period_usecs);
00123 }
00124
00125 void JackFrameTimer::ResetFrameTime(jack_time_t callback_usecs)
00126 {
00127 if (!fFirstWakeUp) {
00128 JackTimer* timer = WriteNextStateStart();
00129 timer->fCurrentWakeup = callback_usecs;
00130 timer->fCurrentCallback = callback_usecs;
00131 WriteNextStateStop();
00132 TrySwitchState();
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00141 void JackFrameTimer::ReadFrameTime(JackTimer* timer)
00142 {
00143 UInt16 next_index = GetCurrentIndex();
00144 UInt16 cur_index;
00145 do {
00146 cur_index = next_index;
00147 memcpy(timer, ReadCurrentState(), sizeof(JackTimer));
00148 next_index = GetCurrentIndex();
00149 } while (cur_index != next_index);
00150 }
00151
00152
00153
00154 void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs)
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 JackTimer* timer = WriteNextStateStart();
00190 timer->fPeriodUsecs = (float)period_usecs;
00191 timer->fCurrentCallback = callback_usecs;
00192 timer->fNextWakeUp = callback_usecs;
00193 timer->fFilterOmega = period_usecs * 7.854e-7f;
00194 WriteNextStateStop();
00195 TrySwitchState();
00196 }
00197
00198 void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs)
00199 {
00200 JackTimer* timer = WriteNextStateStart();
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 float delta = (float)((int64_t)callback_usecs - (int64_t)timer->fNextWakeUp);
00225 delta *= timer->fFilterOmega;
00226 timer->fCurrentWakeup = timer->fNextWakeUp;
00227 timer->fCurrentCallback = callback_usecs;
00228 timer->fFrames += buffer_size;
00229 timer->fPeriodUsecs += timer->fFilterOmega * delta;
00230 timer->fNextWakeUp += (int64_t)floorf(timer->fPeriodUsecs + 1.41f * delta + 0.5f);
00231 timer->fInitialized = true;
00232
00233 WriteNextStateStop();
00234 TrySwitchState();
00235 }
00236
00237 }
00238