Home of the G3UKB Acorn-SDR project

architecture


This page provides an architecture overview. The architecture relied on the Internet Communications Engine (ICE). For details of the ICE system please refer to the Ice page.

the nodes


Quick reference to the nodes currently implemented. Not all are complete (see notes) and only a subset is required for each profile depending on the DSP and hardware support as well as any special facilities the profile might need.





There are two data paths. 

  1. The event service interface ( see design overview) is used by every node. Even if the node has no unique control signals, which is highly unlikely, it is still required to implement the life-cycle interface. The interfaces are further described later in the description. The event interface is used for all control signals between nodes. Its a loose coupled message oriented interface. It can be used as an RPC (Remote Procedure Call) interface but I use all one-way asynchronous transfers and thus it has the semantics of messaging.
  2. The PTP transfer interface provides direct paths between the nodes and this is used for bulk data transfers, primarily samples for processing or display. This is a pure efficiency measure. I would prefer to use the event interface for everything but I was concerned about the overhead. However, when I implement displays I will try it through the event interface to see how it performs.

Node descriptions

Key:

Red - the node is complete for the current function of the radio. It will be enhanced as the radio function matures. Note that DttSp signal processing core is the latest drop and will be moved on from time to time. However, it's red because I have not completed the integration of the functions.

Blue - are nodes that are probably feature complete although may still be subject to change. 

NodeDescription
ConsoleThe console is the GUI component. It performs only the interpretation of user gesticulations and presentation of results. There can be more than one GUI node in a system.
PersistThis is the system persistent model for profiles, capabilities and state data.
OzyThe Ozy node provides access to the HPSDR hardware.
InstrStreams in data from a Jack connected device. This is usually an ALSA device providing access to a sound card. It could however be another application.
OutstrStreams out data from a Jack connected device. This is usually an ALSA device providing access to a sound card. It could however be another application. In this case output to a digimodes program for example.
PyDspA simple Python DSP node using the SciPy library. This may progress further and was an experiment to see how well it performed. It also got Acorn off the ground before the DttSp integration was done. It is also an ideal teaching node for learning DSP.
DttSpThe full DttSp core signal processing implementation built into a node.
Ozy + PyDspAn experimental node which combined the Ozy node and the PyDsp node such that the network transfers are avoided. This was done to determine if the issues I was having with 192KHz operation was network latency or delays. In the event it wasn't but the node does provide better performance on smaller machines.
SDR1K ControllerThe parallel port/USB interface control to the SDR1K hardware.
Softrock ControllerIn effect a dummy node as there is no control for the softrocks I current posses. The node is still necessary in order to provide some of the events back to the console node. This node will become a true controller when I have some USB controllable versions of the softrock.

wish list

There are a number of additional nodes that I would like to produce when time permits.  Some of these will be Python and some possibly C++, I don't have any plans at the moment for any of the other language bindings like Java unless another language offers something I can't do in either Python or C++.

NodeDescription
Graphic DisplaysI am undecided at the moment whether graphic displays belong in the main GUI node or should be a separate node. The advantage of a separate node is better parallelism specially on multi-core machines. Also the node can be C++ to give the best possible performance, while the main GUI remain Python for flexibility where there are no pressing performance requirements. The architecture is built to allow the UI to be in separate parts.
CATA CAT interface is a must for serious work. Again the event based architecture makes it easy for a separate node to control the operation of the radio and receive updates as if it were a GUI.
HP Ozy/DttSpThe architecture is flexible in its current form. This is due to the partitioning of function across the nodes. So its easy to augment the current Ozy driver with another node, maybe the next iteration of Ozy which could use Gb Ethernet without rebuilding anything else. It just becomes another profile. Flexibility and performance are usually at odds with one another. I can anticipate that I will need to build a high performance node in C++ that builds a single executable with say the Ozy driver and DttSp. This would give performance characteristics similar to current monolithic systems but it would still be part of the same architecture with a different profile set up.
DigimodesIt has long been a desire to build in digimodes rather than have reliance on external programs. However, at the moment I have neither. Until I start experimenting with digimodes I don't know what the best architecture will be so this is just a holding place for that work.
ScriptingA scripting node will allow user extensions to be written in Python. Essentially it will be a pre configured UI node with an easy to use library and some means to build up scripts.
MemoriesAgain, I'm not sure this will be a node or part of the main GUI. Just a holding place at the moment.

anatomy of a node

A node is not a single piece of code but has a structure. The structure follows a pattern that can just be stamped out for new nodes thus making node creation quite a straight forward process. Of course one still has to write the functional part of the node which can be simple to very complex. 



All nodes have a service module which is the entry point for the process. This is the module that mostly interacts with and sets up the connections and interfaces. All messages are received in this module and dispatched to the implementation. The implementation may be one or several modules with one of more classes. This depends on the function of the node. The implementation is passed references to the interfaces it needs to dispatch messages to, so generally, outgoing messagesa are sent directly from the implementation. The extension is specific to a Python node and would not exist for a C++ or java node. Python is a capable scripting language and is very concise and expressive, however, compared to compiled languages it is slow and is also single threaded (python threads run within a single OS process). Where performance, or low level hardware access is required a C extension is written. Extensions currently exist for the Ozy driver, the DttSp core and the SDR1K driver. It is very likely an extension will be written for the displays as they require good performance.

interfaces

Interfaces are a pretty important part of the architecture.

The easiest way to think of an interface is as a wrapper around the node. The only way in and out of the node is through the interface. A node may implement any number of interfaces but most nodes will only implement 2 or 3 and may connect to 2 or 3 external interfaces.

An interface definition is expressed in the Ice IDL (Interface Definition Language). The language supports a lot of features but generally it is pretty simple to understand. Here is the definition for the life-cycle interface which is probably one of the simplest.

#ifndef LIFE_CYCLE_ICE
#define LIFE_CYCLE_ICE

// Interface for the life cycle of a process
// Most processes should listen for these
module AcornLifeCycle
{
    interface LifeCycle
    {  
        void start();
        void stop();
        void terminate();      
    };
};

#endif

This supports just three calls with no parameters. Of course an IDL definition on its own is no real use to a programming language so the definition must be translated into something the language understands. Ice offers a number of language bindings and for each binding there is a tool to code generate the required glue for the language. For Python the generator is called 'slice2py'. Run this against a definition and it will generate the required python code which can then be imported. A Python module must import both interfaces that it uses, and those that it implements. Subsequent calls into the Ice runtime then sets up the connections and binds the implemented interfaces.

Here is a slightly more complex interface for the persistence service.

#ifndef PERSIST_ICE
#define PERSIST_ICE

module AcornPersist
{
    class UnionDiscriminator {
    };
    class MemberInt extends UnionDiscriminator {
        int i;
    };
    class MemberFloat extends UnionDiscriminator {
        float f;
    };
    class MemberString extends UnionDiscriminator {
       string s;
    };

    interface Persist
    {
        void put(string category, string key, UnionDiscriminator value, int radio);
        UnionDiscriminator get(string category, string key, int radio);
        void save();
        string getProfiles();
        void setProfile(string profile);
        string getProfile();
    };
};

#endif

This is a way to send data of different types which can be efficiently marshalled.

There are 7 interfaces currently defined in the system.

InterfacePurpose
life_cycleTo control the life-cycle of a node. Not all nodes understand the concept of starting and stopping so they may no-op these but terminate must be implemented as this is used to close the system down.
commandCurrently used as the command interface to hardware so generally implemented by any node that connects to hardware.
dspThe superset of possible dsp commands.
persistManages the profiles, getting and setting data and saving the current state of the in-memory structures to the database files.
streaminManages an incoming IQ audio stream.
streamoutManages an outgoing IQ audio stream.
updateThis namespace actually has two interfaces, update and config. Update is used to update anyone interested in presentation state such as a GUI or a CAT node. Config is used to notify configuration changes that should be implemented immediately.