sound_type snd_make_slider(int index, time_type t0, rate_type sr, time_type d) { register slider_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; if (index < 0 || index >= SLIDERS_MAX) { xlfail("slider index out of range"); } falloc_generic(susp, slider_susp_node, "snd_make_slider"); susp->susp.fetch = slider__fetch; susp->index = index; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = slider_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = slider_print_tree; susp->susp.name = "slider"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_ifft(time_type t0, rate_type sr, LVAL src, long stepsize, LVAL window) { register ifft_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, ifft_susp_node, "snd_make_ifft"); susp->index = stepsize; susp->length = 0; susp->array = NULL; susp->window_len = 0; susp->outbuf = NULL; susp->src = src; susp->stepsize = stepsize; susp->window = NULL; susp->samples = NULL; susp->table = get_window_samples(window, &susp->window, &susp->window_len); susp->susp.fetch = ifft__fetch; /* initialize susp state */ susp->susp.free = ifft_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = ifft_mark; susp->susp.print_tree = ifft_print_tree; susp->susp.name = "ifft"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_log(sound_type input) { register log_susp_type susp; rate_type sr = input->sr; time_type t0 = input->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, log_susp_node, "snd_make_log"); susp->susp.fetch = log_s_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < input->t0) sound_prepend_zeros(input, t0); /* minimum start time over all inputs: */ t0_min = min(input->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = log_toss_fetch; } /* initialize susp state */ susp->susp.free = log_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = log_mark; susp->susp.print_tree = log_print_tree; susp->susp.name = "log"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(input); susp->susp.current = 0; susp->input = input; susp->input_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_mandolin(time_type t0, double freq, time_type d, double body_size, double detune, rate_type sr) { register mandolin_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, mandolin_susp_node, "snd_make_mandolin"); susp->mymand = initInstrument(MANDOLIN, round(sr)); controlChange(susp->mymand, 1, detune); controlChange(susp->mymand, 2, MAND_CONTROL_CHANGE_CONST * body_size);; susp->temp_ret_value = noteOn(susp->mymand, freq, 1.0); susp->susp.fetch = mandolin__fetch; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = mandolin_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = mandolin_print_tree; susp->susp.name = "mandolin"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_pwl(time_type t0, rate_type sr, LVAL lis) { register pwl_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, pwl_susp_node, "snd_make_pwl"); susp->bpt_ptr = lis; susp->incr = 0.0; susp->lvl = 0.0; { long temp = 0; compute_incr(susp, &temp, 0); }; susp->susp.fetch = pwl__fetch; /* initialize susp state */ susp->susp.free = pwl_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = pwl_mark; susp->susp.print_tree = pwl_print_tree; susp->susp.name = "pwl"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_reson(sound_type s, double hz, double bw, int normalization) { register reson_susp_type susp; rate_type sr = s->sr; time_type t0 = s->t0; int interp_desc = 0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, reson_susp_node, "snd_make_reson"); susp->c3 = exp(bw * -PI2 / s->sr); susp->c3p1 = susp->c3 + 1.0; susp->c3t4 = susp->c3 * 4.0; susp->omc3 = 1.0 - susp->c3; susp->c2 = susp->c3t4 * cos(hz * PI2 / s->sr) / susp->c3p1; susp->c1 = (normalization == 0 ? 1.0 : (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->y1 = 0.0; susp->y2 = 0.0; /* select a susp fn based on sample rates */ interp_desc = (interp_desc << 2) + interp_style(s, sr); switch (interp_desc) { case INTERP_n: susp->susp.fetch = reson_n_fetch; break; case INTERP_s: susp->susp.fetch = reson_s_fetch; break; default: snd_badsr(); break; } susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s->t0) sound_prepend_zeros(s, t0); /* minimum start time over all inputs: */ t0_min = min(s->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = reson_toss_fetch; } /* initialize susp state */ susp->susp.free = reson_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = reson_mark; susp->susp.print_tree = reson_print_tree; susp->susp.name = "reson"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s); susp->susp.current = 0; susp->s = s; susp->s_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
LVAL snd_make_yin(sound_type s, double low_step, double high_step, long stepsize) { LVAL result; int j; register yin_susp_type susp; rate_type sr = s->sr; time_type t0 = s->t0; falloc_generic(susp, yin_susp_node, "snd_make_yin"); susp->susp.fetch = yin_fetch; susp->terminate_cnt = UNKNOWN; /* initialize susp state */ susp->susp.free = yin_free; susp->susp.sr = sr / stepsize; susp->susp.t0 = t0; susp->susp.mark = yin_mark; susp->susp.print_tree = yin_print_tree; susp->susp.name = "yin"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s); susp->susp.current = 0; susp->s = s; susp->s_cnt = 0; susp->m = (long) (sr / step_to_hz(high_step)); if (susp->m < 2) susp->m = 2; /* add 1 to make sure we round up */ susp->middle = (long) (sr / step_to_hz(low_step)) + 1; susp->blocksize = susp->middle * 2; susp->stepsize = stepsize; /* blocksize must be at least step size to implement stepping */ if (susp->stepsize > susp->blocksize) susp->blocksize = susp->stepsize; susp->block = (sample_type *) malloc(susp->blocksize * sizeof(sample_type)); susp->temp = (float *) malloc((susp->middle - susp->m + 1) * sizeof(float)); susp->fillptr = susp->block; susp->endptr = susp->block + susp->blocksize; xlsave1(result); result = newvector(2); /* create array for F0 and harmonicity */ /* create sounds to return */ for (j = 0; j < 2; j++) { sound_type snd = sound_create((snd_susp_type)susp, susp->susp.t0, susp->susp.sr, 1.0); LVAL snd_lval = cvsound(snd); /* nyquist_printf("yin_create: sound %d is %x, LVAL %x\n", j, snd, snd_lval); */ setelement(result, j, snd_lval); susp->chan[j] = snd->list; /* DEBUG: ysnd[j] = snd; */ } xlpop(); return result; }
sound_type snd_make_flute_freq(double freq, sound_type breath_env, sound_type freq_env, rate_type sr) { register flute_freq_susp_type susp; /* sr specified as input parameter */ time_type t0 = breath_env->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, flute_freq_susp_node, "snd_make_flute_freq"); susp->myflute = initInstrument(FLUTE, round(sr)); controlChange(susp->myflute, 1, 0.0);; susp->temp_ret_value = noteOn(susp->myflute, freq, 1.0); susp->breath_scale = breath_env->scale * FLUTE_CONTROL_CHANGE_CONST; susp->frequency = freq; /* make sure no sample rate is too high */ if (breath_env->sr > sr) { sound_unref(breath_env); snd_badsr(); } else if (breath_env->sr < sr) breath_env = snd_make_up(sr, breath_env); if (freq_env->sr > sr) { sound_unref(freq_env); snd_badsr(); } else if (freq_env->sr < sr) freq_env = snd_make_up(sr, freq_env); susp->susp.fetch = flute_freq_ns_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < breath_env->t0) sound_prepend_zeros(breath_env, t0); if (t0 < freq_env->t0) sound_prepend_zeros(freq_env, t0); /* minimum start time over all inputs: */ t0_min = min(breath_env->t0, min(freq_env->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = flute_freq_toss_fetch; } /* initialize susp state */ susp->susp.free = flute_freq_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = flute_freq_mark; susp->susp.print_tree = flute_freq_print_tree; susp->susp.name = "flute_freq"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->breath_env = breath_env; susp->breath_env_cnt = 0; susp->freq_env = freq_env; susp->freq_env_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void nyx_set_input_audio(nyx_audio_callback callback, void *userdata, int num_channels, long len, double rate) { LVAL val; int ch; nyx_set_audio_params(rate, len); if (num_channels > 1) { val = newvector(num_channels); } xlprot1(val); for (ch = 0; ch < num_channels; ch++) { nyx_susp_type susp; sound_type snd; falloc_generic(susp, nyx_susp_node, "nyx_set_input_audio"); susp->callback = callback; susp->userdata = userdata; susp->len = len; susp->channel = ch; susp->susp.fetch = nyx_susp_fetch; susp->susp.keep_fetch = NULL; susp->susp.free = nyx_susp_free; susp->susp.mark = NULL; susp->susp.print_tree = nyx_susp_print_tree; susp->susp.name = "nyx"; susp->susp.toss_cnt = 0; susp->susp.current = 0; susp->susp.sr = rate; susp->susp.t0 = 0.0; susp->susp.log_stop_cnt = 0; snd = sound_create((snd_susp_type) susp, 0.0, rate, 1.0); if (num_channels > 1) { setelement(val, ch, cvsound(snd)); } else { val = cvsound(snd); } } setvalue(xlenter("S"), val); xlpop(); }
sound_type snd_make_clip(sound_type s, double level) { register clip_susp_type susp; rate_type sr = s->sr; time_type t0 = s->t0; int interp_desc = 0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, clip_susp_node, "snd_make_clip"); susp->level = (sample_type) level; /* select a susp fn based on sample rates */ interp_desc = (interp_desc << 2) + interp_style(s, sr); switch (interp_desc) { case INTERP_n: susp->susp.fetch = clip_n_fetch; break; case INTERP_s: susp->susp.fetch = clip_s_fetch; break; default: snd_badsr(); break; } susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s->t0) sound_prepend_zeros(s, t0); /* minimum start time over all inputs: */ t0_min = min(s->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = clip_toss_fetch; } /* initialize susp state */ susp->susp.free = clip_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = clip_mark; susp->susp.print_tree = clip_print_tree; susp->susp.name = "clip"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s); susp->susp.current = 0; susp->s = s; susp->s_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_follow(sound_type sndin, double floor, double risetime, double falltime, long lookahead) { register follow_susp_type susp; rate_type sr = sndin->sr; time_type t0 = sndin->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, follow_susp_node, "snd_make_follow"); susp->lookahead = lookahead = lookahead + 1; susp->delaybuf = create_buf(floor, lookahead); susp->delayptr = susp->delaybuf; susp->prevptr = susp->delaybuf + lookahead - 1; *(susp->prevptr) = (sample_type) floor;; susp->endptr = susp->delaybuf + lookahead; susp->floor = floor; floor = log(floor);; susp->rise_factor = exp(- floor / (sndin->sr * risetime + 0.5)); susp->fall_factor = exp(floor / (sndin->sr * falltime + 0.5)); susp->value = susp->floor; susp->susp.fetch = follow_s_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < sndin->t0) sound_prepend_zeros(sndin, t0); /* minimum start time over all inputs: */ t0_min = min(sndin->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = follow_toss_fetch; } /* initialize susp state */ susp->susp.free = follow_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = follow_mark; susp->susp.print_tree = follow_print_tree; susp->susp.name = "follow"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->sndin = sndin; susp->sndin_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_stkchorus(sound_type s1, double baseDelay, double depth, double freq, double mix) { register stkchorus_susp_type susp; rate_type sr = s1->sr; time_type t0 = s1->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; /* combine scale factors of linear inputs (S1) */ scale_factor *= s1->scale; s1->scale = 1.0F; /* try to push scale_factor back to a low sr input */ if (s1->sr < sr) { s1->scale = scale_factor; scale_factor = 1.0F; } falloc_generic(susp, stkchorus_susp_node, "snd_make_stkchorus"); susp->mych = initStkChorus(baseDelay, depth, freq, round(sr)); stkEffectSetMix(susp->mych, mix); susp->susp.fetch = stkchorus_n_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s1->t0) sound_prepend_zeros(s1, t0); /* minimum start time over all inputs: */ t0_min = min(s1->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = stkchorus_toss_fetch; } /* initialize susp state */ susp->susp.free = stkchorus_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = stkchorus_mark; susp->susp.print_tree = stkchorus_print_tree; susp->susp.name = "stkchorus"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s1); susp->susp.current = 0; susp->s1 = s1; susp->s1_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_abs(sound_type input) { register abs_susp_type susp; rate_type sr = input->sr; time_type t0 = input->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; /* combine scale factors of linear inputs (INPUT) */ scale_factor *= input->scale; input->scale = 1.0F; /* try to push scale_factor back to a low sr input */ if (input->sr < sr) { input->scale = scale_factor; scale_factor = 1.0F; } falloc_generic(susp, abs_susp_node, "snd_make_abs"); susp->susp.fetch = abs_n_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < input->t0) sound_prepend_zeros(input, t0); /* minimum start time over all inputs: */ t0_min = min(input->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = abs_toss_fetch; } /* initialize susp state */ susp->susp.free = abs_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = abs_mark; susp->susp.print_tree = abs_print_tree; susp->susp.name = "abs"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(input); susp->susp.current = 0; susp->input = input; susp->input_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_whiteg(time_type t0, rate_type sr, time_type d) { register whiteg_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, whiteg_susp_node, "snd_make_whiteg"); susp->susp.fetch = whiteg__fetch; susp->terminate_cnt = check_terminate_cnt(round((d) * sr)); /* initialize susp state */ susp->susp.free = whiteg_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = whiteg_print_tree; susp->susp.name = "whiteg"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_const(double c, time_type t0, rate_type sr, time_type d) { register const_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, const_susp_node, "snd_make_const"); susp->c = (sample_type) c; susp->susp.fetch = const__fetch; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = const_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = const_print_tree; susp->susp.name = "const"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_fromobject(time_type t0, rate_type sr, LVAL src) { register fromobject_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, fromobject_susp_node, "snd_make_fromobject"); susp->done = false; susp->src = src; susp->susp.fetch = fromobject__fetch; /* initialize susp state */ susp->susp.free = fromobject_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = fromobject_mark; susp->susp.print_tree = fromobject_print_tree; susp->susp.name = "fromobject"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_pvshell(char *name, rate_type sr, time_type t0, h_fn_type h, pvs_free_fn_type free_fn, sound_type f, sound_type g, void *state, long n) { register pvshell_susp_type susp; falloc_generic(susp, pvshell_susp_node, "snd_make_pvshell"); susp->susp.fetch = pvshell_fetch; /* initialize susp state */ susp->susp.free = pvshell_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = pvshell_mark; susp->susp.print_tree = pvshell_print_tree; susp->susp.name = name; susp->logically_stopped = false; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; /* copy the sound so that we have a private "reader" object */ susp->pvshell.f = (f ? sound_copy(f) : f); susp->pvshell.f_cnt = 0; susp->pvshell.g = (g ? sound_copy(g) : g); susp->pvshell.g_cnt = 0; susp->pvshell.h = h; susp->pvshell.free_fn = free_fn; susp->pvshell.flags = 0; /* terminated and logically stopped flags -- these are for the client of pvshell to use */ assert(n <= PVSHELL_STATE_MAX); memcpy(susp->pvshell.state, state, n); susp->started = false; return sound_create((snd_susp_type)susp, t0, sr, 1.0); }
sound_type snd_make_sine(time_type t0, double hz, rate_type sr, time_type d) { register sine_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, sine_susp_node, "snd_make_sine"); susp->phase = 0; susp->ph_incr = round(((hz * SINE_TABLE_LEN) * (1 << SINE_TABLE_SHIFT) / sr)); susp->susp.fetch = sine__fetch; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = sine_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = sine_print_tree; susp->susp.name = "sine"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_sitar(time_type t0, double freq, time_type dur, rate_type sr) { register sitar_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, sitar_susp_node, "snd_make_sitar"); susp->mysitar = initInstrument(SITAR, round(sr)); susp->temp_ret_value = noteOn(susp->mysitar, freq, 1.0); susp->susp.fetch = sitar__fetch; susp->terminate_cnt = round((dur) * sr); /* initialize susp state */ susp->susp.free = sitar_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = sitar_print_tree; susp->susp.name = "sitar"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_quantize(sound_type s1, long steps) { register quantize_susp_type susp; rate_type sr = s1->sr; time_type t0 = s1->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, quantize_susp_node, "snd_make_quantize"); susp->factor = s1->scale * steps; scale_factor = (sample_type) (1.0 / steps);; susp->susp.fetch = quantize_n_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s1->t0) sound_prepend_zeros(s1, t0); /* minimum start time over all inputs: */ t0_min = min(s1->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = quantize_toss_fetch; } /* initialize susp state */ susp->susp.free = quantize_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = quantize_mark; susp->susp.print_tree = quantize_print_tree; susp->susp.name = "quantize"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s1); susp->susp.current = 0; susp->s1 = s1; susp->s1_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_alpassvc(sound_type input, sound_type delaysnd, double feedback, double maxdelay) { register alpassvc_susp_type susp; rate_type sr = input->sr; time_type t0 = max(input->t0, delaysnd->t0); int interp_desc = 0; sample_type scale_factor = 1.0F; time_type t0_min = t0; /* combine scale factors of linear inputs (INPUT) */ scale_factor *= input->scale; input->scale = 1.0F; /* try to push scale_factor back to a low sr input */ if (input->sr < sr) { input->scale = scale_factor; scale_factor = 1.0F; } falloc_generic(susp, alpassvc_susp_node, "snd_make_alpassvc"); susp->delay_scale_factor = (float) (input->sr * delaysnd->scale); susp->feedback = feedback; susp->buflen = max(2, (long) (input->sr * maxdelay + 2.5)); susp->delaybuf = (sample_type *) calloc (susp->buflen + 1, sizeof(sample_type)); susp->delayptr = susp->delaybuf; susp->endptr = susp->delaybuf + susp->buflen; /* make sure no sample rate is too high */ if (delaysnd->sr > sr) { sound_unref(delaysnd); snd_badsr(); } /* select a susp fn based on sample rates */ interp_desc = (interp_desc << 2) + interp_style(input, sr); interp_desc = (interp_desc << 2) + interp_style(delaysnd, sr); switch (interp_desc) { case INTERP_ns: /* handled below */ case INTERP_nn: susp->susp.fetch = alpassvc_nn_fetch; break; case INTERP_ni: susp->susp.fetch = alpassvc_ni_fetch; break; case INTERP_nr: susp->susp.fetch = alpassvc_nr_fetch; break; default: snd_badsr(); break; } susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < input->t0) sound_prepend_zeros(input, t0); if (t0 < delaysnd->t0) sound_prepend_zeros(delaysnd, t0); /* minimum start time over all inputs: */ t0_min = min(input->t0, min(delaysnd->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = alpassvc_toss_fetch; } /* initialize susp state */ susp->susp.free = alpassvc_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = alpassvc_mark; susp->susp.print_tree = alpassvc_print_tree; susp->susp.name = "alpassvc"; susp->susp.log_stop_cnt = UNKNOWN; susp->started = false; susp->susp.current = 0; susp->input = input; susp->input_cnt = 0; susp->delaysnd = delaysnd; susp->delaysnd_cnt = 0; susp->delaysnd_pHaSe = 0.0; susp->delaysnd_pHaSe_iNcR = delaysnd->sr / sr; susp->delaysnd_n = 0; susp->output_per_delaysnd = sr / delaysnd->sr; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_coterm(sound_type s1, sound_type s2) { register coterm_susp_type susp; rate_type sr = s1->sr; time_type t0 = max(s1->t0, s2->t0); int interp_desc = 0; sample_type scale_factor = 1.0F; time_type t0_min = t0; long lsc; /* combine scale factors of linear inputs (S1) */ scale_factor *= s1->scale; s1->scale = 1.0F; /* try to push scale_factor back to a low sr input */ if (s1->sr < sr) { s1->scale = scale_factor; scale_factor = 1.0F; } falloc_generic(susp, coterm_susp_node, "snd_make_coterm"); /* make sure no sample rate is too high */ if (s2->sr > sr) { sound_unref(s2); snd_badsr(); } /* select a susp fn based on sample rates */ interp_desc = (interp_desc << 2) + interp_style(s1, sr); interp_desc = (interp_desc << 2) + interp_style(s2, sr); switch (interp_desc) { case INTERP_ns: /* handled below */ case INTERP_nn: susp->susp.fetch = coterm_nn_fetch; break; case INTERP_ni: susp->susp.fetch = coterm_ni_fetch; break; case INTERP_nr: susp->susp.fetch = coterm_nr_fetch; break; default: snd_badsr(); break; } susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s1->t0) sound_prepend_zeros(s1, t0); if (t0 < s2->t0) sound_prepend_zeros(s2, t0); /* minimum start time over all inputs: */ t0_min = min(s1->t0, min(s2->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = coterm_toss_fetch; } /* initialize susp state */ susp->susp.free = coterm_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = coterm_mark; susp->susp.print_tree = coterm_print_tree; susp->susp.name = "coterm"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s1); lsc = logical_stop_cnt_cvt(s2); if (susp->susp.log_stop_cnt > lsc) susp->susp.log_stop_cnt = lsc; susp->started = false; susp->susp.current = 0; susp->s1 = s1; susp->s1_cnt = 0; susp->s2 = s2; susp->s2_cnt = 0; susp->s2_pHaSe = 0.0; susp->s2_pHaSe_iNcR = s2->sr / sr; susp->s2_n = 0; susp->output_per_s2 = sr / s2->sr; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
sound_type snd_make_tonev(sound_type s1, sound_type hz) { register tonev_susp_type susp; rate_type sr = s1->sr; time_type t0 = max(s1->t0, hz->t0); int interp_desc = 0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, tonev_susp_node, "snd_make_tonev"); susp->scale1 = s1->scale; susp->c2 = 0.0; susp->c1 = 0.0; susp->prev = 0.0; hz->scale = (sample_type) (hz->scale * (PI2 / s1->sr)); /* make sure no sample rate is too high */ if (hz->sr > sr) { sound_unref(hz); snd_badsr(); } /* select a susp fn based on sample rates */ interp_desc = (interp_desc << 2) + interp_style(s1, sr); interp_desc = (interp_desc << 2) + interp_style(hz, sr); switch (interp_desc) { case INTERP_sn: /* handled below */ case INTERP_ss: /* handled below */ case INTERP_nn: /* handled below */ case INTERP_ns: susp->susp.fetch = tonev_ns_fetch; break; case INTERP_si: /* handled below */ case INTERP_ni: susp->susp.fetch = tonev_ni_fetch; break; case INTERP_sr: /* handled below */ case INTERP_nr: susp->susp.fetch = tonev_nr_fetch; break; default: snd_badsr(); break; } susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < s1->t0) sound_prepend_zeros(s1, t0); if (t0 < hz->t0) sound_prepend_zeros(hz, t0); /* minimum start time over all inputs: */ t0_min = min(s1->t0, min(hz->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = tonev_toss_fetch; } /* initialize susp state */ susp->susp.free = tonev_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = tonev_mark; susp->susp.print_tree = tonev_print_tree; susp->susp.name = "tonev"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s1); susp->started = false; susp->susp.current = 0; susp->s1 = s1; susp->s1_cnt = 0; susp->hz = hz; susp->hz_cnt = 0; susp->hz_pHaSe = 0.0; susp->hz_pHaSe_iNcR = hz->sr / sr; susp->hz_n = 0; susp->output_per_hz = sr / hz->sr; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void nyx_set_input_audio(nyx_audio_callback callback, void *userdata, int num_channels, long len, double rate) { sample_type scale_factor = 1.0; time_type t0 = 0.0; nyx_susp_type *susp; sound_type *snd; double stretch_len; LVAL warp; int ch; susp = (nyx_susp_type *)malloc(num_channels * sizeof(nyx_susp_type)); snd = (sound_type *)malloc(num_channels * sizeof(sound_type)); for(ch=0; ch < num_channels; ch++) { falloc_generic(susp[ch], nyx_susp_node, "nyx_set_input_audio"); susp[ch]->callback = callback; susp[ch]->userdata = userdata; susp[ch]->len = len; susp[ch]->channel = ch; susp[ch]->susp.sr = rate; susp[ch]->susp.t0 = t0; susp[ch]->susp.mark = NULL; susp[ch]->susp.print_tree = nyx_susp_print_tree; susp[ch]->susp.current = 0; susp[ch]->susp.fetch = nyx_susp_fetch; susp[ch]->susp.free = nyx_susp_free; susp[ch]->susp.name = "nyx"; snd[ch] = sound_create((snd_susp_type)susp[ch], t0, rate, scale_factor); } /* Bind the sample rate to the "*sound-srate*" global */ setvalue(xlenter("*SOUND-SRATE*"), cvflonum(rate)); /* Bind selection len to "len" global */ setvalue(xlenter("LEN"), cvflonum(len)); if (len > 0) stretch_len = len / rate; else stretch_len = 1.0; /* Set the "*warp*" global based on the length of the audio */ xlprot1(warp); warp = cons(cvflonum(0), /* time offset */ cons(cvflonum(stretch_len), /* time stretch */ cons(NULL, /* cont. time warp */ NULL))); setvalue(xlenter("*WARP*"), warp); xlpop(); if (num_channels > 1) { LVAL array = newvector(num_channels); for(ch=0; ch<num_channels; ch++) setelement(array, ch, cvsound(snd[ch])); setvalue(xlenter("S"), array); } else { LVAL s = cvsound(snd[0]); setvalue(xlenter("S"), s); } }
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 */
sound_type snd_make_convolve(sound_type x_snd, sound_type h_snd) { register convolve_susp_type susp; rate_type sr = x_snd->sr; time_type t0 = x_snd->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; table_type table; double log_len; falloc_generic(susp, convolve_susp_node, "snd_make_convolve"); table = sound_to_table(h_snd); susp->h_len = table->length; log_len = log(table->length) / M_LN2; /* compute log-base-2(length) */ susp->M = (int) log_len; if (susp->M != log_len) susp->M++; /* round up */ susp->N = 1 << susp->M; /* size of data blocks */ susp->M++; /* M = log2(2 * N) */ susp->H = (sample_type *) calloc(2 * susp->N, sizeof(susp->H[0])); if (!susp->H) { xlabort("memory allocation failure in convolve"); } memcpy(susp->H, table->samples, sizeof(susp->H[0]) * susp->N); table_unref(table); /* don't need table now */ /* remaining N samples are already zero-filled */ if (fftInit(susp->M)) { free(susp->H); xlabort("fft initialization error in convolve"); } rffts(susp->H, susp->M, 1); susp->X = (sample_type *) calloc(2 * susp->N, sizeof(susp->X[0])); susp->R = (sample_type *) calloc(2 * susp->N, sizeof(susp->R[0])); if (!susp->X || !susp->R) { free(susp->H); if (susp->X) free(susp->X); if (susp->R) free(susp->R); xlabort("memory allocation failed in convolve"); } susp->R_current = susp->R + susp->N; susp->susp.fetch = &convolve_s_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < x_snd->t0) sound_prepend_zeros(x_snd, t0); /* minimum start time over all inputs: */ t0_min = min(x_snd->t0, t0); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = convolve_toss_fetch; } /* initialize susp state */ susp->susp.free = convolve_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = convolve_mark; susp->susp.print_tree = convolve_print_tree; susp->susp.name = "convolve"; susp->logically_stopped = false; susp->susp.log_stop_cnt = logical_stop_cnt_cvt(x_snd); susp->susp.current = 0; susp->x_snd = x_snd; susp->x_snd_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
LVAL snd_make_read( unsigned char *filename, /* file to read */ time_type offset, /* offset to skip (in seconds) */ time_type t0, /* start time of resulting sound */ long *format, /* AIFF, IRCAM, NeXT, etc. */ long *channels, /* number of channels */ long *mode, /* sample format: PCM, ALAW, etc. */ long *bits, /* BPS: bits per sample */ long *swap, /* swap bytes */ double *srate, /* srate: sample rate */ double *dur, /* duration (in seconds) to read */ long *flags, /* which parameters have been set */ long *byte_offset) /* byte offset in file of first sample */ { register read_susp_type susp; /* srate specified as input parameter */ sample_type scale_factor = 1.0F; sf_count_t frames; double actual_dur; falloc_generic(susp, read_susp_node, "snd_make_read"); memset(&(susp->sf_info), 0, sizeof(SF_INFO)); susp->sf_info.samplerate = ROUND(*srate); susp->sf_info.channels = *channels; switch (*mode) { case SND_MODE_ADPCM: susp->sf_info.format = SF_FORMAT_IMA_ADPCM; break; case SND_MODE_PCM: if (*bits == 8) susp->sf_info.format = SF_FORMAT_PCM_S8; else if (*bits == 16) susp->sf_info.format = SF_FORMAT_PCM_16; else if (*bits == 24) susp->sf_info.format = SF_FORMAT_PCM_24; else if (*bits == 32) susp->sf_info.format = SF_FORMAT_PCM_32; else { susp->sf_info.format = SF_FORMAT_PCM_16; *bits = 16; } break; case SND_MODE_ULAW: susp->sf_info.format = SF_FORMAT_ULAW; break; case SND_MODE_ALAW: susp->sf_info.format = SF_FORMAT_ALAW; break; case SND_MODE_FLOAT: susp->sf_info.format = SF_FORMAT_FLOAT; break; case SND_MODE_UPCM: susp->sf_info.format = SF_FORMAT_PCM_U8; *bits = 8; break; } if (*format == SND_HEAD_RAW) susp->sf_info.format |= SF_FORMAT_RAW; if (*swap) { /* set format to perform a byte swap (change from cpu endian-ness) */ /* write the code so it will only compile if one and only one ENDIAN setting is defined */ #ifdef XL_LITTLE_ENDIAN long format = SF_ENDIAN_BIG; #endif #ifdef XL_BIG_ENDIAN long format = SF_ENDIAN_LITTLE; #endif susp->sf_info.format |= format; } susp->sndfile = NULL; if (ok_to_open((const char *) filename, "rb")) susp->sndfile = sf_open((const char *) filename, SFM_READ, &(susp->sf_info)); if (!susp->sndfile) { char error[240]; sprintf(error, "SND-READ: Cannot open file '%s' because of %s", filename, sf_strerror(susp->sndfile)); xlfail(error); } if (susp->sf_info.channels < 1) { sf_close(susp->sndfile); xlfail("Must specify 1 or more channels"); } /* report samplerate from file, but if user provided a double * as sample rate, don't replace it with an integer. */ if ((susp->sf_info.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { *srate = susp->sf_info.samplerate; } /* compute dur */ frames = sf_seek(susp->sndfile, 0, SEEK_END); actual_dur = ((double) frames) / *srate; if (offset < 0) offset = 0; /* round offset to an integer frame count */ frames = (sf_count_t) (offset * *srate + 0.5); offset = ((double) frames) / *srate; actual_dur -= offset; if (actual_dur < 0) { sf_close(susp->sndfile); xlfail("SND-READ: offset is beyond end of file"); } if (actual_dur < *dur) *dur = actual_dur; sf_seek(susp->sndfile, frames, SEEK_SET); /* return to read loc in file */ /* initialize susp state */ susp->susp.sr = *srate; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = read_print_tree; /*jlh empty function... */ susp->susp.current = 0; susp->susp.log_stop_cnt = UNKNOWN; /* watch for overflow */ if (*dur * *srate + 0.5 > (unsigned long) 0xFFFFFFFF) { susp->cnt = 0x7FFFFFFF; } else { susp->cnt = ROUND((*dur) * *srate); } switch (susp->sf_info.format & SF_FORMAT_TYPEMASK) { case SF_FORMAT_WAV: *format = SND_HEAD_WAVE; break; case SF_FORMAT_AIFF: *format = SND_HEAD_AIFF; break; case SF_FORMAT_AU: *format = SND_HEAD_NEXT; break; case SF_FORMAT_RAW: *format = SND_HEAD_RAW; break; case SF_FORMAT_PAF: *format = SND_HEAD_PAF; break; case SF_FORMAT_SVX: *format = SND_HEAD_SVX; break; case SF_FORMAT_NIST: *format = SND_HEAD_NIST; break; case SF_FORMAT_VOC: *format = SND_HEAD_VOC; break; case SF_FORMAT_W64: *format = SND_HEAD_W64; break; case SF_FORMAT_MAT4: *format = SND_HEAD_MAT4; break; case SF_FORMAT_MAT5: *format = SND_HEAD_MAT5; break; case SF_FORMAT_PVF: *format = SND_HEAD_PVF; break; case SF_FORMAT_XI: *format = SND_HEAD_XI; break; case SF_FORMAT_HTK: *mode = SND_HEAD_HTK; break; case SF_FORMAT_SDS: *mode = SND_HEAD_SDS; break; case SF_FORMAT_AVR: *mode = SND_HEAD_AVR; break; case SF_FORMAT_WAVEX: *format = SND_HEAD_WAVE; break; case SF_FORMAT_SD2: *format = SND_HEAD_SD2; break; case SF_FORMAT_FLAC: *format = SND_HEAD_FLAC; break; case SF_FORMAT_CAF: *format = SND_HEAD_CAF; break; case SF_FORMAT_OGG: *format = SND_HEAD_OGG; break; default: *format = SND_HEAD_NONE; break; } *channels = susp->sf_info.channels; switch (susp->sf_info.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: *bits = 8; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_16: *bits = 16; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_24: *bits = 24; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_32: *bits = 32; *mode = SND_MODE_PCM; break; case SF_FORMAT_PCM_U8: *bits = 8; *mode = SND_MODE_UPCM; break; case SF_FORMAT_FLOAT: *bits = 32; *mode = SND_MODE_FLOAT; break; case SF_FORMAT_DOUBLE: *bits = 64; *mode = SND_MODE_DOUBLE; break; case SF_FORMAT_ULAW: *bits = 8; *mode = SND_MODE_ULAW; break; case SF_FORMAT_ALAW: *bits = 8; *mode = SND_MODE_ALAW; break; case SF_FORMAT_IMA_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_MS_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_GSM610: *bits = 16; *mode = SND_MODE_GSM610; break; case SF_FORMAT_VOX_ADPCM: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G721_32: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G723_24: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_G723_40: *bits = 16; *mode = SND_MODE_ADPCM; break; case SF_FORMAT_DWVW_12: *bits = 12; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_16: *bits = 16; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_24: *bits = 24; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DWVW_N: *bits = 32; *mode = SND_MODE_DWVW; break; case SF_FORMAT_DPCM_8: *bits = 8; *mode = SND_MODE_DPCM; break; case SF_FORMAT_DPCM_16: *bits = 16; *mode = SND_MODE_DPCM; break; default: *mode = SND_MODE_UNKNOWN; break; } sndread_file_open_count++; #ifdef MACINTOSH if (sndread_file_open_count > 24) { nyquist_printf("Warning: more than 24 sound files are now open\n"); } #endif /* report info back to caller */ if ((susp->sf_info.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { *flags = SND_HEAD_CHANNELS | SND_HEAD_MODE | SND_HEAD_BITS | SND_HEAD_SRATE | SND_HEAD_LEN | SND_HEAD_TYPE; } if (susp->sf_info.channels == 1) { susp->susp.fetch = read__fetch; susp->susp.free = read_free; susp->susp.name = "read"; return cvsound(sound_create((snd_susp_type)susp, t0, *srate, scale_factor)); } else { susp->susp.fetch = multiread_fetch; susp->susp.free = multiread_free; susp->susp.name = "multiread"; return multiread_create(susp); } }
sound_type snd_make_sax_all(double freq, sound_type breath_env, sound_type freq_env, double vibrato_freq, double vibrato_gain, sound_type reed_stiffness, sound_type noise_env, sound_type blow_pos, sound_type reed_table_offset, rate_type sr) { register sax_all_susp_type susp; /* sr specified as input parameter */ time_type t0 = breath_env->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, sax_all_susp_node, "snd_make_sax_all"); susp->sax = initInstrument(SAXOFONY, round(sr)); noteOn(susp->sax, freq, 1.0); controlChange(susp->sax, 29, SAX_CONTROL_CHANGE_CONST * vibrato_freq); controlChange(susp->sax, 1, SAX_CONTROL_CHANGE_CONST * vibrato_gain);; susp->frequency = freq; susp->breath_scale = breath_env->scale * SAX_CONTROL_CHANGE_CONST; susp->reed_scale = reed_stiffness->scale * SAX_CONTROL_CHANGE_CONST; susp->noise_scale = noise_env->scale * SAX_CONTROL_CHANGE_CONST; susp->blow_scale = blow_pos->scale * SAX_CONTROL_CHANGE_CONST; susp->offset_scale = reed_table_offset->scale * SAX_CONTROL_CHANGE_CONST; /* make sure no sample rate is too high */ if (breath_env->sr > sr) { sound_unref(breath_env); snd_badsr(); } else if (breath_env->sr < sr) breath_env = snd_make_up(sr, breath_env); if (freq_env->sr > sr) { sound_unref(freq_env); snd_badsr(); } else if (freq_env->sr < sr) freq_env = snd_make_up(sr, freq_env); if (reed_stiffness->sr > sr) { sound_unref(reed_stiffness); snd_badsr(); } else if (reed_stiffness->sr < sr) reed_stiffness = snd_make_up(sr, reed_stiffness); if (noise_env->sr > sr) { sound_unref(noise_env); snd_badsr(); } else if (noise_env->sr < sr) noise_env = snd_make_up(sr, noise_env); if (blow_pos->sr > sr) { sound_unref(blow_pos); snd_badsr(); } else if (blow_pos->sr < sr) blow_pos = snd_make_up(sr, blow_pos); if (reed_table_offset->sr > sr) { sound_unref(reed_table_offset); snd_badsr(); } else if (reed_table_offset->sr < sr) reed_table_offset = snd_make_up(sr, reed_table_offset); susp->susp.fetch = sax_all_nsnnnn_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < breath_env->t0) sound_prepend_zeros(breath_env, t0); if (t0 < freq_env->t0) sound_prepend_zeros(freq_env, t0); if (t0 < reed_stiffness->t0) sound_prepend_zeros(reed_stiffness, t0); if (t0 < noise_env->t0) sound_prepend_zeros(noise_env, t0); if (t0 < blow_pos->t0) sound_prepend_zeros(blow_pos, t0); if (t0 < reed_table_offset->t0) sound_prepend_zeros(reed_table_offset, t0); /* minimum start time over all inputs: */ t0_min = min(breath_env->t0, min(freq_env->t0, min(reed_stiffness->t0, min(noise_env->t0, min(blow_pos->t0, min(reed_table_offset->t0, t0)))))); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = sax_all_toss_fetch; } /* initialize susp state */ susp->susp.free = sax_all_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = sax_all_mark; susp->susp.print_tree = sax_all_print_tree; susp->susp.name = "sax_all"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->breath_env = breath_env; susp->breath_env_cnt = 0; susp->freq_env = freq_env; susp->freq_env_cnt = 0; susp->reed_stiffness = reed_stiffness; susp->reed_stiffness_cnt = 0; susp->noise_env = noise_env; susp->noise_env_cnt = 0; susp->blow_pos = blow_pos; susp->blow_pos_cnt = 0; susp->reed_table_offset = reed_table_offset; susp->reed_table_offset_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }