SFS Manual for Programmers
5. Subroutine Reference
SFS FILE MANAGEMENT
SFS DATA SETS
SFS3 Routine Reference
ERROR() - REPORT ERROR MESSAGE AND TERMINATE PROCESS
extern char *progname; void error(format,param,param,..) char *format; /* printf format string */ args param,..; /* parameters */
error() prints a message to to the standard error and then terminates the current process using exit(2) with a value of 1. The message is prefixed with 'sfs:' or the contents of the global variable progname if declared. The text of the message is made up from format and the supplied params, with format containing the 'printf' style format for the message, and params containing the arguments.
error() also deletes any temporary files created with sfschannel(SFS3)
#define PROGNAME "yourprog" char *progname=PROGNAME; : error("cannot open file '%s', code %d",filename,errno); : error("process fails");
GETITEM() - LOCATE AND LOAD SFS DATA SET
#include "sfs.h" void getitem(filename,it,ty,item,buff) char *filename; /* pathname of file */ int it; /* item type */ char *ty; /* item specifier */ struct item_header *item; /* returned item header */ char **buff; /* returned buffer address */
getitem() searches filename for a data set of type it and of subtype specification ty. If the data set is found, its item header is returned in item and the data is loaded into a dynamically-allocated buffer, the address of which is returned in buff. The equivalent code fragment is:
fid = sfsopen(filename,"r",NULL); sfsitem(fid,it,ty,&item); buff = sfsbuffer(&item,item.numframes); sfsread(fid,0,item.numframes,buff); sfsclose(fid);
getitem() does not return on failure, instead it terminates the process with error(SFS3).
The buffer allocated by getitem() may be released with free(3).
GETLINE() - READ A LINE FROM STANDARD INPUT
char *getline(buff,len) char *buff; /* input buffer */ int len; /* length of input buffer */
getline() is a routine to read a line of input from the standard input, and place it into buff. A maximum of len-1 characters are read in, and any remaining characters on the line and the terminating '\n' character are discarded.
getline() returns buff on success, and the NULL pointer on end-of-file.
HISTMATCH() - MATCH STRING EXPRESSION AGAINST ITEM HISTORY
int histmatch(exp,targ,ret0,ret1,...) char *exp; /* match expression */ char *targ; /* target string */ char *ret0,*ret1,... /* returned sub-strings */
histmatch() is a function to perform string matching on speech file histories as stored in item headers and processed using the label routines. It returns a code expressing a match between a match expression exp, and a target string (item history) targ. The code is '1' for success, '0' for failure, and '-1' for an error on the string expression.
The following string match characters are currently supported in exp:
char param; histmatch("inwd(freq=%0)","inwd(freq=12800)",param); infreq = atoi(param); /* equal to 12800 */
The parameter exp may contain a single match expression or a sequence of expressions separated by '\033' (ESCAPE) characters. Each expression in exp must match whole target string.
histmatch() returns at the first matching expression.
ITSPEC() - DECODE ITEM SPECIFICATION
int itspec(string,type,match) char *string; /* item type specification */ int *type; /* returned type */ char **match; /* returned subtype match */
An item specification is composed of two parts: an item datatype selector and an item subtype selector; the routine itspec() decodes an item specification into a datatype number and a subtype match string suitable for use with getitem() and sfsitem(). The datatype selector can be specified as a digit string or as a two-character mnemonic (SP, LX, etc: lower case is automatically converted). The subtype selector may take one of three forms:
When the subtype part of the item specification is not present, itspec() returns suitable strings according to the entries in the summary table below:
itspec() returns 0 on success, 1 on failure.
itspec() modifies its string argument when the subtype part of the specification is a history match. The pointer in ty points either to a component of string or to a dynamically allocated area.
LABELS - ITEM TEXT LABELLING ROUTINES
char *lab_store(item) /* store/return expanded history */ struct item_header *item; /* item header */ void lab_reset() /* reset expanded history database */ void lab_initfile(filename) /* initialise expanded history dbase. */ char *filename; /* for this file */ char *lab_getmatch(code) /* get history match from short code */ char *code; /* short code */ char *lab_gettext(history) /* get text description */ char *history; /* expanded history */
These routines provide a simple mechanism for accessing and describing data sets using short codes and textual descriptions rather than the more formal mechanisms of item numbering and item histories. The routines lab_getmatch() and lab_gettext() access a labels file where the mappings between short codes and history matches, and the mappings between history matches and text descriptions are kept, see labels(SFS5).
lab_store() adds an item history to an internal database of histories for the file. It returns the expanded history for the item, which is simply the item history but with all referred items (recursively) expanded. For example if the item list was:
1.01 inwd 2.01 inwd(freq=10000) 3.01 tx(2.01) 12.01 fmanal(1.01,3.01)
then the expanded histories would be:
1.01 inwd 2.01 inwd(freq=10000) 3.01 tx(inwd(freq=10000)) 12.01 fmanal(inwd,tx(inwd(freq=10000)))
Notice that to expand the history for an item, lab_store() requires to be passed the histories of all earlier items in the file. The expanded histories can be obtained as the file is processed, or they can be set up for the whole file with a simple loop, like:
fid = sfsopen(filename,"r",NULL); while (sfsnextitem(fid,&item)) lab_store(&item);
or with a call to the routine lab_initfile() (below).
lab_reset() resets the internal database of histories, so that another file can be processed within the same program.
lab_initfile() scans the items in the given file, and calls lab_store() for each item.
lab_getmatch() takes a short code specifying a type of data set and returns a string match expression that selects appropriate items on the basis of their expanded history. The string match expressions are stored in a labels file and expect to be used with the string match function histmatch(SFS3). lab_getmatch() returns NULL if the code cannot be found.
lab_gettext() takes an expanded item history and returns a text description of the item. The text descriptions are stored in the labels file, and the first text description is returned which matches the given history. The routine returns NULL if no text description can be found. For the structure of the labels file see labels(SFS5). Thus to obtain a text description of an arbitrary item, one could use the code:
char *text; /* : */ lab_reset(); /* if required */ lab_initfile(filename); /* if file not scanned */ /* : */ if ((text = lab_gettext(lab_store(&item)))==NULL) printf("hist=%s\n",item.history) else printf("text=%s\n",text);
The labels files searched by the label routines is determined by the environment variable SFSLABEL (multiple files separated by ':'). If SFSLABEL is not present, the default file: SFSBASE/data/labels is used.
PARAM() - DECODE NUMERIC ENTRY IN HISTORY AND PARAMETER STRINGS
double param(string,parameter,default) char *string; /* target string */ char *parameter; /* parameter to find */ double default; /* default value */
param() provides a convenient mechanism for extracting numeric parameter values from item histories and parameter lists. The routine is given the address of the string, the name of the parameter and a default value. If the routine finds the substring '<parameter>=' in string then it returns the floating point value of the following number. If the substring is not found, the default value is returned. If the substring '<parameter>' is found, the value 1.0 is returned. Valid parameter names begin with an alphabetic character. Valid separator characters are: ' ', ',', ';', '(', & ')'.
Example calls might be:
sampfreq = param(item.history,"freq",12800.0);
linkflag = param(item.history,"linked",0.0);
PARAMS() - DECODE STRING ENTRY IN HISTORY AND PARAMETER STRINGS
char *params(string,parameter,default) char *string; /* target string */ char *parameter; /* parameter to find */ char *default; /* default string */
params() provides a convenient mechanism for extracting string parameter values from item histories and parameter lists. The routine is given the address of the string, the name of the parameter and a default value. If the routine finds the substring '<parameter>=' in string then it returns the value string up to the next separator. If the substring is not found, the default string is returned. If the substring '<parameter>' is found, then that string is returned. Valid parameter names begin with an alphabetic character. Valid separator characters are: ',', ';', '(', & ')'.
An example call might be:
match = params(item.history,"type",NULL);
PATHNAME() - GET FULL PATHNAME OF FILE
char *pathname(name) char *name; /* relative pathname of file */
pathname() is a subroutine to return the full pathname of file. For pathnames not beginning with '/', it concatenates name with the current working directory and eliminates strings such as './' and 'dir/..'. The routine returns a pointer to a static area.
PLAYBACK - REPLAY WAVEFORM THROUGH DAC
int dac_open(devicename) char *devicename; /* device selection =NULL for default */ int dac_playback(buff,count,freq,nbits,nchan,nrep) short *buff; /* waveform buffer */ int count; /* number samples */ double freq; /* sampling frequency */ int nbits; /* number of bits =12 or =16 */ int nchan; /* number of channels */ int nrep; /* number of repetitions */ void dac_close(rapid) int rapid; /* rapid close flag */
The SFS DAC routines support a number of audio systems. When SFS is built a number of supported devices are specified and included in SFS programs. At run-time the user selects one of the supported devices through the use of the environment variable 'DAC'.
The routine dac_open() determines the currently required device and attempts to open it. The routine dac_playback() replays a waveform from memory. The routine dac_close() closes the connection to the audio device.
PUTITEM() - STORE SFS DATA SET TO FILE
void putitem(filename,item,numf,buff) char *filename; /* pathname of file */ struct item_header *item; /* item header */ int numf; /* # frames to write */ char *buff; /* buffer address */
putitem() adds to an existing data file filename the data set described by item, numf and buff.
The equivalent code fragment is:
int ofid; ofid=sfschannel(filename,&item); sfswrite(ofid,numf,buff); sfsupdate(filename);
If an error occurs, putitem() terminates the process with a call to error().
PUTNITEMS() - STORE MULTIPLE SFS DATA SETS TO A FILE
void putNitems(filename,item,numf,buff,numitem) char *filename; /* pathname of file */ struct item_header *item; /* item header */ int numf; /* # frames to write */ char *buff; /* buffer address */ int numitem; /* number of items */
putNitems() is a generalisation of putitem() for adding multiple items to a file. putNitems() stores the data sets passed in item, numf and buff in temporary files and only updates the existing data file filename the last time it is called. The parameter numitem should be used to specify the number of data sets.
Example use is:
#define NUMITEMS 3 : putNitems(filename,&item1,numf1,data1,NUMITEMS); : putNitems(filename,&item2,numf2,data2,NUMITEMS); : putNitems(filename,&item3,numf3,data3,NUMITEMS);
There is an operational constraint on the number of simultaneous open files and hence the maximum number of items that can be stored simultaneously with putNitems().
SFSBASE() - GET SFS BASE DIRECTORY
sfsbase() returns a pointer to a static area containing the pathname of the base subdirectory for the SFS software. The default directory is built in to the software but may be overridden with the environment variable SFSBASE.
SFSBUFFER() - ALLOCATE BUFFER AREA FOR SFS DATA
#include "sfs.h" char *sfsbuffer(item,numf) struct item_header *item; /* item header */ int numf; /* buffer size in frames */
sfsbuffer() creates a memory buffer to hold data frames in a suitable format for reading or writing data from/to a file with sfsread() and sfswrite() for any item type.
sfsbuffer() takes details about the item frame format from the item header, and the size of the buffer in frames (for framesize equal to 1, 1 frame = 1 sample). The buffers are constructed as arrays of the primitive data structure for the item: e.g. short sp; struct lp_rec lp; struct fm_rec fm; etc.
Note that creating a general output buffer for annotation items is inefficient since the maximum space must be allocated for each label, so you should consider using a (sfs) buffer of length 1, or creating an array of an_rec within your own program (and performing appropriate memory allocation for the labels).
SFSCHANNEL() - OPEN OUTPUT CHANNEL TO SFS DATA FILE
#include "sfs.h" int sfschannel(filename,item) char *filename; /* speech file pathname */ struct item_header *item; /* output item header */
sfschannel() opens an output file to hold data to be added to a speech file. The name of the speech file is used to create a temporary file in the same directory, and to associate an output item to a particular file. The item header should be created with sfsheader() and have the history and params fields initialised separately.
sfschannel() returns a file descriptor greater than 0 on success, and -1 on failure. File descriptors returned by sfschannel() are closed by sfsupdate().
SFSCLOSE() - CLOSE SFS DATA FILE DESCRIPTOR
int sfsclose(fid) int fid; /* file descriptor */
sfsclose() closes a file descriptor opened with sfsopen(). Note that there is a maximum number of files that may be opened simultaneously.
SFSDUP() - DUPLICATE SFS DATA FILE DESCRIPTOR
int sfsdup(fid) int fid; /* file descriptor */
sfsdup() duplicates a file descriptor opened on a file using sfsopen(). This routine should be preferred to opening the file twice. The duplicate descriptor is positioned in the file identically to the original descriptor at the time sfsdup() was called.
SFSFILE() - SEARCH FOR SFS DATA FILE
char *sfsfile(filename) char *filename; /* speech file pathname */
sfsfile() returns a pointer to a static area containing the full pathname of a speech file. The environment variable SFSPATH specifies a list of directories separated by ':'. These directories are searched in turn and if the given file is found, then the full pathname is returned. If the file is not found, the original filename is returned unchanged.
SFSITEM() - LOCATE ITEM IN SFS DATA FILE
#include "sfs.h" int sfsitem(fid,datatype,spec,item) int fid; /* file descriptor */ int datatype; /* generic data type */ char *spec; /* item specification */ struct item_header *item; /* returned item header */
sfsitem() attempts to locate an item in a file opened with sfsopen() that meets the specification given by the variables datatype and spec. The variable datatype should contain the item 'datatype' code for the data set. The variable spec is a pointer to a string containing either the number of the data set expressed as a string (with '0' for last) or a string match expression that should be matched against the history fields of the items in the file of the type datatype. Thus if spec is "*", the first item of the given type is located. If datatype is given as 0, the routine locates the first item of any type in the file.
sfsitem() returns 1 on success and 0 on failure. If the item is found and item is not NULL, then the item header is returned.
SFSHEADER() - INITIALISE SFS DATA SET HEADER
#include "sfs.h" int sfsstruct; void sfsheader(item,it,floating,datasize,framesize,frameduration, offset,windowsize,overlap,lxsync) struct item_header *item; /* item header */ int datatype; /* item type */ int floating; /* structured/integer/floating */ int datasize; /* datum size */ int framesize; /* frame size */ double frameduration; /* frame duration */ double offset; /* data set offset */ int windowsize; /* fixed frame window size */ int overlap; /* fixed frame overlap */ int lxsync; /* excitation synchronous flag */
sfsheader() should be used to initialise item headers for all new data sets. The entire item header is first cleared then the arguments are used to initialise appropriate fields. sfsheader() also adds machine-specific information to the header so that the exact format of floating point numbers etc, can be determined by sfsread(). Thus you should not use old item headers for new data, since these may have been created on a different machine.
SFSNEXTITEM() - LOCATE NEXT ITEM IN SFS DATA FILE
#include "sfs.h" int sfsnextitem(fid,item) int fid; /* file descriptor */ struct item_header *item; /* returned item header */
sfsnextitem() locates the next data set in a file opened with sfsopen(), and returns the item header if found.
If the item argument is supplied as NULL, sfsnextitem() rewinds to the top of the file. The next call with a valid item argument will return the first item header in the file.
sfsnextitem() returns 1 on success and 0 if there is no next data set.
SFSOPEN() - OPEN A SFS DATA FILE
#include "sfs.h" int sfsopen(filename,mode,head) char *filename; /* speech file pathname */ char *mode; /* access mode requested */ struct main_header *head; /* returned main header */
sfsopen() attempts to open filename to check that it is a valid speech file. There are four supported operations requested as a string passed in mode:
For any operation, default action is performed if head is supplied as NULL.
sfsopen() returns the file identifier or 0 if the operation is successful. It returns -1 if the file does not exist, and -2 for any other error.
SFSREAD() - READ SFS DATA INTO BUFFER
#include "sfs.h" int sfsread(fid,start,numf,buff) int fid; /* file descriptor */ int start; /* index of first frame */ int numf; /* number of frames to load */ char *buff; /* buffer address */
sfsread() loads the whole or part of a data set into memory once it has been located by sfsitem() or sfsnextitem(). The routine takes the file descriptor fid, the start index of the data in frames start, the number of frames to be loaded numf, and the address of a memory buffer in which to place the data buff. This buffer can be created with sfsbuffer().
sfsread() returns the number of frames actually loaded, or zero if there is a read error. Read access to unstructured and fixed-length structured items can be made in any frame order, read access to variable-length structured items (currently only annotations) must be made in serial order.
Foreign or linked data sets are automatically decoded by sfsread().
SFSUPDATE() - ADD A NEW DATA SET TO A SFS FILE
int sfsupdate(filename) char *filename; /* speech file pathname */
sfsupdate() is the main routine for adding new data items to speech database files. Apart from a few special utility programs, all file update programs should use this routine to add data sets to the file. Once data has been stored using sfschannel() and sfswrite() this routine should be called to update the speech file.
sfsupdate() returns 1 on success and 0 on error. In either case, all temporary files created by sfschannel() for the given file are deleted.
sfsupdate() checks the contents of the new datasets against the contents of the datafile. It uses the criterion that two items are duplicated if their history fields are identical. If no duplicate items are found, the data sets are appended to the datafile. If duplicate items are found, the file is restructured. If the duplicate datafile item has not been subsequently processed it is deleted. If the duplicate item has been used as input to a subsequent item, it is 'truncated' to its item header only (and with its datatype field negated). In all cases the subtype fields of the new items are automatically given numbers according to their position in the file.
SFSWRITE() - WRITE DATA TO SFS DATA FILE
#include "sfs.h" int sfswrite(fid,numf,buff) int fid; /* output file descriptor */ int numf; /* number of frames to write */ char *buff; /* buffer address */
sfswrite() should be used to write new information to the output channel opened by sfschannel(). The routine takes the file descriptor provided by sfschannel() fid, the number of frames to be written numf, and a pointer to the buffer where the data is held buff. Note that the buffer should be created with sfsbuffer(), or should be constructed using the same conventions.
sfswrite() automatically updates the numframes and length fields in the item header associated with the channel.
sfswrite() returns the number of frames written on success and 0 on failure.
SFSWRITELINK() - WRITE A LINK ITEM TO A SFS DATA FILE
int sfswritelink(item,numf,link,filename) struct item_header *item; /* output item header */ long numf; /* number of frames linked */ struct link_header *link; /* output link header */ char *filename; /* output file name */
sfswritelink() opens an output channel on the given file using the supplied item header. It then writes the link header as data down the channel. When the program later calls sfsupdate() the item header and link headers are written to the output file with the appropriate settings for the numframes and datapresent fields in the item header.
TTYTEST() - TEST IF PROCESS CONNECTED TO FOREGROUND TERMINAL
ttytest() is a routine to check if it is sensible to report messages to the standard output. It returns 1 if the process is connected to a terminal and is running in the foreground, and 0 otherwise.
VIDEO - TERMINAL-INDEPENDENT TEXT ENHANCEMENT ROUTINES
void initvideo(flag); int flag; void italicon(); void italicoff(); void boldon(); void boldoff(); void uparrow();
initvideo() is an optional routine that may be used to enforce the generation of terminal codes even if the process is not connected to a terminal. If flag is set then the following routines always produce codes. Default action is only to send codes if the process is talking to a terminal, in which case this routine need not be called.
italicon() sends appropriate codes to the terminal to turn italics (or underlining) on.
italicoff() sends appropriate codes to the terminal to turn italics (or underlining) off.
boldon() sends appropriate codes to the terminal to turn bold (or reverse video) on.
boldoff() sends appropriate codes to the terminal to turn bold (or reverse video) off.
uparrow() sends appropriate codes to the terminal to move the cursor up one line.
|© 2000 Mark Huckvale University College London|