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(); }
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; } }