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