/* -*-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
*
* 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
#include <mLib/exc.h>
#include <mLib/dstr.h>
+#include "au.h"
+#include "aunum.h"
#include "err.h"
#include "rxglue.h"
#include "txport.h"
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
{ "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 }
};