New audio subsystem.
[jog] / au.h
diff --git a/au.h b/au.h
new file mode 100644 (file)
index 0000000..7678943
--- /dev/null
+++ b/au.h
@@ -0,0 +1,198 @@
+/* -*-c-*-
+ *
+ * $Id: au.h,v 1.1 2002/02/02 19:16:28 mdw Exp $
+ *
+ * Audio handling
+ *
+ * (c) 2002 Mark Wooding
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Jog: Programming for a jogging machine.
+ *
+ * Jog 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.
+ * 
+ * Jog 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 Jog; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: au.h,v $
+ * Revision 1.1  2002/02/02 19:16:28  mdw
+ * New audio subsystem.
+ *
+ */
+
+#ifndef AU_H
+#define AU_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stddef.h>
+
+#include <mLib/bits.h>
+#include <mLib/sym.h>
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* --- An audio sample --- *
+ *
+ * We maintain a cache of sample data, keyed by textual tags.  An entry in
+ * the cache may indicate one of three states:
+ *
+ *   * a tag for a sample which doesn't exist (negative answer);
+ *
+ *   * a sample whose data is currently resident; or
+ *
+ *   * sample with nonresident data.
+ *
+ * A negative answer is indicated by the @AUF_NOMATCH@ flag.  If an entry has
+ * resident data, the @a@ pointer is non-null.
+ */
+
+typedef struct au_sample {
+  sym_base s;                          /* Base structure for name lookup */
+  unsigned f;                          /* Flags for this entry */
+  struct au_data *a;                   /* Sample data, if present */
+} au_sample;
+
+#define AUF_NOMATCH 1u                 /* Cached non-match for this tag */
+
+/* --- Audio data --- *
+ *
+ * The actual sample data, in an internal representation chosen by the
+ * system-specific layer.
+ *
+ * The sample data can be in one of two states: in-use or spare.  Sample data
+ * is considered to be in-use if the @ref@ field is nonzero.  Spare sample
+ * data is left in-memory for efficiency's sake, but will be discarded
+ * (least-recently-used first) when the total size of sample data (as
+ * measured by the @sz@ fields) exceeds @AU_CACHEMAX@.
+ */
+
+typedef struct au_data {
+  struct au_data *next, *prev;         /* Other samples in this list */
+  unsigned ref;                                /* Reference count for sample data */
+  struct au_sample *s;                 /* Parent sample node */
+  octet *p;                            /* Pointer to sample file data */
+  size_t sz;                           /* Size of sample file data */
+} au_data;
+
+#define AU_CACHEMAX 0x01000000         /* Maximum resident sample data */
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @au_init@ --- *
+ *
+ * Arguments:  @const char *dir@ = samples directory, or null
+ *             @size_t max@ = maximum cache size
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes the audio subsystem.
+ */
+
+extern void au_init(const char */*dir*/, size_t /*max*/);
+
+/* --- @au_shutdown@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Shuts down the audio subsystem.
+ */
+
+extern void au_shutdown(void);
+
+/* --- @au_find@ --- *
+ *
+ * Arguments:  @const char *tag@ = sample tag string
+ *
+ * Returns:    A pointer to the sample corresponding to the tag, or null if
+ *             the sample wasn't found.
+ *
+ * Use:                Looks up a sample by its name.
+ */
+
+extern au_sample *au_find(const char */*tag*/);
+
+/* --- @au_fetch@ --- *
+ *
+ * Arguments:  @au_sample *s@ = sample pointer
+ *
+ * Returns:    A pointer to the audio data for the sample.
+ *
+ * Use:                Fetches a sample, and decodes it, if necessary.  The decoded
+ *             sample data is left with an outstanding reference to it, so
+ *             it won't be freed.  This is used internally by @au_queue@,
+ *             before passing the fetched sample data to the system-specific
+ *             layer for playback.  It can also be used to lock sample data
+ *             in memory (e.g., for the `abort' error message), or (by
+ *             freeing it immediately afterwards) to prefetch a sample which
+ *             will be used soon, to reduce the latency before the sample is
+ *             heard.
+ */
+
+extern au_data *au_fetch(au_sample */*s*/);
+
+/* --- @au_queue@ --- *
+ *
+ * Arguments:  @au_sample *s@ = sample pointer
+ *
+ * Returns:    Zero on success, nonzero on failure.
+ *
+ * Use:                Queues a sample to be played.
+ */
+
+extern int au_queue(au_sample */*s*/);
+
+/* --- @au_free@, @au_free_unlocked@ --- *
+ *
+ * Arguments:  @au_data *a@ = pointer to audio data block
+ *
+ * Returns:    ---
+ *
+ * Use:                Frees a sample data block when it's no longer required.
+ */
+
+extern void au_free(au_data */*a*/);
+extern void au_free_unlocked(au_data */*a*/);
+
+/* --- @au_play@, @au_tryplay@ --- *
+ *
+ * Arguments:  @const char *tag@ = sample tag string
+ *
+ * Returns:    Zero on success, nonzero on failure.
+ *
+ * Use:                Convenience functions for queueing samples by tag.
+ *             If @au_tryplay@ cannot find the requested sample, it returns
+ *             a zero value; if @au_play@ cannot find the sample, it aborts
+ *             the program.
+ */
+
+extern int au_play(const char */*tag*/);
+extern int au_tryplay(const char */*tag*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif