21 #include "JackGraphManager.h"    22 #include "JackConstants.h"    23 #include "JackError.h"    32 static void AssertBufferSize(jack_nframes_t buffer_size)
    34     if (buffer_size > BUFFER_SIZE_MAX) {
    35         jack_log(
"JackGraphManager::AssertBufferSize frames = %ld", buffer_size);
    36         assert(buffer_size <= BUFFER_SIZE_MAX);
    40 void JackGraphManager::AssertPort(jack_port_id_t port_index)
    42     if (port_index >= fPortMax) {
    43         jack_log(
"JackGraphManager::AssertPort port_index = %ld", port_index);
    44         assert(port_index < fPortMax);
    48 JackGraphManager* JackGraphManager::Allocate(
int port_max)
    51     void* shared_ptr = JackShmMem::operator 
new(
sizeof(JackGraphManager) + port_max * 
sizeof(JackPort));
    52     return new(shared_ptr) JackGraphManager(port_max);
    55 void JackGraphManager::Destroy(JackGraphManager* manager)
    58     manager->~JackGraphManager();
    59     JackShmMem::operator 
delete(manager);
    62 JackGraphManager::JackGraphManager(
int port_max)
    64     assert(port_max <= PORT_NUM_MAX);
    66     for (
int i = 0; i < port_max; i++) {
    67         fPortArray[i].Release();
    73 JackPort* JackGraphManager::GetPort(jack_port_id_t port_index)
    75     AssertPort(port_index);
    76     return &fPortArray[port_index];
    79 jack_default_audio_sample_t* JackGraphManager::GetBuffer(jack_port_id_t port_index)
    81     return fPortArray[port_index].GetBuffer();
    85 void JackGraphManager::InitRefNum(
int refnum)
    88     manager->InitRefNum(refnum);
    93 void JackGraphManager::RunCurrentGraph()
    96     manager->ResetGraph(fClientTiming);
   100 bool JackGraphManager::RunNextGraph()
   104     manager->ResetGraph(fClientTiming);
   109 bool JackGraphManager::IsFinishedGraph()
   112     return (manager->GetActivation(FREEWHEEL_DRIVER_REFNUM) == 0);
   116 int JackGraphManager::ResumeRefNum(JackClientControl* control, JackSynchro* table)
   119     return manager->ResumeRefNum(control, table, fClientTiming);
   123 int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, 
long usec)
   126     return manager->SuspendRefNum(control, table, fClientTiming, usec);
   129 void JackGraphManager::TopologicalSort(std::vector<jack_int_t>& sorted)
   139     } 
while (cur_index != next_index); 
   143 void JackGraphManager::DirectConnect(
int ref1, 
int ref2)
   146     manager->DirectConnect(ref1, ref2);
   147     jack_log(
"JackGraphManager::ConnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld", CurIndex(fCounter), ref1, ref2);
   152 void JackGraphManager::DirectDisconnect(
int ref1, 
int ref2)
   155     manager->DirectDisconnect(ref1, ref2);
   156     jack_log(
"JackGraphManager::DisconnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld", CurIndex(fCounter), ref1, ref2);
   161 bool JackGraphManager::IsDirectConnection(
int ref1, 
int ref2)
   164     return manager->IsDirectConnection(ref1, ref2);
   168 void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buffer_size)
   170     AssertPort(port_index);
   171     AssertBufferSize(buffer_size);
   174     JackPort* port = GetPort(port_index);
   177     if (!port->IsUsed()) {
   178         jack_log(
"JackGraphManager::GetBuffer : port = %ld is released state", port_index);
   182     jack_int_t len = manager->Connections(port_index);
   185     if (port->fFlags & JackPortIsOutput) {
   186         return (port->fTied != NO_PORT) ? GetBuffer(port->fTied, buffer_size) : GetBuffer(port_index);
   191         port->ClearBuffer(buffer_size);
   192         return port->GetBuffer();
   195     } 
else if (len == 1) {
   196         jack_port_id_t src_index = manager->GetPort(port_index, 0);
   199         if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) {
   201             buffers[0] = GetBuffer(src_index, buffer_size);
   202             port->MixBuffers(buffers, 1, buffer_size);
   203             return port->GetBuffer();
   206             return GetBuffer(src_index, buffer_size);
   212         const jack_int_t* connections = manager->GetConnections(port_index);
   213         void* buffers[CONNECTION_NUM_FOR_PORT];
   214         jack_port_id_t src_index;
   217         for (i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((src_index = connections[i]) != EMPTY); i++) {
   218             AssertPort(src_index);
   219             buffers[i] = GetBuffer(src_index, buffer_size);
   222         port->MixBuffers(buffers, i, buffer_size);
   223         return port->GetBuffer();
   230     AssertPort(port_index);
   231     JackPort* port = GetPort(port_index);
   245     if ((port->fFlags & JackPortIsOutput) == 0) { 
   246         jack_port_id_t src_index;
   247         for (
int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((src_index = connections[i]) != EMPTY); i++) {
   257 jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, 
JackConnectionManager* manager, 
int hop_count)
   260     jack_nframes_t max_latency = 0;
   261     jack_port_id_t dst_index;
   264         return GetPort(port_index)->GetLatency();
   266     for (
int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) {
   267         if (src_port_index != dst_index) {
   268             AssertPort(dst_index);
   269             JackPort* dst_port = GetPort(dst_index);
   270             jack_nframes_t this_latency = (dst_port->fFlags & JackPortIsTerminal)
   271                                           ? dst_port->GetLatency()
   272                                           : ComputeTotalLatencyAux(dst_index, port_index, manager, hop_count + 1);
   273             max_latency = ((max_latency > this_latency) ? max_latency : this_latency);
   277     return max_latency + GetPort(port_index)->GetLatency();
   281 int JackGraphManager::ComputeTotalLatency(jack_port_id_t port_index)
   285     JackPort* port = GetPort(port_index);
   286     AssertPort(port_index);
   290         port->fTotalLatency = ComputeTotalLatencyAux(port_index, port_index, 
ReadCurrentState(), 0);
   292     } 
while (cur_index != next_index); 
   294     jack_log(
"JackGraphManager::GetTotalLatency port_index = %ld total latency = %ld", port_index, port->fTotalLatency);
   299 int JackGraphManager::ComputeTotalLatencies()
   301     jack_port_id_t port_index;
   302     for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) {
   303         JackPort* port = GetPort(port_index);
   304         if (port->IsUsed()) {
   305             ComputeTotalLatency(port_index);
   311 void JackGraphManager::RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode)
   314     JackPort* port = GetPort(port_index);
   316     jack_port_id_t dst_index;
   318     for (
int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) {
   319         AssertPort(dst_index);
   320         JackPort* dst_port = GetPort(dst_index);
   323         dst_port->GetLatencyRange(mode, &other_latency);
   325         if (other_latency.
max > latency.
max) {
   326                         latency.
max = other_latency.
max;
   328                 if (other_latency.
min < latency.
min) {
   329                         latency.
min = other_latency.
min;
   333     if (latency.
min == UINT32_MAX) {
   337         port->SetLatencyRange(mode, &latency);
   340 void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode)
   347         RecalculateLatencyAux(port_index, mode);
   349     } 
while (cur_index != next_index); 
   355 void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size)
   357     jack_log(
"JackGraphManager::SetBufferSize size = %ld", buffer_size);
   359     jack_port_id_t port_index;
   360     for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) {
   361         JackPort* port = GetPort(port_index);
   362         if (port->IsUsed()) {
   363             port->ClearBuffer(buffer_size);
   369 jack_port_id_t JackGraphManager::AllocatePortAux(
int refnum, 
const char* port_name, 
const char* port_type, JackPortFlags flags)
   371     jack_port_id_t port_index;
   374     for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) {
   375         JackPort* port = GetPort(port_index);
   376         if (!port->IsUsed()) {
   377             jack_log(
"JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s", port_index, port_name, port_type);
   378             if (!port->Allocate(refnum, port_name, port_type, flags)) {
   385     return (port_index < fPortMax) ? port_index : NO_PORT;
   389 jack_port_id_t JackGraphManager::AllocatePort(
int refnum, 
const char* port_name, 
const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size)
   392     jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags);
   394     if (port_index != NO_PORT) {
   395         JackPort* port = GetPort(port_index);
   397         port->ClearBuffer(buffer_size);
   400         if (flags & JackPortIsOutput) {
   401             res = manager->AddOutputPort(refnum, port_index);
   403             res = manager->AddInputPort(refnum, port_index);
   408             port_index = NO_PORT;
   417 int JackGraphManager::ReleasePort(
int refnum, jack_port_id_t port_index)
   420     JackPort* port = GetPort(port_index);
   423     if (port->fFlags & JackPortIsOutput) {
   424         DisconnectAllOutput(port_index);
   425         res = manager->RemoveOutputPort(refnum, port_index);
   427         DisconnectAllInput(port_index);
   428         res = manager->RemoveInputPort(refnum, port_index);
   436 void JackGraphManager::GetInputPorts(
int refnum, jack_int_t* res)
   439     const jack_int_t* input = manager->GetInputPorts(refnum);
   440     memcpy(res, input, 
sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT);
   444 void JackGraphManager::GetOutputPorts(
int refnum, jack_int_t* res)
   447     const jack_int_t* output = manager->GetOutputPorts(refnum);
   448     memcpy(res, output, 
sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT);
   453 void JackGraphManager::RemoveAllPorts(
int refnum)
   455     jack_log(
"JackGraphManager::RemoveAllPorts ref = %ld", refnum);
   457     jack_port_id_t port_index;
   460     const jack_int_t* input = manager->GetInputPorts(refnum);
   461     while ((port_index = input[0]) != EMPTY) {
   462         int res = ReleasePort(refnum, port_index);
   464             jack_error(
"JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index);
   471     const jack_int_t* output = manager->GetOutputPorts(refnum);
   472     while ((port_index = output[0]) != EMPTY) {
   473         int res = ReleasePort(refnum, port_index);
   475             jack_error(
"JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index);
   485 void JackGraphManager::DisconnectAllPorts(
int refnum)
   488     jack_log(
"JackGraphManager::DisconnectAllPorts ref = %ld", refnum);
   491     const jack_int_t* input = manager->GetInputPorts(refnum);
   492     for (i = 0; i < PORT_NUM_FOR_CLIENT && input[i] != EMPTY ; i++) {
   493         DisconnectAllInput(input[i]);
   496     const jack_int_t* output = manager->GetOutputPorts(refnum);
   497     for (i = 0; i < PORT_NUM_FOR_CLIENT && output[i] != EMPTY; i++) {
   498         DisconnectAllOutput(output[i]);
   505 void JackGraphManager::DisconnectAllInput(jack_port_id_t port_index)
   507     jack_log(
"JackGraphManager::DisconnectAllInput port_index = %ld", port_index);
   510     for (
unsigned int i = 0; i < fPortMax; i++) {
   511         if (manager->IsConnected(i, port_index)) {
   512             jack_log(
"JackGraphManager::Disconnect i = %ld  port_index = %ld", i, port_index);
   513             Disconnect(i, port_index);
   520 void JackGraphManager::DisconnectAllOutput(jack_port_id_t port_index)
   522     jack_log(
"JackGraphManager::DisconnectAllOutput port_index = %ld ", port_index);
   525     const jack_int_t* connections = manager->GetConnections(port_index);
   526     while (connections[0] != EMPTY) {
   527         Disconnect(port_index, connections[0]); 
   533 int JackGraphManager::DisconnectAll(jack_port_id_t port_index)
   535     AssertPort(port_index);
   537     JackPort* port = GetPort(port_index);
   538     if (port->fFlags & JackPortIsOutput) {
   539         DisconnectAllOutput(port_index);
   541         DisconnectAllInput(port_index);
   547 void JackGraphManager::GetConnections(jack_port_id_t port_index, jack_int_t* res)
   550     const jack_int_t* connections = manager->GetConnections(port_index);
   551     memcpy(res, connections, 
sizeof(jack_int_t) * CONNECTION_NUM_FOR_PORT);
   556 void JackGraphManager::Activate(
int refnum)
   558     DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum);
   559     DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM);
   568 void JackGraphManager::Deactivate(
int refnum)
   571     if (IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) {
   572         DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM);
   574         jack_log(
"JackServer::Deactivate client = %ld was not activated", refnum);
   578     if (IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) {
   579         DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum);
   581         jack_log(
"JackServer::Deactivate client = %ld was not activated", refnum);
   586 int JackGraphManager::GetInputRefNum(jack_port_id_t port_index)
   588     AssertPort(port_index);
   590     int res = manager->GetInputRefNum(port_index);
   596 int JackGraphManager::GetOutputRefNum(jack_port_id_t port_index)
   598     AssertPort(port_index);
   600     int res = manager->GetOutputRefNum(port_index);
   605 int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
   608     jack_log(
"JackGraphManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst);
   609     JackPort* src = GetPort(port_src);
   610     JackPort* dst = GetPort(port_dst);
   613     if (!src->fInUse || !dst->fInUse) {
   615             jack_error(
"JackGraphManager::Connect port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName);
   617             jack_error(
"JackGraphManager::Connect port_dst = %ld not used name = %s", port_dst, GetPort(port_dst)->fName);
   621     if (src->fTypeId != dst->fTypeId) {
   622         jack_error(
"JackGraphManager::Connect different port types port_src = %ld port_dst = %ld", port_src, port_dst);
   626     if (manager->IsConnected(port_src, port_dst)) {
   627         jack_error(
"JackGraphManager::Connect already connected port_src = %ld port_dst = %ld", port_src, port_dst);
   632     res = manager->Connect(port_src, port_dst);
   634         jack_error(
"JackGraphManager::Connect failed port_src = %ld port_dst = %ld", port_src, port_dst);
   637     res = manager->Connect(port_dst, port_src);
   639         jack_error(
"JackGraphManager::Connect failed port_dst = %ld port_src = %ld", port_dst, port_src);
   643     if (manager->IsLoopPath(port_src, port_dst)) {
   644         jack_log(
"JackGraphManager::Connect: LOOP detected");
   645         manager->IncFeedbackConnection(port_src, port_dst);
   647         manager->IncDirectConnection(port_src, port_dst);
   656 int JackGraphManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
   659     jack_log(
"JackGraphManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst);
   660     bool in_use_src = GetPort(port_src)->fInUse;
   661     bool in_use_dst = GetPort(port_dst)->fInUse;
   664     if (!in_use_src || !in_use_dst) {
   666             jack_error(
"JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName);
   668             jack_error(
"JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_dst, GetPort(port_dst)->fName);
   672     if (!manager->IsConnected(port_src, port_dst)) {
   673         jack_error(
"JackGraphManager::Disconnect not connected port_src = %ld port_dst = %ld", port_src, port_dst);
   678     res = manager->Disconnect(port_src, port_dst);
   680         jack_error(
"JackGraphManager::Disconnect failed port_src = %ld port_dst = %ld", port_src, port_dst);
   683     res = manager->Disconnect(port_dst, port_src);
   685         jack_error(
"JackGraphManager::Disconnect failed port_dst = %ld port_src = %ld", port_dst, port_src);
   689     if (manager->IsFeedbackConnection(port_src, port_dst)) {
   690         jack_log(
"JackGraphManager::Disconnect: FEEDBACK removed");
   691         manager->DecFeedbackConnection(port_src, port_dst);
   693         manager->DecDirectConnection(port_src, port_dst);
   702 int JackGraphManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst)
   705     return manager->IsConnected(port_src, port_dst);
   709 int JackGraphManager::CheckPorts(jack_port_id_t port_src, jack_port_id_t port_dst)
   711     JackPort* src = GetPort(port_src);
   712     JackPort* dst = GetPort(port_dst);
   714     if ((dst->fFlags & JackPortIsInput) == 0) {
   715         jack_error(
"Destination port in attempted (dis)connection of %s and %s is not an input port", src->fName, dst->fName);
   719     if ((src->fFlags & JackPortIsOutput) == 0) {
   720         jack_error(
"Source port in attempted (dis)connection of %s and %s is not an output port", src->fName, dst->fName);
   727 int JackGraphManager::GetTwoPorts(
const char* src_name, 
const char* dst_name, jack_port_id_t* port_src, jack_port_id_t* port_dst)
   729     jack_log(
"JackGraphManager::CheckConnect src_name = %s dst_name = %s", src_name, dst_name);
   731     if ((*port_src = GetPort(src_name)) == NO_PORT) {
   732         jack_error(
"Unknown source port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name);
   736     if ((*port_dst = GetPort(dst_name)) == NO_PORT) {
   737         jack_error(
"Unknown destination port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name);
   745 jack_port_id_t JackGraphManager::GetPort(
const char* name)
   747     for (
unsigned int i = 0; i < fPortMax; i++) {
   748         JackPort* port = GetPort(i);
   749         if (port->IsUsed() && port->NameEquals(name)) {
   761 void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, 
const char** res, jack_port_id_t port_index)
   763     const jack_int_t* connections = manager->GetConnections(port_index);
   768     memset(res, 0, 
sizeof(
char*) * CONNECTION_NUM_FOR_PORT);
   770     for (i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((index = connections[i]) != EMPTY); i++) {
   771         JackPort* port = GetPort(index);
   772         res[i] = port->fName;
   785 const char** JackGraphManager::GetConnections(jack_port_id_t port_index)
   787     const char** res = (
const char**)malloc(
sizeof(
char*) * CONNECTION_NUM_FOR_PORT);
   788     UInt16 cur_index, next_index;
   797     } 
while (cur_index != next_index); 
   808 void JackGraphManager::GetPortsAux(
const char** matching_ports, 
const char* port_name_pattern, 
const char* type_name_pattern, 
unsigned long flags)
   811     regex_t port_regex, type_regex;
   813     if (port_name_pattern && port_name_pattern[0]) {
   814         regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB);
   816     if (type_name_pattern && type_name_pattern[0]) {
   817         regcomp(&type_regex, type_name_pattern, REG_EXTENDED | REG_NOSUB);
   821     memset(matching_ports, 0, 
sizeof(
char*) * fPortMax);
   823     for (
unsigned int i = 0; i < fPortMax; i++) {
   824         bool matching = 
true;
   825         JackPort* port = GetPort(i);
   827         if (port->IsUsed()) {
   830                 if ((port->fFlags & flags) != flags) {
   835             if (matching && port_name_pattern && port_name_pattern[0]) {
   836                 if (regexec(&port_regex, port->GetName(), 0, NULL, 0)) {
   840             if (matching && type_name_pattern && type_name_pattern[0]) {
   841                 if (regexec(&type_regex, port->GetType(), 0, NULL, 0)) {
   847                 matching_ports[match_cnt++] = port->fName;
   852     matching_ports[match_cnt] = 0;
   854     if (port_name_pattern && port_name_pattern[0]) {
   855         regfree(&port_regex);
   857     if (type_name_pattern && type_name_pattern[0]) {
   858         regfree(&type_regex);
   868 const char** JackGraphManager::GetPorts(
const char* port_name_pattern, 
const char* type_name_pattern, 
unsigned long flags)
   870     const char** res = (
const char**)malloc(
sizeof(
char*) * fPortMax);
   871     UInt16 cur_index, next_index;
   878         GetPortsAux(res, port_name_pattern, type_name_pattern, flags);
   880     } 
while (cur_index != next_index);  
   891 void JackGraphManager::Save(JackConnectionManager* dst)
   894     memcpy(dst, manager, 
sizeof(JackConnectionManager));
   899 void JackGraphManager::Restore(JackConnectionManager* src)
   902     memcpy(manager, src, 
sizeof(JackConnectionManager));
 JackConnectionManager * ReadCurrentState()
Returns the current state : only valid in the RT reader thread.
void WriteNextStateStop()
Stop write operation : make the next state ready to be used by the RT thread.
SERVER_EXPORT void jack_error(const char *fmt,...)
JackConnectionManager * WriteNextStateStart()
Start write operation : setup and returns the next state to update, check for recursive write calls.
UInt16 GetCurrentIndex()
Returns the current state index.
JackConnectionManager * TrySwitchState()
Tries to switch to the next state and returns the new current state (either the same as before if cas...
int RequestMonitor(bool onoff)
int RequestMonitor(jack_port_id_t port_index, bool onoff)
const jack_int_t * GetConnections(jack_port_id_t port_index) const
Get the connection port array.
SERVER_EXPORT void jack_log(const char *fmt,...)