00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __JackConnectionManager__
00021 #define __JackConnectionManager__
00022
00023 #include "JackConstants.h"
00024 #include "JackActivationCount.h"
00025 #include <assert.h>
00026
00027 namespace Jack
00028 {
00029
00030 struct JackClientControl;
00031
00036 template <int SIZE>
00037 class JackFixedArray
00038 {
00039
00040 private:
00041
00042 jack_int_t fTable[SIZE];
00043 uint32_t fCounter;
00044
00045 public:
00046
00047 JackFixedArray()
00048 {
00049 Init();
00050 }
00051
00052 virtual ~JackFixedArray()
00053 {}
00054
00055 void Init()
00056 {
00057 for (int i = 0; i < SIZE; i++)
00058 fTable[i] = EMPTY;
00059 fCounter = 0;
00060 }
00061
00062 bool AddItem(jack_int_t index)
00063 {
00064 for (int i = 0; i < SIZE; i++) {
00065 if (fTable[i] == EMPTY) {
00066 fTable[i] = index;
00067 fCounter++;
00068 return true;
00069 }
00070 }
00071 return false;
00072 }
00073
00074 bool RemoveItem(jack_int_t index)
00075 {
00076 for (int i = 0; i < SIZE; i++) {
00077 if (fTable[i] == index) {
00078 fCounter--;
00079
00080 if (i == SIZE - 1) {
00081 fTable[i] = EMPTY;
00082 } else {
00083 int j;
00084 for (j = i; j <= SIZE - 2 && fTable[j] != EMPTY; j++) {
00085 fTable[j] = fTable[j + 1];
00086 }
00087 fTable[j] = EMPTY;
00088 }
00089 return true;
00090 }
00091 }
00092 return false;
00093 }
00094
00095 jack_int_t GetItem(jack_int_t index) const
00096 {
00097 return (index < SIZE) ? fTable[index] : EMPTY;
00098 }
00099
00100 const jack_int_t* GetItems() const
00101 {
00102 return fTable;
00103 }
00104
00105 bool CheckItem(jack_int_t index) const
00106 {
00107 for (int i = 0; i < SIZE && fTable[i] != EMPTY; i++) {
00108 if (fTable[i] == index)
00109 return true;
00110 }
00111 return false;
00112 }
00113
00114 uint32_t GetItemCount() const
00115 {
00116 return fCounter;
00117 }
00118
00119 };
00120
00125 template <int SIZE>
00126 class JackFixedArray1 : public JackFixedArray<SIZE>
00127 {
00128 private:
00129
00130 bool fUsed;
00131
00132 public:
00133
00134 JackFixedArray1()
00135 {
00136 Init();
00137 }
00138
00139 virtual ~JackFixedArray1()
00140 {}
00141
00142 void Init()
00143 {
00144 JackFixedArray<SIZE>::Init();
00145 fUsed = false;
00146 }
00147
00148 bool IsAvailable()
00149 {
00150 if (fUsed) {
00151 return false;
00152 } else {
00153 fUsed = true;
00154 return true;
00155 }
00156 }
00157 };
00158
00163 template <int SIZE>
00164 class JackFixedMatrix
00165 {
00166 private:
00167
00168 jack_int_t fTable[SIZE][SIZE];
00169
00170 public:
00171
00172 JackFixedMatrix()
00173 {}
00174
00175 virtual ~JackFixedMatrix()
00176 {}
00177
00178 void Init(jack_int_t index)
00179 {
00180 for (int i = 0; i < SIZE; i++) {
00181 fTable[index][i] = 0;
00182 fTable[i][index] = 0;
00183 }
00184 }
00185
00186 const jack_int_t* GetItems(jack_int_t index) const
00187 {
00188 return fTable[index];
00189 }
00190
00191 jack_int_t IncItem(jack_int_t index1, jack_int_t index2)
00192 {
00193 fTable[index1][index2]++;
00194 return fTable[index1][index2];
00195 }
00196
00197 jack_int_t DecItem(jack_int_t index1, jack_int_t index2)
00198 {
00199 fTable[index1][index2]--;
00200 return fTable[index1][index2];
00201 }
00202
00203 jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const
00204 {
00205 return fTable[index1][index2];
00206 }
00207
00211 void GetOutputTable(jack_int_t index, jack_int_t* output) const
00212 {
00213 int i, j;
00214
00215 for (i = 0; i < SIZE; i++)
00216 output[i] = EMPTY;
00217
00218 for (i = 0, j = 0; i < SIZE; i++) {
00219 if (fTable[index][i] > 0) {
00220 output[j] = i;
00221 j++;
00222 }
00223 }
00224 }
00225
00226 bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00227 {
00228 for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00229 if (output[i] == index)
00230 return true;
00231 }
00232 return false;
00233 }
00234
00235 };
00236
00241 template <int SIZE>
00242 class JackLoopFeedback
00243 {
00244 private:
00245
00246 int fTable[SIZE][3];
00247
00251 bool AddConnectionAux(int ref1, int ref2)
00252 {
00253 for (int i = 0; i < SIZE; i++) {
00254 if (fTable[i][0] == EMPTY) {
00255 fTable[i][0] = ref1;
00256 fTable[i][1] = ref2;
00257 fTable[i][2] = 1;
00258 JackLog("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00259 return true;
00260 }
00261 }
00262 jack_error("Feedback table is full !!\n");
00263 return false;
00264 }
00265
00269 bool RemoveConnectionAux(int ref1, int ref2)
00270 {
00271 for (int i = 0; i < SIZE; i++) {
00272 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00273 fTable[i][0] = EMPTY;
00274 fTable[i][1] = EMPTY;
00275 fTable[i][2] = 0;
00276 JackLog("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00277 return true;
00278 }
00279 }
00280 jack_error("Feedback connection not found\n");
00281 return false;
00282 }
00283
00284 int IncConnection(int index)
00285 {
00286 fTable[index][2]++;
00287 return fTable[index][2];
00288 }
00289
00290 int DecConnection(int index)
00291 {
00292 fTable[index][2]--;
00293 return fTable[index][2];
00294 }
00295
00296 public:
00297
00298 JackLoopFeedback()
00299 {
00300 Init();
00301 }
00302 virtual ~JackLoopFeedback()
00303 {}
00304
00305 void Init()
00306 {
00307 for (int i = 0; i < SIZE; i++) {
00308 fTable[i][0] = EMPTY;
00309 fTable[i][1] = EMPTY;
00310 fTable[i][2] = 0;
00311 }
00312 }
00313
00314 bool IncConnection(int ref1, int ref2)
00315 {
00316 int index = GetConnectionIndex(ref1, ref2);
00317
00318 if (index >= 0) {
00319 IncConnection(index);
00320 return true;
00321 } else {
00322 return AddConnectionAux(ref1, ref2);
00323 }
00324 }
00325
00326 bool DecConnection(int ref1, int ref2)
00327 {
00328 int index = GetConnectionIndex(ref1, ref2);
00329
00330 if (index >= 0) {
00331 JackLog("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld\n", ref1, ref2, index);
00332 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00333 } else {
00334 return false;
00335 }
00336 }
00337
00341 int GetConnectionIndex(int ref1, int ref2) const
00342 {
00343 for (int i = 0; i < SIZE; i++) {
00344 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00345 return i;
00346 }
00347 return -1;
00348 }
00349
00350 };
00351
00356 struct JackClientTiming
00357 {
00358 jack_time_t fSignaledAt;
00359 jack_time_t fAwakeAt;
00360 jack_time_t fFinishedAt;
00361 jack_client_state_t fStatus;
00362
00363 JackClientTiming():fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered)
00364 {}
00365 ~JackClientTiming()
00366 {}
00367 };
00368
00383 class JackConnectionManager
00384 {
00385
00386 private:
00387
00388 JackFixedArray<CONNECTION_NUM> fConnection[PORT_NUM];
00389 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00390 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00391 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00392 JackActivationCount fInputCounter[CLIENT_NUM];
00393 JackLoopFeedback<CONNECTION_NUM> fLoopFeedback;
00395 bool IsLoopPathAux(int ref1, int ref2) const;
00396
00397 public:
00398
00399 JackConnectionManager();
00400 ~JackConnectionManager();
00401
00402
00403 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00404 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00405 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00406
00407 jack_int_t Connections(jack_port_id_t port_index) const;
00408 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const;
00409 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00410
00411 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00412 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00413 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00414
00415 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00416 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00417 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00418
00419
00420 int AddInputPort(int refnum, jack_port_id_t port_index);
00421 int AddOutputPort(int refnum, jack_port_id_t port_index);
00422
00423 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00424 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00425
00426 const jack_int_t* GetInputPorts(int refnum);
00427 const jack_int_t* GetOutputPorts(int refnum);
00428
00429
00430 void InitRefNum(int refnum);
00431 int GetInputRefNum(jack_port_id_t port_index) const;
00432 int GetOutputRefNum(jack_port_id_t port_index) const;
00433
00434
00435 bool IsDirectConnection(int ref1, int ref2) const;
00436 void DirectConnect(int ref1, int ref2);
00437 void DirectDisconnect(int ref1, int ref2);
00438
00439 int GetActivation(int refnum) const;
00440
00441
00442 void ResetGraph(JackClientTiming* timing);
00443 int ResumeRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing);
00444 int SuspendRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing, long time_out_usec);
00445 };
00446
00447 }
00448
00449 #endif
00450