00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackConnectionManager.h"
00021 #include "JackClientControl.h"
00022 #include "JackEngineControl.h"
00023 #include "JackGlobals.h"
00024 #include "JackError.h"
00025 #include <iostream>
00026 #include <assert.h>
00027
00028 namespace Jack
00029 {
00030
00031 JackConnectionManager::JackConnectionManager()
00032 {
00033 int i;
00034 jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager));
00035
00036 for (i = 0; i < PORT_NUM; i++) {
00037 fConnection[i].Init();
00038 }
00039
00040 fLoopFeedback.Init();
00041
00042 jack_log("JackConnectionManager::InitClients");
00043 for (i = 0; i < CLIENT_NUM; i++) {
00044 InitRefNum(i);
00045 }
00046 }
00047
00048 JackConnectionManager::~JackConnectionManager()
00049 {}
00050
00051
00052
00053
00054
00055 bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const
00056 {
00057 jack_log("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", ref1, ref2);
00058
00059 if (ref1 < GetEngineControl()->fDriverNum || ref2 < GetEngineControl()->fDriverNum) {
00060 return false;
00061 } else if (ref1 == ref2) {
00062 return true;
00063 } else {
00064 jack_int_t output[CLIENT_NUM];
00065 fConnectionRef.GetOutputTable(ref1, output);
00066
00067 if (fConnectionRef.IsInsideTable(ref2, output)) {
00068 return true;
00069 } else {
00070 for (int i = 0; i < CLIENT_NUM && output[i] != EMPTY; i++) {
00071 if (IsLoopPathAux(output[i], ref2))
00072 return true;
00073 }
00074 return false;
00075 }
00076 }
00077 }
00078
00079
00080
00081
00082
00086 int JackConnectionManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
00087 {
00088 jack_log("JackConnectionManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst);
00089
00090 if (fConnection[port_src].AddItem(port_dst)) {
00091 return 0;
00092 } else {
00093 jack_error("Connection table is full !!");
00094 return -1;
00095 }
00096 }
00097
00101 int JackConnectionManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
00102 {
00103 jack_log("JackConnectionManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst);
00104
00105 if (fConnection[port_src].RemoveItem(port_dst)) {
00106 return 0;
00107 } else {
00108 jack_error("Connection not found !!");
00109 return -1;
00110 }
00111 }
00112
00116 bool JackConnectionManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const
00117 {
00118 return fConnection[port_src].CheckItem(port_dst);
00119 }
00120
00124 const jack_int_t* JackConnectionManager::GetConnections(jack_port_id_t port_index) const
00125 {
00126 return fConnection[port_index].GetItems();
00127 }
00128
00129
00130
00131
00132
00136 int JackConnectionManager::AddInputPort(int refnum, jack_port_id_t port_index)
00137 {
00138 if (fInputPort[refnum].AddItem(port_index)) {
00139 jack_log("JackConnectionManager::AddInputPort ref = %ld port = %ld", refnum, port_index);
00140 return 0;
00141 } else {
00142 jack_error("Maximum number of input ports is reached for application ref = %ld", refnum);
00143 return -1;
00144 }
00145 }
00146
00150 int JackConnectionManager::AddOutputPort(int refnum, jack_port_id_t port_index)
00151 {
00152 if (fOutputPort[refnum].AddItem(port_index)) {
00153 jack_log("JackConnectionManager::AddOutputPort ref = %ld port = %ld", refnum, port_index);
00154 return 0;
00155 } else {
00156 jack_error("Maximum number of output ports is reached for application ref = %ld", refnum);
00157 return -1;
00158 }
00159 }
00160
00164 int JackConnectionManager::RemoveInputPort(int refnum, jack_port_id_t port_index)
00165 {
00166 jack_log("JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld ", refnum, port_index);
00167
00168 if (fInputPort[refnum].RemoveItem(port_index)) {
00169 return 0;
00170 } else {
00171 jack_error("Input port index = %ld not found for application ref = %ld", port_index, refnum);
00172 return -1;
00173 }
00174 }
00175
00179 int JackConnectionManager::RemoveOutputPort(int refnum, jack_port_id_t port_index)
00180 {
00181 jack_log("JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld ", refnum, port_index);
00182
00183 if (fOutputPort[refnum].RemoveItem(port_index)) {
00184 return 0;
00185 } else {
00186 jack_error("Output port index = %ld not found for application ref = %ld", port_index, refnum);
00187 return -1;
00188 }
00189 }
00190
00194 const jack_int_t* JackConnectionManager::GetInputPorts(int refnum)
00195 {
00196 return fInputPort[refnum].GetItems();
00197 }
00198
00202 const jack_int_t* JackConnectionManager::GetOutputPorts(int refnum)
00203 {
00204 return fOutputPort[refnum].GetItems();
00205 }
00206
00210 void JackConnectionManager::InitRefNum(int refnum)
00211 {
00212 fInputPort[refnum].Init();
00213 fOutputPort[refnum].Init();
00214 fConnectionRef.Init(refnum);
00215 fInputCounter[refnum].SetValue(0);
00216 }
00217
00221 void JackConnectionManager::ResetGraph(JackClientTiming* timing)
00222 {
00223
00224 for (int i = 0; i < CLIENT_NUM; i++) {
00225 fInputCounter[i].Reset();
00226 timing[i].fStatus = NotTriggered;
00227 }
00228 }
00229
00233 int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec)
00234 {
00235 bool res;
00236 if ((res = table[control->fRefNum].TimedWait(time_out_usec))) {
00237 timing[control->fRefNum].fStatus = Running;
00238 timing[control->fRefNum].fAwakeAt = GetMicroSeconds();
00239 }
00240 return (res) ? 0 : -1;
00241 }
00242
00246 int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing)
00247 {
00248 jack_time_t current_date = GetMicroSeconds();
00249 const jack_int_t* outputRef = fConnectionRef.GetItems(control->fRefNum);
00250 int res = 0;
00251
00252
00253 timing[control->fRefNum].fStatus = Finished;
00254 timing[control->fRefNum].fFinishedAt = current_date;
00255
00256 for (int i = 0; i < CLIENT_NUM; i++) {
00257
00258
00259 if (outputRef[i] > 0) {
00260
00261
00262 timing[i].fStatus = Triggered;
00263 timing[i].fSignaledAt = current_date;
00264
00265 if (!fInputCounter[i].Signal(table + i, control)) {
00266 jack_log("JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld ", control->fRefNum, i);
00267 res = -1;
00268 }
00269 }
00270 }
00271
00272 return res;
00273 }
00274
00278 void JackConnectionManager::IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00279 {
00280 int ref1 = GetOutputRefNum(port_src);
00281 int ref2 = GetInputRefNum(port_dst);
00282
00283 assert(ref1 >= 0 && ref2 >= 0);
00284
00285 DirectConnect(ref1, ref2);
00286 jack_log("JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00287 }
00288
00292 void JackConnectionManager::DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00293 {
00294 int ref1 = GetOutputRefNum(port_src);
00295 int ref2 = GetInputRefNum(port_dst);
00296
00297 assert(ref1 >= 0 && ref2 >= 0);
00298
00299 DirectDisconnect(ref1, ref2);
00300 jack_log("JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00301 }
00302
00306 void JackConnectionManager::DirectConnect(int ref1, int ref2)
00307 {
00308 assert(ref1 >= 0 && ref2 >= 0);
00309
00310 if (fConnectionRef.IncItem(ref1, ref2) == 1) {
00311 jack_log("JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld", ref1, ref2);
00312 fInputCounter[ref2].IncValue();
00313 }
00314 }
00315
00319 void JackConnectionManager::DirectDisconnect(int ref1, int ref2)
00320 {
00321 assert(ref1 >= 0 && ref2 >= 0);
00322
00323 if (fConnectionRef.DecItem(ref1, ref2) == 0) {
00324 jack_log("JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld", ref1, ref2);
00325 fInputCounter[ref2].DecValue();
00326 }
00327 }
00328
00332 bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const
00333 {
00334 assert(ref1 >= 0 && ref2 >= 0);
00335 return (fConnectionRef.GetItemCount(ref1, ref2) > 0);
00336 }
00337
00341 int JackConnectionManager::GetInputRefNum(jack_port_id_t port_index) const
00342 {
00343 for (int i = 0; i < CLIENT_NUM; i++) {
00344 if (fInputPort[i].CheckItem(port_index))
00345 return i;
00346 }
00347
00348 return -1;
00349 }
00350
00354 int JackConnectionManager::GetOutputRefNum(jack_port_id_t port_index) const
00355 {
00356 for (int i = 0; i < CLIENT_NUM; i++) {
00357 if (fOutputPort[i].CheckItem(port_index))
00358 return i;
00359 }
00360
00361 return -1;
00362 }
00363
00367 bool JackConnectionManager::IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const
00368 {
00369 return IsLoopPathAux(GetInputRefNum(port_dst), GetOutputRefNum(port_src));
00370 }
00371
00372 bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const
00373 {
00374 return (fLoopFeedback.GetConnectionIndex(GetOutputRefNum(port_src), GetInputRefNum(port_dst)) >= 0);
00375 }
00376
00377 bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00378 {
00379 int ref1 = GetOutputRefNum(port_src);
00380 int ref2 = GetInputRefNum(port_dst);
00381
00382
00383 jack_log("JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00384 assert(ref1 >= 0 && ref2 >= 0);
00385
00386 if (ref1 != ref2)
00387 DirectConnect(ref2, ref1);
00388
00389 return fLoopFeedback.IncConnection(ref1, ref2);
00390 }
00391
00392 bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00393 {
00394 int ref1 = GetOutputRefNum(port_src);
00395 int ref2 = GetInputRefNum(port_dst);
00396
00397
00398 jack_log("JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00399 assert(ref1 >= 0 && ref2 >= 0);
00400
00401 if (ref1 != ref2)
00402 DirectDisconnect(ref2, ref1);
00403
00404 return fLoopFeedback.DecConnection(ref1, ref2);
00405 }
00406
00407 }
00408
00409