An audio formatter (a logical device that produces audio output) can have several components, e.g., a speech component and multiple sound components. The state space of the audio formatter, henceforth referred to as the audio space, is modeled as the direct sum (or cross product) of the state spaces of these components. Thus, given an audio formatter with n components, its state is an n-tuple (s1,s2,⋯,sn), where si is the state of component i. Each component subspace is a multi-dimensional space, with dimensions corresponding to parameters that can be modified on the corresponding hardware component. In AS TE R we have:
AFL state variables capture the current and global states of each component space. The AFL block introduces a new lexical scope with local copies of all the current component-state variables. For example, variable *current-speech-state* is the local state of the speech component (in the current block) and *global-speech-state* is its global state. Each component subspace provides operators for moving in that subspace. Operators select points (either by name or by applying transformations to other points) and are used to form AFL expressions. When a block terminates (prematurely or otherwise), effects of all local assignments made within that block are undone. Components of the audio formatter may have independent threads of control. AFL provides primitives for synchronizing these multiple threads. Blocks also serve as implicit cobegin statements; events started within a block are completed before the block terminates.
AFL rendering rules typically introduce a new block, set the state of the audio formatter and execute some actions. When the audio rendering has been completed, the block terminates, resulting in the state of the audio formatter being reset.
Here is an outline of a typical AFL rendering rule:
(def-reading-rule ...
(afl:new-block ... (afl:local-set-state ...) ...))