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