C-SPAN - programming language for formant synthesizer control


C-SPAN is a programming language which can be used to construct sets of control parameters for producing synthetic speech with a formant synthesizer. You should view a C-SPAN program as a specification for constructing a number of synthesizer control parameter tables, with each parameter specified every 10ms. The advantage of a C-SPAN program over the parameter table is that interpolations within the table are calculated automatically, so that only turning points in a parameter specification with time need to be specified. In addition, the C-SPAN language allows for the construction of a number of syntheses sharing common components, and a C-SPAN program may be readily constructed for building a set of stimuli for use in a speech perception experiment, for example.


C-SPAN is actually implemented as a set of macros for a standard C-language compiler. When a C-SPAN program is compiled, it is built into a C source module and linked with a standard run-time object module to construct a program which when run builds one or more synthesizer parameter tables from the C-SPAN program specification. These tables can be saved in SFS speech files or replayed through a hardware synthesizer. For details of compilation and execution of C-SPAN programs see the SPAN manual page.

The benefit of the C-language implementation is that C-SPAN programs can make use of all the facilities of the C language in addition to the commands provided by C_SPAN which are detailed below. Thus a C-SPAN program can use global and local variables, call sub-routines and use the C pre-processor to modify the command language.


The basic source file structure follows the C language. Statements must be separated by semicolons, Comments must be enclosed in /* ... */. The main subroutine must be called SYNTH(), and take no arguments. The user is free to construct other subroutines which can be called from SYNTH(). Thus the basic C-SPAN program looks like:

/* comments */
	/* parameter settings in here */


The following commands are available for overall control of a synthesis:

LENGTH(t) This sets the overall length of the synthesis to t milliseconds. The default length is taken from the lastest time at which an assignment is made. You need this command if modifications to a synthesis reduce its length.

CLEAR This clears the entire synthesis table, and resets the start time and end times to zero.

FLUSH This command forces construction of the synthesizer parameter table at this point in the specification. The synthesizer parameter table is constructed automatically at the end of the SYNTH() routine, so you only need this command if your program builds more than one synthesis.

SAVE This command saves the current time position in the synthesis on an internal stack. Since all settings of AT(t) and WAIT(t) affect the current time position, regardless of whether they are made in SYNTH() or in a subroutine, you may need to save the current time to make local parameter settings and then restore it.

RESTORE This command restores the last current time position save with SAVE.


The parameter setting statements are all of the form <paramname>(<value>,<interpolation>) where <paramname> is from the list:

FX(v,i) Fundamental frequency (Hz).

F1(v,i) Frequency of formant 1 (Hz).

A1(v,i) Amplitude of formant 1 (dB).

F2(v,i) Frequency of formant 2 (Hz).

A2(v,i) Amplitude of formant 2 (dB).

F3(v,i) Frequency of formant 3 (Hz).

A3(v,i) Amplitude of formant 3 (dB).

F4(v,i) Frequency of formant 4 (Hz).

A4(v,i) Amplitude of formant 4 (dB).

FN(v,i) Frequency of nasal formant (Hz).

AN(v,i) Amplitude of nasal formant (dB).

VR(v,i) Voicing ratio, in range 0(unvoiced) to 248(voiced).

and where <value> is a decimal number representing the value to which to set the control parameter at the current time. The value NUL can be used to signify that no change to the currently specified value at this position is requested (if only the interpolation type was to be changed, for example).

The parameter <interpolation> is from this list:

FIX Set value at this time with no interpolation.

LIN Set value at this time and interpolate to the first subsequent specification for this parameter. Interpolations are actually performed after all specifications are made, so you do not need to specify the end value of the interpolation before the start value.

LOG Set value at this time and logarithmically interpolate to the first subsequent setting of this parameter.

NUL Make no changes to the interpolation setting currently specified at this time position.

In addition to these parameter settings the command GET(p,t) returns the value of parameter p (FX,F1, etc) at time t. The global variable NOW contains the current time position. This command does not make any changes to the parameter table. If you request the value of a parameter in an interpolated region, GET returns the interpolated value using the current specifications for the start and end points.

There is no range checking on the values used in these parameter settings. The allowed ranges will depend on the formant synthesizer that you will be using to make the synthetic speech. Similarly, some synthesizers may not make use of all the parameters (e.g. the JSRU system has a fixed F4 and AN is linked to A1). There is no synthesizer specific code in the C-SPAN language.


AT(t) Set the current time position in the synthesis to absolute t milliseconds. Only one current time position is maintained globally, so be careful of constructions such as:

FX(90,FIX);		/* does NOT change FX at time 100 */
	A1(0,FIX); A2(0,FIX); A3(0,FIX);

Use the SAVE and RESTORE commands within subroutines to preserve the current time position outside the routine.

WAIT(t) Move the current time position on by t milliseconds.

The global variable NOW contains the current time position.


/* test.spn - demonstration C-SPAN program */

#define SILENCE A1(0,LIN);A2(0,LIN);A3(0,LIN);A4(0,LIN);AN(0,LIN);

/* Synthesis 0 */
	/* set up central vowel */
	FX(120,LOG); VR(248,LIN);
	F1(500,LIN); F2(1000,LIN); F3(1500,LIN);

	/* ramp up amplitudes */
	A1(40,FIX); A2(35,FIX); A3(30,FIX); AN(GET(A1,NOW),FIX);

	/* ramp down amplitudes */

	/* end at /i/ vowel */
	F1(250,FIX); F2(2500,FIX); F3(3300,FIX);

	/* make this synthesis */

/* Synthesis 1 */
	/* change end to /a/ vowel */
	F1(600,FIX);	F2(750,FIX);	F3(2500,FIX);

	/* and re-make it */



1.0 Mark Huckvale


span(1), enspan(1)


Should be a mechanism for using parameter names as variables.
Fri Jul 09 14:54:50 2004