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