void pwl__fetch(register pwl_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; register double incr_reg; register double lvl_reg; falloc_sample_block(out, "pwl__fetch"); out_ptr = out->samples; snd_list->block = out; while (cnt < max_sample_block_len) { /* outer loop */ /* first compute how many samples to generate in inner loop: */ /* don't overflow the output sample block: */ togo = max_sample_block_len - cnt; if (susp->bpt_ptr == NULL) { out: togo = 0; /* indicate termination */ break; /* we're done */ } { long cur = susp->susp.current + cnt; long nn = getfixnum(car(susp->bpt_ptr)) - cur; if (nn == 0) { if (compute_lvl(susp) || compute_incr(susp, &nn, cur)) goto out; } togo = MIN(nn, togo); } n = togo; incr_reg = susp->incr; lvl_reg = susp->lvl; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = (sample_type) lvl_reg; lvl_reg += incr_reg;; } while (--n); /* inner loop */ susp->lvl += susp->incr * togo; out_ptr += togo; cnt += togo; } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } } /* pwl__fetch */
/* * returns true if it is time to terminate */ boolean compute_incr(pwl_susp_type susp, long *n, long cur) { double target; while (*n == 0) { *n = getfixnum(car(susp->bpt_ptr)) - cur; /* if there is a 2nd element of the pair, get the target */ if (cdr(susp->bpt_ptr)) target = getflonum(car(cdr(susp->bpt_ptr))); else target = 0.0; if (*n > 0) susp->incr = (target - susp->lvl) / *n; else if (compute_lvl(susp)) return true; } return false; }