.TH LIBSF 3carl CARL
.SH NAME
libsf - subroutine library for csound file system.
.SH SYNOPSIS
.nf
.B # include <carl/sndio.h>
.B float sfexpr(expression, sample_rate);
.B 	char *expression;
.B 	float sample_rate;
.B CSNDFILE *cpsfd(sound_file_descriptor);
.B 	CSNDFILE *sound_file_descriptor;	
.B float fsndi(sound_file_descriptor, sample_index);
.B 	CSNDFILE *sound_file_descriptor;	
.B	long sample_index;
.B CSNDFILE *accesf(name);
.B	char *name;
.B CSNDFILE *opensf(name, mode);
.B 	char *name, *mode;
.B extern int sferror;
.B CSNDFILE *setsfd(sount_file_descriptor, ctrl, arg);
.B 	CSNDFILE *sound_file_descriptor;
.B	char *ctrl, *arg;
.B closesf(sound_file_descriptor);
.B 	CSNDFILE *sound_file_descriptor;
.B allclosesf();
.fi
.SH DESCRIPTION
.PP
.SH SFEXPR
.B sfexpr
(
.B expression,
.B sample_rate
)
is an expression evaluator similar to that used in
.I cmusic(1carl)
but modified for figuring sample-rate dependent expressions, such
as specifications of begin/end times in sound files.
Rather than giving the full documentation here, only differences
from 
.B expr(3carl)
will be noted.
.PP
.B sfexpr()
first evaluates the expression without reference to postoperators,
then multiplys the result of the expression by the
.B sampling_rate,
and then applys the postoperators.
The typical usage of
.B sfexpr()
is for users to supply expressions in seconds, and 
.B sfexpr()
converts this to sample indices at the specified sampling rate.
.IP Prefix operator: 
\- (minus).
.IP Infix operators: 
+, \-, *, /, ^, %.
All prefix and infix operators are applied to the expression first,
then the result is multiplied by the 
.B sampling_rate,
and then postoperators are interpreted.
.IP Postoperators: 
.B k, m, s, ms, S,
where 
.B dB 
converts to dB of amplitude (e.g., -6dB is approximately equal to .5), 
.B K 
multiplies by 1024, 
.B k 
multiplies by 1000,
.B m
(minutes) multiplies by 60,
.B s
(seconds - default postoperator) multiplies by 1,
.B ms
(milliseconds) multiplies by .001,
.B S
(samples) divides by the 
.B sampling_rate
(which recovers the result as a sample index expression).
.PP
The upshot of this is that all time expressions except those in which the
.B S
postoperator appears are taken to be times in seconds, and are multiplied
by the sampling rate to get a sample index.  Where the 
.B S
postoperator appears, the expression is considered to be a 
sample index already, and the multiplication by the sampling rate
is nullified. 
.PP
Note: by setting the value of
.B sampling_rate
to 1.0, 
.B sfexpr()
can be used to compute the natural value of expressions.
.PP 
.SH CPSFD
.B cpsfd
(
.B sound_file_descriptor
)
returns a pointer to a
copy of the 
.B sound_file_descriptor 
passed to it.
.PP
.SH FSNDI
.B fsndi
(
.B sound_file_descriptor, 
.B sample_index
)
returns the sample value of the sound file pointed to by
.B sound_file_descriptor
at the location specified by
.B sample_index.
.PP
.SH ACCESF
.B accesf
(
.B name
)
returns 0 if 
the sound file mentioned in
.B name
exists and the directory path can be traversed by this process,
otherwise it returns -1.
.PP
.SH OPENSF
.B opensf
(
.B name, 
.B mode
)
opens the named sound file.  The 
.B mode
argument takes a string that obeys command-line flag syntax to specify
reading, writing, or both. If writing only, the file is created;
any existing file is deleted.  Additional flags then specify the
properties of the new sound file.  The file is opened by calling the
program
.I opensf(1carl)
via 
.B popen(2).
Please refer to 
.I opensf(1carl)
for a description of the mode flags.
If the open is successful, a pointer to a 
.B CSNDFILE
structure 
is returned, else NULL.  The value of
the global variable
.B sfexpr
will be set to the value of any error detected.
.PP
.SH FILE MODES AND ALLOCATION
New files are created by default as 
.I non-realtime.
This simply means that the system does not need to fit the file into
one contiguous block.  No space is claimed for a new file so created
until the first attempt to put something in it.  A new file will be
made 
.I realtime
by mentioning any of the following flags:
.IP -tn
sets file to realtime and claims 1 cylinder by default;
.IP -TN
sets file to realtime and claims enough cylinders for time 
in seconds requested.
.IP -CN
sets file to realtime and N cylinders.
.SH SETSFD
.B setsfd
(
.B sfd, 
.B ctrl, 
.B arg
)
sets a field on a
.B CSNDFILE
sound file descriptor structure.  It returns a pointer to the modified 
structure.  If
.B sfd
is NULL, a new empty 
sound file descriptor is created, and its address is returned.
The 
.B ctrl
string specifies the field to be modified, as described in
.B <carl/sndio.h>,
and 
.B arg
is the data in string format to be substituted.
.PP
.SH CLOSESF
.B closesf
(
.B sound_file_descriptor
)
takes a pointer to a sound file descriptor and closes it via
.B popen(3)
and 
.I closesf(1carl).
.B allclosesf()
closes all open sound files by walking a linked list of open
sound files maintained by
.B opensf().
.SH SYSTEM LEVEL OPENSF AND CLOSESF
Two routines,
.B CSNDFILE 
.B sndesc 
.B *sopensf(name, mode, sfd)
.B char *name; 
.B char *mode; 
.B CSNDFILE *sfd;
and
.B sclosesf(sfd)
.B CSNDFILE *sfd;
are the 
.I csound
system's privileged versions of
.B opensf()
and
.B closesf().
The difference is that these routines actually do the i/o to the
sound file system disk and must therefor be executed in programs that
are set-user-id disk, 
whereas 
.B opensf()
and
.B closesf()
are front ends to programs
.I opensf(1carl)
and
.I closesf(1carl),
which in turn are set-user-id programs that call
.B sopensf()
and
.B sclosesf().
In any event, 
the following is a synopsis of 
.B sopensf().
.PP
.nf
.IP Arguments:
.RS .5i
name : filename spec, can be partial name
mode : string of following
.RS .5i
r 	read access
w 	write access
rw 	fully buffered read/write access
[r|w] F cause sdf file to be updated after each write
.RE
sfd : sound file descriptor
.RS .5i
if NULL, use name to determine file
if !NULL, use filename on sfd to determine file and
.RS .5i
if creating file (i.e., mode includes "w" and
file doesn't exist) use attributes of the sdf
to configure the file for nc, ns, fs, etc.
The new sfd will NOT have a pointer to the 
same disk block (if any) as the sfd passed as argument.
.RE
.RE
.RE
.SH FILES
These subroutines are in libcarl.a.  At CARL, they are also
in libsf.a.
.SH AUTHOR
D. Gareth Loy
