00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackEngineControl.h"
00022 #include "JackGraphManager.h"
00023 #include "JackClientControl.h"
00024 #include <algorithm>
00025 #include <math.h>
00026
00027 namespace Jack
00028 {
00029
00030 void JackEngineControl::CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t callback_usecs)
00031 {
00032
00033 fTransport.CycleBegin(fSampleRate, callback_usecs);
00034
00035
00036 fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs);
00037
00038
00039 GetTimeMeasure(table, manager, callback_usecs);
00040 CalcCPULoad(table, manager);
00041 }
00042
00043 void JackEngineControl::CycleEnd(JackClientInterface** table)
00044 {
00045 fTransport.CycleEnd(table, fSampleRate, fBufferSize);
00046 }
00047
00048 void JackEngineControl::InitFrameTime()
00049 {
00050 fFrameTimer.InitFrameTime();
00051 }
00052
00053 void JackEngineControl::ResetFrameTime(jack_time_t callback_usecs)
00054 {
00055 fFrameTimer.ResetFrameTime(fSampleRate, callback_usecs, fPeriodUsecs);
00056 }
00057
00058 void JackEngineControl::ReadFrameTime(JackTimer* timer)
00059 {
00060 fFrameTimer.ReadFrameTime(timer);
00061 }
00062
00063
00064 #ifdef WIN32
00065 inline jack_time_t MAX(jack_time_t a, jack_time_t b)
00066 {
00067 return (a < b) ? b : a;
00068 }
00069 #else
00070 #define MAX(a,b) std::max((a),(b))
00071 #endif
00072
00073 void JackEngineControl::CalcCPULoad(JackClientInterface** table, JackGraphManager* manager)
00074 {
00075 jack_time_t lastCycleEnd = fLastProcessTime;
00076
00077 for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) {
00078 JackClientInterface* client = table[i];
00079 JackClientTiming* timing = manager->GetClientTiming(i);
00080 if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) {
00081 lastCycleEnd = MAX(lastCycleEnd, timing->fFinishedAt);
00082 }
00083 }
00084
00085
00086 fRollingClientUsecs[fRollingClientUsecsIndex++] = lastCycleEnd - fLastTime;
00087
00088 if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) {
00089 fRollingClientUsecsIndex = 0;
00090 }
00091
00092
00093
00094
00095
00096 if (++fRollingClientUsecsCnt % fRollingInterval == 0) {
00097
00098 jack_time_t maxUsecs = 0;
00099 for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) {
00100 maxUsecs = MAX(fRollingClientUsecs[i], maxUsecs);
00101 }
00102
00103 fMaxUsecs = MAX(fMaxUsecs, maxUsecs);
00104 fSpareUsecs = jack_time_t((maxUsecs < fPeriodUsecs) ? fPeriodUsecs - maxUsecs : 0);
00105 fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f));
00106 }
00107 }
00108
00109 void JackEngineControl::ResetRollingUsecs()
00110 {
00111 memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs));
00112 fRollingClientUsecsIndex = 0;
00113 fRollingClientUsecsCnt = 0;
00114 fSpareUsecs = 0;
00115 fRollingInterval = (int)floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs);
00116 }
00117
00118 void JackEngineControl::GetTimeMeasure(JackClientInterface** table, JackGraphManager* manager, jack_time_t callback_usecs)
00119 {
00120 int pos = (++fAudioCycle) % TIME_POINTS;
00121
00122 fLastTime = fCurTime;
00123 fCurTime = callback_usecs;
00124
00125 fLastProcessTime = fProcessTime;
00126 fProcessTime = GetMicroSeconds();
00127
00128 if (fLastTime > 0) {
00129 fMeasure[pos].fEngineTime = fLastTime;
00130 fMeasure[pos].fAudioCycle = fAudioCycle;
00131
00132 for (int i = 0; i < CLIENT_NUM; i++) {
00133 JackClientInterface* client = table[i];
00134 JackClientTiming* timing = manager->GetClientTiming(i);
00135 if (client && client->GetClientControl()->fActive) {
00136 fMeasure[pos].fClientTable[i].fRefNum = i;
00137 fMeasure[pos].fClientTable[i].fSignaledAt = timing->fSignaledAt;
00138 fMeasure[pos].fClientTable[i].fAwakeAt = timing->fAwakeAt;
00139 fMeasure[pos].fClientTable[i].fFinishedAt = timing->fFinishedAt;
00140 fMeasure[pos].fClientTable[i].fStatus = timing->fStatus;
00141 }
00142 }
00143 }
00144 }
00145
00146 void JackEngineControl::ClearTimeMeasures()
00147 {
00148 for (int i = 0; i < TIME_POINTS; i++) {
00149 for (int j = 0; j < CLIENT_NUM; j++) {
00150 fMeasure[i].fClientTable[j].fRefNum = 0;
00151 fMeasure[i].fClientTable[j].fSignaledAt = 0;
00152 fMeasure[i].fClientTable[j].fAwakeAt = 0;
00153 fMeasure[i].fClientTable[j].fFinishedAt = 0;
00154 }
00155 }
00156 fLastTime = fCurTime = 0;
00157 }
00158
00159 }