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