Cortex DEVELOPER NOTES Eric Moon, The Mead Group, Inc.
begun 22 July, 1999
updated 21 October, 1999
OVERVIEW
The purpose of this document: a "spec-in-progress" for the Cortex routing tool and its associated libraries. The header files will always be the most up-to-date documentation, but design constraints, case scenarios, etc. go here.
PURPOSE
Cortex is a package aimed at developers of BeOS media (audio/video) software. It includes full source code for a standalone media-node routing and testing application. For the current release, dr2, the node-management code has been rewritten as a reusable module; hopefully this module will come in handy for developers writing complex (multi-node) media applications.
JUSTIFICATION
Why am I squandering my time on a free, publicly supported development tool when there's an urgent need for new shrinkwrap-quality BeOS audio/video applications?
The new Media Kit has opened up a new software niche: completely interoperable audio and video tools, without the chaos of competing 'plug-in' formats. Properly engineered BeOS media nodes will Just Work... in theory.
The reality is that the sample code released so far by Be is scarce and somewhat inconsistent. This does NOT reflect badly upon the hard-working DTS folks: the generality of the Media Kit opens up a lot of ground to cover. A publicly available collection of well-tested Media Kit code -- both in the application and node arenas -- is essential.
MODULES
In addition, most of the Cortex modules are being written with futher purposes in mind; my long-term goal is the development of an expandable performance-oriented media sequencer (supporting audio, MIDI, video, etc.) Cortex makes a good 'playground' for testing architecture & design ideas.
BACK-END COMPONENTS
As much as possible of Cortex is being designed for reuse. All reusable classes and functions can be isolated in a namespace, since many of the classes have rather obvious and conflict-prone names ('Connection', 'NodeGroup', etc.) This namespace can be configured via the preprocessor variable CORTEX_NAMESPACE (if not defined, no namespace is used at all.)
*NodeManager
This class acts as a sort of 'connection roster': it provides simplified facilities for creating and connecting nodes. By watching the Media Roster NodeManager maintains references to all existing nodes in the system, and tracks the connections between them.
Why would you want to use this component? The most important function it performs is connection management. Say your application instantiates an audio output node and, by default, connects it to the system mixer. There is no reason why the user shouldn't be able to reroute that connection through a filter, or connect it to an audio-recording application. However, your application needs to be aware that the connection it originally created might not exist any longer: NodeManager takes care of that. It also automatically disconnects and releases any nodes you create, simplifying the application shutdown process.
*** feature in development ***
NodeManager, and its related classes (NodeGroup, NodeRef, and Connection) will soon support serialization (loading & saving) in an XML format. Having a 'human-readable' way of saving the state of an application's nodes makes a lot of sense for development and testing purposes. With a bit of extension and a message-savvy scripting language, Cortex could be used for thorough testing of media nodes: a script could run through every possible format combination, looking for formats that break or confuse a node.
USER INTERFACE COMPONENTS
TipManager
TipManager handles pop-up tips (aka ToolTips or bubble help.) A given instance is bound to a particular BView, and handles display of tips for that view and any of its descendants. A tip can be connected to a certain
rectangular region in a view, or the whole view.
TipManager has changed significantly in dr2.0.2; it now derives privately from BWindow, allowing it to receive mouse events directly rather than polling the mouse position.
ValControl
ValControl is an abstract control designed for simple manipulation of all sorts of values, both continuous and discrete. For now, the only completed subclass is NumericValControl, which provides direct mouse- and keyboard-based editing of numbers (integer or fixed-point.) It can also be connected to a BContinuousParameter (this is a first step towards a ValControl-based BMediaTheme.)
MEDIA-NODE DEVELOPMENT
IAudioOp, IAudioOpFactory, IAudioOpHost, IParameterSet
These interfaces provide the foundation for a basic audio-filtering framework. IAudioOp represents an abstract audio operation, which is bound at construction time to a particular IAudioOpHost. Currently the host interface only has one operation, whose purpose is to allow access to an IParameterSet: this interface makes it easy to decouple a media node's parameters from the node itself. Generally a given IAudioOp implementation will "know" a given IParameterSet.
IAudioOpFactory implementations are responsible for creating an IAudioOp capable of handling a particular format combination. The factory object is also expected to return an IParameterSet.
AudioFilterNode
AudioFilterNode is a media-node implementation that works with the above audio-filtering framework. Passed an IAudioOpFactory in the constructor, the node automatically creates and uses audio operations from the factory as needed. Hook methods are provided to simplify the task of format negotiation a bit.
SUPPORT/LIBRARIES
IObservable
IObservable, its implementations ObservableHandler and ObservableLooper, and the helper functions found in observe.h comprise one approach to carrying out the "Observer" pattern using BeOS messaging.
The IObservable implementations use Owen Smith's MultiInvoker.
ProfileTarget, ProfileBlock
These simple profiling tools may help cover the gaps left by the profile utility. You can create ProfileBlock objects on the stack to measure the time taken by a given block of code. I won't make any guarantees about the performance of these tools, though they've helped me find a few slow spots in UI code.