[linux-audio-dev] LAAGA 0.1.0 tarball available

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] LAAGA 0.1.0 tarball available
From: Paul Davis (pbd_AT_Op.Net)
Date: Sat Jun 30 2001 - 20:06:54 EEST


    http://www.op.net/~pbd/laaga-0.1.0.tar.gz (130kB)

WHAT IS LAAGA?
--------------

LAAGA is a library and a server application designed to provide
developers of applications using streaming media (audio, video, MIDI,
etc.) with an API that:

      1) is simple, robust and portable
      2) fully supports low-latency "real time" operation
             (e.g. audio I/O latencies in the sub-5msec range)
      3) provides inter-application sharing of any kind
            of data
      4) allows sharing of an audio interface (this goal
            is not considered particularly important but
            emerges naturally from the design of the system)

A LAAGA system consists of a server application, and a series of
clients that read and/or write data. Clients may be standalone
applications that use the library to communicate with the server, or
they may be dynamically loaded "plugins" that run within the address
space and execution context of the server. Clients can register (at
any time) an arbitrary number of arbitrarily typed "ports" where they
can read and write data. Data is delivered to ports simply by writing
to memory areas accessed via the library. Any port within a running
LAAGA system can be connected to any other port of the same type and
appropriate polarity.

The design of the LAAGA server fully supports low latency operation,
allowing a number of applications to be run in complete sample
synchronization as well as share data in an environment providing
sub-5msec I/O latency.

LAAGA also removes all responsibility from client applications for
dealing with audio interface h/w. This is the task of a specialized
client (typically called the "driver" of the server), and no other
client deals with any of the concepts typically associated with audio
h/w.

Instead, LAAGA clients merely provide callback functions that will be
executed "at the right" time by the library. They do not open audio
interfaces, configure them in any way, or concern them with details
like sample format, interleaving, etc.

LAAGA ports may be used to move arbitrary data types between
clients. There is currently one builtin data type, "32 bit float mono
audio". Other port types may be created on an ad-hoc basis by clients,
and ports of those types may be connected together just as with
builtin types.

LAAGA only supports clients running on the same host as the server.

CHANGES (since last "audioengine" release)
------------------------------------------

     * name change everywhere to "laaga"
     * support for non-audio port types (untested, but probably implemented)
     * support for client-side multi-input mixdown (of any data type
          that we have the code to mix down for)
     * removal of PortIsMulti flag; if port type supports mixdown,
          multiple input connections are always legal; otherwise,
          they are always illegal.
     * better client/server communication model, appears
         to provide for clean handling of client shutdown under
         all (most) circumstances
     * port names are now always the "full name"
     * laaga_port_tie() now works for client who want
         to hard-wire their output ports to their input ports

Enclosed below is the client-side API header file for people who want
to see the API rather than look at the implementation. I also plan to
try and draw some diagrams soon to show the design.

There is still work to be done on how to create in-process clients.
However, they are already supported once created - the ALSA-driver is
both a driver and an in-process client, but it uses a different method
to create its "client-ness", since its already been dynamically loaded
by the engine anyway (so no further call to dlopen() is needed nor
makes sense)

Other items still to do:

    * more work on support for non-audio ports
    * figure out how to reliably get the server to exit
    * an RT-friendly pool-based memory allocator
    * what to do if we run out of ports?

Comments, bug reports, ideas welcome.

**********************************************************************
With this release, it is my belief that this implementation represents
a genuine, workable, can-be-made-totally-reliable example of a system
that meets all the goals laid out by Kai for LAAGA. In fact, I can't
help note that its remarkably close to the goals of MAIA as well.
**********************************************************************

--p

/*
    Copyright (C) 2001 Paul Davis
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id$
*/

#ifndef __laaga_h__
#define __laaga_h__

#include <glib.h>
#include <laaga/types.h>
#include <laaga/port.h>
#include <laaga/error.h>

/* a client calls this function to initiate use of LAAGA.
   The callback arguments will be called as follows:

   process: whenever the LAAGA server decides that audio data
            is available, this callback will be executed
            with the number of frames of audio data to be
            generated/captured passed as its argument.
            
   buffer_size: called whenever the laaga decides
                to change the maximum size of the argument
                that could be passed to the process callback.
                this will also be called once during the execution
                of laaga_open().

   sample_rate: called whenever the laaga changes the
                sample rate of the output device. this will
                also be called once during the execution of
                laaga_open().

   The buffer size and sample rate callbacks are guaranteed
   to be called synchronously and single-threaded with
   respect to the calling of the "process" callback. that is,
   the code executed by these callbacks need not meet RT
   constraints, and it does need to use synchronization primitives
   to avoid problems with the process callback.

   Any or all of the callbacks may be passed as NULL to indicate
   that the client does not wish to be notified of the relevant
   event/condition.
*/

laaga_client_t *
laaga_client_new (const char *client_name,
                  LaagaProcessCallback, void *process_arg,
                  LaagaBufferSizeCallback, void *bufsize_arg,
                  LaagaSampleRateCallback, void *srate_arg);

/* this shuts down the connection between the engine and the client */

int laaga_client_close (laaga_client_t *client);

/* call this to start this client running after a successful
   call to laaga_open().
*/

int laaga_activate (laaga_client_t *client);

/* call this to (temporarily) stop execution of this client.
   this will fail if the client has any existing connections
   in which it acts as the source. laaga_activate()
   will restart this client.
*/

int laaga_deactivate (laaga_client_t *client);

/* this creates a new port for the client.

   a port is an object used for moving data in or out of the client.
   the data may be of any type. ports may be connected to each other
   in various ways.

   a port has a short name, which may be any non-NULL and non-zero
   length string, and is passed as the first argument. a port's full
   name is the name of the client concatenated with a colon (:) and
   then its short name.

   a port has a type, which may be any non-NULL and non-zero length
   string, and is passed as the second argument. for types that are
   not built into the laaga API (currently just
   LAAGA_DEFAULT_AUDIO_TYPE) the client MUST supply a non-zero
   size for the buffer as the fourth argument. for builtin types, the
   fourth argument is ignored.

   a port has a set of flags, enumerated below and passed as the third
   argument in the form of a bitmask created by AND-ing together the
   desired flags. the flags "IsInput" and "IsOutput" are mutually
   exclusive and it is an error to use them both.

*/

enum PortFlags {
    PortIsInput = 0x1,
    PortIsOutput = 0x2,
    PortIsPhysical = 0x4 /* refers to a physical connection */
};

#define LAAGA_DEFAULT_AUDIO_TYPE "32 bit float mono audio"

laaga_port_t *
laaga_port_register (laaga_client_t *,
                     const char *port_name,
                     const char *port_type,
                     unsigned long flags,
                     unsigned long buffer_size);

/* this removes the port from the client */

int laaga_port_unregister (laaga_client_t *, laaga_port_t *);

/* This returns a pointer to the memory area associated with the
   specified port. It can only be called from within the client's
   "process" callback. For an output port, it will be a memory area
   that can be written to; for an input port, it will be an area
   containing the data from the port's connection(s), or
   zero-filled. if there are multiple inbound connections, the data
   will be mixed appropriately.
*/

void *laaga_port_get_buffer (laaga_port_t *, nframes_t);

/* these two functions establish and disestablish a connection
   between two ports. when a connection exists, data written
   to the source port will be available to be read at the destination
   port.

   the types of both ports must be identical to establish a connection.

   the flags of the source port must include PortIsOutput.
   the flags of the destination port must include PortIsInput.
*/

int laaga_port_connect (laaga_client_t *,
                        const char *source_port,
                        const char *destination_port);

int laaga_port_disconnect (laaga_client_t *,
                           const char *source_port,
                           const char *destination_port);

/* A client may call this on a pair of its own ports to
   semi-permanently wire them together. This means that
   a client that wants to direct-wire an input port to
   an output port can call this and then no longer
   have to worry about moving data between them. Any data
   arriving at the input port will appear automatically
   at the output port.

   The `destination' port must be an output port. The `source'
   port must be an input port. Both ports must belong to
   the same client. You cannot use this to tie ports between
   clients. Thats what a connection is for.
*/

int laaga_port_tie (laaga_port_t *dst, laaga_port_t *src);

/* This undoes the effect of laaga_port_tie(). The port
   should be same as the `destination' port passed to
   laaga_port_tie().
*/

int laaga_port_untie (laaga_port_t *port);

/* a client may call this function to prevent other objects
   from changing the connection status of the named port.
*/

int laaga_port_lock (laaga_client_t *, laaga_port_t *);
int laaga_port_unlock (laaga_client_t *, laaga_port_t *);

/* this returns the sample rate of the laaga */

unsigned long laaga_get_sample_rate (laaga_client_t *);

/* this returns the current maximum size that will
   ever be passed to the "process" callback. it should only
   be used *before* the client has been activated.
*/

unsigned long laaga_get_buffer_size (laaga_client_t *);

/* This function returns a list of ports that match the specified
   arguments.
   
   port_name_pattern: a regular expression used to select ports by name.
                      if NULL or of zero length, no selection based on
                      name will be carried out.

   type_name_pattern: a regular expression used to select ports by type.
                      if NULL or of zero length, no selection based on
                      type will be carried out.

   flags: a value used to select ports by their flags. if
                      zero, no selection based on flags will be carried out.
*/

GSList *laaga_get_ports (laaga_client_t *,
                         const char *port_name_pattern,
                         const char *type_name_pattern,
                         unsigned long flags);

/* If a client is told to become the timebase for the entire system,
   it calls this function. If it returns zero, then the client has
   the responsibility to call laaga_update_time() at the end
   of its process() callback. Whatever time it provides (in frames
   since its reference zero time) becomes the current timebase
   for the entire system.
*/

int laaga_engine_takeover_timebase (laaga_client_t *);
void laaga_update_time (laaga_client_t *, nframes_t);

void laaga_listen_for_ports (laaga_client_t *, LaagaPortRegistrationCallback, void *);

#endif /* __laaga_h__ */


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Sat Jun 30 2001 - 20:08:38 EEST