mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-08 15:52:53 +02:00
74 lines
2.4 KiB
C
74 lines
2.4 KiB
C
/* 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);
|
|
}
|
|
|
|
|