00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackGraphManager.h"
00021 #include "JackConstants.h"
00022 #include <assert.h>
00023 #include <stdlib.h>
00024 #include <algorithm>
00025 #include <regex.h>
00026
00027 namespace Jack
00028 {
00029
00030 static inline jack_nframes_t MAX(jack_nframes_t a, jack_nframes_t b)
00031 {
00032 return (a < b) ? b : a;
00033 }
00034
00035 static void AssertPort(jack_port_id_t port_index)
00036 {
00037 if (port_index >= PORT_NUM) {
00038 JackLog("JackGraphManager::AssertPort port_index = %ld\n", port_index);
00039 assert(port_index < PORT_NUM);
00040 }
00041 }
00042
00043 static void AssertBufferSize(jack_nframes_t buffer_size)
00044 {
00045 if (buffer_size > BUFFER_SIZE_MAX) {
00046 JackLog("JackGraphManager::AssertBufferSize frames = %ld\n", buffer_size);
00047 assert(buffer_size <= BUFFER_SIZE_MAX);
00048 }
00049 }
00050
00051 JackPort* JackGraphManager::GetPort(jack_port_id_t port_index)
00052 {
00053 AssertPort(port_index);
00054 return &fPortArray[port_index];
00055 }
00056
00057 float* JackGraphManager::GetBuffer(jack_port_id_t port_index)
00058 {
00059 return fPortArray[port_index].GetBuffer();
00060 }
00061
00062
00063 int JackGraphManager::GetConnectionsNum(jack_port_id_t port_index)
00064 {
00065 JackConnectionManager* manager = ReadCurrentState();
00066 return manager->Connections(port_index);
00067 }
00068
00069
00070 void JackGraphManager::InitRefNum(int refnum)
00071 {
00072 JackConnectionManager* manager = WriteNextStateStart();
00073 manager->InitRefNum(refnum);
00074 WriteNextStateStop();
00075 }
00076
00077
00078 void JackGraphManager::RunCurrentGraph()
00079 {
00080 JackConnectionManager* manager = ReadCurrentState();
00081 manager->ResetGraph(fClientTiming);
00082 }
00083
00084
00085 bool JackGraphManager::RunNextGraph()
00086 {
00087 bool res;
00088 JackConnectionManager* manager = TrySwitchState(&res);
00089 manager->ResetGraph(fClientTiming);
00090 return res;
00091 }
00092
00093
00094 bool JackGraphManager::IsFinishedGraph()
00095 {
00096 JackConnectionManager* manager = ReadCurrentState();
00097 return (manager->GetActivation(FREEWHEEL_DRIVER_REFNUM) == 0);
00098 }
00099
00100
00101 int JackGraphManager::ResumeRefNum(JackClientControl* control, JackSynchro** table)
00102 {
00103 JackConnectionManager* manager = ReadCurrentState();
00104 return manager->ResumeRefNum(control, table, fClientTiming);
00105 }
00106
00107
00108 int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro** table, long usec)
00109 {
00110 JackConnectionManager* manager = ReadCurrentState();
00111 return manager->SuspendRefNum(control, table, fClientTiming, usec);
00112 }
00113
00114 JackClientTiming* JackGraphManager::GetClientTiming(int ref)
00115 {
00116 return &fClientTiming[ref];
00117 }
00118
00119
00120 void JackGraphManager::DirectConnect(int ref1, int ref2)
00121 {
00122 JackConnectionManager* manager = WriteNextStateStart();
00123 manager->DirectConnect(ref1, ref2);
00124 JackLog("JackGraphManager::ConnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld\n", CurIndex(fCounter), ref1, ref2);
00125 WriteNextStateStop();
00126 }
00127
00128
00129 void JackGraphManager::DirectDisconnect(int ref1, int ref2)
00130 {
00131 JackConnectionManager* manager = WriteNextStateStart();
00132 manager->DirectDisconnect(ref1, ref2);
00133 JackLog("JackGraphManager::DisconnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld\n", CurIndex(fCounter), ref1, ref2);
00134 WriteNextStateStop();
00135 }
00136
00137
00138 bool JackGraphManager::IsDirectConnection(int ref1, int ref2)
00139 {
00140 JackConnectionManager* manager = ReadCurrentState();
00141 return manager->IsDirectConnection(ref1, ref2);
00142 }
00143
00144
00145 void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buffer_size)
00146 {
00147 AssertPort(port_index);
00148 AssertBufferSize(buffer_size);
00149
00150 JackConnectionManager* manager = ReadCurrentState();
00151 JackPort* port = GetPort(port_index);
00152
00153 if (!port->IsUsed()) {
00154
00155 JackLog("JackGraphManager::GetBuffer : port = %ld is released state\n", port_index);
00156 return GetBuffer(0);
00157 }
00158
00159
00160 if (port->fFlags & JackPortIsOutput) {
00161 return (port->fTied != NO_PORT) ? GetBuffer(port->fTied, buffer_size) : GetBuffer(port_index);
00162 }
00163
00164
00165 jack_int_t len = manager->Connections(port_index);
00166
00167 if (len == 0) {
00168 port->ClearBuffer(buffer_size);
00169 return port->GetBuffer();
00170 } else if (len == 1) {
00171 assert(manager->GetPort(port_index, 0) != port_index);
00172 return GetBuffer(manager->GetPort(port_index, 0), buffer_size);
00173 } else {
00174
00175 const jack_int_t* connections = manager->GetConnections(port_index);
00176 void* buffers[CONNECTION_NUM];
00177 jack_port_id_t src_index;
00178 int i;
00179
00180 for (i = 0; (i < CONNECTION_NUM) && ((src_index = connections[i]) != EMPTY); i++) {
00181 AssertPort(src_index);
00182 buffers[i] = GetBuffer(src_index, buffer_size);
00183 }
00184
00185 JackPort* port = GetPort(port_index);
00186 port->MixBuffers(buffers, i, buffer_size);
00187 return port->GetBuffer();
00188 }
00189 }
00190
00191
00192 int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff)
00193 {
00194 AssertPort(port_index);
00195 JackPort* port = GetPort(port_index);
00196
00206 port->RequestMonitor(onoff);
00207
00208 const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index);
00209 if ((port->fFlags & JackPortIsOutput) == 0) {
00210 jack_port_id_t src_index;
00211 for (int i = 0; (i < CONNECTION_NUM) && ((src_index = connections[i]) != EMPTY); i++) {
00212
00213 RequestMonitor(src_index, onoff);
00214 }
00215 }
00216
00217 return 0;
00218 }
00219
00220
00221 jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count)
00222 {
00223 const jack_int_t* connections = manager->GetConnections(port_index);
00224 jack_nframes_t max_latency = 0;
00225 jack_port_id_t dst_index;
00226
00227 if (hop_count > 8)
00228 return GetPort(port_index)->GetLatency();
00229
00230 for (int i = 0; (i < CONNECTION_NUM) && ((dst_index = connections[i]) != EMPTY); i++) {
00231 if (src_port_index != dst_index) {
00232 AssertPort(dst_index);
00233 JackPort* dst_port = GetPort(dst_index);
00234 jack_nframes_t this_latency = (dst_port->fFlags & JackPortIsTerminal)
00235 ? dst_port->GetLatency()
00236 : ComputeTotalLatencyAux(dst_index, port_index, manager, hop_count + 1);
00237 max_latency = MAX(max_latency, this_latency);
00238 }
00239 }
00240
00241 return max_latency + GetPort(port_index)->GetLatency();
00242 }
00243
00244
00245 int JackGraphManager::ComputeTotalLatency(jack_port_id_t port_index)
00246 {
00247 UInt16 cur_index;
00248 UInt16 next_index;
00249 JackPort* port = GetPort(port_index);
00250 AssertPort(port_index);
00251
00252 do {
00253 cur_index = GetCurrentIndex();
00254 port->fTotalLatency = ComputeTotalLatencyAux(port_index, port_index, ReadCurrentState(), 0);
00255 next_index = GetCurrentIndex();
00256 } while (cur_index != next_index);
00257
00258 JackLog("JackGraphManager::GetTotalLatency port_index = %ld total latency = %ld\n", port_index, port->fTotalLatency);
00259 return 0;
00260 }
00261
00262
00263 int JackGraphManager::ComputeTotalLatencies()
00264 {
00265 jack_port_id_t port_index;
00266 for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) {
00267 JackPort* port = GetPort(port_index);
00268 if (port->IsUsed())
00269 ComputeTotalLatency(port_index);
00270 }
00271 return 0;
00272 }
00273
00274
00275 void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size)
00276 {
00277 JackLock lock(this);
00278 JackLog("JackGraphManager::SetBufferSize size = %ld\n", (long int)buffer_size);
00279
00280 jack_port_id_t port_index;
00281 for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) {
00282 JackPort* port = GetPort(port_index);
00283 if (port->IsUsed())
00284 port->ClearBuffer(buffer_size);
00285 }
00286 }
00287
00288
00289 jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
00290 {
00291 jack_port_id_t port_index;
00292
00293
00294 for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) {
00295 JackPort* port = GetPort(port_index);
00296 if (!port->IsUsed()) {
00297 JackLog("JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s\n", port_index, port_name, port_type);
00298 if (!port->Allocate(refnum, port_name, port_type, flags))
00299 return NO_PORT;
00300 break;
00301 }
00302 }
00303
00304 return (port_index < PORT_NUM) ? port_index : NO_PORT;
00305 }
00306
00307
00308 jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size)
00309 {
00310 JackLock lock(this);
00311 JackConnectionManager* manager = WriteNextStateStart();
00312 jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags);
00313
00314 if (port_index != NO_PORT) {
00315 JackPort* port = GetPort(port_index);
00316 assert(port);
00317 port->ClearBuffer(buffer_size);
00318
00319 int res;
00320 if (flags & JackPortIsOutput) {
00321 res = manager->AddOutputPort(refnum, port_index);
00322 } else {
00323 res = manager->AddInputPort(refnum, port_index);
00324 }
00325
00326 if (res < 0) {
00327 port->Release();
00328 port_index = NO_PORT;
00329 }
00330 }
00331
00332 WriteNextStateStop();
00333 return port_index;
00334 }
00335
00336
00337 int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index)
00338 {
00339 JackLock lock(this);
00340 JackConnectionManager* manager = WriteNextStateStart();
00341 JackPort* port = GetPort(port_index);
00342 int res;
00343
00344 if (port->fFlags & JackPortIsOutput) {
00345 DisconnectAllOutput(port_index);
00346 res = manager->RemoveOutputPort(refnum, port_index);
00347 } else {
00348 DisconnectAllInput(port_index);
00349 res = manager->RemoveInputPort(refnum, port_index);
00350 }
00351
00352 port->Release();
00353 WriteNextStateStop();
00354 return res;
00355 }
00356
00357 void JackGraphManager::GetInputPorts(int refnum, jack_int_t* res)
00358 {
00359 JackConnectionManager* manager = WriteNextStateStart();
00360 const jack_int_t* input = manager->GetInputPorts(refnum);
00361 memcpy(res, input, sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT);
00362 WriteNextStateStop();
00363 }
00364
00365 void JackGraphManager::GetOutputPorts(int refnum, jack_int_t* res)
00366 {
00367 JackConnectionManager* manager = WriteNextStateStart();
00368 const jack_int_t* output = manager->GetOutputPorts(refnum);
00369 memcpy(res, output, sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT);
00370 WriteNextStateStop();
00371 }
00372
00373
00374 void JackGraphManager::RemoveAllPorts(int refnum)
00375 {
00376 JackLog("JackGraphManager::RemoveAllPorts ref = %ld\n", refnum);
00377 JackConnectionManager* manager = WriteNextStateStart();
00378 jack_port_id_t port_index;
00379
00380
00381 const jack_int_t* input = manager->GetInputPorts(refnum);
00382 while ((port_index = input[0]) != EMPTY) {
00383 ReleasePort(refnum, port_index);
00384 }
00385
00386
00387 const jack_int_t* output = manager->GetOutputPorts(refnum);
00388 while ((port_index = output[0]) != EMPTY) {
00389 ReleasePort(refnum, port_index);
00390 }
00391
00392 WriteNextStateStop();
00393 }
00394
00395
00396 void JackGraphManager::DisconnectAllPorts(int refnum)
00397 {
00398 int i;
00399 JackLog("JackGraphManager::DisconnectAllPorts ref = %ld\n", refnum);
00400 JackConnectionManager* manager = WriteNextStateStart();
00401
00402 const jack_int_t* input = manager->GetInputPorts(refnum);
00403 for (i = 0; i < PORT_NUM_FOR_CLIENT && input[i] != EMPTY ; i++) {
00404 DisconnectAllInput(input[i]);
00405 }
00406
00407 const jack_int_t* output = manager->GetOutputPorts(refnum);
00408 for (i = 0; i < PORT_NUM_FOR_CLIENT && output[i] != EMPTY; i++) {
00409 DisconnectAllOutput(output[i]);
00410 }
00411
00412 WriteNextStateStop();
00413 }
00414
00415
00416 void JackGraphManager::DisconnectAllInput(jack_port_id_t port_index)
00417 {
00418 JackLog("JackGraphManager::DisconnectAllInput port_index = %ld \n", port_index);
00419 JackConnectionManager* manager = WriteNextStateStart();
00420
00421 for (int i = 0; i < PORT_NUM; i++) {
00422 if (manager->IsConnected(i, port_index)) {
00423 JackLog("JackGraphManager::Disconnect i = %ld port_index = %ld\n", i, port_index);
00424 Disconnect(i, port_index);
00425 }
00426 }
00427 WriteNextStateStop();
00428 }
00429
00430
00431 void JackGraphManager::DisconnectAllOutput(jack_port_id_t port_index)
00432 {
00433 JackLog("JackGraphManager::DisconnectAllOutput port_index = %ld \n", port_index);
00434 JackConnectionManager* manager = WriteNextStateStart();
00435
00436 const jack_int_t* connections = manager->GetConnections(port_index);
00437 while (connections[0] != EMPTY) {
00438 Disconnect(port_index, connections[0]);
00439 }
00440 WriteNextStateStop();
00441 }
00442
00443
00444 int JackGraphManager::DisconnectAll(jack_port_id_t port_index)
00445 {
00446 AssertPort(port_index);
00447
00448 JackPort* port = GetPort(port_index);
00449 if (port->fFlags & JackPortIsOutput) {
00450 DisconnectAllOutput(port_index);
00451 } else {
00452 DisconnectAllInput(port_index);
00453 }
00454 return 0;
00455 }
00456
00457
00458 void JackGraphManager::GetConnections(jack_port_id_t port_index, jack_int_t* res)
00459 {
00460 JackConnectionManager* manager = WriteNextStateStart();
00461 const jack_int_t* connections = manager->GetConnections(port_index);
00462 memcpy(res, connections, sizeof(jack_int_t) * CONNECTION_NUM);
00463 WriteNextStateStop();
00464 }
00465
00466
00467 void JackGraphManager::Activate(int refnum)
00468 {
00469 DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum);
00470 DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 void JackGraphManager::Deactivate(int refnum)
00480 {
00481 DisconnectAllPorts(refnum);
00482
00483
00484 if (IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) {
00485 DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM);
00486 } else {
00487 JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum);
00488 }
00489
00490
00491 if (IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) {
00492 DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum);
00493 } else {
00494 JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum);
00495 }
00496 }
00497
00498
00499 int JackGraphManager::GetInputRefNum(jack_port_id_t port_index)
00500 {
00501 AssertPort(port_index);
00502 JackConnectionManager* manager = WriteNextStateStart();
00503 int res = manager->GetInputRefNum(port_index);
00504 WriteNextStateStop();
00505 return res;
00506 }
00507
00508
00509 int JackGraphManager::GetOutputRefNum(jack_port_id_t port_index)
00510 {
00511 AssertPort(port_index);
00512 JackConnectionManager* manager = WriteNextStateStart();
00513 int res = manager->GetOutputRefNum(port_index);
00514 WriteNextStateStop();
00515 return res;
00516 }
00517
00518 int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
00519 {
00520 JackConnectionManager* manager = WriteNextStateStart();
00521 JackLog("JackGraphManager::Connect port_src = %ld port_dst = %ld\n", port_src, port_dst);
00522 JackPort* src = GetPort(port_src);
00523 JackPort* dst = GetPort(port_dst);
00524 int res = 0;
00525
00526 if (!src->fInUse || !dst->fInUse) {
00527 if (!src->fInUse)
00528 jack_error("JackGraphManager::Connect: port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName);
00529 if (!dst->fInUse)
00530 jack_error("JackGraphManager::Connect: port_dst = %ld not used name = %s", port_dst, GetPort(port_dst)->fName);
00531 res = -1;
00532 goto end;
00533 }
00534 if (src->fTypeId != dst->fTypeId) {
00535 jack_error("JackGraphManager::Connect: different port types: port_src = %ld port_dst = %ld", port_src, port_dst);
00536 res = -1;
00537 goto end;
00538 }
00539 if (manager->IsConnected(port_src, port_dst)) {
00540 jack_error("JackGraphManager::Connect already connected port_src = %ld port_dst = %ld", port_src, port_dst);
00541 res = EEXIST;
00542 goto end;
00543 }
00544
00545 res = manager->Connect(port_src, port_dst);
00546 if (res < 0) {
00547 jack_error("JackGraphManager::Connect failed port_src = %ld port_dst = %ld", port_src, port_dst);
00548 goto end;
00549 }
00550 manager->Connect(port_dst, port_src);
00551 if (res < 0) {
00552 jack_error("JackGraphManager::Connect failed port_dst = %ld port_src = %ld", port_dst, port_src);
00553 goto end;
00554 }
00555
00556 if (manager->IsLoopPath(port_src, port_dst)) {
00557 JackLog("JackGraphManager::Connect: LOOP detected\n");
00558 manager->IncFeedbackConnection(port_src, port_dst);
00559 } else {
00560 manager->IncDirectConnection(port_src, port_dst);
00561 }
00562
00563 end:
00564 WriteNextStateStop();
00565 return res;
00566 }
00567
00568
00569 int JackGraphManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
00570 {
00571 JackConnectionManager* manager = WriteNextStateStart();
00572 JackLog("JackGraphManager::Disconnect port_src = %ld port_dst = %ld\n", port_src, port_dst);
00573 bool in_use_src = GetPort(port_src)->fInUse;
00574 bool in_use_dst = GetPort(port_dst)->fInUse;
00575 int res = 0;
00576
00577 if (!in_use_src || !in_use_dst) {
00578 if (!in_use_src)
00579 jack_error("JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName);
00580 if (!in_use_dst)
00581 jack_error("JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_dst, GetPort(port_dst)->fName);
00582 res = -1;
00583 goto end;
00584 }
00585 if (!manager->IsConnected(port_src, port_dst)) {
00586 jack_error("JackGraphManager::Disconnect not connected port_src = %ld port_dst = %ld", port_src, port_dst);
00587 res = -1;
00588 goto end;
00589 }
00590
00591 manager->Disconnect(port_src, port_dst);
00592 if (res < 0) {
00593 jack_error("JackGraphManager::Disconnect failed port_src = %ld port_dst = %ld", port_src, port_dst);
00594 goto end;
00595 }
00596 manager->Disconnect(port_dst, port_src);
00597 if (res < 0) {
00598 jack_error("JackGraphManager::Disconnect failed port_dst = %ld port_src = %ld", port_dst, port_src);
00599 goto end;
00600 }
00601
00602 if (manager->IsFeedbackConnection(port_src, port_dst)) {
00603 JackLog("JackGraphManager::Disconnect: FEEDBACK removed\n");
00604 manager->DecFeedbackConnection(port_src, port_dst);
00605 } else {
00606 manager->DecDirectConnection(port_src, port_dst);
00607 }
00608
00609 end:
00610 WriteNextStateStop();
00611 return res;
00612 }
00613
00614
00615 int JackGraphManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst)
00616 {
00617 JackConnectionManager* manager = ReadCurrentState();
00618 return manager->IsConnected(port_src, port_dst);
00619 }
00620
00621
00622 int JackGraphManager::CheckPorts(jack_port_id_t port_src, jack_port_id_t port_dst)
00623 {
00624 JackPort* src = GetPort(port_src);
00625 JackPort* dst = GetPort(port_dst);
00626
00627 if ((dst->fFlags & JackPortIsInput) == 0) {
00628 jack_error("Destination port in attempted (dis)connection of %s and %s is not an input port", src->fName, dst->fName);
00629 return -1;
00630 }
00631
00632 if ((src->fFlags & JackPortIsOutput) == 0) {
00633 jack_error("Source port in attempted (dis)connection of %s and %s is not an output port", src->fName, dst->fName);
00634 return -1;
00635 }
00636
00637 return 0;
00638 }
00639
00640 int JackGraphManager::CheckPorts(const char* src_name, const char* dst_name, jack_port_id_t* port_src, jack_port_id_t* port_dst)
00641 {
00642 JackLog("JackGraphManager::CheckConnect src_name = %s dst_name = %s\n", src_name, dst_name);
00643
00644 if ((*port_src = GetPort(src_name)) == NO_PORT) {
00645 jack_error("Unknown source port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name);
00646 return -1;
00647 }
00648
00649 if ((*port_dst = GetPort(dst_name)) == NO_PORT) {
00650 jack_error("Unknown destination port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name);
00651 return -1;
00652 }
00653
00654 return CheckPorts(*port_src, *port_dst);
00655 }
00656
00657
00658 jack_port_id_t JackGraphManager::GetPort(const char* name)
00659 {
00660 for (int i = 0; i < PORT_NUM; i++) {
00661 JackPort* port = GetPort(i);
00662 if (port->IsUsed() && port->NameEquals(name))
00663 return i;
00664 }
00665 return NO_PORT;
00666 }
00667
00672
00673 void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index)
00674 {
00675 const jack_int_t* connections = manager->GetConnections(port_index);
00676 jack_int_t index;
00677 int i;
00678
00679 for (i = 0; (i < CONNECTION_NUM) && ((index = connections[i]) != EMPTY); i++) {
00680 JackPort* port = GetPort(index);
00681 res[i] = port->fName;
00682 }
00683
00684 res[i] = NULL;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694 const char** JackGraphManager::GetConnections(jack_port_id_t port_index)
00695 {
00696 const char** res = (const char**)malloc(sizeof(char*) * (CONNECTION_NUM + 1));
00697 UInt16 cur_index;
00698 UInt16 next_index;
00699 AssertPort(port_index);
00700
00701 do {
00702 cur_index = GetCurrentIndex();
00703 GetConnectionsAux(ReadCurrentState(), res, port_index);
00704 next_index = GetCurrentIndex();
00705 } while (cur_index != next_index);
00706
00707 return res;
00708 }
00709
00710
00711 const char** JackGraphManager::GetPortsAux(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
00712 {
00713 unsigned long match_cnt = 0;
00714 regex_t port_regex;
00715 regex_t type_regex;
00716 bool matching;
00717
00718 if (port_name_pattern && port_name_pattern[0]) {
00719 regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB);
00720 }
00721 if (type_name_pattern && type_name_pattern[0]) {
00722 regcomp(&type_regex, type_name_pattern, REG_EXTENDED | REG_NOSUB);
00723 }
00724
00725 const char** matching_ports = (const char**)malloc(sizeof(char*) * PORT_NUM);
00726
00727 for (int i = 0; i < PORT_NUM; i++) {
00728 matching = true;
00729 JackPort* port = GetPort(i);
00730
00731 if (port->IsUsed()) {
00732
00733 if (flags) {
00734 if ((port->fFlags & flags) != flags) {
00735 matching = false;
00736 }
00737 }
00738
00739 if (matching && port_name_pattern && port_name_pattern[0]) {
00740 if (regexec(&port_regex, port->GetName(), 0, NULL, 0)) {
00741 matching = false;
00742 }
00743 }
00744 if (matching && type_name_pattern && type_name_pattern[0]) {
00745 if (regexec(&type_regex, port->GetType(), 0, NULL, 0)) {
00746 matching = false;
00747 }
00748 }
00749
00750 if (matching) {
00751 matching_ports[match_cnt++] = port->fName;
00752 }
00753 }
00754 }
00755
00756 matching_ports[match_cnt] = 0;
00757
00758 if (match_cnt == 0) {
00759 free(matching_ports);
00760 matching_ports = NULL;
00761 }
00762
00763 if (port_name_pattern && port_name_pattern[0]) {
00764 regfree(&port_regex);
00765 }
00766 if (type_name_pattern && type_name_pattern[0]) {
00767 regfree(&type_regex);
00768 }
00769
00770 return matching_ports;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 const char** JackGraphManager::GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
00780 {
00781 const char** matching_ports = NULL;
00782 UInt16 cur_index;
00783 UInt16 next_index;
00784
00785 do {
00786 cur_index = GetCurrentIndex();
00787 if (matching_ports) {
00788 free(matching_ports);
00789 JackLog("JackGraphManager::GetPorts retry... \n");
00790 }
00791 matching_ports = GetPortsAux(port_name_pattern, type_name_pattern, flags);
00792 next_index = GetCurrentIndex();
00793 } while (cur_index != next_index);
00794
00795 return matching_ports;
00796 }
00797
00798
00799 void JackGraphManager::Save(JackConnectionManager* dst)
00800 {
00801 JackConnectionManager* manager = WriteNextStateStart();
00802 memcpy(dst, manager, sizeof(JackConnectionManager));
00803 WriteNextStateStop();
00804 }
00805
00806
00807 void JackGraphManager::Restore(JackConnectionManager* src)
00808 {
00809 JackConnectionManager* manager = WriteNextStateStart();
00810 memcpy(manager, src, sizeof(JackConnectionManager));
00811 WriteNextStateStop();
00812 }
00813
00814 }
00815
00816