Skip to content

Instantly share code, notes, and snippets.

@kimburgess
Created March 28, 2012 10:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kimburgess/2225173 to your computer and use it in GitHub Desktop.
Save kimburgess/2225173 to your computer and use it in GitHub Desktop.
Utilization of NCL graph library for managing signal distribution
Copyright (C) 2012 Queensland Department of Justice and Attorney General.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
/**
* System signal routing management.
*
* This provides a layer of abstraction between physical signal connectivity and
* presents a set of logical devices to the rest of the system. Routing of
* signals through stacked switchers and video processors is handled within.
*/
program_name='signal-distribution'
include 'graph'
define_constant
// Tweakable for memory utilization
MAX_SWITCHER_SIZE = 16
MAX_SWITCHERS = 8
define_type
structure matrix {
integer id
dev dv
integer inputNodes[MAX_SWITCHER_SIZE]
integer outputNodes[MAX_SWITCHER_SIZE]
}
define_variable
// signal nodes ID's
volatile integer CAMERA_BENCH
volatile integer CAMERA_WITNESS
volatile integer PRIMARY_LCD
volatile integer GALLERY_LCD1
volatile integer GALLERY_LCD2
volatile integer LAPTOP_PROSECUTION
volatile integer LAPTOP_DEFENCE
// switchers ID's
volatile integer PRIMARY_MATRIX
volatile integer SECONDARY_MATRIX
// our network graph
volatile graph signalNetwork
// switcher table
volatile matrix switchers[MAX_SWITCHERS]
/**
* Defines a switcher within our signal network.
*
* This should be a logical switcher rather than one defined by the box its in.
* It is assumed that every input can connect to every output - if you have
* multiple switch levels define a switcher for each.
*
* @param duetVirtual the device to send SNAPI formed switch commands to
* @param numInputs the number of inputs on the switcher
* @param numOutputs the number of outputs on the switcher
* @return an integer containing the switcher ID
*/
define_function integer defineSwitcher(dev duetVirtual, integer numInputs,
integer numOutputs) {
local_var integer nextID
stack_var matrix switcher
stack_var integer i, j
nextID++
switcher.id = nextID
switcher.dv = duetVirtual
// create a node for each input
for (i = 1; i <= numInputs; i++) {
switcher.inputNodes[i] = graph_create_node(signalNetwork)
}
set_length_array(switcher.inputNodes, numInputs)
// ... and each output
for (i = 1; i <= numOutputs; i++) {
switcher.outputNodes[i] = graph_create_node(signalNetwork)
}
set_length_array(switcher.outputNodes, numOutputs)
// then create the edges to join them
for (i = 1; i <= numInputs; i++) {
for (j = 1; j <= numOutputs; j++) {
graph_create_edge(signalNetwork,
switcher.inputNodes[i],
switcher.outputNodes[j])
}
}
switchers[switcher.id] = switcher
set_length_array(switchers, switcher.id + 1)
return switcher.id
}
/**
* Defines a link between stacked switchers.
*
* @param fromSwitcher the id of the switcher the link is from
* @param output the output we are coming from
* @param toSwitcher the id of the switcher we are linking to
* @param input the input the link is to
*/
define_function defineLink(integer fromSwitcher, integer output,
integer toSwitcher, integer input) {
graph_create_edge(signalNetwork,
switchers[fromSwitcher].outputNodes[output],
switchers[toSwitcher].inputNodes[input])
}
/**
* Defines a signal source.
*
* @param switcher the id of the switcher the node is connected to
* @param input the input this source is attached to
* @return the source ID
*/
define_function integer defineSource(integer switcher, integer input) {
stack_var integer nodeID
nodeID = graph_create_node(signalNetwork)
graph_create_edge(signalNetwork,
nodeID,
switchers[switcher].inputNodes[input])
return nodeID
}
/**
* Defines a signal sink.
*
* @param switcher the id of the switcher the node is connected to
* @param output the output this sink is attached to
* @return the sink ID
*/
define_function integer defineSink(integer switcher, integer output) {
stack_var integer nodeID
nodeID = graph_create_node(signalNetwork)
graph_create_edge(signalNetwork,
switchers[switcher].outputNodes[output],
nodeID)
return nodeID
}
/**
* Find the last occurance of the passed integer within an array.
*
* @param array an array containing the integers to search
* @param item the integer to search for
* @return the index of the last occurance of item in array[]
*/
define_function integer getIndex(integer array[], integer item) {
stack_var integer i
for (i = length_array(array); i > 0; i--) {
if (array[i] == item) {
return i
}
}
return 0
}
/**
* Perform the switching required across the signal network to route the passed
* source to the destination.
*
* @param source the source ID to route from
* @param destination the sink ID to route to
* @param a boolean, true if the route was possible
*/
define_function char route(integer source, integer sink) {
local_var integer previousSource
stack_var integer path[8]
stack_var integer hop
stack_var integer switcher
stack_var integer input
stack_var integer output
// only recompute the graph if we need to
if (source != previousSource) {
graph_compute_paths(signalNetwork, source)
}
previousSource = source
path = graph_get_shortest_path(signalNetwork, sink)
if (length_array(path) == 1) {
return false
}
// do the routes than need to be made for the path
for (hop = length_array(path); hop > 0; hop--) {
for (switcher = length_array(switchers); switcher > 0; switcher--) {
// checkout if the node is an input node on a switcher
input = getIndex(switchers[switcher].inputNodes, path[hop])
// if it is, do the patch
if (input > 0) {
// shift focus to the next node which will be the output
hop--
output = getIndex(switchers[switcher].outputNodes, path[hop])
// do the patch
send_command switchers[switcher].dv, "'CI', itoa(input), 'O', itoa(output)"
break
}
}
}
return true
}
define_start
// define signal network here
PRIMARY_MATRIX = defineSwitcher(vdvPrimaryMatrix, 16, 16)
SECONDARY_MATRIX = defineSwitcher(vdvSecondaryMatrix, 6, 1)
defineLink(SECONDARY_MATRIX, 1, PRIMARY_MATRIX, 14)
CAMERA_BENCH = defineSource(PRIMARY_MATRIX, 1)
LAPTOP_PROSECUTION = defineSource(SECONDARY_MATRIX, 1)
LAPTOP_DEFENCE = defineSource(SECONDARY_MATRIX, 2)
PRIMARY_LCD = defineSink(PRIMARY_MATRIX, 1)
GALLERY_LCD1 = defineSink(PRIMARY_MATRIX, 2)
GALLERY_LCD2 = defineSink(PRIMARY_MATRIX, 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment