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