JackConnectionManager.h

00001 /*
00002 Copyright (C) 2004-2008 Grame  
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #ifndef __JackConnectionManager__
00021 #define __JackConnectionManager__
00022 
00023 #include "JackConstants.h"
00024 #include "JackActivationCount.h"
00025 #include <assert.h>
00026 
00027 namespace Jack
00028 {
00029 
00030 struct JackClientControl;
00031 
00036 template <int SIZE>
00037 class JackFixedArray
00038 {
00039 
00040     private:
00041 
00042         jack_int_t fTable[SIZE];
00043         uint32_t fCounter;
00044 
00045     public:
00046 
00047         JackFixedArray()
00048         {
00049             Init();
00050         }
00051 
00052         virtual ~JackFixedArray()
00053         {}
00054 
00055         void Init()
00056         {
00057             for (int i = 0; i < SIZE; i++)
00058                 fTable[i] = EMPTY;
00059             fCounter = 0;
00060         }
00061 
00062         bool AddItem(jack_int_t index) 
00063         {
00064             for (int i = 0; i < SIZE; i++) {
00065                 if (fTable[i] == EMPTY) {
00066                     fTable[i] = index;
00067                     fCounter++;
00068                     return true;
00069                 }
00070             }
00071             return false;
00072         }
00073 
00074         bool RemoveItem(jack_int_t index)
00075         {
00076             for (int i = 0; i < SIZE; i++) {
00077                 if (fTable[i] == index) {
00078                     fCounter--;
00079                     // Shift all indexes
00080                     if (i == SIZE - 1) {
00081                         fTable[i] = EMPTY;
00082                     } else {
00083                         int j;
00084                         for (j = i; j <= SIZE - 2 && fTable[j] != EMPTY; j++) {
00085                             fTable[j] = fTable[j + 1];
00086                         }
00087                         fTable[j] = EMPTY;
00088                     }
00089                     return true;
00090                 }
00091             }
00092             return false;
00093         }
00094 
00095         jack_int_t GetItem(jack_int_t index) const 
00096         {
00097             return (index < SIZE) ? fTable[index] : EMPTY;
00098         }
00099 
00100         const jack_int_t* GetItems() const
00101         {
00102             return fTable;
00103         }
00104 
00105         bool CheckItem(jack_int_t index) const
00106         {
00107             for (int i = 0; i < SIZE && fTable[i] != EMPTY; i++) {
00108                 if (fTable[i] == index)
00109                     return true;
00110             }
00111             return false;
00112         }
00113 
00114         uint32_t GetItemCount() const
00115         {
00116             return fCounter;
00117         }
00118 
00119 };
00120 
00125 template <int SIZE>
00126 class JackFixedArray1 : public JackFixedArray<SIZE>
00127 {
00128     private:
00129 
00130         bool fUsed;
00131 
00132     public:
00133 
00134         JackFixedArray1()
00135         {
00136             Init();
00137         }
00138 
00139         virtual ~JackFixedArray1()
00140         {}
00141 
00142         void Init()
00143         {
00144             JackFixedArray<SIZE>::Init();
00145             fUsed = false;
00146         }
00147 
00148         bool IsAvailable() 
00149         {
00150             if (fUsed) {
00151                 return false;
00152             } else {
00153                 fUsed = true;
00154                 return true;
00155             }
00156         }
00157 };
00158 
00163 template <int SIZE>
00164 class JackFixedMatrix
00165 {
00166     private:
00167 
00168         jack_int_t fTable[SIZE][SIZE];
00169 
00170     public:
00171 
00172         JackFixedMatrix()
00173         {}
00174 
00175         virtual ~JackFixedMatrix()
00176         {}
00177 
00178         void Init(jack_int_t index)
00179         {
00180             for (int i = 0; i < SIZE; i++) {
00181                 fTable[index][i] = 0;
00182                 fTable[i][index] = 0;
00183             }
00184         }
00185 
00186         const jack_int_t* GetItems(jack_int_t index) const
00187         {
00188             return fTable[index];
00189         }
00190 
00191         jack_int_t IncItem(jack_int_t index1, jack_int_t index2)
00192         {
00193             fTable[index1][index2]++;
00194             return fTable[index1][index2];
00195         }
00196 
00197         jack_int_t DecItem(jack_int_t index1, jack_int_t index2)
00198         {
00199             fTable[index1][index2]--;
00200             return fTable[index1][index2];
00201         }
00202 
00203         jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const
00204         {
00205             return fTable[index1][index2];
00206         }
00207 
00211         void GetOutputTable(jack_int_t index, jack_int_t* output) const
00212         {
00213             int i, j;
00214 
00215             for (i = 0; i < SIZE; i++)
00216                 output[i] = EMPTY;
00217 
00218             for (i = 0, j = 0; i < SIZE; i++) {
00219                 if (fTable[index][i] > 0) {
00220                     output[j] = i;
00221                     j++;
00222                 }
00223             }
00224         }
00225 
00226         bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00227         {
00228             for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00229                 if (output[i] == index)
00230                     return true;
00231             }
00232             return false;
00233         }
00234 
00235 };
00236 
00241 template <int SIZE>
00242 class JackLoopFeedback
00243 {
00244     private:
00245 
00246         int fTable[SIZE][3];
00247 
00251         bool AddConnectionAux(int ref1, int ref2)
00252         {
00253             for (int i = 0; i < SIZE; i++) {
00254                 if (fTable[i][0] == EMPTY) {
00255                     fTable[i][0] = ref1;
00256                     fTable[i][1] = ref2;
00257                     fTable[i][2] = 1;
00258                     JackLog("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00259                     return true;
00260                 }
00261             }
00262             jack_error("Feedback table is full !!\n");
00263             return false;
00264         }
00265 
00269         bool RemoveConnectionAux(int ref1, int ref2)
00270         {
00271             for (int i = 0; i < SIZE; i++) {
00272                 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00273                     fTable[i][0] = EMPTY;
00274                     fTable[i][1] = EMPTY;
00275                     fTable[i][2] = 0;
00276                     JackLog("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00277                     return true;
00278                 }
00279             }
00280             jack_error("Feedback connection not found\n");
00281             return false;
00282         }
00283 
00284         int IncConnection(int index)
00285         {
00286             fTable[index][2]++;
00287             return fTable[index][2];
00288         }
00289 
00290         int DecConnection(int index)
00291         {
00292             fTable[index][2]--;
00293             return fTable[index][2];
00294         }
00295 
00296     public:
00297 
00298         JackLoopFeedback()
00299         {
00300             Init();
00301         }
00302         virtual ~JackLoopFeedback()
00303         {}
00304 
00305         void Init()
00306         {
00307             for (int i = 0; i < SIZE; i++) {
00308                 fTable[i][0] = EMPTY;
00309                 fTable[i][1] = EMPTY;
00310                 fTable[i][2] = 0;
00311             }
00312         }
00313 
00314         bool IncConnection(int ref1, int ref2)
00315         {
00316             int index = GetConnectionIndex(ref1, ref2);
00317 
00318             if (index >= 0) { // Feedback connection is already added, increment counter
00319                 IncConnection(index);
00320                 return true;
00321             } else {
00322                 return AddConnectionAux(ref1, ref2); // Add the feedback connection
00323             }
00324         }
00325 
00326         bool DecConnection(int ref1, int ref2)
00327         {
00328             int index = GetConnectionIndex(ref1, ref2);
00329 
00330             if (index >= 0) {
00331                 JackLog("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld\n", ref1, ref2, index);
00332                 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00333             } else {
00334                 return false;
00335             }
00336         }
00337 
00341         int GetConnectionIndex(int ref1, int ref2) const
00342         {
00343             for (int i = 0; i < SIZE; i++) {
00344                 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00345                     return i;
00346             }
00347             return -1;
00348         }
00349 
00350 };
00351 
00356 struct JackClientTiming
00357 {
00358     jack_time_t fSignaledAt;
00359     jack_time_t fAwakeAt;
00360     jack_time_t fFinishedAt;
00361         jack_client_state_t fStatus;
00362         
00363         JackClientTiming():fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered)
00364     {}
00365         ~JackClientTiming()
00366     {}
00367 };
00368 
00383 class JackConnectionManager
00384 {
00385 
00386     private:
00387 
00388         JackFixedArray<CONNECTION_NUM> fConnection[PORT_NUM];                   
00389         JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];    
00390         JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];    
00391         JackFixedMatrix<CLIENT_NUM> fConnectionRef;                                             
00392         JackActivationCount fInputCounter[CLIENT_NUM];                                  
00393         JackLoopFeedback<CONNECTION_NUM> fLoopFeedback;                                 
00395         bool IsLoopPathAux(int ref1, int ref2) const;
00396   
00397     public:
00398 
00399         JackConnectionManager();
00400         ~JackConnectionManager();
00401 
00402         // Connections management
00403         int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00404         int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00405         bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00406 
00407         jack_int_t Connections(jack_port_id_t port_index) const;
00408         jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const;
00409         const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00410 
00411         bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00412         bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00413         bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00414 
00415         bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00416         void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00417         void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00418 
00419         // Ports management
00420         int AddInputPort(int refnum, jack_port_id_t port_index);
00421         int AddOutputPort(int refnum, jack_port_id_t port_index);
00422 
00423         int RemoveInputPort(int refnum, jack_port_id_t port_index);
00424         int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00425 
00426         const jack_int_t* GetInputPorts(int refnum);
00427         const jack_int_t* GetOutputPorts(int refnum);
00428 
00429         // Client management
00430                 void InitRefNum(int refnum);
00431                 int GetInputRefNum(jack_port_id_t port_index) const;
00432         int GetOutputRefNum(jack_port_id_t port_index) const;
00433 
00434         // Connect/Disconnect 2 refnum "directly"
00435         bool IsDirectConnection(int ref1, int ref2) const;
00436         void DirectConnect(int ref1, int ref2);
00437         void DirectDisconnect(int ref1, int ref2);
00438 
00439         int GetActivation(int refnum) const;
00440 
00441         // Graph
00442         void ResetGraph(JackClientTiming* timing);
00443         int ResumeRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing);
00444         int SuspendRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing, long time_out_usec);
00445 };
00446 
00447 } // end of namespace
00448 
00449 #endif
00450 

Generated on Thu Feb 14 11:16:01 2008 for Jackdmp by  doxygen 1.5.1