This document is a work in progress. As such, some areas are incomplete, vague, or have open questions. Such areas are marked with comments enclosed in brackets such as the following: [The status section should be removed in the final document.]
This document has some rough parts, but the need to distribute to consortium members for comment outweighs the need for further editing. Please send comments to audio@x.org. Typographical comments should be sent directly to the author, Mark Welch (mw@x.org).
Where possible, the function man pages approximately follow Unix-style man page conventions. The object def inition man pages approximately follow the Motif man page standard, as used in OSF/Motif Programmer's Ref erence (Englewood Cliffs, NJ : Prentice-Hall : 1993).
Following is a table showing the various integer types used in the interface and their respective meanings:
---------------------------------------- | Type | Definition | ======================================== | XaUint8 | unsigned 8-bit integer | ---------------------------------------- | XaInt8 | signed 8-bit integer | ---------------------------------------- | XaUint16 | unsigned 16-bit integer | ---------------------------------------- | XaInt16 | signed 16-bit integer | ---------------------------------------- | XaUint32 | unsigned 32-bit integer | ---------------------------------------- | XaInt32 | signed 32-bit integer | ----------------------------------------
const
const char *foo;
pointer to constant characters
char * const foo;
constant pointer to non-constant characters
const char * const foo;
constant pointer to constant characters
An example function here provides a summary of constant usage [will replace with something else later]:
/* For simple declarations, read right to left to get const stuff right.
** in the comments below,
** p = "pointer"
** c = "constant"
** i = "integer"
**
** compile with gcc -c -pedantic to show errors
*/
ConstDemo()
{
int victim = -1;
const int * pfoo0 = &victim; /* pic */
int const * pfoo1 = &victim; /* pci (same as above) */
int * const pfoo2 = &victim; /* cpi */
const int * const pfoo3 = &victim; /* cpic */
int const * const pfoo4 = &victim; /* cpci (same as above) */
/* legal assignments */
pfoo0 = &victim;
pfoo1 = &victim;
*pfoo2 = 0;
/* illegal assignments */
*pfoo0 = 0;
*pfoo1 = 0;
pfoo2 = &victim;
*pfoo3 = 0;
pfoo3 = &victim;
*pfoo4 = 0;
pfoo4 = &victim;
}
[table of contents here - take Name section from each page]
Introduction to X Audio function and object interfaces
#include <Xalib.h>
Each object man page contains a table which defines a set of object resources used by the programmer to specify data. The programmer can also set the resource values for the inherited classes to set attributes for the object. To reference a resource by name or by class in a .Xdefaults file, [do something approximating the following: remove the XaN or XaC prefix and use the remaining letters.] To specify one of the defined values for a resource in a .Xdefaults file, [remove the Xa prefix and use the remaining letters (in either lowercase or uppercase, but include any underscores between words).] The codes in the access column indicate if the given resource can be set at creation time (C), set by using XaSet (S), retrieved by using XaGet (G), must be supplied at creation time (M), or is not applicable (N/A).
XaAudio XaOpenAudio(const char *networkID, XaUint16 errStringLenIn, char *errStringOut, XaUint16 *argcInOut, char **argvInOut);
XaOpenAudio opens a connection to an audio server specified by networkID. The networkID is a null-terminated string. On POSIX-conformant systems, if networkID is NULL, the value of the XAUDIO environment variable will be used. The encoding and interpretation of the audio server name is implementation dependent. Strings in the ANSI Host Portable Character Encoding are supported; support for other characters is implementation dependent. On POSIX-conformant systems, the network ID has the form:
tcp/
hostName[:portNumber] or
decnet/
hostName::objName or
local/
hostName:path.
XaOpenAudio also parses the command line (as specified by argcInOut and argvInOut). After XaOpenAudio has been called, argcInOut and argvInOut contain only those parameters that were not in the standard option table [or in the table specified by the options argument? Should we have a separate options argument?] If the modified argcInOut is not zero, most applications simply print out the modified argvInOut along with a message listing the allowable options.
Upon successful completion, XaOpenAudio returns an opaque pointer of type XaAudio to the client. If a connection could not be opened, a NULL pointer is returned and errStringOut is filled with text explaining the reason for the failure. [Some other more explicit error code? Plus, we have I18N problems here as well.]
XaOpenAudio uses the ICE (Inter-Client Exchange) protocol to open and configure the connection to the audio server. See the ICE specification for more information on ICE connection management and possible error return strings.
ICE specification, XaCloseAudio()
void (*XaCloseReplyFunc)(void *callbackData);
void XaCloseAudio(XaAudio connection, XaCloseReplyFunc callbackFunc, void *callbackData);
XaCloseAudio closes an existing connection to an audio server specified by connection. When closing the connection, XaCloseAudio performs a sync on the connection via XaPing, then closes the connection. [Object lifetime stuff goes here]
If replyFunc is non-NULL, XaCloseAudio executes asynchronously, returning to the caller. When the closure is completed in this case, replyFunc is called with the callbackData pointer originally passed to XaCloseAudio.
None.
[X Audio uses the ICE library to manage server connections.]
[ICE specification,] XaOpenAudio(), XaPing()
void XaFlush(XaAudio connection);
XaFlush flushes the request buffer on connection. Audio applications that have registered error or event handlers need not use this function, because the request buffer is automatically flushed as needed by calls to XaPending. [Other situations in which a flush will occur?]
Requests that have been flushed are not guaranteed to have been completely processed at the time that XaFlush returns. To guarantee the processing of pending requests, call the XaPing function.
None.
[notes here]
typedef void (*XaPingReplyFunc)(XaAudio connection, void *callbackData);
void XaPing(XaAudio connection, const XaBoolean discard, XaPingReplyFunc callback, void *callbackData);
XaPing notifies the client when all currently pending requests on connection have been processed by the server and all events and errors due to that processing have been received by the client library. [if discard stays in: verbiage on discarding events on the event queue?] If XaPing is executed asynchronously, the value of discard is ignored, and no messages are flushed from the request buffer.
If callbackFunc is NULL, the call blocks until the synchronization is complete. If callbackFunc is not NULL, XaPing executes asynchronously, returning immediately to the caller, and the callback function specified in callbackFunc will be called upon completion of XaPing. The callback function is passed two parameters: the audio connection handle and the callbackData pointer initially passed to XaPing.
None.
typedef void (*XaFindReplyFunc)(XaAudio connection, XaUint32 numReturnTags,
const XaTag * const returnTags, void *callbackData);
XaUint32 XaFind(XaAudio connection, XaBoolean searchRemote, XaTag objectClass, XaTag **returnTags, XaFindReplyFunc callbackFunc, void *callbackData, ...)
Given an object class and a set of search terms, XaFind looks for all objects of class objectClass whose attributes match the criteria provided. If searchRemote is XaTrue [?], the search will be performed on the server; otherwise, the client's object database will be searched.
If callbackFunc is NULL, the number of objects that match the search terms is returned, and the tags of these objects are passed back in returnTags. The array pointed to by the returnTags parameter must be deallocated (using free(3)) by the client application.
If callbackFunc is non-NULL, XaFindObject executes asynchronously, immediately returning 0 to the caller and setting the dereferenced value of returnTags to NULL. Upon completion of the find request, the function pointed to by callbackFunc is called with four parameters: the XaAudio connection object, the number of tags found by the request, a pointer to the array of tags, and the client-specified utility pointer initially passed in the callbackData parameter of XaFindObject.
[perhaps some examples would help]
typedef void (*XaFindReplyFunc)(XaAudio connection, XaAtom returnAtom, void *callbackData);
XaAtom XaFindAtom(XaAudio connection, const char *searchString, const XaBoolean create, XaFindReplyFunc callbackFunc, void *callbackData);
Given a searchString, XaFind looks for an existing string object corresponding to searchString.
If callbackFunc is NULL, and a string object exists in the server corresponding to searchString, the atom of that object is returned. The returned atom is valid for the life of the connection. If a corresponding object does not exist, and create is XaTrue, a new atom will be created and returned.
If callbackFunc is non-NULL, XaFindAtom executes asynchronously, immediately returning XaAnone to the caller. Upon completion of the find request, the function pointed to by callbackFunc is called with four parameters: the XaAudio connection object, the number of tags found by the request (either 0 or 1), a pointer to the returned tag, and the client-specified utility pointer initially passed in the callbackData parameter of XaFindAtom.
XaTag XaCreate(XaAudio connection, XaAtom objectClassName, ...);
XaCreate creates a new object of class objectClassName. The initial attribute values are copied name-value pairs in the variable parameter list supplied to XaCreate, if any are supplied, in addition to the class object defined in either the client library (for file objects, file readers, and error handlers) or the server (for all other types of objects). The last entry in the parameter list must be a name entry containing a NULL pointer. XaCreate returns a tag corresponding to the newly created object.
[Notes:
still a question of whether we copy initial values from the resource database, then use the parameter list to override. would that be more Xt-like?
Do we require the use of object names? How do we handle object names: as atoms, strings, or something else?
]
XaCreate treats the provided resource data as name-value pairs. See the XaArgList manual page for more information on how to specify complex resource data.
[The exceptions to this rule are when the resource name is one of the following constants:
The last entry in the parameter list must be a name entry containing NULL.]
The tag of the newly created object is returned. The returned tag is valid for the life of the object.
void XaDestroy(XaAudio connection, XaTag targetObject);
XaDestroy deallocates storage space for all attributes of the object referred to by targetObject, and removes targetObject from the resource pool to which it belonged. Deletion is shallow: if attributes of targetObject contain tags referring to other objects, the referenced objects are not destroyed.
[Not sure about the need for deep deletion. Pro: might be very useful in cases where a client wants to delete a flow and associated client data devices, as only objects for which the client has delete permissions are affected anyway. Con: Can be dangerous if misused, and can confuse people to an extent..]
[more verbiage]
None.
void XaSet(XaAudio connection, XaTag object, ...);
XaSet copies resource values in the argument list into the corresponding named attributes in the object whose reference is object. Any applicable event handlers that have been defined on any of the attributes changed by XaSet are activated. [more verbiage on event handling]
XaSet treats the provided resource data as name-value pairs. The exceptions to this rule are when the resource name is one of the following constants:
[ We have discussed timed sets/gets, in which the caller would specify an absolute or relative time at which a change is to occur. No consensus has been reached on this. ]
The last entry in the parameter list must be a name entry containing NULL.
[Async operation?]
typedef (*XaGetReplyFunc)(XaAudio connection, XaTag object, XaArgList *returnValues, void *callbackData);
void[?] XaGet(XaAudio connection, XaTag object, XaGetReplyFunc callbackFunc, void *callbackData, ...);
XaGet queries the server for the values of one or more attributes of the object referenced by object. The values are then copied into return pointers whose addresses are provided by the caller (for synchronous requests) and/or into an XaArgList which is then passed to a callback function (for asynchronous requests).
XaGet treats the provided request data as name-address pairs, where pointers each are expected to point to 32-bit values. The exceptions to this rule are when the resource name is one of the following constants:
#define XA_MAX_DIMENSIONS 6
struct XaArrayExtents
{
XaUint32 dimensions[XA_MAX_DIMENSIONS];
/* size of each dimension */
};
typedef struct XaArrayExtents XaArrayExtents;
The last entry in the parameter list must be a name entry containing NULL.
If callbackFunc is NULL, XaGet returns in each return pointer the value to the corresponding attribute name according to the rules described above.
If callbackFunc is non-NULL, then XaGet operates asynchronously, returning immediately to the caller. When the XaGet request completes, callbackFunc will be called with four parameters: the audio connection handle, the tag of the object from which values were requested, a pointer to an XaArgList (returnValues) containing returned values from the XaGet call, and the utility pointer callbackData originally passed to XaGet. The returnValues structure contains the names and appropriate pointers that were supplied in the initial XaGet call; use XaArgListGet to retrieve individual values from this array. When XaGet operates asynchronously, the contents of the memory pointed to by the return pointers are undefined at return time; they are filled in by the time callbackFunc is called.
[When passing a preallocated array into an asynchronous XaGet call, and the array is not reallocated to receive a larger array, whether the callback function receives the originally supplied array when XaArgListGet is called is undefined. A note should be made here to the effect that the XaArgListGet may not operate uniformly in this case, since the client app need not free arrays retrieved under these circumstances. Thoughts?]
typedef void (*XaReadReplyFunc)(XaAudio connection, XaTime start, XaTime end, XaTag referenceTime, XaUint32 numBits, CARD8 leftPad, char *returnBuff, void *handlerData);
void XaRead(XaAudio connection, XaTag port, XaTime atTime, XaTag referenceTime, XaUint32 minBits, XaUint32 maxBits, char **buff, XaUint32 *bitsReturned, INT8 *leftPad, XaReadReplyFunc callback, void *callbackData);
XaRead reads data from an input port in the audio server. At least minBits and at most maxBits are read from the port, beginning at the time specified by the atTime and referenceTime parameters. [See the Programmer's Guide for more information on the use of these parameters.]
If the port is not an input port (i.e. if the port's inputBuffer attribute is set to a value other than XaTnone), XaRead will return an empty buffer.
[who allocates, who frees the audio data? If we're passing a handle to buff, that implies that the library allocates it; however, the client app has enough knowledge about buffer size to do the allocation. Perhaps make the client app allocate the buffer and pass it as a char *, then use the same buffer in the callback function?]
[info about async execution and XaFinish]
[info about return values and what they mean]
void XaWrite(XaAudio connection, XaTag port, XaTime atTime, XaTag referenceTime, XaUint32 *numBits, char *buff, CARD8 leftPad);
XaWrite writes data to a port in the audio server beginning at the specified time.
[info about the client data device needing to be designated as a source of data in the server, etc.]
[info about how to specify count parameters, how a 0 and nonzero value are interpreted, etc.]
[do we want to let XaWrite execute asynchronously? We could do this by calling an "asynchronous XaPing" within the XaWrite call.]
[info about return values and what they mean]
XaBoolean XaPending(void);
XaBoolean XaProcessNextEvent(XaAudio connection, XaBoolean wait);
void XaMainLoop(XaAudio connection);
void XaXtProcessEvents(XtPointer connection, int *fd, XtInputId *id);
The XaPending function returns a nonzero result if events have been received by the server for processing.
The XaProcessEvent function reads the next event, error, reply, or other input message in the event queue and processes it. If no events are pending and wait is XaTrue, execution blocks until an event is received by the client application for processing. XaProcessEvent returns XaTrue if an event was processed, or XaFalse if wait is false and no event was found.
The XaMainLoop function checks for and dispatches incoming Xt or Xa events by calling XaProcessEvent. This constitutes the main loop of X Audio applications, and, as such, it does not return. Applications are expected to exit in response to some user action. There is nothing special about XaMainLoop; it is simply an infinite loop that calls XaProcessEvent. Applications can provide their own version of this loop, which tests some global termination flag or (for applications that also use the Xt toolkit) tests that the number of top-level widgets is larger than zero before circling back to the call to XaProcessEvent.
The XaXtProcessEvents function is for use by Xt applications as a source for X Audio input events [description of what parameters to pass to XtAppAddInput]
void XaPushErrorHandler(XaAudio connection, XaErrorHandlerFunc handlerFunc, void *handlerData);
void XaPopErrorHandler(XaAudio connection, XaErrorHandlerFunc handlerFunc);
XaPushErrorHandler and XaPopErrorHandler manage a stack of error handler routines that exist on the connection object. [more text to come...]
#include <Xa/Xalib.h>
A Connection object is never directly instantiated, but is created by calling XaOpenAudio. The Connection object
#include <Xa/Xalib.h>
An EventHandler object is a client-side object which sends events to the client based on a specified change in one or more other objects in the client or the server.
EventHandler inherits behavior and attributes from Object.
The class name constant is XaCeventHandler, and is defined to be the string "EventHandler".
See the intro man page for a description of the attribute table format.
---------------------------------------------------------- | Name | Type | Default | Access | ========================================================== | XaNhandlerFunc | XaArgVal | NULL | CSG | ---------------------------------------------------------- | XaNhandlerData | XaArgVal | NULL | CSG | ---------------------------------------------------------- | XaNactive | BOOL | XaFalse | CSG | ---------------------------------------------------------- | XaNeventType | EVENTTYPE | XaAchange | CG | ---------------------------------------------------------- | XaNtargetObject | TAG | XaTnone | CSG | ---------------------------------------------------------- | XaNmonAttributes | TAG[c] | XaTnone | CSG | ---------------------------------------------------------- | XaNalarms | TAG[c] | XaTnone | CSG | ---------------------------------------------------------- | XaNconditions | TAG[c] | XaTnone | CSG | ---------------------------------------------------------- | XaNretAttributes | TAG[c] | XaTnone | CSG | ----------------------------------------------------------
A pointer to the function to be called when the event handler's conditions are met. The signature of this function is:
void (*XaEventHandlerCallbackFunc)(XaAudio connection, XaTag callingEventHandler, XaTag eventTag, void *handlerData);
connection refers to the audio server connection from which the event was received. callingEventHandler is the tag of the event handler which caused the callback function to be called. The eventTag parameter points to the actual event received by the client. handlerData is the value of the XaNhandlerData attribute of the event handler object.
A pointer to be passed as the handlerData parameter to XaNhandlerFunc (see above) when it is called.
A flag indicating whether the event handler (and associated objects) will send and dispatch events for processing.
The type of event being monitored by this event handler. Possible values are XaAchange, XaAcreate, and XaAdelete.
Specifies the tag of the object to monitor for changes. If the event monitor is watching for change events (XaAchange), XaNtargetObject contains the tag of the object which is being watched for changes.
If the event monitor is watching for create events (XaAcreate), XaNtargetObject should contain either the atom of a class name, or the tag of a class object. When a client-visible object is created of the target class (or of a subclass of the target class), a create event will be sent to the client. If a create event handler is given a target object which is not a class object, an error is reported.
If the event monitor is watching for delete events (XaAdelete), the target object may be either the tag of a specific instance of an object (as with change events) or the atom or tag of a class object. In the latter case, delete events will be reported when a client-visible object is destroyed whose class is the same or a subclass of the target class.
Specifies a collection of tags of attributes to be monitored. If any of these attributes change in any way on the target object, an event is generated.
Specifies a collection of alarm objects. An alarm object contains an attribute and specified conditions under which a change in that attribute causes an event to be sent. See the Alarm man page for more information.
Specifies a collection of condition objects which, if met, cause a previously generated event to be sent to and/or dispatched in the client.
Specifies a collection of tags of the target object's attributes to be sent when an event is generated.
See the "Core Class" section of the protocol specification for a more detailed list and description of the inherited attributes of EventHandler.
condition object to use when monitoring client-side objects
#include <Xa/Xalib.h>
[ClientCondition class desc]
ClientCondition inherits behavior and attributes from [Object?].
The class name constant is XaCclientCondition, and is defined to be the string "ClientCondition".
See the intro man page for a description of the attribute table format.
------------------------------------------------------------- | Name | Type | Default | Access | ============================================================= | [attr name] | [attr type] | [attr default] | [access] | -------------------------------------------------------------
[attribute desc]
See the "Core Class" section of the protocol specification for a more detailed list and description of the inherited attributes of ClientCondition.
an audio file
#include <Xa/Xalib.h>
[File class desc]
File inherits behavior and attributes from [Object?].
The class name constant is XaCfile, and is defined to be the string "File".
See the intro man page for a description of the attribute table format.
------------------------------------------------------------- | Name | Type | Default | Access | ============================================================= | [attr name] | [attr type] | [attr default] | [access] | -------------------------------------------------------------
[attribute desc]
See the "Core Class" section of the protocol specification for a more detailed list and description of the inherited attributes of File.
#include <Xa/Xalib.h>
[Player class desc]
Player inherits behavior and attributes from [Object?].
The class name constant is XaCplayer, and is defined to be the string "Player".
See the intro man page for a description of the attribute table format.
------------------------------------------------------------- | Name | Type | Default | Access | ============================================================= | [attr name] | [attr type] | [attr default] | [access] | -------------------------------------------------------------
[attribute desc]
See the "Core Class" section of the protocol specification for a more detailed list and description of the inherited attributes of Player.
#include <Xa/Xalib.h>
[Recorder class desc]
Recorder inherits behavior and attributes from [Object?].
The class name constant is XaCrecorder, and is defined to be the string "Recorder".
See the intro man page for a description of the attribute table format.
------------------------------------------------------------- | Name | Type | Default | Access | ============================================================= | [attr name] | [attr type] | [attr default] | [access] | -------------------------------------------------------------
[attribute desc]
See the "Core Class" section of the protocol specification for a more detailed list and description of the inherited attributes of Recorder.