Skip to content

Instantly share code, notes, and snippets.

@kimburgess
Created March 30, 2012 03:21
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/2246182 to your computer and use it in GitHub Desktop.
Save kimburgess/2246182 to your computer and use it in GitHub Desktop.
Updated version of graph library wrapper for 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.
program_name='signal-config'
define_variable
// signal sources
volatile integer SOURCE_A
volatile integer SOURCE_B
volatile integer SOURCE_C
// signal sinks
volatile integer DISPLAY_A
volatile integer DISPLAY_B
volatile integer RECORDER
// switchers
volatile integer SDI_MATRIX
volatile integer DVI_MATRIX
volatile integer STACKED_DVI_MATRIX
define_start
// switchers
SDI_MATRIX = defineSwitcher('sdi matrix', vdvSDIMatrix, 32, 32)
DVI_MATRIX= defineSwitcher('dvi matrix', vdvDVIMatrix, 16, 16)
STACKED_DVI_MATRIX = defineSwitcher('sales people suck', vdvDVISwitch, 6, 1)
// native format links
defineLink(DVI_MATRIX, 1, SDI_MATRIX , 9)
defineLink(SDI_MATRIX, 32, DVI_MATRIX, 8)
// sources
SOURCE_A = defineSource(SDI_MATRIX, 4)
SOURCE_B = defineSource(SDI_MATRIX, 5)
SOURCE_C = defineSource(STACKED_DVI_MATRIX, 6)
//sinks
DISPLAY_A = defineSink(DVI_MATRIX, 10)
DISPLAY_B = defineSink(DVI_MATRIX, 11)
RECORDER = defineSink(SDI_MATRIX, 1)
println("'Signal network created.'")
println("' total nodes: ', itoa(length_array(signalNetwork.nodes))")
println("' total edges: ', itoa(length_array(signalNetwork.edges))")
/*
Then just call route(<source>, <destination>) and it will do the rest.
*/
/**
* 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 'io'
include 'graph'
define_constant
// Tweakable for memory utilization
MAX_SWITCHER_SIZE = 16
MAX_SWITCHERS = 8
define_type
structure matrix {
integer id
char name[32]
dev dv
integer inputNodes[MAX_SWITCHER_SIZE]
integer outputNodes[MAX_SWITCHER_SIZE]
}
define_variable
// 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(char name[32], dev duetVirtual,
integer numInputs, integer numOutputs) {
local_var integer nextID
stack_var matrix switcher
stack_var integer i, j
nextID++
switcher.id = nextID
switcher.name = name
switcher.dv = duetVirtual
switchers[switcher.id] = switcher
set_length_array(switcher.inputNodes, numInputs)
set_length_array(switcher.outputNodes, numOutputs)
set_length_array(switchers, switcher.id + 1)
return switcher.id
}
/**
* Defines a direct 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) {
stack_var integer sourceNode
stack_var integer sinkNode
sourceNode = defineSink(fromSwitcher, output)
sinkNode = defineSource(toSwitcher, input)
graph_create_edge(signalNetwork,
sourceNode,
sinkNode,
2)
}
/**
* Defines a signal processor used to link areas of the network with different
* signal formats.
*
* @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 defineProcessor(integer fromSwitcher, integer output,
integer toSwitcher, integer input) {
stack_var integer inputNode
stack_var integer outputNode
inputNode = defineSink(fromSwitcher, output)
outputNode = defineSource(toSwitcher, input)
graph_create_edge(signalNetwork,
inputNode,
outputNode,
5)
}
/**
* 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
stack_var integer i
// create the node
nodeID = graph_create_node(signalNetwork)
// expand the inputNode array if necessary
if (length_array(switchers[switcher].inputNodes) < input) {
set_length_array(switchers[switcher].inputNodes, input)
}
// link the node to the switcher input
switchers[switcher].inputNodes[input] = nodeID
// create an edge from the input to each utilized output on the switcher
for (i = 1; i <= length_array(switchers[switcher].outputNodes); i++) {
if (switchers[switcher].outputNodes[i] != GRAPH_NULL_NODE_ID) {
graph_create_edge(signalNetwork,
nodeID,
switchers[switcher].outputNodes[i],
1)
}
}
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
stack_var integer i
// create the node
nodeID = graph_create_node(signalNetwork)
// expand the inputNode array if necessary
if (length_array(switchers[switcher].outputNodes) < output) {
set_length_array(switchers[switcher].outputNodes, output)
}
// link it to the switcher output
switchers[switcher].outputNodes[output] = nodeID
// create an edge from each defined input on the switcher
for (i = 1; i <= length_array(switchers[switcher].inputNodes); i++) {
if (switchers[switcher].inputNodes[i] != GRAPH_NULL_NODE_ID) {
graph_create_edge(signalNetwork,
switchers[switcher].inputNodes[i],
nodeID,
1)
}
}
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) {
// no route
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])
println("'connecting ', switchers[switcher].name,
' input ', itoa(input), ' to output ', itoa(output)")
// do the patch
send_command switchers[switcher].dv, "'CI', itoa(input), 'O', itoa(output)"
break
}
}
}
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment