00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <assert.h>
00022 #include "JackConnectionManager.h"
00023 #include "JackClientControl.h"
00024 #include "JackError.h"
00025
00026 namespace Jack
00027 {
00028
00029 JackConnectionManager::JackConnectionManager()
00030 {
00031 int i;
00032 JackLog("JackConnectionManager::InitConnections size = %ld \n", sizeof(JackConnectionManager));
00033
00034 for (i = 0; i < PORT_NUM; i++) {
00035 fConnection[i].Init();
00036 }
00037
00038 fLoopFeedback.Init();
00039
00040 JackLog("JackConnectionManager::InitClients\n");
00041 for (i = 0; i < CLIENT_NUM; i++) {
00042 InitRefNum(i);
00043 }
00044 }
00045
00046 JackConnectionManager::~JackConnectionManager()
00047 {}
00048
00049
00050
00051
00052
00053 bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const
00054 {
00055 JackLog("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00056
00057 if (ref1 == AUDIO_DRIVER_REFNUM
00058 || ref2 == AUDIO_DRIVER_REFNUM
00059 || ref1 == FREEWHEEL_DRIVER_REFNUM
00060 || ref2 == FREEWHEEL_DRIVER_REFNUM
00061 || ref1 == LOOPBACK_DRIVER_REFNUM
00062 || ref2 == LOOPBACK_DRIVER_REFNUM) {
00063 return false;
00064 } else if (ref1 == ref2) {
00065 return true;
00066 } else {
00067 jack_int_t output[CLIENT_NUM];
00068 fConnectionRef.GetOutputTable(ref1, output);
00069
00070 if (fConnectionRef.IsInsideTable(ref2, output)) {
00071 return true;
00072 } else {
00073 for (int i = 0; i < CLIENT_NUM && output[i] != EMPTY; i++) {
00074 if (IsLoopPathAux(output[i], ref2))
00075 return true;
00076 }
00077 return false;
00078 }
00079 }
00080 }
00081
00082
00083
00084
00085
00086 int JackConnectionManager::GetActivation(int refnum) const
00087 {
00088 return fInputCounter[refnum].GetValue();
00089 }
00090
00094 int JackConnectionManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
00095 {
00096 JackLog("JackConnectionManager::Connect port_src = %ld port_dst = %ld\n", port_src, port_dst);
00097
00098 if (fConnection[port_src].AddItem(port_dst)) {
00099 return 0;
00100 } else {
00101 jack_error("Connection table is full !!");
00102 return -1;
00103 }
00104 }
00105
00109 int JackConnectionManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
00110 {
00111 JackLog("JackConnectionManager::Disconnect port_src = %ld port_dst = %ld\n", port_src, port_dst);
00112
00113 if (fConnection[port_src].RemoveItem(port_dst)) {
00114 return 0;
00115 } else {
00116 jack_error("Connection not found !!");
00117 return -1;
00118 }
00119 }
00120
00124 bool JackConnectionManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const
00125 {
00126 return fConnection[port_src].CheckItem(port_dst);
00127 }
00128
00132 jack_int_t JackConnectionManager::Connections(jack_port_id_t port_index) const
00133 {
00134 return fConnection[port_index].GetItemCount();
00135 }
00136
00137 jack_port_id_t JackConnectionManager::GetPort(jack_port_id_t port_index, int connection) const
00138 {
00139 assert(connection < CONNECTION_NUM);
00140 return (jack_port_id_t)fConnection[port_index].GetItem(connection);
00141 }
00142
00146 const jack_int_t* JackConnectionManager::GetConnections(jack_port_id_t port_index) const
00147 {
00148 return fConnection[port_index].GetItems();
00149 }
00150
00151
00152
00153
00154
00158 int JackConnectionManager::AddInputPort(int refnum, jack_port_id_t port_index)
00159 {
00160 if (fInputPort[refnum].AddItem(port_index)) {
00161 JackLog("JackConnectionManager::AddInputPort ref = %ld port = %ld\n", refnum, port_index);
00162 return 0;
00163 } else {
00164 jack_error("Maximum number of input ports is reached for application ref = %ld", refnum);
00165 return -1;
00166 }
00167 }
00168
00172 int JackConnectionManager::AddOutputPort(int refnum, jack_port_id_t port_index)
00173 {
00174 if (fOutputPort[refnum].AddItem(port_index)) {
00175 JackLog("JackConnectionManager::AddOutputPort ref = %ld port = %ld\n", refnum, port_index);
00176 return 0;
00177 } else {
00178 jack_error("Maximum number of output ports is reached for application ref = %ld", refnum);
00179 return -1;
00180 }
00181 }
00182
00186 int JackConnectionManager::RemoveInputPort(int refnum, jack_port_id_t port_index)
00187 {
00188 JackLog("JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld \n", refnum, port_index);
00189
00190 if (fInputPort[refnum].RemoveItem(port_index)) {
00191 return 0;
00192 } else {
00193 jack_error("Input port index = %ld not found for application ref = %ld", port_index, refnum);
00194 return -1;
00195 }
00196 }
00197
00201 int JackConnectionManager::RemoveOutputPort(int refnum, jack_port_id_t port_index)
00202 {
00203 JackLog("JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld \n", refnum, port_index);
00204
00205 if (fOutputPort[refnum].RemoveItem(port_index)) {
00206 return 0;
00207 } else {
00208 jack_error("Output port index = %ld not found for application ref = %ld", port_index, refnum);
00209 return -1;
00210 }
00211 }
00212
00216 const jack_int_t* JackConnectionManager::GetInputPorts(int refnum)
00217 {
00218 return fInputPort[refnum].GetItems();
00219 }
00220
00224 const jack_int_t* JackConnectionManager::GetOutputPorts(int refnum)
00225 {
00226 return fOutputPort[refnum].GetItems();
00227 }
00228
00232 void JackConnectionManager::InitRefNum(int refnum)
00233 {
00234 fInputPort[refnum].Init();
00235 fOutputPort[refnum].Init();
00236 fConnectionRef.Init(refnum);
00237 fInputCounter[refnum].SetValue(0);
00238 }
00239
00243 void JackConnectionManager::ResetGraph(JackClientTiming* timing)
00244 {
00245
00246 for (int i = 0; i < CLIENT_NUM; i++) {
00247 fInputCounter[i].Reset();
00248 timing[i].fStatus = NotTriggered;
00249 }
00250 }
00251
00255 int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing, long time_out_usec)
00256 {
00257 bool res;
00258 if ((res = table[control->fRefNum]->TimedWait(time_out_usec))) {
00259 timing[control->fRefNum].fStatus = Running;
00260 timing[control->fRefNum].fAwakeAt = GetMicroSeconds();
00261 }
00262 return (res) ? 0 : -1;
00263 }
00264
00268 int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing)
00269 {
00270 jack_time_t current_date = GetMicroSeconds();
00271 const jack_int_t* outputRef = fConnectionRef.GetItems(control->fRefNum);
00272 int res = 0;
00273
00274
00275 timing[control->fRefNum].fStatus = Finished;
00276 timing[control->fRefNum].fFinishedAt = current_date;
00277
00278 for (int i = 0; i < CLIENT_NUM; i++) {
00279
00280
00281 if (outputRef[i] > 0) {
00282
00283
00284 timing[i].fStatus = Triggered;
00285 timing[i].fSignaledAt = current_date;
00286
00287 if (!fInputCounter[i].Signal(table[i], control)) {
00288 JackLog("JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld \n", control->fRefNum, i);
00289 res = -1;
00290 }
00291 }
00292 }
00293
00294 return res;
00295 }
00296
00300 void JackConnectionManager::IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00301 {
00302 int ref1 = GetOutputRefNum(port_src);
00303 int ref2 = GetInputRefNum(port_dst);
00304
00305 assert(ref1 >= 0 && ref2 >= 0);
00306
00307 DirectConnect(ref1, ref2);
00308 JackLog("JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld\n", ref1, ref2);
00309 }
00310
00314 void JackConnectionManager::DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00315 {
00316 int ref1 = GetOutputRefNum(port_src);
00317 int ref2 = GetInputRefNum(port_dst);
00318
00319 assert(ref1 >= 0 && ref2 >= 0);
00320
00321 DirectDisconnect(ref1, ref2);
00322 JackLog("JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld\n", ref1, ref2);
00323 }
00324
00328 void JackConnectionManager::DirectConnect(int ref1, int ref2)
00329 {
00330 assert(ref1 >= 0 && ref2 >= 0);
00331
00332 if (fConnectionRef.IncItem(ref1, ref2) == 1) {
00333 JackLog("JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld\n", ref1, ref2);
00334 fInputCounter[ref2].IncValue();
00335 }
00336 }
00337
00341 void JackConnectionManager::DirectDisconnect(int ref1, int ref2)
00342 {
00343 assert(ref1 >= 0 && ref2 >= 0);
00344
00345 if (fConnectionRef.DecItem(ref1, ref2) == 0) {
00346 JackLog("JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld\n", ref1, ref2);
00347 fInputCounter[ref2].DecValue();
00348 }
00349 }
00350
00354 bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const
00355 {
00356 assert(ref1 >= 0 && ref2 >= 0);
00357 return fConnectionRef.GetItemCount(ref1, ref2);
00358 }
00359
00363 int JackConnectionManager::GetInputRefNum(jack_port_id_t port_index) const
00364 {
00365 for (int i = 0; i < CLIENT_NUM; i++) {
00366 if (fInputPort[i].CheckItem(port_index))
00367 return i;
00368 }
00369
00370 return -1;
00371 }
00372
00376 int JackConnectionManager::GetOutputRefNum(jack_port_id_t port_index) const
00377 {
00378 for (int i = 0; i < CLIENT_NUM; i++) {
00379 if (fOutputPort[i].CheckItem(port_index))
00380 return i;
00381 }
00382
00383 return -1;
00384 }
00385
00389 bool JackConnectionManager::IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const
00390 {
00391 return IsLoopPathAux(GetInputRefNum(port_dst), GetOutputRefNum(port_src));
00392 }
00393
00394 bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const
00395 {
00396 return (fLoopFeedback.GetConnectionIndex(GetOutputRefNum(port_src), GetInputRefNum(port_dst)) >= 0);
00397 }
00398
00399 bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00400 {
00401 int ref1 = GetOutputRefNum(port_src);
00402 int ref2 = GetInputRefNum(port_dst);
00403
00404
00405 JackLog("JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld\n", ref1, ref2);
00406 assert(ref1 >= 0 && ref2 >= 0);
00407
00408 if (ref1 != ref2)
00409 DirectConnect(ref2, ref1);
00410
00411 return fLoopFeedback.IncConnection(ref1, ref2);
00412 }
00413
00414 bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00415 {
00416 int ref1 = GetOutputRefNum(port_src);
00417 int ref2 = GetInputRefNum(port_dst);
00418
00419
00420 JackLog("JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld\n", ref1, ref2);
00421 assert(ref1 >= 0 && ref2 >= 0);
00422
00423 if (ref1 != ref2)
00424 DirectDisconnect(ref2, ref1);
00425
00426 return fLoopFeedback.DecConnection(ref1, ref2);
00427 }
00428
00429 }
00430
00431