infra: Clean up project setup
[jog] / rxglue.c
index 9126ff4..c1b83d1 100644 (file)
--- 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
  *
  * 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 <mLib/exc.h>
 #include <mLib/dstr.h>
 
+#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 }
 };