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
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 jack_log("JackConnectionManager::Connect port_src = %ld port_dst = %ld", 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 jack_log("JackConnectionManager::Disconnect port_src = %ld port_dst = %ld", 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 const jack_int_t* JackConnectionManager::GetConnections(jack_port_id_t port_index) const
00133 {
00134 return fConnection[port_index].GetItems();
00135 }
00136
00137
00138
00139
00140
00144 int JackConnectionManager::AddInputPort(int refnum, jack_port_id_t port_index)
00145 {
00146 if (fInputPort[refnum].AddItem(port_index)) {
00147 jack_log("JackConnectionManager::AddInputPort ref = %ld port = %ld", refnum, port_index);
00148 return 0;
00149 } else {
00150 jack_error("Maximum number of input ports is reached for application ref = %ld", refnum);
00151 return -1;
00152 }
00153 }
00154
00158 int JackConnectionManager::AddOutputPort(int refnum, jack_port_id_t port_index)
00159 {
00160 if (fOutputPort[refnum].AddItem(port_index)) {
00161 jack_log("JackConnectionManager::AddOutputPort ref = %ld port = %ld", refnum, port_index);
00162 return 0;
00163 } else {
00164 jack_error("Maximum number of output ports is reached for application ref = %ld", refnum);
00165 return -1;
00166 }
00167 }
00168
00172 int JackConnectionManager::RemoveInputPort(int refnum, jack_port_id_t port_index)
00173 {
00174 jack_log("JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld ", refnum, port_index);
00175
00176 if (fInputPort[refnum].RemoveItem(port_index)) {
00177 return 0;
00178 } else {
00179 jack_error("Input port index = %ld not found for application ref = %ld", port_index, refnum);
00180 return -1;
00181 }
00182 }
00183
00187 int JackConnectionManager::RemoveOutputPort(int refnum, jack_port_id_t port_index)
00188 {
00189 jack_log("JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld ", refnum, port_index);
00190
00191 if (fOutputPort[refnum].RemoveItem(port_index)) {
00192 return 0;
00193 } else {
00194 jack_error("Output port index = %ld not found for application ref = %ld", port_index, refnum);
00195 return -1;
00196 }
00197 }
00198
00202 const jack_int_t* JackConnectionManager::GetInputPorts(int refnum)
00203 {
00204 return fInputPort[refnum].GetItems();
00205 }
00206
00210 const jack_int_t* JackConnectionManager::GetOutputPorts(int refnum)
00211 {
00212 return fOutputPort[refnum].GetItems();
00213 }
00214
00218 void JackConnectionManager::InitRefNum(int refnum)
00219 {
00220 fInputPort[refnum].Init();
00221 fOutputPort[refnum].Init();
00222 fConnectionRef.Init(refnum);
00223 fInputCounter[refnum].SetValue(0);
00224 }
00225
00229 void JackConnectionManager::ResetGraph(JackClientTiming* timing)
00230 {
00231
00232 for (int i = 0; i < CLIENT_NUM; i++) {
00233 fInputCounter[i].Reset();
00234 timing[i].fStatus = NotTriggered;
00235 }
00236 }
00237
00241 int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec)
00242 {
00243 bool res;
00244 if ((res = table[control->fRefNum].TimedWait(time_out_usec))) {
00245 timing[control->fRefNum].fStatus = Running;
00246 timing[control->fRefNum].fAwakeAt = GetMicroSeconds();
00247 }
00248 return (res) ? 0 : -1;
00249 }
00250
00254 int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing)
00255 {
00256 jack_time_t current_date = GetMicroSeconds();
00257 const jack_int_t* outputRef = fConnectionRef.GetItems(control->fRefNum);
00258 int res = 0;
00259
00260
00261 timing[control->fRefNum].fStatus = Finished;
00262 timing[control->fRefNum].fFinishedAt = current_date;
00263
00264 for (int i = 0; i < CLIENT_NUM; i++) {
00265
00266
00267 if (outputRef[i] > 0) {
00268
00269
00270 timing[i].fStatus = Triggered;
00271 timing[i].fSignaledAt = current_date;
00272
00273 if (!fInputCounter[i].Signal(table + i, control)) {
00274 jack_log("JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld ", control->fRefNum, i);
00275 res = -1;
00276 }
00277 }
00278 }
00279
00280 return res;
00281 }
00282
00286 void JackConnectionManager::IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00287 {
00288 int ref1 = GetOutputRefNum(port_src);
00289 int ref2 = GetInputRefNum(port_dst);
00290
00291 assert(ref1 >= 0 && ref2 >= 0);
00292
00293 DirectConnect(ref1, ref2);
00294 jack_log("JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00295 }
00296
00300 void JackConnectionManager::DecDirectConnection(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 DirectDisconnect(ref1, ref2);
00308 jack_log("JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
00309 }
00310
00314 void JackConnectionManager::DirectConnect(int ref1, int ref2)
00315 {
00316 assert(ref1 >= 0 && ref2 >= 0);
00317
00318 if (fConnectionRef.IncItem(ref1, ref2) == 1) {
00319 jack_log("JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld", ref1, ref2);
00320 fInputCounter[ref2].IncValue();
00321 }
00322 }
00323
00327 void JackConnectionManager::DirectDisconnect(int ref1, int ref2)
00328 {
00329 assert(ref1 >= 0 && ref2 >= 0);
00330
00331 if (fConnectionRef.DecItem(ref1, ref2) == 0) {
00332 jack_log("JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld", ref1, ref2);
00333 fInputCounter[ref2].DecValue();
00334 }
00335 }
00336
00340 bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const
00341 {
00342 assert(ref1 >= 0 && ref2 >= 0);
00343 return (fConnectionRef.GetItemCount(ref1, ref2) > 0);
00344 }
00345
00349 int JackConnectionManager::GetInputRefNum(jack_port_id_t port_index) const
00350 {
00351 for (int i = 0; i < CLIENT_NUM; i++) {
00352 if (fInputPort[i].CheckItem(port_index))
00353 return i;
00354 }
00355
00356 return -1;
00357 }
00358
00362 int JackConnectionManager::GetOutputRefNum(jack_port_id_t port_index) const
00363 {
00364 for (int i = 0; i < CLIENT_NUM; i++) {
00365 if (fOutputPort[i].CheckItem(port_index))
00366 return i;
00367 }
00368
00369 return -1;
00370 }
00371
00375 bool JackConnectionManager::IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const
00376 {
00377 return IsLoopPathAux(GetInputRefNum(port_dst), GetOutputRefNum(port_src));
00378 }
00379
00380 bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const
00381 {
00382 return (fLoopFeedback.GetConnectionIndex(GetOutputRefNum(port_src), GetInputRefNum(port_dst)) >= 0);
00383 }
00384
00385 bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00386 {
00387 int ref1 = GetOutputRefNum(port_src);
00388 int ref2 = GetInputRefNum(port_dst);
00389
00390
00391 jack_log("JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00392 assert(ref1 >= 0 && ref2 >= 0);
00393
00394 if (ref1 != ref2)
00395 DirectConnect(ref2, ref1);
00396
00397 return fLoopFeedback.IncConnection(ref1, ref2);
00398 }
00399
00400 bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
00401 {
00402 int ref1 = GetOutputRefNum(port_src);
00403 int ref2 = GetInputRefNum(port_dst);
00404
00405
00406 jack_log("JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
00407 assert(ref1 >= 0 && ref2 >= 0);
00408
00409 if (ref1 != ref2)
00410 DirectDisconnect(ref2, ref1);
00411
00412 return fLoopFeedback.DecConnection(ref1, ref2);
00413 }
00414
00415 }
00416
00417