/* -*-c-*-
*
- * $Id: au.c,v 1.1 2002/02/02 19:16:28 mdw Exp $
+ * $Id: au.c,v 1.2 2002/02/02 22:43:50 mdw Exp $
*
* High-level audio subsystem
*
/*----- Revision history --------------------------------------------------*
*
* $Log: au.c,v $
+ * Revision 1.2 2002/02/02 22:43:50 mdw
+ * Provide a decent interface for finding out about the audio cache and
+ * configuring its capacity.
+ *
* Revision 1.1 2002/02/02 19:16:28 mdw
* New audio subsystem.
*
static sym_table au_tab; /* Sample cache, by name */
static const char *au_dir = AUDIODIR; /* Directory containing samples */
static struct { au_data *next, *prev; } au_spare; /* Lists for sample data */
-static size_t au_sz, au_max; /* Size of cached samples */
+static au_cacheinfo cache; /* Cache usage information */
#define AU_SPARE ((au_data*)&au_spare)
#define f_init 1u
static void prune(void)
{
T( trace(T_AU, "au: pruning cache (%lu/%lu)",
- (unsigned long)au_sz, (unsigned long)au_max); )
- while (au_sz > au_max && AU_SPARE->next != AU_SPARE) {
+ (unsigned long)cache.sz_total, (unsigned long)cache.sz_max); )
+ while (cache.sz_total > cache.sz_max && AU_SPARE->next != AU_SPARE) {
au_data *a = AU_SPARE->next;
au_sample *s = a->s;
assert(!a->ref);
AU_SPARE->next = a->next;
a->next->prev = AU_SPARE;
s->a = 0;
- au_sz -= a->sz;
+ cache.sz_spare -= a->sz;
+ cache.sz_total -= a->sz;
+ cache.n_spare--;
+ cache.n_total--;
ausys_free(a);
T( trace(T_AU, "au: ... discarded `%s' (%lu/%lu)", SYM_NAME(s),
- (unsigned long)au_sz, (unsigned long)au_max); )
+ (unsigned long)cache.sz_total, (unsigned long)cache.sz_max); )
}
}
sym_create(&au_tab);
AU_SPARE->next = AU_SPARE->prev = AU_SPARE;
- au_max = max;
+ cache.sz_max = max;
/* --- Initialize the system-specific subsystem --- */
T( trace(T_AU, "au: shutdown ok"); )
}
+/* --- @au_getcacheinfo@ --- *
+ *
+ * Arguments: @au_cacheinfo *c@ = where to put the information
+ *
+ * Returns: ---
+ *
+ * Use: Extracts audio cache information.
+ */
+
+void au_getcacheinfo(au_cacheinfo *c)
+{
+ ausys_lock();
+ *c = cache;
+ ausys_unlock();
+ assert(c->sz_spare + c->sz_queue == c->sz_total);
+ assert(c->n_spare + c->n_queue == c->n_total);
+}
+
+/* --- @au_setcachelimit@ --- *
+ *
+ * Arguments: @size_t max@ = new cache limit
+ *
+ * Returns: ---
+ *
+ * Use: Reconfigures the maximum cache size. This probably isn't
+ * very useful, but it was easy...
+ */
+
+void au_setcachelimit(size_t max)
+{
+ ausys_lock();
+ cache.sz_max = max;
+ prune();
+ ausys_unlock();
+}
+
/* --- @au_find@ --- *
*
* Arguments: @const char *tag@ = sample tag string
a->prev->next = a->next;
a->next->prev = a->prev;
a->next = a->prev = 0;
+ cache.sz_spare -= a->sz;
+ cache.sz_queue += a->sz;
+ cache.n_spare--;
+ cache.n_queue++;
+ cache.hits++;
}
a->ref++;
T( trace(T_AU, "au: reusing sample `%s'", SYM_NAME(s)); )
if ((a = ausys_decode(s, d.buf, d.len)) == 0)
goto fail_0;
- au_sz += a->sz;
a->ref = 1;
a->next = a->prev = 0;
a->s = s;
/* --- Done --- */
ausys_lock();
+ cache.sz_queue += a->sz;
+ cache.sz_total += a->sz;
+ cache.n_queue++;
+ cache.n_total++;
+ cache.misses++;
prune();
ausys_unlock();
goto done;
a->prev = AU_SPARE->prev;
AU_SPARE->prev->next = a;
AU_SPARE->prev = a;
+ cache.sz_queue -= a->sz;
+ cache.sz_spare += a->sz;
+ cache.n_queue--;
+ cache.n_spare++;
T( trace(T_AU, "au: drop last ref to `%s'", SYM_NAME(a->s)); )
prune();
}