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

Part II/2B: Control Driver Data Structures

Sections

Types

csys_bussstruct, csys_instrstruct, csys_labelstruct, csys_presetstruct, csys_routestruct, csys_samplestruct, csys_sendstruct, csys_targetstruct, csys_varstruct

Variables

absolutetime, csys_argc, csys_argv, csys_bus, csys_global, csys_instr, csys_labels, csys_preset, csys_route, csys_sample, csys_send, csys_sfront_argc, csys_sfront_argv csys_target, direction, endtime, globaltune, listenerDirection, listenerPosition, maxBack, maxFront, minBack, minFront, params, position, scorebeats, tempo,

Introduction

Control drivers communicate SASL, MIDI, and special events to the sa.c program. To communicate an event such as the creation of an instrument instance or the updating of a global variable, the control driver needs to be able to specify the name of the instrument or variable, in a language that the main program understands.

This section describes the data structures, constants, and functions that are available to the control driver. These resources serve to map the ASCII name or MP4 symbol number of a SAOL element to an index number that the sa.c understands. These resources also supply information about the current state of the sa.c program, such as the current score time.

These resources are designed so that the control driver can be written to work with all SAOL programs. By searching through the data structures, the control driver can discover the variables, instruments, and other SAOL elements as part of its initialization (i.e. during the csys_setup call).

In this section, we first describe the resources that pertain to the SAOL program, and then describe the resources that reflect other aspects of the sa.c program.

 

SAOL Variables

A SAOL instrument may have parameter variables and local variables. In addition, the global block of a SAOL program may define global variables, and future global table variables may be defined implicitly.

In the following sections of this chapter, we define data structures that describe SAOL instruments and SAOL global variables. Both of these data structures uses csys_varstruct to describe variables. The right panel shows this struct and explains its fields.

The most common reason for a control driver to examine a csys_varstruct is to find a particular variable, and then return its index value to the main program.

The other fields in csys_varstruct are attributes a control driver may need to search over to find the right variable to return. The name field is the ASCII name of the variable, useful for SAOL programs presented to sfront via the -orc option. The token field is the MP4 file symbol number for the variable, useful for SAOL programs presented to sfront via the -bit or -bitc options.

The remaining fields describe attributes of the variable, such as width, rate, and import status.

csys_varstruct

typedef struct csys_varstruct {
  int index;
  char * name;
  int token;
  int type;
  int tag;
  int width;
  int use;
} csys_varstruct;

Field descriptions

int index:  

  The value that the control driver
  function csys_saslevents() passes
  to the caller, to identify the
  variable. Also passed to service
  functions to identify a variable. 
    
char * name: 

  The ASCII name of the variable,
  if one exists. If the SAOL program
  is part of an MP4 file without a
  symbol table entry for the variable,
  the name is a##, where ## is the MP4
  file token number for the variable
        
int token:

  The MP4 symbol number for the 
  variable in the MP4 file. This
  value may be -1 if the SAOL did 
  not originate in an MP4 file, in
  some versions of sfront.

int type:

  The type of the variable, which 
  takes on one of these constant
   values:

  CSYS_IRATE
  CSYS_KRATE
  CSYS_ARATE
  CSYS_TABLE

  The values of these symbols are
  subject to change, so use the 
  symbols to ensure future
  compatability. The type codes
  either the rate of the 
  variable, or the fact that it is a
  table (tables are always i-rate).

int tag:     

  Special attributes a SAOL variable 
  may have, one of:

  CSYS_NORMAL
  CSYS_IMPORT
  CSYS_EXPORT
  CSYS_IMPORTEXPORT
  CSYS_PFIELD 

  The tag indicates if the SAOL 
  variable has an imports or exports
  tag, or is a parameter field in
  an instr. If the variable has none
  of these, it is tagged with
  CSYS_NORMAL.

int width:   

  The width of the variable, for 
  array signal variables. Scalars
  and tables have width 1.

int use:     

  Codes whether SAOL program could
  potentially read or write the 
  variable.  Intended purpose is to
  let control drivers optimize for
  variables that are never read or
  never written. Values are:

  CSYS_UNUSED
  CSYS_READ
  CSYS_WRITTEN
  CSYS_WRITTEN_AND_READ

Global Variables

The right panel shows the two data structures that describe the global variables and future tables in a SAOL program.

The first data structure is an array of csys_varstruct structs. It is designed for applications where the control driver does not know the contents of the SAOL program a priori, but needs to build a model of the program as it executes.

The CSYS_GLOBALNUM constant lets the control driver know how many global variables exist. If it is nonzero, it is also the size of the array csys_global.

Some control drivers may be written for a specific SAOL program in mind. For these programs, it may be easier to use the second data structure described on the right panel. This set of constants code the csys_global[].index value for every global variable directly.

csys_global

#define CSYS_GLOBALNUM ##

csys_varstruct csys_global
  [max(1,CSYS_GLOBALNUM)];


The symbol CSYS_GLOBALNUM holds 
the number of global variables
(signal and table) in the array. 
The array csys_global[] holds the
csys_varstruct elements
that describes the variable.

If CSYS_GLOBALNUM is zero, there
are no global variables. A dummy
csys_global[1] will be defined in
this case.

Global Constants

In addition to the csys_global[]
array, a global constant:


#define CSYS_SASL_GBL_varName ##

is defined for each global variable.


varName is the ASCII name for the
variable, or a## if the variable
is in an MP4 file without a symbol
table entry for the variable.

## is an integer that is the 
csys_varstruct index value for
the variable varName. 

Instrument Information

The control driver may access several datastructures that refer to SAOL instrs. These datastructures use the csys_instrstruct struct, shown on the right panel, to describe an instrument.

The csys_instrstruct struct shares much in common with the csys_varstruct struct described in the last section. The index field of csys_instrstruct is returned to functions such as csys_saslevent to specify an instrument, while the name and token fields provide ASCII and MP4 file names for an instrument.

The remaining fields describe attributes of the SAOL instrument code, such as the parameter fields and local variables of the instrument, the output width of the instrument, and the ways the instrument are used in the Structured Audio file.

csys_instrstruct

typedef struct csys_instrstruct
{
  int index;
  char * name;
  int token;
  int numvars;
  csys_varstruct * vars;
  int outwidth;
  int status;
} csys_instrstruct;

Field Descriptions

int index:  

  The value that the control driver
  function csys_saslevents() passes
  to the caller, to identify the
  instr. Also passed to service
  functions to identify a variable. 
  
    
char * name: 

  The ASCII name of the instr,
  if one exists. If the SAOL program
  is part of an MP4 file without a
  symbol table entry for the instr,
  the name is a##, where ## is the MP4
  file token number for the instr.
        
int token:

  The symbol number for the instr in 
  the MP4 file. This value may be -1
  if the SAOL did not originate in an
  MP4 file, in some versions of sfront.
  Note that the startup instrument
  may not have a symbol associated 
  with it -- use the status byte 
  (see below) to locate the startup 
  instrument.

int numvars: 

  The total number of pfields, local
  signal variables, and local table
  variables in the instr. Also 
  available as the constant 
  CSYS_instrName_VARNUM, with 
  instrName matching the name 
  string above.

csys_varstruct * vars: 

  An array, of size numvars, of 
  csys_varstruct to
  describe each pfield and local
  signal or table variable. 

int outwidth: 

  The width of the output() 
  statements in the instr. 

int status:  

  A status word that describes 
  how the instr is used. Different
  bits in the status words are set
  to reflect each use of the instr.
  A bitwise AND of the status word
  with each constant below indicates
  the instr is used in the manner
  described:

  CSYS_STATUS_EFFECTS

      Indicates that the instr is
      used as an effects instrument,
      i.e. it is the target of a
      send() statement in the global
      block.

  CSYS_STATUS_SCORE

      Indicates the instr is used 
      by a SASL score line. (for 
      binary files, in either the
      configuration or streaming part
      of the file).

  CSYS_STATUS_MIDI

      Indicates the instr is used
      by a MIDI event (for binary
      files, in either the 
      configuration or streaming
      part of the file).

  CSYS_STATUS_DYNAMIC

      Indicates the instr is the
      target of a SAOL instr
      statement.

  CSYS_STATUS_STARTUP

      Indictates the instr is the 
      startup instr.

SAOL Instruments

The right panel shows the two data structures that describe the instruments in a SAOL program.

The first data structure is the array csys_instr. It is designed for applications where the control driver does not know the contents of the SAOL program a priori. The driver may search csys_instr to discover the structure of the SAOL program.

The CSYS_INSTRNUM indicates the number of instruments in the SAOL program. The ordering of instruments in csys_instr has meaning: it denotes the execution order of the SAOL program.

Uses of the csys_instr array include:

  • Looking up the index values for instruments to return in csys_midievents() and csys_saslevents() calls.
  • Looking up the index values for imports variables in the vars field to implement labelled control statements (but see the next section for a more efficient data structure for this purpose).

In addition, several data structured described in later sections of this chapter index into csys_instr[].

Some control drivers may be written for a specific SAOL program in mind. For these programs, it may be easier to use the second data structure described on the right panel. This set of constants code the csys_instr[].index value for every instrument directly, as well as the csys_instr[].vars[].index value for variables that may be targeted by labelled SASL control statements.

csys_instr


#define CSYS_INSTRNUM ##

 csys_instrstruct
     csys_instr[CSYS_INSTRNUM];




CSYS_INSTRNUM is the number of
instrument definitions in the
SAOL or MP4 file. csys_instr
is an array that describe each
instrument.

Useful facts about csys_instr:

[1] csys_instr[x].index == x

This fact can simplify coding
of control driver applications,
and will not be broken going
forward.

[2] The order of instruments 
in csys_instr[] is the execution
order of the instruments in 
the SAOL program.

Instr Constants

In addition to the csys_instr[]
array, a global constant:


#define CSYS_SASL_INSTR_instrName  ##

is defined for each instr.


instrName is the ASCII name for
the instr, or a## if the instr
is in an MP4 file without a symbol
table entry for the instr.

## is an integer that is the 
csys_instrstruct index value for
the instr instrName. This number
can also be used to index into 
csys_instr[]. 

The symbol CSYS_SASL_NOINSTR can
be used to specify the "no 
instrument."


Instr Variable Constants

If an instr has variables that are fair targets for a SASL labelled control statements (i.e. they are declared with the imports tag and do not have a matching global variable), there will be a definition for CSYS_SASL_IMPORT_instrName_varName Where instrName is the instrument name and varName is the variable name (ASCII or a## name, as described above for instrName). This constant will be the equal to csys_instr[].vars[].index however, note that csys_instr[].vars [CSYS_SASL_IMPORT_instrName_varName] does not produce valid data -- a search needs to be done to find the matching vars[] element.

Target Control Variables

The instrument variables that may targeted by a SASL labelled control statement have several properties:

  • Variables must be imports.
  • Variables must be k-rate.
  • Variables must be scalar (not arrays).
  • Variables must be signal (not tables).
  • Variables must not have a corresponding variable in the global block

Sfront uses these properties to construct the csys_target array, shown on the right panel, that lists all local variables of all instruments that may be targeted by labelled control statements.

Implementations of MP4 streaming decoders can search through this short array for a candidate variable, and send the appropriate labelled control events via the midi_saslevent() function.

csys_targetstruct

typedef struct csys_targetstruct
{
  char * name;
  int token;
  int numinstr;
  int * instrindex;
  int * varindex;
} csys_targetstruct;

Describes a SAOL variable that
appears as a local variable in
one or more instruments, and that
has the correct properties to be
a target for a SASL labelled 
control statement.

char * name:  

    The name of the control
    variable, following the
    conventions of the name
    field of csys_instrstruct.

int token:  

    MP4 symbol number, that
    follows the conventions
    of the token field of 
    csys_instrstruct.

int numinstr: 

    Number of instrs that have
    this variable in targetable
    form.

int * instrindex:

    An array, of size numinstr,
    of indexes into csys_instr[],
    one for each instr that has
    the variable in a targetable
    form. The csys_saslevent 
    function requires this number
    in the *id field for a 
    labelled control statement.

int * varindex;

   An array, of size numinstr, 
   that gives the vars[].index
   value for the targeted 
   variable. In other words

   instrindex[i] == x
   varindex[i] == y

   then the 

   csys_instr[x].vars[].index == y
   
   for the element of vars that
   holds the targeted variable.
   Note that y doesn't index 
   into the vars[] array itself.
   
   The csys_saslevent function,
   used for labelled control 
   statements, required y in the
   *pnum field.

csys_target

#define CSYS_TARGETNUM ##

csys_targetstruct csys_target
       [max(1,CSYS_TARGETNUM];


CSYS_TARGETNUM is the number 
of instr variables that are
targetable by control statements
in the SAOL program.

If CSYS_TARGETNUM is greater
than zero, csys_target is an
array that holds information
about each targetable 
variable.


Instr Preset Numbers

As explained in this section of the MP4-SA book, a SAOL instrument that is capable of being controlled by MIDI events has one or more preset numbers. A MIDI event stream sent to the sa.c program using the csys_midievent function should start with a series of PChange commands, that sets the MIDI preset number (and thus, the SAOL instrument) for each MIDI channel in use.

These PChange commands will be in a valid MP4 file that uses MIDI events in SA_access_units. However, some control driver applications may need to dynamically set the preset number for each MIDI channel.

For example, a program for selecting SAOL instrument voices to be controlled by an MIDI keyboard would let the user choose SAOL instrument voices for each MIDI channel. This program would send PChange commands via the csys_midievent function to make the instrument selection happen.

The csys_presets array shown the right panel provides the mapping between SAOL instruments and preset numbers. The array contains one entry for each preset number defined in a SAOL instrument definition (recall each instrument may have multiple preset numbers, but no preset number may be used by two instruments).

The index entry for each array element points into the csys_instr array. The preset entry is the preset number. The array is ordered by preset number.

csys_presetstruct

typedef struct csys_presetstruct {
  int index;
  int preset;
} csys_presetstruct;


Maps MIDI presets numbers to 
SAOL instruments.

index: 

    An index into array
    csys_instr coding
    the SAOL instr associated
    with preset number.

preset:

    The preset number.
  

csys_presets

#define CSYS_PRESETNUM    ##

csys_presetstruct csys_presets
     [max(1,CSYS_PRESETNUM)];


The constant CSYS_PRESETNUM is the
number of preset numbers defined
in the SAOL program. If it is
non-zero, then the array 
csys_presets holds information
about each preset defined, using
the csys_presetstruct fields
described above. 

Elements in csys_presets are
ordered with respect to preset
number.

Sample Block Data

SAOL wavetable declarations that use the sample wavetable generator are coded in an MP4 file by pointing to a sample event block that is encoded in the configuration block. SASL table commands in the configuration block that use the sample wavetable generator also point to a sample event.

These sample events have their own MP4 symbol number, and can be referenced by SASL table commands in the SA_access_unit event stream.

The csys_samples array holds information on all sample event blocks encoded in the configuration block.

Note that sfront writes all sample event blocks to WAV files in the local directory, which are read by the sa.c program during execution. The csys_samples array includes the name of that file.

csys_samplestruct

typedef struct csys_samplestruct 
{
  int index;
  int token;
  char * name;
  char * fname;
} csys_samplestruct;


Describes a sample event.

Fields:

  int index: 

     Index number for the 
     sample event. Will be
     used by future special
     events.

  int token:

     The MP4 symbol number for
     the sample event in the
     binary file.
	
  char * name: 

     An ASCII version of the
     symbol number for the 
     sample event, in the
     form a##.

  char *fname;

     The name of the Microsoft
     WAV file that holds the
     sample block. This file
     is placed in the same 
     directory as the MP4 file
     when sfront decodes the file.

csys_samples


#define CSYS_SAMPLENUM ##

csys_samplestruct csys_samples
        [max(1,CSYS_SAMPLENUM)];


CSYS_SAMPLENUM is the number of
sample events in the 
configuration block. The array
csys_samples[] holds information
about each sample event.

Audio Bussing

The global block of a SAOL program defines an audio signal processing path, through the use of send and route statements. This chapter of the MP4-SA book describes the audio pathway of SAOL programs in-depth.

Audio bus information cannot be directly used in any SASL or MIDI control driver event. However, to support control driver applications that create graphical descriptions of SAOL programs, and to support future special events, the control driver interface includes a set of data structures that reflect the audio path of a SAOL program. The right panel describes these data structures.

The primary data structure, csys_bus, describes each bus in the SAOL program, included the special output_bus and input_bus. Two secondary data structures, csys_route and csys_send, describe each send and route statement.

Note that no data structure exists that holds information about sequence statements. The order of instruments in the csys_instr array denotes the execution order of instruments, and implicitly codes all sequence statements.

csys_busstruct

typedef struct csys_busstruct
{
  int index;
  char * name;
  int width;
  int oflag; 
} csys_busstruct;


Describes a bus in a SAOL
program.

Fields:

  int index:

     The index value of
     the bus, to be used
     in future special
     events.

  char * name;

     The name of the bus.
     The special buses 
     input_bus and 
     output_bus will
     always appear as those
     strings. User-defined
     buses may be given names
     from the ASCII SAOL file,
     or tokenized names from
     the MP4-SA symbol numbers
     (i.e. a##).

  int width;

     The width of the bus.

  int oflag; 

     The number of outbus()
     statements, in all 
     instruments, that write onto
     this bus.

csys_bus

#define CSYS_BUSNUM ##
 
csys_busstruct csys_bus
    [max(1,CSYS_BUSNUM)];


CSYS_BUSNUM is the number
of audio buses in the SAOL
program. csys_bus is an 
array describing each bus.

Note that 

csys_bus[i].index == i

csys_sendstruct

typedef struct csys_sendstruct 
{
  int instr;
  int nbus;
  int * bus;
} csys_sendstruct;

Describes a SAOL send statement.

Fields:

 int instr:   

   The instr the send statement
   creates, coded as an index
   into the csys_instr
   array. 

 int nbus:

   The number of buses that 
   make up the SAOL input[]
   standard name value sent
   to the instr.

 int *bus: 

   An array, of size nbus, 
   that lists the buses that
   make up SAOL input[] 
   standard name value sent
   to the instr, in order. 
   Each element of the array
   indexes csys_bus[].

csys_send

#define CSYS_SENDNUM ##
 
csys_sendstruct csys_send
      [max(1,CSYS_SENDNUM)];

CSYS_SENDNUM is the number of
send statements in the global
block of the SAOL program. 
csys_send[] is an array that
describes each send statement.

csys_routestruct

typedef struct csys_routestruct
{
  int bus;
  int ninstr;
  int * instr;
} csys_routestruct;

Describes a SAOL route statement.

Fields:

 int bus:

   The bus the route statement
   writes, coded as an index
   into the csys_bus[] array.

 int ninstr: 

   The number of instrs whose
   outputs are written to
   the bus.

  int *instr:

   An array, of size ninstr,
   that lists the instrs whose
   outputs form the value added
   to the bus, in order. Each 
   element is an index into 
   the csys_instr array.


csys_route

#define CSYS_ROUTENUM ##
 
csys_routestruct csys_route
       [max(1,CSYS_ROUTENUM)];

CSYS_ROUTENUM is the number of
route statements in the global
block of the program. The 
array csys_route[] describes
each route statement.

SASL Labels

The MP4 binary file format supports two different ways of coding SASL commands. The configuration block (StructuredAudioSpecificConfig) at the start of the MP4 file, which contains the SAOL program, may also hold a SASL score. holds the SAOL program, can also hold a SASL score. In addition, SASL lines can be coded in the SA_access_unit streaming events that follow the configuration block.

The control driver interface supports compliant execution of SASL events in SA_access_units. These events may include labelled SASL control statements whose labels are also used in SASL instrument commands in the configuration block.

The csys_labels array shown on the right panel holds information about all labels used in the SASL score in the configuration block.

The array elements are csys_labelstruct structs, which provides the ASCII name and MP4 symbol for the label. the index value for the label which should be used as an argument to csys_saslevent to identify the label.

The csys_labels array is of size CSYS_LABELNUM, and the numeric values for csys_labels[x].index is (x+1). Thus, if a control driver wishes to create label values that are not used by any SASL commands in the configuration block, these labels should have a numeric value greater than CSYS_LABELNUM. Use the constant CSYS_NOLABEL to indicate an unlabeled event.

csys_labelstruct


typedef struct csys_labelstruct
{
  int index;
  char * name;
  int token;
  int iflag[CSYS_INSTRNUM];
} csys_labelstruct;

Describes SASL labels used in
the configuration block.

Fields:

 int index:  

   The value used in 
   csys_saslevent calls
   to identify the label.

 char * name: 

   The ASCII name of the
   SASL label. If the 
   label is part of an
   MP4 file without a 
   symbol table entry for
   the label, the name is
   a##, where ## is the 
   MP4 symbol number.

 int token: 

   The MP4 symbol number
   for the label. This 
   number may be -1 if
   the SASL did not come
   from an MP4 file, in
   some versions of sfront.

 int iflag[CSYS_INSTRNUM]: 

   For each instr k, 
   iflag[k] is 1 if a SASL
   instr statement exists
   for the instr that uses
   this label; otherwise,
   iflag[k] is zero. The
   index position of iflag[]
   matches the index position
   of the csys_instr[]
   array that describes each
   instr in the SAOL program.


csys_labels


#define CSYS_LABELNUM  ##

csys_labelstruct csys_labels
       [max(1,CSYS_LABELNUM)];


CSYS_LABELNUM is the number of
unique SASL labels in the
configuration block of the 
MP4 file (or in the -sco 
ASCII file). 

If CSYS_LABELNUM is nonzero,
csys_labels holds information
about each label.

Note that

csys_labels[i].index == i + 1

If a control driver wishes to
create new label numbers, these
numbers should be greater than
CSYS_LABELNUM.

The constant CSYS_NOLABEL codes
that a statement is unlabelled.

System Status

When a control driver sends a new MIDI or SASL event to the main program to execute, it does not include a timestamp value. Instead, the control driver checks the value of global variables that hold the current time, and uses this information to send new MIDI or SASl events at the correct time.

The right panel describes these internal variables and associated constants, that hold time and tempo information.

The variables are made available on a read only basis, so that the control driver can present new events at the correct time, notes will be played in tune, ect.

Time Variables


float scorebeats;

   The current time of the 
   score, in units of
   score time (beats).

float absolutetime;

   The current time of the
   score, in units of
   seconds.

float endtime;

   The current ending time
   of the score, in units
   of score time (beats).

float tempo;

   The current tempo, in 
   beats per second.

Time Constants

ARATE

  Audio rate of the SAOL 
  program, in units of
  Hz.

ATIME

  1.0F/ARATE

KRATE

  Control rate of the
  SAOL program, in units
  of Hz.

KTIME

  1.0F/KRATE

ACYCLE

  The number of audio 
  cycles in a control 
  cycle. An integer.

CSYS_GIVENENDTIME

  Has the value 1 if 
  the variable endtime
  was given in a SASL
  statement by the 
  user, and thus should
  be respected. If 0,
  it is an estimate by
  sfront of the last 
  note played.

Tuning Variable

float globaltune;

  Current tuning of the 
  SAOL program. Default
  is 440Hz. It codes the
  frequency of A below
  middle C.

AudioBIFS Standard Names

The MPEG 4 Systems standard includes the audio mixdown tool for MPEG 4 Audio, which is named AudioBIFS.

AudioBIFS uses a SAOL decoder to do audio processing. Several standard names are defined for use in AudioBIFS, including params[128], an application dependent array that Structured Audio programs can read and write to communicate with the decoder.

To support writing control drivers that implement AudioBIFS functionality, the control driver may read and write the global variables shown on the right panel. These variables are the underlying SAOL state variables for the AudioBIFS parameters.

In practice, params[128] is the most useful AudioBIFS standard name for most control drivers. Since it may be an lval in SAOL programs, it serves as a standard syntax to communicate application specific data between a SAOL program and an decoder.

AudioBIFS Variables

float direction[3];
float listenerDirection[3];
float listenerPosition[3];
float minBack;
float minFront;
float maxBack;
float maxFront;
float params[128];
float position[3];

Utility Functions

Most communication between a control driver and the main sa.c program is done via the csys_midievent and csys_saslevent functions. A secondary method of communication is via utility functions that the control driver may call.

At present, there is only one utility function, csys_terminate, that lets the control driver prematurely terminate the sa.c program, and print an error message on stderr. The right panel describes this function.

csys_terminate

void csys_terminate(char * message)

Terminates the sa.c program,
by printing the Run-Time Error
banner on stdout. The string message
is printed as part of the banner.
sa.c will return -1 as
its exit code.

Command Line Contents

During initialization, the control driver may need to access the command-line options of the sfront invocation that created the sa.c file that created it. The control driver has access to these options in the csys_sfront_argc and csys_sfront_argv variables shown on the right panel.

These variables are copied from the argc and argv parameters of the main function for sfront. The csys_sfront_argc variable indicates the total number of arguments on the command line, including the word "sfront".

The csys_sfront_argv variable is an array of strings of size csys_sfront_argc. Each string is a command-line token, with separating spaces removed. Like all of the data structures available for inspection by the control driver, csys_sfront_argv and csys_sfront_argc may not be changed.

The control driver may also access the command line options of the sa.c program that contains it, by inspecting the csys_argc and csys_argv variables described on the right panel. The control driver may also define command line options for users to put on the sa.c command line in order to configure the control driver.

The right panel shows the syntax that these driver-specific command line options must follow.

In the section of this chapter that describes registering control drivers with sfront, we show how to communicate these options to users, by printing out help information when sfront executes. Alternatively, it could also print out help information during the csys_setup call during sa.c execution.

sfront command line

int csys_sfront_argc;    
char ** csys_sfront_argv; 

sa.c command line

int csys_argc;    
char ** csys_argv; 

Command line convention

A control driver may define its own
command line arguments for the sa.c
program (but not sfront). For driver
xx, command line arguments must
use the following convention:

  -csys_xxx[_yyy] [p1 p2]   

where

   xxx   is the name of the driver
   yyy   is the name of the option
         for the driver. this can
         be deleted if the driver 
         only has one option.
   p#    is a parameter for the option.
         options can have zero,
         one, or more than one 
         parameters. a parameter
         can not start with a -
         (except when used as the
         sign of a number) and may
         not contain spaces.

Example:

The linmidi driver could define:

  -csys_linmidi_transpose p1

as an option for setting a constant
transposition of MIDI note number. The
same program could be invoked with 
transpositions an octave above or below
normal by using the options:

  -csys_linmidi_transpose 12 
  -csys_linmidi_transpose -12 

MIDI and SASL Constants

The description of the csys_midievent and csys_saslevent functions in the next section includes the definition of several constants related to MIDI and SASL. The absolute value of some of these constants were carefully chosen, so that they could be useful in parsing MIDI and MP4 files. Those constants are shown on the right panel, along with the numerical values.

Next section: Part II/2C: Writing the Control Driver.

SASL Event Constants



These map to SASL code 
numbers MP4 files.

CSYS_SASL_INSTR    0x00
CSYS_SASL_CONTROL  0x01
CSYS_SASL_TABLE    0x02
CSYS_SASL_ENDTIME  0x04
CSYS_SASL_TEMPO    0x05


These map to wavetable
generator token numbers

CSYS_SASL_TGEN_SAMPLE     0x6F
CSYS_SASL_TGEN_DATA       0x70
CSYS_SASL_TGEN_RANDOM     0x71
CSYS_SASL_TGEN_STEP       0x72
CSYS_SASL_TGEN_LINESEG    0x73
CSYS_SASL_TGEN_EXPSEG     0x74
CSYS_SASL_TGEN_CUBICSEG   0x75
CSYS_SASL_TGEN_POLYNOMIAL 0x76
CSYS_SASL_TGEN_SPLINE     0x77
CSYS_SASL_TGEN_WINDOW     0x78
CSYS_SASL_TGEN_HARM       0x79
CSYS_SASL_TGEN_HARM_PHASE 0x7A
CSYS_SASL_TGEN_PERIODIC   0x7B
CSYS_SASL_TGEN_BUZZ       0x7C
CSYS_SASL_TGEN_CONCAT     0x7D
CSYS_SASL_TGEN_EMPTY      0x7E
CSYS_SASL_TGEN_DESTROY    0x7F

MIDI Event Constants


The number of channels in MIDI

CSYS_MIDI_NUMCHAN  16


These map to MIDI command
nibbles

CSYS_MIDI_NOTEOFF  0x80
CSYS_MIDI_NOTEON   0X90
CSYS_MIDI_PTOUCH   0xA0
CSYS_MIDI_CC       0xB0
CSYS_MIDI_PROGRAM  0xC0
CSYS_MIDI_CTOUCH   0xD0
CSYS_MIDI_WHEEL    0xE0


These map to MIDI controller
numbers

CSYS_MIDI_CC_BANKSELECT_MSB  0x00   
CSYS_MIDI_CC_MODWHEEL_MSB    0x01   
CSYS_MIDI_CC_BREATHCNTRL_MSB 0x02   
CSYS_MIDI_CC_FOOTCNTRL_MSB   0x04
CSYS_MIDI_CC_PORTAMENTO_MSB  0x05   
CSYS_MIDI_CC_DATAENTRY_MSB   0x06
CSYS_MIDI_CC_CHANVOLUME_MSB  0x07   
CSYS_MIDI_CC_BALANCE_MSB     0x08   
CSYS_MIDI_CC_PAN_MSB         0x0A   
CSYS_MIDI_CC_EXPRESSION_MSB  0x0B   
CSYS_MIDI_CC_EFFECT1_MSB     0x0C   
CSYS_MIDI_CC_EFFECT2_MSB     0x0D   
CSYS_MIDI_CC_GEN1_MSB        0x10   
CSYS_MIDI_CC_GEN2_MSB        0x11   
CSYS_MIDI_CC_GEN3_MSB        0x12  
CSYS_MIDI_CC_GEN4_MSB        0x13
CSYS_MIDI_CC_BANKSELECT_LSB  0x20   
CSYS_MIDI_CC_MODWHEEL_LSB    0x21   
CSYS_MIDI_CC_BREATHCNTRL_LSB 0x22   
CSYS_MIDI_CC_FOOTCNTRL_LSB   0x24
CSYS_MIDI_CC_PORTAMENTO_LSB  0x25   
CSYS_MIDI_CC_DATAENTRY_LSB   0x26
CSYS_MIDI_CC_CHANVOLUME_LSB  0x27   
CSYS_MIDI_CC_BALANCE_LSB     0x28   
CSYS_MIDI_CC_PAN_LSB         0x2A   
CSYS_MIDI_CC_EXPRESSION_LSB  0x2B   
CSYS_MIDI_CC_EFFECT1_LSB     0x2C   
CSYS_MIDI_CC_EFFECT2_LSB     0x2D   
CSYS_MIDI_CC_GEN1_LSB        0x30   
CSYS_MIDI_CC_GEN2_LSB        0x31   
CSYS_MIDI_CC_GEN3_LSB        0x32  
CSYS_MIDI_CC_GEN4_LSB        0x33
CSYS_MIDI_CC_SUSTAIN         0x40
CSYS_MIDI_CC_PORTAMENTO      0x41   
CSYS_MIDI_CC_SUSTENUTO       0x42 
CSYS_MIDI_CC_SOFTPEDAL       0x43 
CSYS_MIDI_CC_LEGATO          0x44
CSYS_MIDI_CC_HOLD2           0x45
CSYS_MIDI_CC_SOUNDCONTROL1   0x46
CSYS_MIDI_CC_SOUNDCONTROL2   0x47
CSYS_MIDI_CC_SOUNDCONTROL3   0x48
CSYS_MIDI_CC_SOUNDCONTROL4   0x49
CSYS_MIDI_CC_SOUNDCONTROL5   0x4A
CSYS_MIDI_CC_SOUNDCONTROL6   0x4B
CSYS_MIDI_CC_SOUNDCONTROL7   0x4C
CSYS_MIDI_CC_SOUNDCONTROL8   0x4D
CSYS_MIDI_CC_SOUNDCONTROL9   0x4E
CSYS_MIDI_CC_SOUNDCONTROL10  0x4F
CSYS_MIDI_CC_GEN5            0x50   
CSYS_MIDI_CC_GEN6            0x51   
CSYS_MIDI_CC_GEN7            0x52  
CSYS_MIDI_CC_GEN8            0x53
CSYS_MIDI_CC_PORTAMENTOSRC   0x54
CSYS_MIDI_CC_EFFECT1DEPTH    0x5B
CSYS_MIDI_CC_EFFECT2DEPTH    0x5C
CSYS_MIDI_CC_EFFECT3DEPTH    0x5D
CSYS_MIDI_CC_EFFECT4DEPTH    0x5E
CSYS_MIDI_CC_EFFECT5DEPTH    0x5F
CSYS_MIDI_CC_DATAENTRYPLUS   0x60
CSYS_MIDI_CC_DATAENTRYMINUS  0x61
CSYS_MIDI_CC_ALLSOUNDOFF     0x78
CSYS_MIDI_CC_RESETALLCONTROL 0x79
CSYS_MIDI_CC_LOCALCONTROL    0x7A
CSYS_MIDI_CC_ALLNOTESOFF     0x7B

Next section: Part II/2C: Writing the Control Driver.

 

Copyright 1999 John Lazzaro and John Wawrzynek.