2 Copyright (C) 2004-2006 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __JackConnectionManager__
21 #define __JackConnectionManager__
23 #include "JackConstants.h"
24 #include "JackActivationCount.h"
30 #define NO_PORT 0xFFFE
35 typedef uint16_t jack_int_t
; // Internal type for ports and refnum
37 struct JackClientControl
;
44 } jack_client_state_t
;
56 jack_int_t fTable
[SIZE
];
66 virtual ~JackFixedArray()
71 for (int i
= 0; i
< SIZE
; i
++)
76 bool AddItem(jack_int_t index
)
78 for (int i
= 0; i
< SIZE
; i
++) {
79 if (fTable
[i
] == EMPTY
) {
88 bool RemoveItem(jack_int_t index
)
90 for (int i
= 0; i
< SIZE
; i
++) {
91 if (fTable
[i
] == index
) {
98 for (j
= i
; j
<= SIZE
- 2 && fTable
[j
] != EMPTY
; j
++) {
99 fTable
[j
] = fTable
[j
+ 1];
109 jack_int_t
GetItem(jack_int_t index
) const
111 return (index
< SIZE
) ? fTable
[index
] : EMPTY
;
114 const jack_int_t
* GetItems() const
119 bool CheckItem(jack_int_t index
) const
121 for (int i
= 0; i
< SIZE
&& fTable
[i
] != EMPTY
; i
++) {
122 if (fTable
[i
] == index
)
128 uint32_t GetItemCount() const
136 \brief Utility class.
140 class JackFixedArray1
: public JackFixedArray
<SIZE
>
153 virtual ~JackFixedArray1()
158 JackFixedArray
<SIZE
>::Init();
174 \brief Utility class.
178 class JackFixedMatrix
182 jack_int_t fTable
[SIZE
][SIZE
];
189 virtual ~JackFixedMatrix()
192 void Init(jack_int_t index
)
194 for (int i
= 0; i
< SIZE
; i
++) {
195 fTable
[index
][i
] = 0;
196 fTable
[i
][index
] = 0;
200 const jack_int_t
* GetItems(jack_int_t index
) const
202 return fTable
[index
];
205 jack_int_t
IncItem(jack_int_t index1
, jack_int_t index2
)
207 fTable
[index1
][index2
]++;
208 return fTable
[index1
][index2
];
211 jack_int_t
DecItem(jack_int_t index1
, jack_int_t index2
)
213 fTable
[index1
][index2
]--;
214 return fTable
[index1
][index2
];
217 jack_int_t
GetItemCount(jack_int_t index1
, jack_int_t index2
) const
219 return fTable
[index1
][index2
];
223 \brief Get the output indexes of a given index.
225 void GetOutputTable(jack_int_t index
, jack_int_t
* output
) const
229 for (i
= 0; i
< SIZE
; i
++)
232 for (i
= 0, j
= 0; i
< SIZE
; i
++) {
233 if (fTable
[index
][i
] > 0) {
240 bool IsInsideTable(jack_int_t index
, jack_int_t
* output
) const
242 for (int i
= 0; i
< SIZE
&& output
[i
] != EMPTY
; i
++) {
243 if (output
[i
] == index
)
252 \brief Utility class.
256 class JackLoopFeedback
263 \brief Add a feedback connection between 2 refnum.
265 bool AddConnectionAux(int ref1
, int ref2
)
267 for (int i
= 0; i
< SIZE
; i
++) {
268 if (fTable
[i
][0] == EMPTY
) {
272 JackLog("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld\n", ref1
, ref2
);
276 jack_error("Feedback table is full !!\n");
281 \brief Remove a feedback connection between 2 refnum.
283 bool RemoveConnectionAux(int ref1
, int ref2
)
285 for (int i
= 0; i
< SIZE
; i
++) {
286 if (fTable
[i
][0] == ref1
&& fTable
[i
][1] == ref2
) {
287 fTable
[i
][0] = EMPTY
;
288 fTable
[i
][1] = EMPTY
;
290 JackLog("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld\n", ref1
, ref2
);
294 jack_error("Feedback connection not found\n");
298 int IncConnection(int index
)
301 return fTable
[index
][2];
304 int DecConnection(int index
)
307 return fTable
[index
][2];
316 virtual ~JackLoopFeedback()
321 for (int i
= 0; i
< SIZE
; i
++) {
322 fTable
[i
][0] = EMPTY
;
323 fTable
[i
][1] = EMPTY
;
328 bool IncConnection(int ref1
, int ref2
)
330 int index
= GetConnectionIndex(ref1
, ref2
);
332 if (index
>= 0) { // Feedback connection is already added, increment counter
333 IncConnection(index
);
336 return AddConnectionAux(ref1
, ref2
); // Add the feedback connection
340 bool DecConnection(int ref1
, int ref2
)
342 int index
= GetConnectionIndex(ref1
, ref2
);
345 JackLog("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld\n", ref1
, ref2
, index
);
346 return (DecConnection(index
) == 0) ? RemoveConnectionAux(ref1
, ref2
) : true;
353 \brief Test if a connection between 2 refnum is a feedback connection.
355 int GetConnectionIndex(int ref1
, int ref2
) const
357 for (int i
= 0; i
< SIZE
; i
++) {
358 if (fTable
[i
][0] == ref1
&& fTable
[i
][1] == ref2
)
367 \brief For client timing measurements.
370 struct JackClientTiming
372 jack_time_t fSignaledAt
;
373 jack_time_t fAwakeAt
;
374 jack_time_t fFinishedAt
;
375 jack_client_state_t fStatus
;
377 JackClientTiming():fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered
)
384 \brief Connection manager.
387 <LI>The <B>fConnection</B> array contains the list (array line) of connected ports for a given port.
388 <LI>The <B>fConnectionCount</B> array contains the number of connected ports to a given port.
389 <LI>The <B>fInputPort</B> array contains the list (array line) of input connected ports for a given client.
390 <LI>The <B>fOutputPort</B> array contains the list (array line) of ouput connected ports for a given client.
391 <LI>The <B>fConnectionRef</B> array contains the number of ports connected between two clients.
392 <LI>The <B>fInputRef</B> array contains the number of input clients connected to a given client.
393 <LI>The <B>fInputCounter</B> array contains the number of input clients connected to a given for activation purpose.
397 class JackConnectionManager
402 JackFixedArray
<CONNECTION_NUM
> fConnection
[PORT_NUM
]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */
403 JackFixedArray1
<PORT_NUM_FOR_CLIENT
> fInputPort
[CLIENT_NUM
]; /*! Table of input port per refnum : to find a refnum for a given port */
404 JackFixedArray
<PORT_NUM_FOR_CLIENT
> fOutputPort
[CLIENT_NUM
]; /*! Table of output port per refnum : to find a refnum for a given port */
405 JackFixedMatrix
<CLIENT_NUM
> fConnectionRef
; /*! Table of port connections by (refnum , refnum) */
406 JackActivationCount fInputCounter
[CLIENT_NUM
]; /*! Activation counter per refnum */
407 JackLoopFeedback
<CONNECTION_NUM
> fLoopFeedback
; /*! Loop feedback connections */
409 bool IsLoopPathAux(int ref1
, int ref2
) const;
413 JackConnectionManager();
414 virtual ~JackConnectionManager();
416 // Connections management
417 int Connect(jack_port_id_t port_src
, jack_port_id_t port_dst
);
418 int Disconnect(jack_port_id_t port_src
, jack_port_id_t port_dst
);
419 bool IsConnected(jack_port_id_t port_src
, jack_port_id_t port_dst
) const;
421 jack_int_t
Connections(jack_port_id_t port_index
) const;
422 jack_port_id_t
GetPort(jack_port_id_t port_index
, int connection
) const;
423 const jack_int_t
* GetConnections(jack_port_id_t port_index
) const;
425 bool IncFeedbackConnection(jack_port_id_t port_src
, jack_port_id_t port_dst
);
426 bool DecFeedbackConnection(jack_port_id_t port_src
, jack_port_id_t port_dst
);
427 bool IsFeedbackConnection(jack_port_id_t port_src
, jack_port_id_t port_dst
) const;
429 bool IsLoopPath(jack_port_id_t port_src
, jack_port_id_t port_dst
) const;
430 void IncDirectConnection(jack_port_id_t port_src
, jack_port_id_t port_dst
);
431 void DecDirectConnection(jack_port_id_t port_src
, jack_port_id_t port_dst
);
434 int AddInputPort(int refnum
, jack_port_id_t port_index
);
435 int AddOutputPort(int refnum
, jack_port_id_t port_index
);
437 int RemoveInputPort(int refnum
, jack_port_id_t port_index
);
438 int RemoveOutputPort(int refnum
, jack_port_id_t port_index
);
440 const jack_int_t
* GetInputPorts(int refnum
);
441 const jack_int_t
* GetOutputPorts(int refnum
);
444 void InitRefNum(int refnum
);
445 int GetInputRefNum(jack_port_id_t port_index
) const;
446 int GetOutputRefNum(jack_port_id_t port_index
) const;
448 // Connect/Disconnect 2 refnum "directly"
449 bool IsDirectConnection(int ref1
, int ref2
) const;
450 void DirectConnect(int ref1
, int ref2
);
451 void DirectDisconnect(int ref1
, int ref2
);
453 int GetActivation(int refnum
) const;
456 void ResetGraph(JackClientTiming
* timing
);
457 int ResumeRefNum(JackClientControl
* control
, JackSynchro
** table
, JackClientTiming
* timing
);
458 int SuspendRefNum(JackClientControl
* control
, JackSynchro
** table
, JackClientTiming
* timing
, long time_out_usec
);
462 } // end of namespace