Example #1
0
void Unison::updateParameters(void)
{
    if(!uv)
        return;
    float increments_per_second = samplerate_f
                                  / (float) update_period_samples;
//	printf("#%g, %g\n",increments_per_second,base_freq);
    for(int i = 0; i < unison_size; ++i) {
        float base = powf(UNISON_FREQ_SPAN, SYNTH_T::numRandom() * 2.0f - 1.0f);
        uv[i].relative_amplitude = base;
        float period = base / base_freq;
        float m      = 4.0f / (period * increments_per_second);
        if(SYNTH_T::numRandom() < 0.5f)
            m = -m;
        uv[i].step = m;
//		printf("%g %g\n",uv[i].relative_amplitude,period);
    }

    float max_speed = powf(2.0f, unison_bandwidth_cents / 1200.0f);
    unison_amplitude_samples = 0.125f * (max_speed - 1.0f)
                               * samplerate_f / base_freq;

    //If functions exceed this limit, they should have requested a bigguer delay
    //and thus are buggy
    if(unison_amplitude_samples >= max_delay - 1) {
#ifndef WIN32
        warnx("BUG: Unison amplitude samples too big");
        warnx("Unision max_delay should be larger");
#endif
        unison_amplitude_samples = max_delay - 2;
    }

    updateUnisonData();
}
Example #2
0
void Unison::process(int bufsize, float *inbuf, float *outbuf)
{
    if(!uv)
        return;
    if(!outbuf)
        outbuf = inbuf;

    float volume    = 1.0f / sqrtf(float(unison_size));
    float xpos_step = 1.0f / (float) update_period_samples;
    float xpos      = (float) update_period_sample_k * xpos_step;
    for(int i = 0; i < bufsize; ++i) {
        if(update_period_sample_k++ >= update_period_samples) {
            updateUnisonData();
            update_period_sample_k = 0;
            xpos = 0.0f;
        }
        xpos += xpos_step;
        float in   = inbuf[i], out = 0.0f;
        float sign = 1.0f;
        for(int k = 0; k < unison_size; ++k) {
            float vpos = uv[k].realpos1 * (1.0f - xpos) + uv[k].realpos2 * xpos;        //optimize
            float pos  = (float)(delay_k + max_delay) - vpos - 1.0f;
            // TOT: fix this!
            int   posi = int(pos);
            //F2I(pos, posi); //optimize!
            int posi_next = posi + 1;
            if(posi >= max_delay)
                posi -= max_delay;
            if(posi_next >= max_delay)
                posi_next -= max_delay;
            float posf = pos - floorf(pos);
            out += ((1.0f - posf) * delay_buffer[posi] + posf
                 * delay_buffer[posi_next]) * sign;
            sign = -sign;
        }
        outbuf[i] = out * volume;
//		printf("%d %g\n",i,outbuf[i]);
        delay_buffer[delay_k] = in;
        delay_k = (++delay_k < max_delay) ? delay_k : 0;
    }
}