From The sfront Reference Manual by John Lazzaro and John Wawrzynek.

Part II/3: Audio Drivers

Sections

Audio Driver Functions

asys_osetup  asys_isetup  asys_iosetup  asys_preamble  asys_putbuf  asys_getbuf  asys_main  asys_orun   asys_iorun  ksyncinit  ksync  asys_oshutdown  asys_ishutdown  asys_ioshutdown 

Introduction

In this chapter, we describe how to add support for new audio file formats and audio hardware devices to sfront. Adding a new format or device involves writing an audio driver that is included in the C file sfront creates.

Users select the new audio driver through the -ain and -aout command line options.

We begin the chapter by discussing the structure of an audio driver. We describe the functions that an audio driver declares to handle initialization, data movement, and synchronization.

We also describe how to register a new driver with sfront, so that a command-line invocation results in the inclusion of the audio driver into the sa.c file.

 

Driver Structure

An audio driver is a file containing a set of C functions. This file is embedded into the sfront executable during compilation, and is copied into the C program sfront creates. Look in sfront/src/lib/asys/ to see examples of audio driver files.

The right panel shows the set of functions contained in an audio driver. In this chapter, we describe the semantics for these functions.

Not all audio drivers use all of the functions listed on the right hand panel. Several factors determine the subset of functions that are in use:

  • User directives. Users may request that an audio driver to do audio output, audio input, or both. The functions a driver declares depends on this request. A driver uses the symbols ASYS_HASOUTPUT and ASYS_HASINPUT to determine its role.
  • Callback support. In many cases, a simple method suffices for the transfer of audio samples between the driver and sfront: the driver declares functions to send and receive data, and sfront calls these functions to do I/O. We call these simple drivers passive drivers. However, some operating systems use a callback technique for audio access: an application registers a function with the operating system, that is called whenever new data is needed for input or output. Sfront supports a second audio driver approach (called active drivers) to handle callback interfaces.
  • Synchronization. Audio drivers may define functions that act to keep the SAOL program execution synchronized with audio input and output. These functions also act to update the SAOL standard name cputime, which SAOL programs use to avoid output glitches.

Naming conventions

Audio drivers must be careful when defining functions, variables, and pre-processor symbols for its own use, to avoid name-space collisions.

Audio drivers may define elements that begin with asysn_drivername_  and ASYS_DRIVERNAME_ , where drivername is the name of the audio driver file (sans extension) located in sfront/src/lib/asys/

If ASYS_KSYNC exists, elements that begin with sync_  and SYNC_  are also permissible.

In addition, if ASYS_HASOUTPUT exists, elements that begin with asyso_ or ASYSO_ are permissible. If ASYS_HASINPUT exists, elements that begin with asysi_ or ASYSI_ are permissible.

If both ASYS_HASINPUT and ASYS_HASOUTPUT exist, elements that begin with asysio_ or ASYSIO_ are permissible.

Audio Driver Functions


(function arguments not shown)

Initialization

int asys_osetup();
int asys_isetup();
int asys_iosetup();

Passive Audio Output

int asys_preamble();
int asys_putbuf();

Passive Audio Input

int asys_getbuf();

Active Drivers

/* declared by driver */

void asys_main();  

/* called by driver */

int asys_orun();  
int asys_iorun();

Synchronization

int ksyncinit();
int ksync();

Shutdown

int asys_oshutdown();
int asys_ishutdown();
int asys_ioshutdown();

Initialization

Users select audio input and output drivers through the -ain and -aout command line options.

Depending on the selection, a particular audio driver may be required to supply audio input, audio output, or both audio input and audio output.

An audio driver determines its role in an sa.c file by detecting if certain pre-processor symbols have been defined, using the pre-processor utilities  ifdef  or  defined .

Specifically, if both ASYS_HASINPUT and ASYS_HASOUTPUT symbols are defined, an audio driver should perform audio input and audio output. If only one of these symbols is defined, the audio driver should only perform audio input (ASYS_HASINPUT defined) or audio output (ASYS_HASOUTPUT defined).

Initialization functions

An audio driver declares an initialization function, which is called at the start of program execution. The exact form of the initialization function depends on the status of ASYS_HASINPUT and ASYS_HASOUTPUT symbols; see the right panel for details.

The initialization function should perform the initial setup needed for the audio file type or the audio hardware. If this setup is successful, the function should return ASYS_DONE, a pre-defined constant. If driver setup failed, the function should return ASYS_ERROR.

The arguments passed by the initialization function describe the audio input and output environment; the argument list may include:

  • srate. Audio sampling rate of the SAOL orchestra.
  • ochannels. The number of output audio channels (equal to the pre-defined constant ASYS_OCHAN).
  • ichannels. The number of input audio channels (equal to the pre-defined constant ASYS_ICHAN).
  • *oname. The output file name, if applicable, or else NULL.
  • *iname. The input file name, if applicable, or else NULL
  • osample. Output data representation for a sample, see below.
  • isample. Input data representation for a sample, see below.
  • toption. Has the value ASYS_RENDER (offline processing), ASYS_PLAYBACK (real-time mode) or ASYS_TIMESYNC (alternative real-time mode). See the synchronization section for details. The pre-defined constant ASYS_TIMEOPTION has the same value as toption.

The exact argument list depends on the function type.

Audio data types

The audio driver states its data type preference as part of the registration procedure. This preference is coded in the osample and isample variables, which may take on the pre-defined constant values ASYS_SHORT (for 16-bit signed integers) or ASYS_FLOAT (for 32-bit floats).

The pre-defined constant ASYS_OTYPENAME has the same value as osample, and the pre-defined constant ASYS_ITYPENAME has the same value as isample.

The correct C keywords for the input and output datatypes are held in the symbols ASYS_OTYPE and ASYS_ITYPE, and may be used in variable declarations.

Driver identity symbols

In some situations, an audio driver may need to know the presence of other drivers active in the system. The symbols ASYS_OUTDRIVER_XX, ASYS_INDRIVER_YY, and CSYS_CDRIVER_ZZ are defined if an audio output driver, audio input driver, or a control driver is present in the system.

The actual strings for XX, YY, and ZZ are the fully-capitalized versions of the driver names (either the full symbol following -cin, -ain, and -aout, or the extension for filename drivers).

Run-time options

An audio driver may define command-line options. Users types these options when executing an sa.c program that contains the driver, to dynamically configure driver parameters (for example, setting a maximum file size).

The right panel describes audio driver parameters in detail.

Initalization Functions

The audio driver declares
one of three functions for
initialization, depending
on user requests. This 
function will be called
once, at the start of 
program execution.

If the user requests only
output driver service, the
symbol ASYS_HASOUTPUT is 
defined, and the driver
should declare:

int asys_osetup(int srate,
                int ochannels,
                int osample,
                char * oname,
                int toption) 

If the user requests only
input driver service, the
symbol ASYS_HASINPUT is 
defined, and the driver
should declare:

i