jMax IRCAM - Centre Georges Pompidou
jMax server kernel API
jMax Documentation

Introduction

The FTS kernel is a set of functionalities on top of which FTS application are built; all these functionalities are available to the application programmer to build its own applications, or part of them (like user objects for the FTS message system).

Moreover, the kernel itself is extensible, and users can easily add new kernel modules, like new device drivers to use new hardware for existing platforms.

This manual document the programming interface for all the FTS kernel functionalities.

In order to use any of the functions or data type defined in this document, you need to include the file "fts.h" in your sources.

The current release of this manual is not complete; we privileged documenting functionalities needed by user object writers for the FTS message system, while other more system related aspects were left behind; anyway, they are always described in the general lines; if you are in the situation you need the kind of functionalities that are described but not fully documented, and you cannot wait for future versions, contact the FTS developement team to get detailed information, by using the fts@ircam.fr mailing list.

FTS do not guarantee binary compatibility with future releases; some of the functions documented in this manual may actually be macros, and their definition may change, or they may become functions and so on.

Moreover, you should not make assumption on the current content of include files in the distribution, like the definition of a data structure, or the size of data type and so on, unless they are explicitly documented in this manual; anything that is not documented may change, or disappear, from a release to an other; if you really think you need to use something defined in an include file, but not documented here, first check with the FTS developement team. 


Memory Management

FTS provides itself a number of memory management operations that substitute the standard C lib ones; all the applications written for FTS should use these primitives, in order to simplify statistics on memory usage and similar things; but it is legal for an object to bypass the fts memory management and to access directly the libc primitives.

The memory management primitives closely resemble the C standard functions.

void *fts_malloc(int size)

Allocate a block of memory of the requested size. Remember that by definition, the memory unit is such that sizeof(char) == 1.

void *fts_zalloc(int size)

Like fts_alloc, but fills the newly allocated structure with zeros.

void *fts_realloc(void *p, int size)

Changes the size of the block pointed to by p to size bytes and returns a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes.

void fts_free(void *p)

The memory block pointer by p is returned to the memory management system; p should point to a memory block allocated by fts_alloc or fts_realloc; the memory block should not be referred anymore after a call to this function. 


Heaps

Typically the fts_malloc primitive is mapped to the native memory allocation subsystem, if any; to get more efficency in handling an heap of omogenous objects, FTS provide a predefined heap allocator module. The heap function are not yet documented in this release of the document


Error Handling

The Error Handling support subsystem provide a set of data structure, functions and conventions to represent errors, to handle errors and to signal errors to clients in FTS applications.

The error handling support is not documented in this release of the document.


FTS data structures

The FTS kernel defines a number of basic data types, and the relative operations, used in most of the kernel API, and freely usable from the user to build applications.

Vectors are documented in a specific document.

Symbols

Symbols are unique representations of strings, in the LISP symbol style; if two pointers point to two symbols representing the same string, they are actually two pointers to the same C object. FTS symbols do not store any other information other than the name they are coding.

Users cannot modify or access the implementation of a symbol; it is a completely opaque structure; the fts_symbol_t type is defined a const pointer to an internal structure.

fts_symbol_t fts_new_symbol(const char *name)

Creates a new symbol corresponding to the string name; the passed string is not copied, so it cannot be reused; use this function with string constants, use the next function for locally allocated buffers. Returns a pointer to the new symbol. If a symbol with the same name already existed, it return a pointer to the existing one, instead of creating a new one; so two successive calls to fts_new_symbol with the same name argument will return the same symbol. Note that symbols are never destroyed, so that values returned by fts_new_symbol are valid until the end of the session.

fts_symbol_t *fts_new_symbol_copy(const char *name)

Creates a new symbol corresponding to the string name; the passed string is internally copied, so it can be reused or freed as the caller needs. Returns a pointer to the new symbol. If a symbol with the same name already existed, it return a pointer to the existing one, instead of creating a new one; so two successive calls to fts_new_symbol with the same name argument will return the same symbol. Note that symbols are never destroyed, so that values returned by fts_new_symbol are valid until the end of the session.

const char *fts_symbol_name(const fts_symbol_t *sym)

Returns the name corresponding to a given symbol. The user should not write or modify in any way the returned value. 

FTS Atoms

Atoms are opaque objects of type fts_atom_t; an atom is a run time typed data item; an atom can store a floating point number, an long integer, a symbol, a string or a pointer. Atoms and array of atoms are used almost anywhere in FTS to represent lists of ethereogenous informations, like in messages, device options and so on. The FTS kernel provides a number of functions to fill an atom, to retrieve it's type or value, and to check its content type. Some` of the functions may be implemented as macros.

void fts_set_int(fts_atom_t *a, int l)

Sets the type of a to int, and it's value to l.

void fts_set_float(fts_atom_t *a, float f)

Sets the type of a to float, and it's value to f.

void fts_set_symbol(fts_atom_t *a, fts_symbol_t *s)

Sets the type of a to symbol, and it's value to s.

void fts_set_string(fts_atom_t *a, char *str)

Sets the type of a to string, and it's value to str.

void fts_set_ptr(fts_atom_t *a, void *p)

Sets the type of a to obj, and it's value to p.

void fts_set_void(fts_atom_t *a)

Sets the type of a to void, i.e. Sets the atom to it's initial, uninitalized status.

int fts_get_int(fts_atom_t *a)

If the atom is of type int, returns it's contents; if not, the results value is not specified.

float fts_get_float(fts_atom_t *a)

If the atom is of type float, returns it's contents; if not, the results value is not specified.

int fts_get_number_int(fts_atom_t *a)

If the atom is a number (float or int), returns it's contents converted to int, (this is always a macro); if not, the resulting value is not specified.

float fts_get_number_float(fts_atom_t *a)

If the atom is a number (float or int), returns it's contents converted to float, (this is always a macro); if not, the resulting value is not specified.

fts_symbol_t *fts_get_symbol(fts_atom_t *a)

If the atom is of type symbol, returns it's contents converted to fts_symbol_t; if not, the resulting value is not specified.

char *fts_get_string(fts_atom_t *a)

If the atom is of type string, returns it's contents converted to char *; if not, the resulting value is not specified.

void *fts_get_ptr(fts_atom_t *a)

If the atom is of type obj (void * pointer), returns it's contents converted to void *; if not, the resulting value is not specified.

int fts_is_int(fts_atom_t *a)

Returns 1 if the atom a is of type int, 0 otherwise.

int fts_is_float(fts_atom_t *a)

Returns 1 if the atom a is of type float, 0 otherwise.

int fts_is_number(fts_atom_t *a)

Returns 1 if the atom a is of type float or int , 0 otherwise.

int fts_is_symbol(fts_atom_t *a)

Returns 1 if the atom a is of type symbol, 0 otherwise.

int fts_is_string(fts_atom_t *a)

Returns 1 if the atom a is of type string, 0 otherwise.

int fts_is_ptr(fts_atom_t *a)

Returns 1 if the atom a is of type obj (void pointer), 0 otherwise.

int fts_is_void(fts_atom_t *a)

Returns 1 if the atom a is of type void (non initialized), 0 otherwise.

fts_type_t fts_get_type(fts_atom_t *a)

Returns one of the constants fts_t_int, fts_t_float, fts_t_symbol, fts_t_string, fts_t_ptr or fts_t_void depending on the type of the atom a. Most of the time it is better to use one of the types predicate above instead of this one. This function is really only usefull inside switch statements on the whole set of FTS types.

int fts_same_types(fts_atom_t *a1, fts_atom_t *a2)

Returns 1 if the two atoms a1 and a2 have the same type, 0 otherwise. 

Atom Lists

Atom Lists are data structures representing a variable length list of atoms; Atom List Iterators are abstractions that allow iterating on an Atom List.

Atom lists and atom list iterators can be allocated explicitly or implicitly as part of other structures. The kernel provides a set of functions for list manipulations and a mechanism to simplify sending the contents of an atom list to a client.

void fts_atom_list_init(fts_atom_list_t *list)

Initialize a statically or implicitly allocated atom list. Calling any other atom list function on a non initialized atom list has unspecified results.

fts_atom_list_t *fts_atom_list_new(void)

Explicitly allocates, initializes and returns a new atom list.

void fts_atom_list_destroy(fts_atom_list_t *list)

Empties the atom list list, freeing all the internally allocated storage. It can be used to clean an atom list, and is recomended before to stopping use of an implicitly or statically allocated atom list.

void fts_atom_list_free(fts_atom_list_t *list)

Frees an explicitly allocated atom list, i.e. one created using fts_atom_list_new; users should not use or refer to the list atom list after calling this function.

void fts_atom_list_append(fts_atom_list_t *list, int ac, const fts_atom_t *atom)

Appends ac atoms stored in the atom array to the end of the atom list list; it is the user's responsability to make sure that atom actually points to an array at least ac atom int.

int fts_atom_list_length( const fts_atom_list_t *list)

Returns the length of the atom list, i.e. the number of atoms currently stored in the atom list.

void fts_atom_list_iterator_init( fts_atom_list_iterator_t *iter, const fts_atom_list_t *list)

Initializes an atom list iterator statically or implicitly allocated to point to the first element of the atom list list. Calling any other atom list iterator function on a non initialized atom list iterator has unspecified results.

fts_atom_list_iterator_t *fts_atom_list_iterator_new( const fts_atom_list_t *list)

Explicitly allocates, and returns a new atom list iterator, initialized to point to the atom list list first element.

void fts_atom_list_iterator_next( fts_atom_list_iterator_t *iter)

Advances the atom list iterator iter to point to the next element of its atom list.

int fts_atom_list_iterator_end( const fts_atom_list_iterator_t *iter)

Returns zero if the atom list iterator points beyond the end of the list.

fts_atom_t *fts_atom_list_iterator_current( const fts_atom_list_iterator_t *iter)

Returns a pointer to the atom currently pointed to by the atom list iterator iter.

Hash Tables

FTS hash tables are data structures mapping symbols to void * pointers. They are intended to be used any time there is the need for naming internal objects. It is recomended that a hash table contains homogenous objects, i.e. that every time objects are named, a different name space is implemented. FTS hash table iterators are abstractions that allow iterations on all the pairs symbol value contained in a hash table.

void fts_hash_table_init( fts_hash_table_t*ht)

Initializes a statically or implicitly allocated hash table. Calling any other atom list function on a non initialized hash table has unspecified results.

fts_hash_table_t *fts_hash_table_new( void)

Explicitly allocates, initializes and returns a new hash table.

void fts_hash_table_destroy(fts_hash_table_t *ht)

Empties the hash table ht, freeing all the internally allocated storage. It can be used to clean an hash table, and is recomended before stopping use of an implicitly or statically allocated hash table.

void fts_hash_table_free(fts_hash_table_t *ht)

Frees an explicitly allocated hash table, i.e. one created using fts_hash_table_new. Users should not use or refer to the ht hash table after calling this function.

int fts_hash_table_lookup(fts_hash_table_t *ht, fts_symbol_t *sym, void **data)

Looks up for the value associated with the symbol sym in the hash table ht, and stores it in the pointer pointed by data. Returns non zero if the value has been found, zero otherwise. The value of the pointer pointed by data is not specified in this case.

int fts_hash_table_insert(fts_hash_table_t *ht, fts_symbol_t *sym, void *data)

If there is no value associated with sym in the hash table sym, it adds the value data associated to the symbol sym and returns non zero, otherwise it returns zero.

void fts_hash_table_apply( fts_hash_table_t*ht, void (*fun)( fts_symbol_t *sym, void *data))

For every association symbol/value defined in the hash table ht, it calls the function fun, passing the symbol as argument sym, and the value as argument data.

int fts_hash_table_remove( fts_hash_table_t*ht, t_symbol *sym)

Removes the symbol sym and its associated value from the hash table ht.

void fts_hash_table_iterator_init( fts_hash_table_iterator_t*iter, const fts_hash_table_t*ht)

Initializes an hash table iterator statically or implicitly allocated to first symbol/value pair of the hash table ht; calling any other hash table iterator function on a non initialized hash table iterator has unspecified results.

fts_hash_table_iterator_t *fts_hash_table_iterator_new( const fts_hash_table_t *ht)

Explicitly allocates, and returns a new hashtable iterator, initialized to point to the first symbol/value pair of the hash table ht.

void fts_hash_table_iterator_next( fts_hash_table_iterator_t*iter)

Advances the hash table iterator iter to point to the next symbol/value pair in its hash table. The order followed by the hash table iterator is not specified, but is guaranteed to cover the whole table.

int fts_hash_table_iterator_end( const fts_hash_table_iterator_t*iter)

Returns zero if the atom list iterator points beyond the end of the table.

fts_symbol_t *fts_hash_table_iterator_current_symbol( const fts_hash_table_iterator_t*iter)

Returns the symbol of the symbol/value pair pointed to by the iterator.

void *fts_hash_table_iterator_current_data( const fts_hash_table_iterator_t*iter)

Returns (as a void *) the value of the symbol/value pair pointed to by the iterator. 

Property Lists

Property lists are another way to represent symbol to value association, more time and memory efficients in case the values to bstore are just a few, or usefull when a symbol can be associated to multiple values.

The property lists are not yet documented in this release of the document


Time Handling

The FTS kernel provides a number of primitives to cope with time; the time itself is a relative concept for FTS, and different times, also user defined, can be defined by definining a new time souce (a clock, in fts terminology); all the fts time related primitives will work with any time source.

Clocks

A clock is the definition of a time source; from the FTS point of view, a time source is just a floating point number (actually, a double precision float) that may change from one scheduling loop to another. The FTS time system is not responsable to actually change this number, but only to react to this changes accordingly to the user requests; the actual time changing must be handled by the module that define the clock.

There are two issues that must be considered while defining and using a clock; the clock time can be expressed in any units, but the time resolution of the FTS time system is always the scheduling tick; i.e., clocks are checked in the control domain, and the control is undersampled with respect to signals by a fixed factor, usually 64.

This have two resulting effects: first, since times are always quantized at run time to the control sampling rate (i.e. an action is executed at the next scheduling tick), so you cannot have a time grain in control smaller than a scheduling tick; second, for the same reason you can have beating between the scheduling tick time and the time used in user algorithm, if the unit used by the user clocks are not multiple of the scheduling tick time; this was a well known problem with the old Max 0.26, that offered only the millisecond as a clock unit, and a scheduling tick of 1.4 ms at 44.1 Khz.

Clocks are named, and are addressed by name in the whole code; users have no access to the clock implementation; FTS provides a number of pre-defined clocks, that are the following:

msec
A free running clock, counting the milliseconds since the FTS boot.
tick
A free running clock, counting the scheduling ticks since the FTS boot.
dsp_msec
A clock running during dsp, counting the milliseconds since dsp started.
dsp_tick
A clock running during dsp, counting the scheduling ticks since dsp started.
All the time related primitives get a clock name (as symbol) as argument; if this clock name is not specified (by passing a null pointer) the default msec clock is taken.

Note that a clock do not need to be defined before the time related objects that use them; for example, the user can allocates an alarm for a clock before this clock is defined.

Using the tick or dsp_tick clocks guarantee that there will be no problem due to the beating between the scheduling clock and the user clock; but the semantic of a patch written with these clocks depend on the sampling rate.

void fts_clock_define(fts_symbol_t *clock_name, double *clock)

Define a new clock, named clock_name, represented by the double pointer by clock.

void fts_clock_undefine(fts_symbol_t *clock_name)

Undefine the clock: undefining a clock *do not* destroy the clock, but just undo the association between the clock name and the int value established with fts_clock_define. The clock is so stopped until the user redefine a clock with the same name.

Note anyway that undefining and redefining a clock can have weird temporary effects on object using the clock; the transition is not guaranteed to be smooth, depend on the value of the clock. For the alarms, the effect is the same as with a clock value change (at the redefinition).

Also, system defined clocks cannot be undefined.

int fts_clock_exists(fts_symbol_t *clock_name)

Returns non zero if a clock named clock_name has been already defined; remember, anyway, that in general you do not need to define a clock before using it.

double fts_clock_get_time(fts_symbol_t *clock_name)

Returns a double representing the current time of the clock named clock_name. The current time is not the current value of the clock variable, but is the time FTS consider as current, i.e. already took in account in scheduling. The difference is somehow subtle: current time change only during scheduling tick, while the physical clock variable can change due to any cause, including interrupt; also it is guaranted that while executing a alarm scheduled for time t, this function will returns t, and not the actual value of the clock variable; this is needed to avoid accumulation errors using clocks units different from ticks. 

Alarms

An alarm is an object of type fts_alarm_t; it can be either allocated and accessed by means of a pointer, or used as a part of an other structure; as most of the kernel objects, it's internal structure is not documented or available to the user; all accesses should be done by means of the following API.

An alarm declare a function to be called when the named clock arrive to a given time; a time can armed, i.e. active, or unarmed; if the alarm is unarmed, the function will not executed, but the alarm keep its timing information.

When the alarm is fired, and its callback function called, the alarm is not unarmed; if needed it must be unarmed by the callback function itself; the reason behind this is that with some clock the time can actually jump backward, and a fired alarm refired; consider for example an alarm that need to be fired one second the start of the dsp engine: it can be created using the "dsp_msec" clock, and left armed after fired, so it will refire again the next time the dsp start.

An alarm can be put a cycle mode: it will fire regularly with a given period; the difference with an alarm that reschedule itself in its callback function is that in case of backward jumping time (like the "dsp_msec" time that is reset at the start of the dsp engine) a cycled alarm will continue to fire, keeping phase coherency with respect to the clock.

void fts_alarm_init(fts_alarm_t *alarm, fts_symbol_t *clock_name, void (* fun)(fts_alarm_t *, void *), void *arg)

Initializes a statically or implicitly allocated alarm. The alarm will use the clock named clock_name; its callback function is fun; the callback function will be called with two arguments, a pointer to the alarm itself, and the void * pointer arg, that will be stored in the alarm; there is no way to change the callback function or its argument after the alarm creation.

fts_alarm_t *fts_alarm_new(fts_symbol_t *clock_name, void (* fun)(fts_alarm_t *, void *), void *arg)

Allocates and init new alarm. The alarm use the clock named clock_name; its callback function is fun; the callback function will be called with two arguments, a pointer to the alarm itself, and the void * pointer arg, that will be stored in the alarm; there is no way to change the callback function or its argument after the alarm creation.

void fts_alarm_free(fts_alarm_t *alarm)

Unarm and frees the alarm alarm; after freeing an alarm, it should not be referred any more.

void fts_alarm_set_time(fts_alarm_t *alarm, double when)

Sets the absolute time at which the alarm callback function will be called; this time, when, is expressed in the time units used by the alarm clock, and can be in the future or in the past (relative to the used clock); this function do not change the armed/unarmed status of the alarm.

void fts_alarm_set_delay(fts_alarm_t *alarm, double when)

Sets the relative time (i.e. time from now) at which the alarm callback function will be called; this time, when, is expressed in the time units used by the alarm clock, and it is relative to the clock current time; it can be positive or negative. This function do not change the armed/unarmed status of the alarm.

void fts_alarm_arm(fts_alarm_t *alarm)

Arm the alarm, i.e. enable it to actually fire the callback function when the time come.

void fts_alarm_unarm(fts_alarm_t *alarm)

Unarm the alarm, i.e. prevent it to actually fire the callback function. The time information of the alarm will not be deleted, so an call to fts_alarm_unarm followed by a call to fts_alarm_arm leave the alarm in its initial state. Remember that an alarm is not automatically unarmed after fired, so you should unarm is explicitly in the callback function, if so wished.

int fts_alarm_is_in_future(fts_alarm_t *alarm)

Returns non zero if the alarm is set to fire in some time in the future (with respect to its clock); the result of this function do not depend on the armed/unarmed status of the alarm.

int fts_alarm_is_armed(fts_alarm_t *alarm)

Returns non zero if the alarm is armed, zero otherwise. 

Timers

An timer is an object of type fts_timer_t; it can be either allocated and accessed by means of a pointer, or used as a part of an other structure; as most of the kernel objects, it's internal structure is not documented or available to the user; all accesses should be done by means of the following API.

A timer implement a simple stop watch, to evalute elapsed time since an specific event, or accumulate multiple elapsed times.

void fts_timer_init(fts_timer_t *timer, fts_symbol_t *clock_name)

Initializes a statically or implicitly allocated timer. The timer will use the clock named clock_name; the internally accumulated elapsed time is set to zero.

fts_timer_t *fts_timer_new(fts_symbol_t *clock_name)

Explicitly allocates, initializes and returns a timer. The timer will use the clock named clock_name; the internally accumulated elapsed time is set to zero.

void fts_timer_free(fts_timer_t *timer)

Frees an explicitly allocated timer, i.e. one created using fts_timer_new; users should not use or refer to the timer timer after calling this function.

void fts_timer_zero(fts_timer_t *timer)

Sets the accumulated elapsed time of timer to zero.

void fts_timer_start(fts_timer_t *timer)

Start the counting of elapsed time of timer.

void fts_timer_stop(fts_timer_t *timer)

Suspend the counting of elapsed time of timer, but leave the current value.

double fts_timer_elapsed_time(fts_timer_t *timer)

Returns the timer accumulated elapsed time. 

Time Gates

A time gate is an object of type fts_time_gate_t; it can be either allocated and accessed by means of a pointer, or used as a part of an other structure; as most of the kernel objects, it's internal structure is not documented or available to the user; all accesses should be done by means of the following API.

A time gate is a gate that when is closed stay closed for a given amount of time; while closed, the gate do not accept any further close command; the main purpose of the time gate is to avoid fast repetition of the same event, like error messages.

void fts_time_gate_init(fts_time_gate_t *gate, fts_symbol_t *clock_name)

Initializes a statically or implicitly allocated time gate. The time gate will use the clock named clock_name; the gate is set to open.

fts_time_gate_t *fts_time_gate_new(fts_symbol_t *clock_name)

Explicitly allocates, initializes and returns a time gate. The time gate will use the clock named clock_name; the gate is set to open.

void fts_time_gate_free(fts_time_gate_t *gate)

Frees an explicitly allocated time gate, i.e. one created using fts_timer_new; users should not use or refer to the gate time gate after calling this function.

int fts_time_gate_close(fts_time_gate_t *gate, double interval)

If the gate is closed, returns zero; otherwise, close it for interval and returns non zero.interval is expressed in the time gate clock units. 


The Module System

Modules are a simple tools to organize and structure FTS applications; from the strict programming point of view a module is simply a data structure that define an initialization and a shutdown function; conventionally, this data structure should correspond to a set of source files implementing a set of coherent functionalities, like a new data type with its operations, or a library of FTS objects and so on.

The init function is often very important; under FTS, the execution of application code usually happen as a reaction to some kind of event, like a timer has elapsed, or data is available on the MIDI input, or a given client message is arrived, or a scheduling phase has been completed.

It may be easy to think the FTS kernel as a set of specialized event dispatching table, mapping certain kind of events to certain parts of application code.

This mapping between system events and application code is realized in the init function of a module; the function declare the functions to be called in the different situations, and install them with the various programming interface availables.

Most of the time, the only non static C symbol declared in an FTS application is the module itself, because all the other functions are installed as pointers in some system structure.

void fts_install_module(fts_module *s)

Install the module pointed by s; a module should be a structure defined as in the following example.

fts_module fts_mess_module = {"Frob", "The new frobber module", frob_init, frob_shutdown;}

The first two component of the structure are a name and a module description, used in debugging messages; the third is a function with zero arguments and returning void that is called as init functin, and the fourth is a similar function called as shutdown function. 


Audio Streams

FTS applications are free to access audio input output devices directly with the device standard programming interface; the audio stream subsystem simplify the handling of audio I/O, from one side providing the audio_in and audio_out logical devices, and from the other integrating audio device handling inside the scheduler.

An audio stream is a audio input or output channel; streams are numbered; any audio physical device can be mapped to any index by means of UCS commands; the audio stream subsystem handle buffer allocation and scheduling for input and output operations

This programming interface is not not documented in this release of this document.


MIDI Input Output

FTS MIDI handling provides multiport MIDI configurations, MIDI unparsing with callback based input, and output operations.

This programming interface is not not documented in this release of this document.


The FTS Device System

The FTS device system represent an abstraction layer over the I/O capability of the hardware it run on; it establish a simple and uniform programming interface to open and close the connection with a I/O channel and to send and receive on that channel.

Depending on the undelying platform, FTS device can correspond to actual device drivers, like on the ISPW or TMS32C40 platform, or to wrappers around existing I/O libraries or devices, like on the SGI platform; a uniform interface will allow complete portability of the sources between the different architectures.

FTS define (for the moment) two kind of devices: character devices and signal devices; character device are very similar to Unix character devices; they model a byte-stream, supporting byte-oriented I/O operations, and optionally seek operations; signal devices are devices modelling the MIDI input

The device system is conceptually divided in two parts: the standard programming interface every device support (documented in this chapter), and a set of functions and data structure to help building a new device driver when needed (documented in the next chapter).

As a complent, the FTS kernel define the concept of logical device, that essentially allow the definition of the role of a specific physical device in a given configuration (like use serial line one as MIDI input, use serial line 2 as client connection and so on); the configuration of logical devices is fully perfomed with the UCS configuration system. 


FTS Character Device API

The FTS Device System is not documented in this release of the document

FTS Signal Device API

The FTS Device System is not documented in this release of the document


Device Creation Support

FTS include a library of macros and functions to aid the device driver developement.

This programming interface is not not documented in this release of this document
Copyright © 1995,1999 IRCAM.
All rights reserved.