예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
파일: log.c 프로젝트: AkiraShirase/audacity
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);
}
예제 #4
0
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);
}
예제 #5
0
파일: pwl.c 프로젝트: nausic/VimProject
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);
}
예제 #6
0
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);
}
예제 #7
0
파일: yin.c 프로젝트: Grunji/audacity
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;
}
예제 #8
0
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);
}
예제 #9
0
파일: nyx.c 프로젝트: tuanmasterit/audacity
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();
}
예제 #10
0
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);
}
예제 #11
0
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);
}
예제 #12
0
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);
}
예제 #13
0
파일: abs.c 프로젝트: AkiraShirase/audacity
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);
}
예제 #14
0
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);
}
예제 #15
0
파일: const.c 프로젝트: andreipaga/audacity
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);
}
예제 #16
0
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);
}
예제 #17
0
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);
}
예제 #18
0
파일: sine.c 프로젝트: andreipaga/audacity
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);
}
예제 #19
0
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);
}
예제 #20
0
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);
}
예제 #21
0
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);
}
예제 #22
0
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);
}
예제 #23
0
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);
}
예제 #24
0
파일: nyx.c 프로젝트: andreipaga/audacity
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);
   }
}
예제 #25
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 */
예제 #26
0
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);
}
예제 #27
0
파일: sndread.c 프로젝트: henricj/nyquist
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);
    }
}
예제 #28
0
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);
}