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 jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager));
00033
00034 for (i = 0; i < PORT_NUM; i++) {
00035 fConnection[i].Init();
00036 }
00037
00038 fLoopFeedback.Init();
00039
00040 jack_log("JackConnectionManager::InitClients");
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 jack_log("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", 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
00089 int JackConnectionManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
00090 {
00091 jack_log("JackConnectionManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst);
00092
00093 if (fConnection[port_src].AddItem(port_dst)) {
00094 return 0;
00095 } else {
00096 jack_error("Connection table is full !!");
00097 return -1;
00098 }
00099 }
00100
00104 int JackConnectionManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
00105 {
00106 jack_log("JackConnectionManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst);
00107
00108 if (fConnection[port_src].RemoveItem(port_dst)) {
00109 return 0;
00110 } else {
00111 jack_error("Connection not found !!");
00112 return -1;
00113 }
00114 }
00115
00119 bool JackConnectionManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const
00120 {
00121 return fConnection[port_src].CheckItem(port_dst);
00122 }
00123
00127 const jack_int_t* JackConnectionManager::GetConnections(jack_port_id_t port_index) const
00128 {
00129 return fConnection[port_index].GetItems();
00130 }
00131
00132
00133
00134
00135
00139 int JackConnectionManager::AddInputPort(int refnum, jack_port_id_t port_index)
00140 {
00141 if (fInputPort[refnum].AddItem(port_index)) {
00142 jack_log("JackConnectionManager::AddInputPort ref = %ld port = %ld", refnum, port_index);
00143 return 0;
00144 } else {
00145 jack_error("Maximum number of input ports is reached for application ref = %ld", refnum);
00146 return -1;
00147 }
00148 }
00149
00153 int JackConnectionManager::AddOutputPort(int refnum, jack_port_id_t port_index)
00154 {
00155 if (fOutputPort[refnum].AddItem(port_index)) {
00156 jack_log("JackConnectionManager::AddOutputPort ref = %ld port = %ld", refnum, port_index);
00157 return 0;
00158 } else {
00159 jack_error("Maximum number of output ports is reached for application ref = %ld", refnum);
00160 return -1;
00161 }
00162 }
00163
00167 int JackConnectionManager::RemoveInputPort(int refnum, jack_port_id_t port_index)
00168 {
00169 jack_log("JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld ", refnum, port_index);
00170
00171 if (fInputPort[refnum].RemoveItem(port_index)) {
00172 return 0;
00173 } else {
00174 jack_error("Input port index = %ld not found for application ref = %ld", port_index, refnum);
00175 return -1;
00176 }
00177 }
00178
00182 int JackConnectionManager::RemoveOutputPort(int refnum, jack_port_id_t port_index)
00183 {
00184 jack_log("JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld ", refnum, port_index);
00185
00186 if (fOutputPort[refnum].RemoveItem(port_index)) {
00187 return 0;
00188 } else {
00189 jack_error("Output port index = %ld not found for application ref = %ld", port_index, refnum);
00190 return -1;
00191 }
00192 }
00193
00197 const jack_int_t* JackConnectionManager::GetInputPorts(int refnum)
00198 {
00199 return fInputPort[refnum].GetItems();
00200 }
00201
00205 const jack_int_t* JackConnectionManager::GetOutputPorts(int refnum)
00206 {
00207 return fOutputPort[refnum].GetItems();
00208 }
00209
00213 void JackConnectionManager::InitRefNum(int refnum)
00214 {
00215 fInputPort[refnum].Init();
00216 fOutputPort[refnum].Init();
00217 fConnectionRef.Init(refnum);
00218 fInputCounter[refnum].SetValue(0);
00219 }
00220
00224 void JackConnectionManager::ResetGraph(JackClientTiming* timing)
00225 {
00226
00227 for (int i = 0; i < CLIENT_NUM; i++) {
00228 fInputCounter[i].Reset();
00229 timing[i].fStatus = NotTriggered;
00230 }
00231 }
00232
00236 int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec)
00237 {
00238 bool res;
00239 if ((res = table[control->fRefNum].TimedWait(time_out_usec))) {
00240 timing[control->fRefNum].fStatus = Running;
00241 timing[control->fRefNum].fAwakeAt = GetMicroSeconds();
00242 }
00243 return (res) ? 0 : -1;
00244 }
00245
00249 int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing)
00250 {
00251 jack_time_t current_date = GetMicroSeconds();
00252 const jack_int_t* outputRef = fConnectionRef.GetItems(control->fRefNum);
00253 int res = 0;
00254
00255
00256 timing[control->fRefNum].fStatus = Finished;
00257 timing[control->fRefNum].fFinishedAt = current_date;
00258
00259 for (int i = 0; i < CLIENT_NUM; i++) {
00260
00261
00262 if (outputRef[i] > 0) {
00263
00264
00265 timing[i].fStatus = Triggered;
00266 timing[i].fSignaledAt = current_date;
00267
00268 if (!fInputCounter[i].Signal(table + i, control)) {
00269 jack_log("JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld ", control->fRefNum, i);
00270 res = -1;
00271 }
00272 }
00273 }
00274
00275 return res;
00276 }
00277
00281 void JackConnectionManager::IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00282 {
00283 int ref1 = GetOutputRefNum(port_src);
00284 int ref2 = GetInputRefNum(port_dst);
00285
00286 assert(ref1 >= 0 && ref2 >= 0);
00287
00288 DirectConnect(ref1, ref2);
00289 jack_log("JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00290 }
00291
00295 void JackConnectionManager::DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00296 {
00297 int ref1 = GetOutputRefNum(port_src);
00298 int ref2 = GetInputRefNum(port_dst);
00299
00300 assert(ref1 >= 0 && ref2 >= 0);
00301
00302 DirectDisconnect(ref1, ref2);
00303 jack_log("JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00304 }
00305
00309 void JackConnectionManager::DirectConnect(int ref1, int ref2)
00310 {
00311 assert(ref1 >= 0 && ref2 >= 0);
00312
00313 if (fConnectionRef.IncItem(ref1, ref2) == 1) {
00314 jack_log("JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld", ref1, ref2);
00315 fInputCounter[ref2].IncValue();
00316 }
00317 }
00318
00322 void JackConnectionManager::DirectDisconnect(int ref1, int ref2)
00323 {
00324 assert(ref1 >= 0 && ref2 >= 0);
00325
00326 if (fConnectionRef.DecItem(ref1, ref2) == 0) {
00327 jack_log("JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld", ref1, ref2);
00328 fInputCounter[ref2].DecValue();
00329 }
00330 }
00331
00335 bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const
00336 {
00337 assert(ref1 >= 0 && ref2 >= 0);
00338 return (fConnectionRef.GetItemCount(ref1, ref2) > 0);
00339 }
00340
00344 int JackConnectionManager::GetInputRefNum(jack_port_id_t port_index) const
00345 {
00346 for (int i = 0; i < CLIENT_NUM; i++) {
00347 if (fInputPort[i].CheckItem(port_index))
00348 return i;
00349 }
00350
00351 return -1;
00352 }
00353
00357 int JackConnectionManager::GetOutputRefNum(jack_port_id_t port_index) const
00358 {
00359 for (int i = 0; i < CLIENT_NUM; i++) {
00360 if (fOutputPort[i].CheckItem(port_index))
00361 return i;
00362 }
00363
00364 return -1;
00365 }
00366
00370 bool JackConnectionManager::IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const
00371 {
00372 return IsLoopPathAux(GetInputRefNum(port_dst), GetOutputRefNum(port_src));
00373 }
00374
00375 bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const
00376 {
00377 return (fLoopFeedback.GetConnectionIndex(GetOutputRefNum(port_src), GetInputRefNum(port_dst)) >= 0);
00378 }
00379
00380 bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00381 {
00382 int ref1 = GetOutputRefNum(port_src);
00383 int ref2 = GetInputRefNum(port_dst);
00384
00385
00386 jack_log("JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00387 assert(ref1 >= 0 && ref2 >= 0);
00388
00389 if (ref1 != ref2)
00390 DirectConnect(ref2, ref1);
00391
00392 return fLoopFeedback.IncConnection(ref1, ref2);
00393 }
00394
00395 bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00396 {
00397 int ref1 = GetOutputRefNum(port_src);
00398 int ref2 = GetInputRefNum(port_dst);
00399
00400
00401 jack_log("JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00402 assert(ref1 >= 0 && ref2 >= 0);
00403
00404 if (ref1 != ref2)
00405 DirectDisconnect(ref2, ref1);
00406
00407 return fLoopFeedback.DecConnection(ref1, ref2);
00408 }
00409
00410 }
00411
00412