diff options
Diffstat (limited to 'nyqsrc/sndmax.c')
-rw-r--r-- | nyqsrc/sndmax.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/nyqsrc/sndmax.c b/nyqsrc/sndmax.c new file mode 100644 index 0000000..a91297b --- /dev/null +++ b/nyqsrc/sndmax.c @@ -0,0 +1,73 @@ +/* sndmax.c -- computes the maximum amplitude in a sound */ + + +/* CHANGE LOG + * -------------------------------------------------------------------- + * 28Apr03 dm min->MIN; fix compiler warning + * 31Jan07 rbd handle negative scale factors + */ + +#ifdef UNIX +#include "sys/types.h" +#endif +#include <stdio.h> +/* #include "snd.h" */ +#include "xlisp.h" +#include "sound.h" +#include "falloc.h" +#include "sndmax.h" +#include "extern.h" + +double sound_max(LVAL snd_expr, long n) +{ + LVAL s_as_lval; + sound_type s = NULL; + long blocklen; + sample_block_values_type sbufp; + register double maximum = 0; + + s_as_lval = xleval(snd_expr); + /* BE CAREFUL - DO NOT ALLOW GC TO RUN WHILE LVAL IS UNPROTECTED */ + if (exttypep(s_as_lval, a_sound)) { + /* if snd_expr was simply a symbol, then s now points to + a shared sound_node. If we read samples from it, then + the sound bound to the symbol will be destroyed, so + copy it first. If snd_expr was a real expression that + computed a new value, then the next garbage collection + will reclaim the sound_node. We need to make the new + sound reachable by the garbage collector to that any + lisp data reachable from the sound do not get collected. + To make the sound reachable, we need to allocate a node, + and the GC might run, so we need to protect the OLD s + but then make it unreachable. + We will let the GC collect the sound in the end. + */ + xlprot1(s_as_lval); + s = sound_copy(getsound(s_as_lval)); + s_as_lval = cvsound(s); /* destroys only ref. to original */ + /* printf("sound_max: copy is %x, lval %x\n", s, s_as_lval); */ + while (n > 0) { + long togo, j; + sample_block_type sampblock = + sound_get_next(s, &blocklen); + if (sampblock == zero_block || blocklen == 0) { + break; + } + togo = MIN(blocklen, n); + sbufp = sampblock->samples; + for (j = 0; j < togo; j++) { + register double samp = *sbufp++; + if (samp > maximum) maximum = samp; + else if (-samp > maximum) maximum = -samp; + } + n -= togo; + } + xlpop(); + } else { + xlerror("sound_max: expression did not return a sound", + s_as_lval); + } + return fabs(maximum * s->scale); +} + + |