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