X-Git-Url: https://git.distorted.org.uk/~mdw/jog/blobdiff_plain/661c4bdc985a2a94e774e35029fc3283a89c3512..HEAD:/rxglue.c diff --git a/rxglue.c b/rxglue.c index 9126ff4..c1b83d1 100644 --- a/rxglue.c +++ b/rxglue.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: rxglue.c,v 1.2 2002/01/30 09:22:48 mdw Exp $ + * $Id: rxglue.c,v 1.4 2002/02/02 22:43:50 mdw Exp $ * * REXX glue for C core functionality * @@ -26,20 +26,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: rxglue.c,v $ - * Revision 1.2 2002/01/30 09:22:48 mdw - * Use memory-allocation functions provided by the REXX interpreter. - * Now that configuration can be applied after initialization, allow - * @txconf@ to set parameters. Make @txsend@ add a newline to its output, - * unless forbidden. - * - * Revision 1.1 2002/01/25 19:34:45 mdw - * Initial revision - * - */ - /*----- Header files ------------------------------------------------------*/ #ifdef HAVE_CONFIG_H @@ -67,6 +53,8 @@ #include #include +#include "au.h" +#include "aunum.h" #include "err.h" #include "rxglue.h" #include "txport.h" @@ -488,6 +476,165 @@ static APIRET APIENTRY rxfn_txready(const char *fn, ULONG ac, RXSTRING *av, return (0); } +/* --- @AUPLAY(TAG, [FLAG])@ --- * + * + * Arguments: @TAG@ = audio sample tag to play + * @FLAG@ = a string to explain what to do more clearly. + * + * Returns: True if it succeeded. + * + * Use: Plays a sample. If @FLAG@ begins with `t', don't report + * errors if the sample can't be found. + */ + +static APIRET APIENTRY rxfn_auplay(const char *fn, ULONG ac, RXSTRING *av, + const char *sn, RXSTRING *r) +{ + dstr d = DSTR_INIT; + int rc = 1; + + if (ac < 1 || !av[0].strlength || ac > 2) + return (-1); + rxs_get(&av[0], &d); + if (ac > 1 && av[1].strlength >= 1 && + (av[1].strptr[0] == 't' || av[1].strptr[0] == 'T')) + rc = au_tryplay(d.buf); + else + au_play(d.buf); + dstr_destroy(&d); + rxs_putf(r, "%d", rc); + return (0); +} + +/* --- @AUFETCH(TAG)@ --- * + * + * Arguments: @TAG@ = audio sample tag to play + * + * Returns: True if it succeeded. + * + * Use: Prefetches a sample into the cache. + */ + +static APIRET APIENTRY rxfn_aufetch(const char *fn, ULONG ac, RXSTRING *av, + const char *sn, RXSTRING *r) +{ + dstr d = DSTR_INIT; + int rc = 0; + au_sample *s; + au_data *a; + + if (ac < 1 || !av[0].strlength || ac > 1) + return (-1); + rxs_get(&av[0], &d); + if ((s = au_find(d.buf)) != 0 && + (a = au_fetch(s)) != 0) { + au_free(a); + rc = 1; + } + dstr_destroy(&d); + rxs_putf(r, "%d", rc); + return (0); +} + +/* --- @AUNUM(TAG)@ --- * + * + * Arguments: @NUM@ = a number to be read + * + * Returns: --- + * + * Use: Reads a number aloud to the audio device. + */ + +static APIRET APIENTRY rxfn_aunum(const char *fn, ULONG ac, RXSTRING *av, + const char *sn, RXSTRING *r) +{ + dstr d = DSTR_INIT; + + if (ac < 1 || !av[0].strlength || ac > 1) + return (-1); + rxs_get(&av[0], &d); + aunum(d.buf); + dstr_destroy(&d); + return (0); +} + +/* --- @AUCACHE([FLAG], [VALUE, ...]@ --- * + * + * Arguments: @FLAG@ = operation to perform + * + * Returns: Dependent on operation. + * + * Use: If @FLAG@ is omitted or `Info', returns audio cache usage + * information as words in the following order: + * + * sz_max Maximum allowed cache size + * sz_total Total size used by samples + * sz_spare Size used by `spare' samples + * sz_queue Size used by queued samples + * n_total Total number of cached samples + * n_spare Number of `spare' samples + * n_queue Number of queued samples + * hits Number of cache hits + * misses Number of cache misses + * + * If @FLAG@ is `Max', sets the maximum cache size to the first + * @VALUE@ (if set), and returns the old maximum on its own. + * + * If @FLAG@ is `Usage', returns the `sz_*' items, as a list of + * words. + * + * If @FLAGS@ is `Numbers', returns the `n_*' items, as a list + * of words. + * + * If @FLAGS@ is `Hits', returns `hits' and `misses' as a pair + * of words. + */ + +static APIRET APIENTRY rxfn_aucache(const char *fn, ULONG ac, RXSTRING *av, + const char *sn, RXSTRING *r) +{ + int i = 1; + au_cacheinfo c; + + au_getcacheinfo(&c); + if (ac < 1 || !av[0].strlength) + goto info; + switch (av[0].strptr[0]) { + case 'i': case 'I': info: + rxs_putf(r, "%lu %lu %lu %lu %u %u %u %lu %lu", + (unsigned long)c.sz_max, (unsigned long)c.sz_total, + (unsigned long)c.sz_spare, (unsigned long)c.sz_queue, + c.n_total, c.n_spare, c.n_total, c.hits, c.misses); + break; + case 'm': case 'M': + if (ac > i) { + long max; + if (rxs_tol(&av[i], &max)) + return (-1); + au_setcachelimit(max); + i++; + } + rxs_putf(r, "%lu", (unsigned long)c.sz_max); + break; + case 'u': case 'U': + rxs_putf(r, "%lu %lu %lu %lu", + (unsigned long)c.sz_max, (unsigned long)c.sz_total, + (unsigned long)c.sz_spare, (unsigned long)c.sz_queue); + break; + case 'n': case 'N': + rxs_putf(r, "%u %u %u", c.n_total, c.n_spare, c.n_total); + break; + case 'h': case 'H': + rxs_putf(r, "%lu %lu", c.hits, c.misses); + break; + default: + return (-1); + } + if (i > ac) + return (-1); + return (0); +} + /* --- @MILLIWAIT(MILLIS)@ --- * * * Arguments: @MILLIS@ = how long (in milliseconds) to wait @@ -527,6 +674,10 @@ static const struct rxfntab rxfntab[] = { { "txrecv", rxfn_txrecv }, { "txeof", rxfn_txeof }, { "txready", rxfn_txready }, + { "auplay", rxfn_auplay }, + { "aufetch", rxfn_aufetch }, + { "aucache", rxfn_aucache }, + { "aunum", rxfn_aunum }, { "milliwait", rxfn_milliwait }, { 0, 0 } };