Esempio n. 1
0
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 */
Esempio n. 2
0
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 */
Esempio n. 3
0
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 */
Esempio n. 4
0
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 */
Esempio n. 5
0
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 */
Esempio n. 6
0
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 */
Esempio n. 7
0
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 */
Esempio n. 8
0
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 */
Esempio n. 9
0
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 */
Esempio n. 10
0
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 */
Esempio n. 11
0
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 */
Esempio n. 12
0
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 */
Esempio n. 13
0
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 */
Esempio n. 14
0
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 */
Esempio n. 15
0
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 */
Esempio n. 16
0
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 */
Esempio n. 17
0
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 */
Esempio n. 18
0
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 */
Esempio n. 19
0
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 */
Esempio n. 20
0
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 */
Esempio n. 21
0
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 */
Esempio n. 22
0
/*
 * 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 */
Esempio n. 23
0
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 */
Esempio n. 24
0
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 */
Esempio n. 25
0
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 */
Esempio n. 26
0
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 */