Logo Search packages:      
Sourcecode: nas version File versions  Download package

auinfo.c

/*
 * Copyright 1993 Network Computing Devices, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name Network Computing Devices, Inc. not be
 * used in advertising or publicity pertaining to distribution of this 
 * software without specific, written prior permission.
 * 
 * THIS SOFTWARE IS PROVIDED 'AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
 * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
 * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
 * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
 * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
 * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * Author:  Jim Fulton <jim@ncd.com>
 *          Network Computing Devices
 * 
 * $NCDId: @(#)auinfo.c,v 1.14 1994/04/07 18:20:41 greg Exp $
 */

#include <stdio.h>
#include <string.h>
#include <audio/audiolib.h>

char *ProgramName;

#if NeedFunctionPrototypes
#define PROTO(list) list
#else
#define PROTO(list) ()
#endif

#ifdef __STDC__                         /* string concat macros */
#define STRCONCAT(a,b) a##b
#define STRCONCAT3(a,b,c) a##b##c
#define STRSTRINGIFY(a) #a
#else
#define STRCONCAT(a,b) a/**/b
#define STRCONCAT3(a,b,c) a/**/b/**/c
#define STRSTRINGIFY(a) "a"
#endif

static void print_formats PROTO((AuServer *));
static void print_devices PROTO((AuServer *));
static void print_server_buckets PROTO((AuServer *));
static void print_client_buckets PROTO((AuServer *));
static void print_elem_types PROTO((AuServer *));
static void print_wave_forms PROTO((AuServer *));
static void print_actions PROTO((AuServer *));

static int maxwidth = 0;            /* reset later */
#define TITLELEN 24
static _AuConst char *TITLEFMT = "%-24s";
#define INDENTPADSTR "    "
#define INDENTPADLEN (sizeof(INDENTPADSTR) - 1)
static _AuConst char *INDENTPAD = INDENTPADSTR;

int
main (argc, argv)
    int argc;
    char **argv;
{
    int i;
    char *audioname = NULL;
    AuServer *aud;
    char *msg = NULL;

    ProgramName = argv[0];

    for (i = 1; i < argc; i++) {
      char *arg = argv[i];

      if (arg[0] == '-') {
          switch (arg[1]) {
            case 'a':               /* -audio server */
            if (++i >= argc) goto usage;
            audioname = argv[i];
            continue;
            case 'w':               /* -width num */
            if (++i >= argc) goto usage;
            maxwidth = atoi (argv[i]);
            continue;
          }
      }
      usage:
      fprintf (stderr, "usage:  %s [-audio server] [-width num]\n",
             ProgramName);
      exit (1);
    }

    if (maxwidth < INDENTPADLEN)
      maxwidth = 79;

    aud = AuOpenServer (audioname, 0, NULL, 0, NULL, &msg);
    if (!aud) {
      fprintf (stderr, "%s:  unable to connect to audio server\n",
             ProgramName);
      exit (1);
    }

    printf (TITLEFMT, "Audio Server:");
    printf ("%s\n", AuServerString(aud));
    printf (TITLEFMT, "Version Number:");
    printf ("%d.%d\n", AuServerProtocolMajorVersion(aud),
                   AuServerProtocolMinorVersion(aud));
    printf (TITLEFMT, "Vendor:");
    printf ("%s\n", AuServerVendor(aud));
    printf (TITLEFMT, "Vendor Release:");
    printf ("%d\n", AuServerVendorRelease(aud));
    printf (TITLEFMT, "Min Sample Rate:");
    printf ("%d\n", AuServerMinSampleRate(aud));
    printf (TITLEFMT, "Max Sample Rate:");
    printf ("%d\n", AuServerMaxSampleRate(aud));
    printf (TITLEFMT, "Max Tracks:");
    printf ("%d\n", AuServerMaxTracks(aud));
    printf (TITLEFMT, "Number of Formats:");
    printf ("%d\n", AuServerNumFormats(aud));
    print_formats (aud);
    printf (TITLEFMT, "Number of Elem Types:");
    printf ("%d\n", AuServerNumElementTypes(aud));
    print_elem_types (aud);
    printf (TITLEFMT, "Number of Wave Forms:");
    printf ("%d\n", AuServerNumWaveForms(aud));
    print_wave_forms (aud);
    printf (TITLEFMT, "Number of Actions:");
    printf ("%d\n", AuServerNumActions(aud));
    print_actions (aud);
    printf (TITLEFMT, "Number of Devices:");
    printf ("%d\n", AuServerNumDevices(aud));
    print_devices (aud);
    printf (TITLEFMT, "Number of Buckets:");
    printf ("%d\n", AuServerNumBuckets(aud));
    print_server_buckets (aud);
    print_client_buckets (aud);
    AuCloseServer (aud);
    exit (0);
}

typedef struct _nametable {
    int value;
    _AuConst char *name;
    int len;
} NameTable;

/*
 * Warning: you must not put any spaces between the , and the "what" value
 * when invoking the following macro.  Otherwise you will screw up the
 * string concatenation.
 */
#define MAKEENTRY(prefix,what) { STRCONCAT(prefix,what), STRSTRINGIFY(what), \
                             sizeof(STRSTRINGIFY(what)) - 1 }
#define MBITENTRY(prefix,what) { STRCONCAT3(prefix,what,Mask), \
                             STRSTRINGIFY(what), \
                             sizeof(STRSTRINGIFY(what)) - 1 }
#define NENTRIES(tab) (sizeof((tab))/sizeof((tab)[0]))

static NameTable _nt_formats[] = {
    MAKEENTRY (AuFormat,ULAW8),           /* no spaces allowed in macro */
    MAKEENTRY (AuFormat,LinearUnsigned8),
    MAKEENTRY (AuFormat,LinearSigned8),
    MAKEENTRY (AuFormat,LinearSigned16MSB),
    MAKEENTRY (AuFormat,LinearUnsigned16MSB),
    MAKEENTRY (AuFormat,LinearSigned16LSB),
    MAKEENTRY (AuFormat,LinearUnsigned16LSB),
};

static NameTable _nt_elemtypes[] = {
    MAKEENTRY (AuElementType,ImportClient),
    MAKEENTRY (AuElementType,ImportDevice),
    MAKEENTRY (AuElementType,ImportBucket),
    MAKEENTRY (AuElementType,ImportWaveForm),
    MAKEENTRY (AuElementType,ImportRadio),
    MAKEENTRY (AuElementType,Bundle),
    MAKEENTRY (AuElementType,MultiplyConstant),
    MAKEENTRY (AuElementType,AddConstant),
    MAKEENTRY (AuElementType,Sum),
    MAKEENTRY (AuElementType,ExportClient),
    MAKEENTRY (AuElementType,ExportDevice),
    MAKEENTRY (AuElementType,ExportBucket),
    MAKEENTRY (AuElementType,ExportRadio),
    MAKEENTRY (AuElementType,ExportMonitor),
};

static NameTable _nt_waveforms[] = {
    MAKEENTRY (AuWaveForm,Square),
    MAKEENTRY (AuWaveForm,Sine),
    MAKEENTRY (AuWaveForm,Saw),
    MAKEENTRY (AuWaveForm,Constant),
};

static NameTable _nt_actions[] = {
    MAKEENTRY (AuElementAction,ChangeState),
    MAKEENTRY (AuElementAction,SendNotify),
    MAKEENTRY (AuElementAction,Noop),
};

static NameTable _nt_devicechangables[] = {
    MBITENTRY (AuCompCommon,ID),
    MBITENTRY (AuCompCommon,Kind),
    MBITENTRY (AuCompCommon,Use),
    MBITENTRY (AuCompCommon,Format),
    MBITENTRY (AuCompCommon,NumTracks),
    MBITENTRY (AuCompCommon,Access),
    MBITENTRY (AuCompCommon,Description),

    MBITENTRY (AuCompDevice,MinSampleRate),
    MBITENTRY (AuCompDevice,MaxSampleRate),
    MBITENTRY (AuCompDevice,Location),
    MBITENTRY (AuCompDevice,Gain),
    MBITENTRY (AuCompDevice,LineMode),
    MBITENTRY (AuCompDevice,Children),
};


static NameTable _nt_compkinds[] = {
    MAKEENTRY (AuComponentKind,PhysicalInput),
    MAKEENTRY (AuComponentKind,PhysicalOutput),
    MAKEENTRY (AuComponentKind,Bucket),
    MAKEENTRY (AuComponentKind,Radio),
    MAKEENTRY (AuComponentKind,PhysicalFeedback),
};


static NameTable _nt_uses[] = {
    MBITENTRY (AuComponentUse,Import),
    MBITENTRY (AuComponentUse,Export),
};

static NameTable _nt_accesses[] = {
    MBITENTRY (AuAccess,Import),
    MBITENTRY (AuAccess,Export),
    MBITENTRY (AuAccess,Destroy),
    MBITENTRY (AuAccess,List),
};

static NameTable _nt_locations[] = {
    MBITENTRY (AuDeviceLocation,Left),
    MBITENTRY (AuDeviceLocation,Center),
    MBITENTRY (AuDeviceLocation,Right),
    MBITENTRY (AuDeviceLocation,Top),
    MBITENTRY (AuDeviceLocation,Middle),
    MBITENTRY (AuDeviceLocation,Bottom),
    MBITENTRY (AuDeviceLocation,Back),
    MBITENTRY (AuDeviceLocation,Front),
    MBITENTRY (AuDeviceLocation,Internal),
    MBITENTRY (AuDeviceLocation,External),
};

static NameTable _nt_linemodes[] = {
    MAKEENTRY (AuDeviceLineMode,None),
    MAKEENTRY (AuDeviceLineMode,Low),
    MAKEENTRY (AuDeviceLineMode,High),
};

#define TA_NONE         0
#define TA_INDIVIDUAL   1
#define TA_ALL          2

#define TEXT_ALIGNMENT  TA_NONE

#if TEXT_ALIGNMENT == TA_INDIVIDUAL
#define ROUNDUP(n) ((((n) + 7) >> 3) << 3)
static int _table_maxlen (tab, nents)
    register NameTable *tab;
    register int nents;
{
    register int m = 0;

    while (nents > 0) {
      if (tab->len > m)
          m = tab->len;
      nents--;
      tab++;
    }
    return m;
}
#endif

#if TEXT_ALIGNMENT == TA_ALL
#define ALL_COLUMN_WIDTH 24
#endif

static NameTable *_lookup_name (tab, nents, val, isbit)
    register NameTable *tab;
    register int nents;
    register int val;
    register AuBool isbit;          /* use bit compare instead of equal? */
{
    static NameTable nttmp;
    static char tmpbuf[20];

    if (isbit && !val)
      return (NameTable *) 0;

    while (nents > 0) {
      if (isbit ? (tab->value & val) : (tab->value == val))
          return tab;
      nents--;
      tab++;
    }
    if (isbit)
      return (NameTable *) 0;

    sprintf (tmpbuf, (isbit ? "0x%lx" : "%d"), val);
    nttmp.value = val;
    nttmp.name = tmpbuf;
    nttmp.len = strlen (tmpbuf);
    return &nttmp;
}


static void _print_names (aud, tab, nents, title, total, getvaliter, p, isbit)
    AuServer *aud;
    NameTable *tab;
    int nents;
    _AuConst char *title;
    int total;
    int (*getvaliter) PROTO((AuServer *, int, AuPointer));
    AuPointer p;
    AuBool isbit;
{
    int i;
    char fmt[20];
    int col;
#if TEXT_ALIGNMENT == TA_NONE
    int move;
#endif
#if TEXT_ALIGNMENT == TA_INDIVIDUAL
    int maxlen = _table_maxlen (tab, nents);
    int move = ROUNDUP(maxlen);

    if (move == maxlen)
      move += 8;
#endif
#if TEXT_ALIGNMENT == TA_ALL
    int move = ALL_COLUMN_WIDTH;
#endif

    if (total < 1)
      return;

    printf (TITLEFMT, title);
    col = TITLELEN;
#if TEXT_ALIGNMENT == TA_NONE
    strcpy (fmt, "%s  ");
#define TAPAD 2
#else
    sprintf (fmt, "%%-%ds", move);  /* reset for moving */
#endif

    for (i = 0; i < total; i++) {
      int val = (*getvaliter) (aud, i, p);
      NameTable *nt = _lookup_name (tab, nents, val, isbit);
      _AuConst char *f = fmt;

      if (!nt)
          continue;

#if TEXT_ALIGNMENT == TA_NONE
      move = nt->len + TAPAD;
#endif

      if (col != TITLELEN) {
          if (col + nt->len > maxwidth) {
            printf ("\n");
            printf (TITLEFMT, "");
            col = TITLELEN;
          } else if (col + move > maxwidth) {
            f = "%s";
          }
      }
      printf (f, nt->name);
      col += move;
      if (col > maxwidth) {
          printf ("\n");
          printf (TITLEFMT, "");
          col = TITLELEN;
      }
    }
    printf ("\n");
}


/* ARGSUSED2 */
static int _get_format (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return AuServerFormat (aud, i);
}

static void print_formats (aud)
    AuServer *aud;
{
    _print_names (aud, _nt_formats, NENTRIES(_nt_formats), 
              "Formats:", AuServerNumFormats(aud), _get_format, 
              NULL, AuFalse);
}

/* ARGSUSED */
static int _get_use (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return (1 << i) & AuCommonUse ((AuCommonPart *) p);
}

/* ARGSUSED */
static int _get_access (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return (1 << i) & AuCommonAccess ((AuCommonPart *) p);
}

static void print_comp (aud, c)
    AuServer *aud;
    register AuCommonPart *c;
{
    register AuMask vmask = AuCommonValueMask (c);

    if (vmask & AuCompCommonIDMask)
      printf ("%s    ID:             0x%lx\n", INDENTPAD,
            AuCommonIdentifier(c));
    if (vmask & AuCompCommonKindMask) {
      NameTable *nt = _lookup_name (_nt_compkinds, NENTRIES(_nt_compkinds),
                              AuCommonKind(c), AuFalse);
      printf ("%s    Kind:           %s\n", INDENTPAD, nt->name);
    }
    if (vmask & AuCompCommonUseMask) 
      _print_names (aud, _nt_uses, NENTRIES(_nt_uses),
                  "        Use:", NENTRIES(_nt_uses), _get_use,
                  (AuPointer) c, AuTrue);
    if (vmask & AuCompCommonFormatMask) {
      NameTable *nt = _lookup_name (_nt_formats, NENTRIES(_nt_formats),
                              AuCommonFormat(c), AuFalse);
      printf ("%s    Format:         %s\n", INDENTPAD, nt->name);
    }
    if (vmask & AuCompCommonNumTracksMask)
      printf ("%s    Num Tracks:     %d\n", INDENTPAD, AuCommonNumTracks(c));
    if (vmask & AuCompCommonAccessMask)
      _print_names (aud, _nt_accesses, NENTRIES(_nt_accesses),
                  "        Access:", NENTRIES(_nt_accesses), _get_access,
                  (AuPointer) c, AuTrue);
    if (vmask & AuCompCommonDescriptionMask)
      printf ("%s    Description:    \"%s\"\n", INDENTPAD, 
            (AuCommonDescription(c)->data ? AuCommonDescription(c)->data :
             ""));
}


/* ARGSUSED */
static int _get_devicechangables (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return (1 << i) & AuDeviceChangableMask((AuDeviceAttributes *) p);
}

/* ARGSUSED */
static int _get_locations (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return (1 << i) & AuDeviceLocation ((AuDeviceAttributes *) p);
}


static void print_device (aud, d)
    AuServer *aud;
    AuDeviceAttributes *d;
{
    AuMask vmask = AuDeviceValueMask (d);

    if (AuDeviceChangableMask(d))
      _print_names (aud, _nt_devicechangables,
                  NENTRIES(_nt_devicechangables),
                  "        Changable:", 32,
                  _get_devicechangables, (AuPointer) d, AuTrue);
    print_comp (aud, &d->common);

    if (vmask & AuCompDeviceMinSampleRateMask)
      printf ("%s    Min Rate:       %d\n", INDENTPAD,
            AuDeviceMinSampleRate(d));
    if (vmask & AuCompDeviceMaxSampleRateMask)
      printf ("%s    Max Rate:       %d\n", INDENTPAD,
            AuDeviceMaxSampleRate(d));
    if (vmask & AuCompDeviceLocationMask)
      _print_names (aud, _nt_locations, NENTRIES(_nt_locations),
                  "        Location:", NENTRIES(_nt_locations),
                  _get_locations, (AuPointer) d, AuTrue);
    if (vmask & AuCompDeviceGainMask)
      printf ("%s    Gain Percent:   %d\n", INDENTPAD,
            AuFixedPointRoundDown(AuDeviceGain(d)));
    if (vmask & AuCompDeviceLineModeMask) {
      NameTable *nt = _lookup_name (_nt_linemodes, NENTRIES(_nt_linemodes),
                              AuDeviceLineMode(d), AuFalse);
      printf ("%s    Line Mode:      %s\n", INDENTPAD, nt->name);
    }
    if (vmask & AuCompDeviceChildrenMask) {
      int i;
      AuDeviceID *kids = AuDeviceChildren(d);

      printf ("%s    Num Children:   %d\n", INDENTPAD,
            AuDeviceNumChildren(d));
      if (AuDeviceNumChildren(d) > 0) {
          printf ("%s    Children:       ", INDENTPAD);
          for (i = 0; i < AuDeviceNumChildren(d); i++)
            printf ("0x%lx ", kids[i]);
          printf ("\n");
      }
    }
}

static void print_devices (aud)
    AuServer *aud;
{

    int i;

    for (i = 0; i < AuServerNumDevices(aud); i++) {
      printf ("%sDevice %d:\n", INDENTPAD, i);
      print_device (aud, AuServerDevice(aud,i));
    }
}

static void
print_bucket(aud, ba)
    AuServer      *aud;
    AuBucketAttributes  *ba;
{
    AuMask vmask = AuBucketValueMask (ba);

    print_comp(aud, &ba->common);
    if (vmask & AuCompBucketSampleRateMask)
      printf ("%s    Sample Rate:    %d\n", INDENTPAD,
            AuBucketSampleRate(ba));
    if (vmask & AuCompBucketNumSamplesMask)
      printf ("%s    Num Samples:    %d\n", INDENTPAD,
            AuBucketNumSamples(ba));
}


static void print_server_buckets (aud)
    AuServer *aud;
{
    int i;

    for (i = 0; i < AuServerNumBuckets(aud); i++) {
      printf("%sBucket %d:\n", INDENTPAD, i);
      print_bucket (aud, AuServerBucket(aud, i));
    }
}


static void print_client_buckets (aud)
    AuServer *aud;
{
    int     num, i;
    AuBucketAttributes  *bas;
    AuBool first = AuTrue;

    bas = AuListBuckets(aud, AuNone, NULL, &num, NULL);

    for (i = 0; i < num; i++) {
      if (AuClientOfID(aud, AuBucketIdentifier(&bas[i])))
      {
          if (first)
          {
            printf("Client Buckets:\n");
            first = AuFalse;
          }
          else
            printf("\n");
          print_bucket (aud, &bas[i]);
      }
    }
    AuFreeBucketAttributes(aud, num, bas);
}


/* ARGSUSED2 */
static int _get_elem_type (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return AuServerElementType (aud, i);
}

static void print_elem_types (aud)
    AuServer *aud;
{
    _print_names (aud, _nt_elemtypes, NENTRIES(_nt_elemtypes),
              "Element Types:", AuServerNumElementTypes(aud),
              _get_elem_type, NULL, AuFalse);
}


/* ARGSUSED2 */
static int _get_wave_form (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return AuServerWaveForm (aud, i);
}

static void print_wave_forms (aud)
    AuServer *aud;
{
    _print_names (aud, _nt_waveforms, NENTRIES(_nt_waveforms), 
              "Wave Forms:", AuServerNumWaveForms(aud), _get_wave_form,
              NULL, AuFalse);
}


/* ARGSUSED2 */
static int _get_action (aud, i, p)
    AuServer *aud;
    int i;
    AuPointer p;
{
    return AuServerAction (aud, i);
}

static void print_actions (aud)
    AuServer *aud;
{
    _print_names (aud, _nt_actions, NENTRIES(_nt_actions), 
              "Actions:", AuServerNumActions(aud), _get_action, 
              NULL, AuFalse);
}




Generated by  Doxygen 1.6.0   Back to index