1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-30 15:49:41 +02:00

Fixed bug in Nyquist SND-AVG where block size smaller than skip size overwrote memory and crashed.

This commit is contained in:
rbdannenberg 2010-09-19 12:19:26 +00:00
parent a1f0e5ed5b
commit 639c8dbfb9

View File

@ -26,11 +26,13 @@ typedef struct avg_susp_struct {
sound_type s; sound_type s;
long s_cnt; long s_cnt;
sample_block_values_type s_ptr; sample_block_values_type s_ptr;
/* blocksize is how many input samples to process for an output sample */
long blocksize; long blocksize;
/* stepsize is how far to advance to get the next block of samples */
long stepsize; long stepsize;
sample_type *block; sample_type *buffer;
sample_type *fillptr; sample_type *fillptr; /* samples are added to buffer at fillptr */
sample_type *endptr; sample_type *endptr; /* until endptr is reached */
process_block_type process_block; process_block_type process_block;
} avg_susp_node, *avg_susp_type; } avg_susp_node, *avg_susp_type;
@ -41,10 +43,10 @@ sample_type average_block(avg_susp_type susp)
double sum = 0.0; double sum = 0.0;
int i; int i;
for (i = 0; i < susp->blocksize; i++) { for (i = 0; i < susp->blocksize; i++) {
sum += susp->block[i]; sum += susp->buffer[i];
} }
for (i = susp->stepsize; i < susp->blocksize; i++) { for (i = susp->stepsize; i < susp->blocksize; i++) {
susp->block[i - susp->stepsize] = susp->block[i]; susp->buffer[i - susp->stepsize] = susp->buffer[i];
} }
return (sample_type) (sum / susp->blocksize); return (sample_type) (sum / susp->blocksize);
} }
@ -57,7 +59,7 @@ sample_type peak_block(avg_susp_type susp)
sample_type minus_peak = 0.0F; sample_type minus_peak = 0.0F;
int i; int i;
for (i = 0; i < susp->blocksize; i++) { for (i = 0; i < susp->blocksize; i++) {
sample_type s = susp->block[i]; sample_type s = susp->buffer[i];
if (s > peak) { if (s > peak) {
peak = s; minus_peak = -s; peak = s; minus_peak = -s;
} else if (s < minus_peak) { } else if (s < minus_peak) {
@ -65,7 +67,7 @@ sample_type peak_block(avg_susp_type susp)
} }
} }
for (i = susp->stepsize; i < susp->blocksize; i++) { for (i = susp->stepsize; i < susp->blocksize; i++) {
susp->block[i - susp->stepsize] = susp->block[i]; susp->buffer[i - susp->stepsize] = susp->buffer[i];
} }
return peak; return peak;
} }
@ -200,7 +202,7 @@ void avg_mark(avg_susp_type susp)
void avg_free(avg_susp_type susp) void avg_free(avg_susp_type susp)
{ {
sound_unref(susp->s); sound_unref(susp->s);
free(susp->block); free(susp->buffer);
ffree_generic(susp, sizeof(avg_susp_node), "avg_free"); ffree_generic(susp, sizeof(avg_susp_node), "avg_free");
} }
@ -215,6 +217,7 @@ void avg_print_tree(avg_susp_type susp, int n)
sound_type snd_make_avg(sound_type s, long blocksize, long stepsize, long op) sound_type snd_make_avg(sound_type s, long blocksize, long stepsize, long op)
{ {
long buffersize;
register avg_susp_type susp; register avg_susp_type susp;
rate_type sr = s->sr; rate_type sr = s->sr;
time_type t0 = s->t0; time_type t0 = s->t0;
@ -249,9 +252,13 @@ sound_type snd_make_avg(sound_type s, long blocksize, long stepsize, long op)
susp->s_cnt = 0; susp->s_cnt = 0;
susp->blocksize = blocksize; susp->blocksize = blocksize;
susp->stepsize = stepsize; susp->stepsize = stepsize;
susp->block = (sample_type *) malloc(blocksize * sizeof(sample_type)); /* We need at least blocksize samples in buffer, but if stepsize > blocksize,
susp->fillptr = susp->block; it is convenient to put stepsize samples in buffer. This allows us to
susp->endptr = susp->block + blocksize; step ahead by stepsize samples just by flushing the buffer. */
buffersize = MAX(blocksize, stepsize);
susp->buffer = (sample_type *) malloc(buffersize * sizeof(sample_type));
susp->fillptr = susp->buffer;
susp->endptr = susp->buffer + buffersize;
susp->process_block = average_block; susp->process_block = average_block;
if (op == op_peak) susp->process_block = peak_block; if (op == op_peak) susp->process_block = peak_block;
/* scale factor gets passed to output signal: */ /* scale factor gets passed to output signal: */