void ifft__fetch(register ifft_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 long index_reg; register sample_type * outbuf_reg; falloc_sample_block(out, "ifft__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->src == NULL) { out: togo = 0; /* indicate termination */ break; /* we're done */ } if (susp->index >= susp->stepsize) { long i; long m, n; LVAL elem; susp->index = 0; susp->array = xleval(cons(s_send, cons(susp->src, consa(s_next)))); if (susp->array == NULL) { susp->src = NULL; goto out; } else if (!vectorp(susp->array)) { xlerror("array expected", susp->array); } else if (susp->samples == NULL) { /* assume arrays are all the same size as first one; now that we know the size, we just have to do this first allocation. */ susp->length = getsize(susp->array); if (susp->length < 1) xlerror("array has no elements", susp->array); if (susp->window && (susp->window_len != susp->length)) xlerror("window size and spectrum size differ", susp->array); /* tricky non-power of 2 detector: only if this is a * power of 2 will the highest 1 bit be cleared when * we subtract 1 ... */ if (susp->length & (susp->length - 1)) xlfail("spectrum size must be a power of 2"); susp->samples = (sample_type *) calloc(susp->length, sizeof(sample_type)); susp->outbuf = (sample_type *) calloc(susp->length, sizeof(sample_type)); } else if (getsize(susp->array) != susp->length) { xlerror("arrays must all be the same length", susp->array); } /* at this point, we have a new array to put samples */ /* the incoming array format is [DC, R1, I1, R2, I2, ... RN] * where RN is the real coef at the Nyquist frequency * but susp->samples should be organized as [DC, RN, R1, I1, ...] */ n = susp->length; /* get the DC (real) coef */ elem = getelement(susp->array, 0); MUST_BE_FLONUM(elem) susp->samples[0] = (sample_type) getflonum(elem); /* get the Nyquist (real) coef */ elem = getelement(susp->array, n - 1); MUST_BE_FLONUM(elem); susp->samples[1] = (sample_type) getflonum(elem); /* get the remaining coef */ for (i = 1; i < n - 1; i++) { elem = getelement(susp->array, i); MUST_BE_FLONUM(elem) susp->samples[i + 1] = (sample_type) getflonum(elem); } susp->array = NULL; /* free the array */ /* here is where the IFFT and windowing should take place */ //fftnf(1, &n, susp->samples, susp->samples + n, -1, 1.0); m = round(log(n) / M_LN2); if (!fftInit(m)) riffts(susp->samples, m, 1); else xlfail("FFT initialization error"); if (susp->window) { n = susp->length; for (i = 0; i < n; i++) { susp->samples[i] *= susp->window[i]; } } /* shift the outbuf */ n = susp->length - susp->stepsize; for (i = 0; i < n; i++) { susp->outbuf[i] = susp->outbuf[i + susp->stepsize]; } /* clear end of outbuf */ for (i = n; i < susp->length; i++) { susp->outbuf[i] = 0; } /* add in the ifft result */ n = susp->length; for (i = 0; i < n; i++) { susp->outbuf[i] += susp->samples[i]; } } togo = min(togo, susp->stepsize - susp->index); n = togo; index_reg = susp->index; outbuf_reg = susp->outbuf; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = outbuf_reg[index_reg++];; } while (--n); /* inner loop */ susp->index = index_reg; susp->outbuf = outbuf_reg; 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; } } /* ifft__fetch */
void aresoncv_ni_fetch(register aresoncv_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 c3co_reg; register double coshz_reg; register double c2_reg; register double c1_reg; register int normalization_reg; register double y1_reg; register double y2_reg; register double bw_pHaSe_iNcR_rEg = susp->bw_pHaSe_iNcR; register double bw_pHaSe_ReG; register sample_type bw_x1_sample_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "aresoncv_ni_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp_check_term_samples(bw, bw_ptr, bw_cnt); susp->bw_x1_sample = susp_fetch_sample(bw, bw_ptr, bw_cnt); } 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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; c3co_reg = susp->c3co; coshz_reg = susp->coshz; c2_reg = susp->c2; c1_reg = susp->c1; normalization_reg = susp->normalization; y1_reg = susp->y1; y2_reg = susp->y2; bw_pHaSe_ReG = susp->bw_pHaSe; bw_x1_sample_reg = susp->bw_x1_sample; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register double y0, current; if (bw_pHaSe_ReG >= 1.0) { /* fixup-depends bw */ /* pick up next sample as bw_x1_sample: */ susp->bw_ptr++; susp_took(bw_cnt, 1); bw_pHaSe_ReG -= 1.0; susp_check_term_samples_break(bw, bw_ptr, bw_cnt, bw_x1_sample_reg); bw_x1_sample_reg = susp_current_sample(bw, bw_ptr); } current = *s1_ptr_reg++; *out_ptr_reg++ = (float) (y0 = c1_reg * current + c2_reg * y1_reg - c3co_reg * y2_reg); y2_reg = y1_reg; y1_reg = y0 - current; bw_pHaSe_ReG += bw_pHaSe_iNcR_rEg; } while (--n); /* inner loop */ togo -= n; susp->y1 = y1_reg; susp->y2 = y2_reg; susp->bw_pHaSe = bw_pHaSe_ReG; susp->bw_x1_sample = bw_x1_sample_reg; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* aresoncv_ni_fetch */
void up_r_fetch(register up_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ sample_type input_DeLtA; sample_type input_val; sample_type input_x2_sample; int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; falloc_sample_block(out, "up_r_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp->input_pHaSe = 1.0; } susp_check_term_log_samples(input, input_ptr, input_cnt); input_x2_sample = susp_current_sample(input, input_ptr); 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; /* grab next input_x2_sample when phase goes past 1.0; */ /* we use input_n (computed below) to avoid roundoff errors: */ if (susp->input_n <= 0) { susp->input_x1_sample = input_x2_sample; susp->input_ptr++; susp_took(input_cnt, 1); susp->input_pHaSe -= 1.0; susp_check_term_log_samples(input, input_ptr, input_cnt); input_x2_sample = susp_current_sample(input, input_ptr); /* input_n gets number of samples before phase exceeds 1.0: */ susp->input_n = (long) ((1.0 - susp->input_pHaSe) * susp->output_per_input); } togo = min(togo, susp->input_n); input_DeLtA = (sample_type) ((input_x2_sample - susp->input_x1_sample) * susp->input_pHaSe_iNcR); input_val = (sample_type) (susp->input_x1_sample * (1.0 - susp->input_pHaSe) + input_x2_sample * susp->input_pHaSe); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = (sample_type) input_val; input_val += input_DeLtA; } while (--n); /* inner loop */ out_ptr += togo; susp->input_pHaSe += togo * susp->input_pHaSe_iNcR; susp->input_n -= 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* up_r_fetch */
void convolve_s_fetch(register convolve_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 sample_type * h_buf_reg; register long h_len_reg; register long x_buf_len_reg; register sample_type * x_buffer_pointer_reg; register sample_type * x_buffer_current_reg; register sample_type x_snd_scale_reg = susp->x_snd->scale; register sample_block_values_type x_snd_ptr_reg; falloc_sample_block(out, "convolve_s_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; /* don't run past the x_snd input sample block: */ susp_check_term_log_samples(x_snd, x_snd_ptr, x_snd_cnt); togo = min(togo, susp->x_snd_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; h_buf_reg = susp->h_buf; h_len_reg = susp->h_len; x_buf_len_reg = susp->x_buf_len; x_buffer_pointer_reg = susp->x_buffer_pointer; x_buffer_current_reg = susp->x_buffer_current; x_snd_ptr_reg = susp->x_snd_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ long i; double sum; /* see if we've reached end of x_buffer */ if ((x_buffer_pointer_reg + x_buf_len_reg) <= (x_buffer_current_reg + h_len_reg)) { /* shift x_buffer from current back to base */ for (i = 1; i < h_len_reg; i++) { x_buffer_pointer_reg[i-1] = x_buffer_current_reg[i]; } /* this will be incremented back to x_buffer_pointer_reg below */ x_buffer_current_reg = x_buffer_pointer_reg - 1; } x_buffer_current_reg++; x_buffer_current_reg[h_len_reg - 1] = (x_snd_scale_reg * *x_snd_ptr_reg++); sum = 0.0; for (i = 0; i < h_len_reg; i++) { sum += x_buffer_current_reg[i] * h_buf_reg[i]; } *out_ptr_reg++ = (sample_type) sum; ; } while (--n); /* inner loop */ susp->x_buffer_pointer = x_buffer_pointer_reg; susp->x_buffer_current = x_buffer_current_reg; /* using x_snd_ptr_reg is a bad idea on RS/6000: */ susp->x_snd_ptr += togo; out_ptr += togo; susp_took(x_snd_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* convolve_s_fetch */
void trigger_fetch(trigger_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 sample_block_values_type input_ptr_reg; falloc_sample_block(out, "trigger_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; /* don't run past the input sample block: */ susp_check_term_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } n = togo; input_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ sample_type s = *input_ptr_reg++; if (susp->previous <= 0 && s > 0) { trigger_susp_type new_trigger; sound_type new_trigger_snd; LVAL result; long delay; /* sample delay to s2 */ time_type now; susp->previous = s; /* don't retrigger */ /**** close off block ****/ togo = togo - n; susp->s1_ptr += togo; susp_took(s1_cnt, togo); cnt += togo; snd_list->block_len = cnt; susp->susp.current += cnt; now = susp->susp.t0 + susp->susp.current / susp->susp.sr; /**** eval closure and add result ****/ D nyquist_printf("trigger_fetch: about to eval closure at %g, " "susp->susp.t0 %g, susp.current %d:\n", now, susp->susp.t0, (int)susp->susp.current); xlsave1(result); result = xleval(cons(susp->closure, consa(cvflonum(now)))); if (exttypep(result, a_sound)) { susp->s2 = sound_copy(getsound(result)); D nyquist_printf("trigger: copied result from closure is %p\n", susp->s2); } else xlerror("closure did not return a (monophonic) sound", result); D nyquist_printf("in trigger: after evaluation; " "%p returned from evform\n", susp->s2); result = NIL; /**** cloan this trigger to become s1 ****/ falloc_generic(new_trigger, trigger_susp_node, "new_trigger"); memcpy(new_trigger, susp, sizeof(trigger_susp_node)); /* don't copy s2 -- it should only be referenced by add */ new_trigger->s2 = NULL; new_trigger_snd = sound_create((snd_susp_type) new_trigger, now, susp->susp.sr, 1.0F); susp->s1 = new_trigger_snd; /* add will have to ask new_trigger for samples, new_trigger * will continue reading samples from s1 (the original input) */ susp->s1_cnt = 0; susp->s1_ptr = NULL; /**** convert to add ****/ susp->susp.mark = add_mark; /* logical stop will be recomputed by add: */ susp->susp.log_stop_cnt = UNKNOWN; susp->susp.print_tree = add_print_tree; /* assume sample rates are the same */ if (susp->s1->sr != susp->s2->sr) xlfail("in trigger: sample rates must match"); /* take care of scale factor, if any */ if (susp->s2->scale != 1.0) { // stdputstr("normalizing next sound in a seq\n"); susp->s2 = snd_make_normalize(susp->s2); } /* figure out which add fetch routine to use */ delay = ROUND((susp->s2->t0 - now) * susp->s1->sr); if (delay > 0) { /* fill hole between s1 and s2 */ D stdputstr("using add_s1_nn_fetch\n"); susp->susp.fetch = add_s1_nn_fetch; susp->susp.name = "trigger:add_s1_nn_fetch"; } else { susp->susp.fetch = add_s1_s2_nn_fetch; susp->susp.name = "trigger:add_s1_s2_nn_fetch"; } D stdputstr("in trigger: calling add's fetch\n"); /* fetch will get called later .. (*(susp->susp.fetch))(susp, snd_list); */ D stdputstr("in trigger: returned from add's fetch\n"); xlpop(); susp->closure = NULL; /* allow garbage collection now */ /**** calculation tree modified, time to exit ****/ /* but if cnt == 0, then we haven't computed any samples */ /* call on new fetch routine to get some samples */ if (cnt == 0) { ffree_sample_block(out, "trigger-pre-adder"); // because adder will reallocate (*susp->susp.fetch)(susp, snd_list); } return; } else { susp->previous = s; /* output zero until ready to add in closure */ *out_ptr_reg++ = 0; } } while (--n); /* inner loop */ /* using input_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, togo); cnt += togo; } /* outer loop */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } } /* trigger_fetch */
void buzz_r_fetch(register buzz_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ sample_type s_fm_val; 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 ph_incr_reg; register float n_2_r_reg; register float n_2_p1_reg; register double phase_reg; falloc_sample_block(out, "buzz_r_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp->s_fm_pHaSe = 1.0; } susp_check_term_log_samples(s_fm, s_fm_ptr, s_fm_cnt); 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; /* grab next s_fm_x1_sample when phase goes past 1.0; */ /* use s_fm_n (computed below) to avoid roundoff errors: */ if (susp->s_fm_n <= 0) { susp_check_term_log_samples(s_fm, s_fm_ptr, s_fm_cnt); susp->s_fm_x1_sample = susp_fetch_sample(s_fm, s_fm_ptr, s_fm_cnt); susp->s_fm_pHaSe -= 1.0; /* s_fm_n gets number of samples before phase exceeds 1.0: */ susp->s_fm_n = (long) ((1.0 - susp->s_fm_pHaSe) * susp->output_per_s_fm); } togo = min(togo, susp->s_fm_n); s_fm_val = susp->s_fm_x1_sample; /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; ph_incr_reg = susp->ph_incr; n_2_r_reg = susp->n_2_r; n_2_p1_reg = susp->n_2_p1; phase_reg = susp->phase; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ long table_index; double x1; sample_type num, denom, samp; table_index = (long) phase_reg; x1 = sine_table[table_index]; denom = (sample_type) (x1 + (phase_reg - table_index) * (sine_table[table_index + 1] - x1)); if (denom < 0.001 && denom > -0.005) { samp = 1.0F; } else { double phn2p1 = phase_reg * n_2_p1_reg * (1.0/SINE_TABLE_LEN); phn2p1 = (phn2p1 - (long) phn2p1) * SINE_TABLE_LEN; table_index = (long) phn2p1; x1 = sine_table[table_index]; num = (sample_type) (x1 + (phn2p1 - table_index) * (sine_table[table_index + 1] - x1)); samp = ((num / denom) - 1.0F) * n_2_r_reg; } *out_ptr_reg++ = samp; phase_reg += ph_incr_reg + s_fm_val; while (phase_reg > SINE_TABLE_LEN) phase_reg -= SINE_TABLE_LEN; /* watch out for negative frequencies! */ while (phase_reg < 0) phase_reg += SINE_TABLE_LEN; } while (--n); /* inner loop */ susp->phase = phase_reg; out_ptr += togo; susp->s_fm_pHaSe += togo * susp->s_fm_pHaSe_iNcR; susp->s_fm_n -= 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* buzz_r_fetch */
void flute_freq_ns_fetch(snd_susp_type a_susp, snd_list_type snd_list) { flute_freq_susp_type susp = (flute_freq_susp_type) a_susp; 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 struct instr * myflute_reg; register float breath_scale_reg; register double frequency_reg; register sample_type freq_env_scale_reg = susp->freq_env->scale; register sample_block_values_type freq_env_ptr_reg; register sample_block_values_type breath_env_ptr_reg; falloc_sample_block(out, "flute_freq_ns_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; /* don't run past the breath_env input sample block: */ susp_check_term_samples(breath_env, breath_env_ptr, breath_env_cnt); togo = min(togo, susp->breath_env_cnt); /* don't run past the freq_env input sample block: */ susp_check_samples(freq_env, freq_env_ptr, freq_env_cnt); togo = min(togo, susp->freq_env_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } n = togo; myflute_reg = susp->myflute; breath_scale_reg = susp->breath_scale; frequency_reg = susp->frequency; freq_env_ptr_reg = susp->freq_env_ptr; breath_env_ptr_reg = susp->breath_env_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ controlChange(myflute_reg, 128, breath_scale_reg * *breath_env_ptr_reg++); setFrequency(myflute_reg, frequency_reg + (freq_env_scale_reg * *freq_env_ptr_reg++)); *out_ptr_reg++ = (sample_type) tick(myflute_reg); } while (--n); /* inner loop */ susp->myflute = myflute_reg; /* using freq_env_ptr_reg is a bad idea on RS/6000: */ susp->freq_env_ptr += togo; /* using breath_env_ptr_reg is a bad idea on RS/6000: */ susp->breath_env_ptr += togo; out_ptr += togo; susp_took(breath_env_cnt, togo); susp_took(freq_env_cnt, 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; } } /* flute_freq_ns_fetch */
void tonev_ns_fetch(snd_susp_type a_susp, snd_list_type snd_list) { tonev_susp_type susp = (tonev_susp_type) a_susp; 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 scale1_reg; register double c2_reg; register double c1_reg; register double prev_reg; register sample_type hz_scale_reg = susp->hz->scale; register sample_block_values_type hz_ptr_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "tonev_ns_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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past the hz input sample block: */ susp_check_term_samples(hz, hz_ptr, hz_cnt); togo = min(togo, susp->hz_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < 0) to_stop = 0; /* avoids rounding errors */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; scale1_reg = susp->scale1; c2_reg = susp->c2; c1_reg = susp->c1; prev_reg = susp->prev; hz_ptr_reg = susp->hz_ptr; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register double b; b = 2.0 - cos((hz_scale_reg * *hz_ptr_reg++)); c2_reg = b - sqrt((b * b) - 1.0); c1_reg = (1.0 - c2_reg) * scale1_reg; *out_ptr_reg++ = (sample_type) (prev_reg = c1_reg * *s1_ptr_reg++ + c2_reg * prev_reg); } while (--n); /* inner loop */ susp->prev = prev_reg; /* using hz_ptr_reg is a bad idea on RS/6000: */ susp->hz_ptr += togo; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, togo); susp_took(hz_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* tonev_ns_fetch */
void alpassvv_nss_fetch(register alpassvv_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 float delay_scale_factor_reg; register long buflen_reg; register sample_type * delayptr_reg; register sample_type * endptr_reg; register sample_type feedback_scale_reg = susp->feedback->scale; register sample_block_values_type feedback_ptr_reg; register sample_type delaysnd_scale_reg = susp->delaysnd->scale; register sample_block_values_type delaysnd_ptr_reg; register sample_block_values_type input_ptr_reg; falloc_sample_block(out, "alpassvv_nss_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; /* don't run past the input input sample block: */ susp_check_term_samples(input, input_ptr, input_cnt); togo = MIN(togo, susp->input_cnt); /* don't run past the delaysnd input sample block: */ susp_check_samples(delaysnd, delaysnd_ptr, delaysnd_cnt); togo = MIN(togo, susp->delaysnd_cnt); /* don't run past the feedback input sample block: */ susp_check_samples(feedback, feedback_ptr, feedback_cnt); togo = MIN(togo, susp->feedback_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } n = togo; delay_scale_factor_reg = susp->delay_scale_factor; buflen_reg = susp->buflen; delayptr_reg = susp->delayptr; endptr_reg = susp->endptr; feedback_ptr_reg = susp->feedback_ptr; delaysnd_ptr_reg = susp->delaysnd_ptr; input_ptr_reg = susp->input_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register sample_type y, z, delaysamp; register int delayi; register sample_type *yptr; /* compute where to read y, we want y to be delay_snd samples * after delay_ptr, where we write the new sample. First, * conver from seconds to samples. Note: don't use actual sound_type * names in comments! The translator isn't smart enough. */ register sample_type fb = (feedback_scale_reg * *feedback_ptr_reg++); delaysamp = (delaysnd_scale_reg * *delaysnd_ptr_reg++) * delay_scale_factor_reg; delayi = (int) delaysamp; /* get integer part */ delaysamp = delaysamp - delayi; /* get phase */ yptr = delayptr_reg + buflen_reg - (delayi + 1); if (yptr >= endptr_reg) yptr -= buflen_reg; /* now get y, the out-put of the delay, using interpolation */ /* note that as phase increases, we use more of yptr[0] because positive phase means longer buffer means read earlier sample */ y = (float) ((yptr[0] * delaysamp) + (yptr[1] * (1.0 - delaysamp))); /* WARNING: no check to keep delaysamp in range, so do this in LISP */ *delayptr_reg++ = z = (sample_type) (fb * y + *input_ptr_reg++); /* Time out to update the buffer: * this is a tricky buffer: buffer[0] == buffer[bufflen] * the logical length is bufflen, but the actual length * is bufflen + 1 to allow for a repeated sample at the * end. This allows for efficient interpolation. */ if (delayptr_reg > endptr_reg) { delayptr_reg = susp->delaybuf; *delayptr_reg++ = *endptr_reg; } *out_ptr_reg++ = (sample_type) (y - fb * z);; } while (--n); /* inner loop */ susp->buflen = buflen_reg; susp->delayptr = delayptr_reg; /* using feedback_ptr_reg is a bad idea on RS/6000: */ susp->feedback_ptr += togo; /* using delaysnd_ptr_reg is a bad idea on RS/6000: */ susp->delaysnd_ptr += togo; /* using input_ptr_reg is a bad idea on RS/6000: */ susp->input_ptr += togo; out_ptr += togo; susp_took(input_cnt, togo); susp_took(delaysnd_cnt, togo); susp_took(feedback_cnt, 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; } } /* alpassvv_nss_fetch */
void coterm_ni_fetch(snd_susp_type a_susp, snd_list_type snd_list) { coterm_susp_type susp = (coterm_susp_type) a_susp; int cnt = 0; /* how many samples computed */ sample_type s2_x2_sample; 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 s2_pHaSe_iNcR_rEg = susp->s2_pHaSe_iNcR; register double s2_pHaSe_ReG; register sample_type s2_x1_sample_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "coterm_ni_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp_check_term_log_samples(s2, s2_ptr, s2_cnt); susp->s2_x1_sample = (susp->s2_cnt--, *(susp->s2_ptr)); } susp_check_term_log_samples(s2, s2_ptr, s2_cnt); s2_x2_sample = *(susp->s2_ptr); 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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < 0) to_stop = 0; /* avoids rounding errors */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; s2_pHaSe_ReG = susp->s2_pHaSe; s2_x1_sample_reg = susp->s2_x1_sample; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ if (s2_pHaSe_ReG >= 1.0) { s2_x1_sample_reg = s2_x2_sample; /* pick up next sample as s2_x2_sample: */ susp->s2_ptr++; susp_took(s2_cnt, 1); s2_pHaSe_ReG -= 1.0; susp_check_term_log_samples_break(s2, s2_ptr, s2_cnt, s2_x2_sample); } {sample_type dummy = (s2_x1_sample_reg * (1 - s2_pHaSe_ReG) + s2_x2_sample * s2_pHaSe_ReG); *out_ptr_reg++ = *s1_ptr_reg++;}; s2_pHaSe_ReG += s2_pHaSe_iNcR_rEg; } while (--n); /* inner loop */ togo -= n; susp->s2_pHaSe = s2_pHaSe_ReG; susp->s2_x1_sample = s2_x1_sample_reg; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* coterm_ni_fetch */
void tonev_nr_fetch(snd_susp_type a_susp, snd_list_type snd_list) { tonev_susp_type susp = (tonev_susp_type) a_susp; int cnt = 0; /* how many samples computed */ sample_type hz_val; 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 scale1_reg; register double c2_reg; register double c1_reg; register double prev_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "tonev_nr_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp->hz_pHaSe = 1.0; } susp_check_term_samples(hz, hz_ptr, hz_cnt); 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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* grab next hz_x1_sample when phase goes past 1.0; */ /* use hz_n (computed below) to avoid roundoff errors: */ if (susp->hz_n <= 0) { register double b; susp_check_term_samples(hz, hz_ptr, hz_cnt); susp->hz_x1_sample = susp_fetch_sample(hz, hz_ptr, hz_cnt); susp->hz_pHaSe -= 1.0; /* hz_n gets number of samples before phase exceeds 1.0: */ susp->hz_n = (long) ((1.0 - susp->hz_pHaSe) * susp->output_per_hz); b = 2.0 - cos(susp->hz_x1_sample); susp->c2 = b - sqrt((b * b) - 1.0); susp->c1 = (1.0 - susp->c2) * susp->scale1; } togo = min(togo, susp->hz_n); hz_val = susp->hz_x1_sample; /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < 0) to_stop = 0; /* avoids rounding errors */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; scale1_reg = susp->scale1; c2_reg = susp->c2; c1_reg = susp->c1; prev_reg = susp->prev; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = (sample_type) (prev_reg = c1_reg * *s1_ptr_reg++ + c2_reg * prev_reg); } while (--n); /* inner loop */ susp->prev = prev_reg; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, togo); susp->hz_pHaSe += togo * susp->hz_pHaSe_iNcR; susp->hz_n -= 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* tonev_nr_fetch */
void alpassvc_nr_fetch(snd_susp_type a_susp, snd_list_type snd_list) { alpassvc_susp_type susp = (alpassvc_susp_type) a_susp; int cnt = 0; /* how many samples computed */ sample_type delaysnd_DeLtA; sample_type delaysnd_val; sample_type delaysnd_x2_sample; int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; register float delay_scale_factor_reg; register double feedback_reg; register long buflen_reg; register sample_type * delayptr_reg; register sample_type * endptr_reg; register sample_block_values_type input_ptr_reg; falloc_sample_block(out, "alpassvc_nr_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp->delaysnd_pHaSe = 1.0; } susp_check_samples(delaysnd, delaysnd_ptr, delaysnd_cnt); delaysnd_x2_sample = *(susp->delaysnd_ptr); 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; /* don't run past the input input sample block: */ susp_check_term_samples(input, input_ptr, input_cnt); togo = min(togo, susp->input_cnt); /* grab next delaysnd_x2_sample when phase goes past 1.0; */ /* we use delaysnd_n (computed below) to avoid roundoff errors: */ if (susp->delaysnd_n <= 0) { susp->delaysnd_x1_sample = delaysnd_x2_sample; susp->delaysnd_ptr++; susp_took(delaysnd_cnt, 1); susp->delaysnd_pHaSe -= 1.0; susp_check_samples(delaysnd, delaysnd_ptr, delaysnd_cnt); delaysnd_x2_sample = *(susp->delaysnd_ptr); /* delaysnd_n gets number of samples before phase exceeds 1.0: */ susp->delaysnd_n = (long) ((1.0 - susp->delaysnd_pHaSe) * susp->output_per_delaysnd); } togo = min(togo, susp->delaysnd_n); delaysnd_DeLtA = (sample_type) ((delaysnd_x2_sample - susp->delaysnd_x1_sample) * susp->delaysnd_pHaSe_iNcR); delaysnd_val = (sample_type) (susp->delaysnd_x1_sample * (1.0 - susp->delaysnd_pHaSe) + delaysnd_x2_sample * susp->delaysnd_pHaSe); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } n = togo; delay_scale_factor_reg = susp->delay_scale_factor; feedback_reg = susp->feedback; buflen_reg = susp->buflen; delayptr_reg = susp->delayptr; endptr_reg = susp->endptr; input_ptr_reg = susp->input_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register sample_type y, z, delaysamp; register int delayi; register sample_type *yptr; /* compute where to read y, we want y to be delay_snd samples * after delay_ptr, where we write the new sample. First, * conver from seconds to samples. Note: don't use actual sound_type * names in comments! The translator isn't smart enough. */ delaysamp = delaysnd_val * delay_scale_factor_reg; delayi = (int) delaysamp; /* get integer part */ delaysamp = delaysamp - delayi; /* get phase */ yptr = delayptr_reg + buflen_reg - (delayi + 1); if (yptr >= endptr_reg) yptr -= buflen_reg; /* now get y, the out-put of the delay, using interpolation */ /* note that as phase increases, we use more of yptr[0] because positive phase means longer buffer means read earlier sample */ y = (float) ((yptr[0] * delaysamp) + (yptr[1] * (1.0 - delaysamp))); /* WARNING: no check to keep delaysamp in range, so do this in LISP */ *delayptr_reg++ = z = (sample_type) (feedback_reg * y + *input_ptr_reg++); /* Time out to update the buffer: * this is a tricky buffer: buffer[0] == buffer[bufflen] * the logical length is bufflen, but the actual length * is bufflen + 1 to allow for a repeated sample at the * end. This allows for efficient interpolation. */ if (delayptr_reg > endptr_reg) { delayptr_reg = susp->delaybuf; *delayptr_reg++ = *endptr_reg; } *out_ptr_reg++ = (sample_type) (y - feedback_reg * z); delaysnd_val += delaysnd_DeLtA; } while (--n); /* inner loop */ susp->buflen = buflen_reg; susp->delayptr = delayptr_reg; /* using input_ptr_reg is a bad idea on RS/6000: */ susp->input_ptr += togo; out_ptr += togo; susp_took(input_cnt, togo); susp->delaysnd_pHaSe += togo * susp->delaysnd_pHaSe_iNcR; susp->delaysnd_n -= 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; } } /* alpassvc_nr_fetch */
void alpass_n_fetch(register alpass_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 feedback_reg; register sample_type * delayptr_reg; register sample_type * endptr_reg; register sample_block_values_type input_ptr_reg; falloc_sample_block(out, "alpass_n_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; /* don't run past the input input sample block: */ susp_check_term_samples(input, input_ptr, input_cnt); togo = min(togo, susp->input_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } n = togo; feedback_reg = susp->feedback; delayptr_reg = susp->delayptr; endptr_reg = susp->endptr; input_ptr_reg = susp->input_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register sample_type y, z; y = *delayptr_reg; *delayptr_reg++ = z = (sample_type) (feedback_reg * y + *input_ptr_reg++); *out_ptr_reg++ = (sample_type) (y - feedback_reg * z); if (delayptr_reg >= endptr_reg) delayptr_reg = susp->delaybuf;; } while (--n); /* inner loop */ susp->delayptr = delayptr_reg; /* using input_ptr_reg is a bad idea on RS/6000: */ susp->input_ptr += togo; out_ptr += togo; susp_took(input_cnt, 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; } } /* alpass_n_fetch */
void aresoncv_nr_fetch(register aresoncv_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ sample_type bw_val; 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 c3co_reg; register double coshz_reg; register double c2_reg; register double c1_reg; register int normalization_reg; register double y1_reg; register double y2_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "aresoncv_nr_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp->bw_pHaSe = 1.0; } susp_check_term_samples(bw, bw_ptr, bw_cnt); 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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* grab next bw_x1_sample when phase goes past 1.0; */ /* use bw_n (computed below) to avoid roundoff errors: */ if (susp->bw_n <= 0) { susp_check_term_samples(bw, bw_ptr, bw_cnt); susp->bw_x1_sample = susp_fetch_sample(bw, bw_ptr, bw_cnt); susp->bw_pHaSe -= 1.0; /* bw_n gets number of samples before phase exceeds 1.0: */ susp->bw_n = (long) ((1.0 - susp->bw_pHaSe) * susp->output_per_bw); } togo = min(togo, susp->bw_n); bw_val = susp->bw_x1_sample; /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; c3co_reg = susp->c3co; coshz_reg = susp->coshz; c2_reg = susp->c2; c1_reg = susp->c1; normalization_reg = susp->normalization; y1_reg = susp->y1; y2_reg = susp->y2; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register double y0, current;current = *s1_ptr_reg++; *out_ptr_reg++ = (float) (y0 = c1_reg * current + c2_reg * y1_reg - c3co_reg * y2_reg); y2_reg = y1_reg; y1_reg = y0 - current; } while (--n); /* inner loop */ susp->y1 = y1_reg; susp->y2 = y2_reg; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, togo); susp->bw_pHaSe += togo * susp->bw_pHaSe_iNcR; susp->bw_n -= 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* aresoncv_nr_fetch */
void avg_s_fetch(avg_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ int togo = 0; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_type *fillptr_reg; register sample_type *endptr_reg = susp->endptr; register sample_block_values_type s_ptr_reg; falloc_sample_block(out, "avg_s_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) * susp->stepsize; /* don't run past the s input sample block: */ susp_check_term_log_samples(s, s_ptr, s_cnt); togo = MIN(togo, susp->s_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo/susp->stepsize) { togo = (susp->terminate_cnt - (susp->susp.current + cnt)) * susp->stepsize; if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo/susp->stepsize) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop * susp->stepsize; } } n = togo; s_ptr_reg = susp->s_ptr; fillptr_reg = susp->fillptr; if (n) do { /* the inner sample computation loop */ *fillptr_reg++ = *s_ptr_reg++; if (fillptr_reg >= endptr_reg) { *out_ptr++ = (*(susp->process_block))(susp); cnt++; fillptr_reg -= susp->stepsize; } } while (--n); /* inner loop */ /* using s_ptr_reg is a bad idea on RS/6000: */ susp->s_ptr += togo; susp->fillptr = fillptr_reg; susp_took(s_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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* avg_s_fetch */
void amosc_s_fetch(register amosc_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 ph_incr_reg; register sample_type * table_ptr_reg; register double table_len_reg; register double phase_reg; register sample_type amod_scale_reg = susp->amod->scale; register sample_block_values_type amod_ptr_reg; falloc_sample_block(out, "amosc_s_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; /* don't run past the amod input sample block: */ susp_check_term_log_samples(amod, amod_ptr, amod_cnt); togo = min(togo, susp->amod_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; ph_incr_reg = susp->ph_incr; table_ptr_reg = susp->table_ptr; table_len_reg = susp->table_len; phase_reg = susp->phase; amod_ptr_reg = susp->amod_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ long table_index = (long) phase_reg; double x1 = (double) (table_ptr_reg[table_index]); *out_ptr_reg++ = (sample_type) (x1 + (phase_reg - table_index) * (table_ptr_reg[table_index + 1] - x1)) * (amod_scale_reg * *amod_ptr_reg++); phase_reg += ph_incr_reg; while (phase_reg > table_len_reg) phase_reg -= table_len_reg; ; } while (--n); /* inner loop */ susp->phase = phase_reg; /* using amod_ptr_reg is a bad idea on RS/6000: */ susp->amod_ptr += togo; out_ptr += togo; susp_took(amod_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* amosc_s_fetch */
void delaycv_nn_fetch(register delaycv_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 sample_type * delayptr_reg; register sample_type * endptr_reg; register sample_block_values_type feedback_ptr_reg; register sample_block_values_type s_ptr_reg; falloc_sample_block(out, "delaycv_nn_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; /* don't run past the s input sample block: */ susp_check_term_samples(s, s_ptr, s_cnt); togo = MIN(togo, susp->s_cnt); /* don't run past the feedback input sample block: */ susp_check_samples(feedback, feedback_ptr, feedback_cnt); togo = MIN(togo, susp->feedback_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } n = togo; delayptr_reg = susp->delayptr; endptr_reg = susp->endptr; feedback_ptr_reg = susp->feedback_ptr; s_ptr_reg = susp->s_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = *delayptr_reg; *delayptr_reg = *delayptr_reg * *feedback_ptr_reg++ + *s_ptr_reg++; if (++delayptr_reg >= endptr_reg) delayptr_reg = susp->delaybuf;; } while (--n); /* inner loop */ susp->delayptr = delayptr_reg; susp->endptr = endptr_reg; /* using feedback_ptr_reg is a bad idea on RS/6000: */ susp->feedback_ptr += togo; /* using s_ptr_reg is a bad idea on RS/6000: */ susp->s_ptr += togo; out_ptr += togo; susp_took(s_cnt, togo); susp_took(feedback_cnt, 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; } } /* delaycv_nn_fetch */
void shape_s_fetch(register shape_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 time_to_index_reg; register double origin_reg; register sample_type * fcn_table_reg; register double table_len_reg; register sample_type sin_scale_reg = susp->sin->scale; register sample_block_values_type sin_ptr_reg; falloc_sample_block(out, "shape_s_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; /* don't run past the sin input sample block: */ susp_check_term_log_samples(sin, sin_ptr, sin_cnt); togo = min(togo, susp->sin_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; time_to_index_reg = susp->time_to_index; origin_reg = susp->origin; fcn_table_reg = susp->fcn_table; table_len_reg = susp->table_len; sin_ptr_reg = susp->sin_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ register double offset, x1; register long table_index; register double phase = (sin_scale_reg * *sin_ptr_reg++); if (phase > 1.0) phase = 1.0; else if (phase < -1.0) phase = -1.0; offset = (phase + origin_reg) * time_to_index_reg; table_index = (long) offset; if (table_index < 0) table_index = 0; if (table_index >= table_len_reg) table_index = ((long) table_len_reg) - 1; x1 = fcn_table_reg[table_index]; *out_ptr_reg++ = (sample_type) (x1 + (offset - table_index) * (fcn_table_reg[table_index + 1] - x1)); ; } while (--n); /* inner loop */ susp->origin = origin_reg; /* using sin_ptr_reg is a bad idea on RS/6000: */ susp->sin_ptr += togo; out_ptr += togo; susp_took(sin_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* shape_s_fetch */
void buzz_s_fetch(register buzz_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 ph_incr_reg; register float n_2_r_reg; register float n_2_p1_reg; register double phase_reg; register sample_type s_fm_scale_reg = susp->s_fm->scale; register sample_block_values_type s_fm_ptr_reg; falloc_sample_block(out, "buzz_s_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; /* don't run past the s_fm input sample block: */ susp_check_term_log_samples(s_fm, s_fm_ptr, s_fm_cnt); togo = min(togo, susp->s_fm_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; ph_incr_reg = susp->ph_incr; n_2_r_reg = susp->n_2_r; n_2_p1_reg = susp->n_2_p1; phase_reg = susp->phase; s_fm_ptr_reg = susp->s_fm_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ long table_index; double x1; sample_type num, denom, samp; table_index = (long) phase_reg; x1 = sine_table[table_index]; denom = (sample_type) (x1 + (phase_reg - table_index) * (sine_table[table_index + 1] - x1)); if (denom < 0.001 && denom > -0.005) { samp = 1.0F; } else { double phn2p1 = phase_reg * n_2_p1_reg * (1.0/SINE_TABLE_LEN); phn2p1 = (phn2p1 - (long) phn2p1) * SINE_TABLE_LEN; table_index = (long) phn2p1; x1 = sine_table[table_index]; num = (sample_type) (x1 + (phn2p1 - table_index) * (sine_table[table_index + 1] - x1)); samp = ((num / denom) - 1.0F) * n_2_r_reg; } *out_ptr_reg++ = samp; phase_reg += ph_incr_reg + (s_fm_scale_reg * *s_fm_ptr_reg++); while (phase_reg > SINE_TABLE_LEN) phase_reg -= SINE_TABLE_LEN; /* watch out for negative frequencies! */ while (phase_reg < 0) phase_reg += SINE_TABLE_LEN; } while (--n); /* inner loop */ susp->phase = phase_reg; /* using s_fm_ptr_reg is a bad idea on RS/6000: */ susp->s_fm_ptr += togo; out_ptr += togo; susp_took(s_fm_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* buzz_s_fetch */
void biquadfilt_n_fetch(register biquadfilt_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 z1_reg; register double z2_reg; register double b0_reg; register double b1_reg; register double b2_reg; register double a1_reg; register double a2_reg; register sample_block_values_type s_ptr_reg; falloc_sample_block(out, "biquadfilt_n_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; /* don't run past the s input sample block: */ susp_check_term_log_samples(s, s_ptr, s_cnt); togo = min(togo, susp->s_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; z1_reg = susp->z1; z2_reg = susp->z2; b0_reg = susp->b0; b1_reg = susp->b1; b2_reg = susp->b2; a1_reg = susp->a1; a2_reg = susp->a2; s_ptr_reg = susp->s_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ double z0; z0 = *s_ptr_reg++ + a1_reg*z1_reg + a2_reg*z2_reg; *out_ptr_reg++ = (sample_type) (z0*b0_reg + z1_reg*b1_reg + z2_reg*b2_reg); z2_reg = z1_reg; z1_reg = z0;; } while (--n); /* inner loop */ susp->z1 = z1_reg; susp->z2 = z2_reg; /* using s_ptr_reg is a bad idea on RS/6000: */ susp->s_ptr += togo; out_ptr += togo; susp_took(s_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* biquadfilt_n_fetch */
void reson_n_fetch(register reson_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 c3_reg; register double c2_reg; register double c1_reg; register double y1_reg; register double y2_reg; register sample_block_values_type s_ptr_reg; falloc_sample_block(out, "reson_n_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; /* don't run past the s input sample block: */ susp_check_term_log_samples(s, s_ptr, s_cnt); togo = min(togo, susp->s_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; c3_reg = susp->c3; c2_reg = susp->c2; c1_reg = susp->c1; y1_reg = susp->y1; y2_reg = susp->y2; s_ptr_reg = susp->s_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ { double y0 = c1_reg * *s_ptr_reg++ + c2_reg * y1_reg - c3_reg * y2_reg; *out_ptr_reg++ = (sample_type) y0; y2_reg = y1_reg; y1_reg = y0; }; } while (--n); /* inner loop */ susp->y1 = y1_reg; susp->y2 = y2_reg; /* using s_ptr_reg is a bad idea on RS/6000: */ susp->s_ptr += togo; out_ptr += togo; susp_took(s_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* reson_n_fetch */
/* * The pitch (F0) is determined by finding two periods whose * inner product accounts for almost all of the energy. Let X and Y * be adjacent vectors of length N in the sample stream. Then, * if 2X*Y > threshold * (X*X + Y*Y) * then the period is given by N * In the algorithm, we compute different sizes until we find a * peak above threshold. Then, we use cubic interpolation to get * a precise value. If no peak above threshold is found, we return * the first peak. The second channel returns the value 2X*Y/(X*X+Y*Y) * which is refered to as the "harmonicity" -- the amount of energy * accounted for by periodicity. * * Low sample rates are advised because of the high cost of computing * inner products (fast autocorrelation is not used). * * The result is a 2-channel signal running at the requested rate. * The first channel is the estimated pitch, and the second channel * is the harmonicity. * * This code is adopted from multiread, currently the only other * multichannel suspension in Nyquist. Comments from multiread include: * The susp is shared by all channels. The susp has backpointers * to the tail-most snd_list node of each channel, and it is by * extending the list at these nodes that sounds are read in. * To avoid a circularity, the reference counts on snd_list nodes * do not include the backpointers from this susp. When a snd_list * node refcount goes to zero, the yin susp's free routine * is called. This must scan the backpointers to find the node that * has a zero refcount (the free routine is called before the node * is deallocated, so this is safe). The backpointer is then set * to NULL. When all backpointers are NULL, the susp itself is * deallocated, because it can only be referenced through the * snd_list nodes to which there are backpointers. */ void yin_fetch(snd_susp_type a_susp, snd_list_type snd_list) { yin_susp_type susp = (yin_susp_type) a_susp; int cnt = 0; /* how many samples computed */ int togo; int n; int i; sample_block_type f0; sample_block_values_type f0_ptr = NULL; sample_block_type harmonicity; sample_block_values_type harmonicity_ptr = NULL; register sample_block_values_type s_ptr_reg; register sample_type *fillptr_reg; register sample_type *endptr_reg = susp->endptr; /* DEBUG: print_ysnds("top of yin_fetch", susp); */ if (susp->chan[0]) { falloc_sample_block(f0, "yin_fetch"); f0_ptr = f0->samples; /* Since susp->chan[i] exists, we want to append a block of samples. * The block, out, has been allocated. Before we insert the block, * we must figure out whether to insert a new snd_list_type node for * the block. Recall that before SND_get_next is called, the last * snd_list_type in the list will have a null block pointer, and the * snd_list_type's susp field points to the suspension (in this case, * susp). When SND_get_next (in sound.c) is called, it appends a new * snd_list_type and points the previous one to internal_zero_block * before calling this fetch routine. On the other hand, since * SND_get_next is only going to be called on one of the channels, the * other channels will not have had a snd_list_type appended. * SND_get_next does not tell us directly which channel it wants (it * doesn't know), but we can test by looking for a non-null block in the * snd_list_type pointed to by our back-pointers in susp->chan[]. If * the block is null, the channel was untouched by SND_get_next, and * we should append a snd_list_type. If it is non-null, then it * points to internal_zero_block (the block inserted by SND_get_next) * and a new snd_list_type has already been appended. */ /* Before proceeding, it may be that garbage collection ran when we * allocated out, so check again to see if susp->chan[j] is Null: */ if (!susp->chan[0]) { ffree_sample_block(f0, "yin_fetch"); f0 = NULL; /* make sure we don't free it again */ f0_ptr = NULL; /* make sure we don't output f0 samples */ } else if (!susp->chan[0]->block) { snd_list_type snd_list = snd_list_create((snd_susp_type) susp); /* printf("created snd_list %x for chan 0 with susp %x\n", snd_list, snd_list->u.susp); */ /* Now we have a snd_list to append to the channel, but a very * interesting thing can happen here. snd_list_create, which * we just called, MAY have invoked the garbage collector, and * the GC MAY have freed all references to this channel, in which * case yin_free(susp) will have been called, and susp->chan[0] * will now be NULL! */ if (!susp->chan[0]) { ffree_snd_list(snd_list, "yin_fetch"); } else { susp->chan[0]->u.next = snd_list; } } /* see the note above: we don't know if susp->chan still exists */ /* Note: We DO know that susp still exists because even if we lost * some channels in a GC, someone is still calling SND_get_next on * some channel. I suppose that there might be some very pathological * code that could free a global reference to a sound that is in the * midst of being computed, perhaps by doing something bizarre in the * closure that snd_seq activates at the logical stop time of its first * sound, but I haven't thought that one through. */ if (susp->chan[0]) { susp->chan[0]->block = f0; /* check some assertions */ if (susp->chan[0]->u.next->u.susp != (snd_susp_type) susp) { nyquist_printf("didn't find susp at end of list for chan 0\n"); } } else if (f0) { /* we allocated f0, but don't need it anymore due to GC */ ffree_sample_block(f0, "yin_fetch"); f0_ptr = NULL; } } /* Now, repeat for channel 1 (comments omitted) */ if (susp->chan[1]) { falloc_sample_block(harmonicity, "yin_fetch"); harmonicity_ptr = harmonicity->samples; if (!susp->chan[1]) { ffree_sample_block(harmonicity, "yin_fetch"); harmonicity = NULL; /* make sure we don't free it again */ harmonicity_ptr = NULL; } else if (!susp->chan[1]->block) { snd_list_type snd_list = snd_list_create((snd_susp_type) susp); /* printf("created snd_list %x for chan 1 with susp %x\n", snd_list, snd_list->u.susp); */ if (!susp->chan[1]) { ffree_snd_list(snd_list, "yin_fetch"); } else { susp->chan[1]->u.next = snd_list; } } if (susp->chan[1]) { susp->chan[1]->block = harmonicity; if (susp->chan[1]->u.next->u.susp != (snd_susp_type) susp) { nyquist_printf("didn't find susp at end of list for chan 1\n"); } } else if (harmonicity) { /* we allocated harmonicity, but don't need it anymore due to GC */ ffree_sample_block(harmonicity, "yin_fetch"); harmonicity_ptr = NULL; } } /* DEBUG: print_ysnds("yin_fetch before outer loop", susp); */ 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) * susp->stepsize; /* don't run past the s input sample block */ susp_check_term_log_samples(s, s_ptr, s_cnt); togo = min(togo, susp->s_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo/susp->stepsize) { togo = (susp->terminate_cnt - (susp->susp.current + cnt)) * susp->stepsize; if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop = 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the output block) */ if (to_stop < togo/susp->stepsize) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we can set * the logical stop flag on this output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new block a the LST */ togo = to_stop * susp->stepsize; } } n = togo; s_ptr_reg = susp->s_ptr; fillptr_reg = susp->fillptr; if (n) do { /* the inner sample computation loop */ *fillptr_reg++ = *s_ptr_reg++; if (fillptr_reg >= endptr_reg) { float f0; float harmonicity; yin_compute(susp, &f0, &harmonicity); if (f0_ptr) *f0_ptr++ = f0; if (harmonicity_ptr) *harmonicity_ptr++ = harmonicity; cnt++; // shift block by stepsize memmove(susp->block, susp->block + susp->stepsize, sizeof(sample_type) * (susp->blocksize - susp->stepsize)); fillptr_reg -= susp->stepsize; } } while (--n); /* inner loop */ /* using s_ptr_reg is a bad idea on RS/6000: */ susp->s_ptr += togo; susp->fillptr = fillptr_reg; susp_took(s_cnt, togo); } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { /* single channels code: snd_list_terminate(snd_list); */ for (i = 0; i < 2; i++) { if (susp->chan[i]) { snd_list_type the_snd_list = susp->chan[i]; susp->chan[i] = the_snd_list->u.next; snd_list_terminate(the_snd_list); } } } else { /* single channel code: snd_list->block_len = cnt; */ susp->susp.current += cnt; for (i = 0; i < 2; i++) { if (susp->chan[i]) { susp->chan[i]->block_len = cnt; susp->chan[i] = susp->chan[i]->u.next; } } } /* test for logical stop */ if (susp->logically_stopped) { /* single channel code: snd_list->logically_stopped = true; */ if (susp->chan[0]) susp->chan[0]->logically_stopped = true; if (susp->chan[1]) susp->chan[1]->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* yin_fetch */
void offset_n_fetch(snd_susp_type a_susp, snd_list_type snd_list) { offset_susp_type susp = (offset_susp_type) a_susp; 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 sample_type offset_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "offset_n_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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < 0) to_stop = 0; /* avoids rounding errors */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; offset_reg = susp->offset; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = *s1_ptr_reg++ + offset_reg; } while (--n); /* inner loop */ /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* offset_n_fetch */
void up_i_fetch(register up_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ sample_type input_x2_sample; 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 input_pHaSe_iNcR_rEg = susp->input_pHaSe_iNcR; register double input_pHaSe_ReG; register sample_type input_x1_sample_reg; falloc_sample_block(out, "up_i_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp_check_term_log_samples(input, input_ptr, input_cnt); susp->input_x1_sample = susp_fetch_sample(input, input_ptr, input_cnt); } susp_check_term_log_samples(input, input_ptr, input_cnt); input_x2_sample = susp_current_sample(input, input_ptr); 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; /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; input_pHaSe_ReG = susp->input_pHaSe; input_x1_sample_reg = susp->input_x1_sample; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ if (input_pHaSe_ReG >= 1.0) { input_x1_sample_reg = input_x2_sample; /* pick up next sample as input_x2_sample: */ susp->input_ptr++; susp_took(input_cnt, 1); input_pHaSe_ReG -= 1.0; susp_check_term_log_samples_break(input, input_ptr, input_cnt, input_x2_sample); } *out_ptr_reg++ = (sample_type) (input_x1_sample_reg * (1 - input_pHaSe_ReG) + input_x2_sample * input_pHaSe_ReG); input_pHaSe_ReG += input_pHaSe_iNcR_rEg; } while (--n); /* inner loop */ togo -= n; susp->input_pHaSe = input_pHaSe_ReG; susp->input_x1_sample = input_x1_sample_reg; 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* up_i_fetch */
void chase_n_fetch(register chase_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 level_reg; register double upslope_reg; register double downslope_reg; register sample_block_values_type input_ptr_reg; falloc_sample_block(out, "chase_n_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; /* don't run past the input input sample block: */ susp_check_term_log_samples(input, input_ptr, input_cnt); togo = MIN(togo, susp->input_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; level_reg = susp->level; upslope_reg = susp->upslope; downslope_reg = susp->downslope; input_ptr_reg = susp->input_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ double x = *input_ptr_reg++; if (x > level_reg) { level_reg += upslope_reg; if (x < level_reg) level_reg = x; } else { level_reg -= downslope_reg; if (x > level_reg) level_reg = x; } *out_ptr_reg++ = (sample_type) level_reg;; } while (--n); /* inner loop */ susp->level = level_reg; susp->upslope = upslope_reg; susp->downslope = downslope_reg; /* using input_ptr_reg is a bad idea on RS/6000: */ susp->input_ptr += togo; out_ptr += togo; susp_took(input_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* chase_n_fetch */
void resonvc_ni_fetch(register resonvc_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 scale1_reg; register double c3co_reg; register double c3p1_reg; register double c3t4_reg; register double omc3_reg; register double c2_reg; register double c1_reg; register int normalization_reg; register double y1_reg; register double y2_reg; register double hz_pHaSe_iNcR_rEg = susp->hz_pHaSe_iNcR; register double hz_pHaSe_ReG; register sample_type hz_x1_sample_reg; register sample_block_values_type s1_ptr_reg; falloc_sample_block(out, "resonvc_ni_fetch"); out_ptr = out->samples; snd_list->block = out; /* make sure sounds are primed with first values */ if (!susp->started) { susp->started = true; susp_check_term_samples(hz, hz_ptr, hz_cnt); susp->hz_x1_sample = susp_fetch_sample(hz, hz_ptr, hz_cnt); susp->c2 = susp->c3t4 * cos(susp->hz_x1_sample) / susp->c3p1; susp->c1 = (susp->normalization == 0 ? susp->scale1 : (susp->normalization == 1 ? susp->omc3 * sqrt(1.0 - susp->c2 * susp->c2 / susp->c3t4) : sqrt(susp->c3p1 * susp->c3p1 - susp->c2 * susp->c2) * susp->omc3 / susp->c3p1)) * susp->scale1; } 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; /* don't run past the s1 input sample block: */ susp_check_term_log_samples(s1, s1_ptr, s1_cnt); togo = min(togo, susp->s1_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) { int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt); /* break if to_stop == 0 (we're at the logical stop) * AND cnt > 0 (we're not at the beginning of the * output block). */ if (to_stop < togo) { if (to_stop == 0) { if (cnt) { togo = 0; break; } else /* keep togo as is: since cnt == 0, we * can set the logical stop flag on this * output block */ susp->logically_stopped = true; } else /* limit togo so we can start a new * block at the LST */ togo = to_stop; } } n = togo; scale1_reg = susp->scale1; c3co_reg = susp->c3co; c3p1_reg = susp->c3p1; c3t4_reg = susp->c3t4; omc3_reg = susp->omc3; c2_reg = susp->c2; c1_reg = susp->c1; normalization_reg = susp->normalization; y1_reg = susp->y1; y2_reg = susp->y2; hz_pHaSe_ReG = susp->hz_pHaSe; hz_x1_sample_reg = susp->hz_x1_sample; s1_ptr_reg = susp->s1_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ if (hz_pHaSe_ReG >= 1.0) { /* fixup-depends hz */ /* pick up next sample as hz_x1_sample: */ susp->hz_ptr++; susp_took(hz_cnt, 1); hz_pHaSe_ReG -= 1.0; susp_check_term_samples_break(hz, hz_ptr, hz_cnt, hz_x1_sample_reg); hz_x1_sample_reg = susp_current_sample(hz, hz_ptr); c2_reg = susp->c2 = c3t4_reg * cos(hz_x1_sample_reg) / c3p1_reg; c1_reg = susp->c1 = (normalization_reg == 0 ? scale1_reg : (normalization_reg == 1 ? omc3_reg * sqrt(1.0 - c2_reg * c2_reg / c3t4_reg) : sqrt(c3p1_reg * c3p1_reg - c2_reg * c2_reg) * omc3_reg / c3p1_reg)) * scale1_reg; } { double y0 = c1_reg * *s1_ptr_reg++ + c2_reg * y1_reg - c3co_reg * y2_reg; *out_ptr_reg++ = (sample_type) y0; y2_reg = y1_reg; y1_reg = y0; }; hz_pHaSe_ReG += hz_pHaSe_iNcR_rEg; } while (--n); /* inner loop */ togo -= n; susp->y1 = y1_reg; susp->y2 = y2_reg; susp->hz_pHaSe = hz_pHaSe_ReG; susp->hz_x1_sample = hz_x1_sample_reg; /* using s1_ptr_reg is a bad idea on RS/6000: */ susp->s1_ptr += togo; out_ptr += togo; susp_took(s1_cnt, 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; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* resonvc_ni_fetch */