static int init_delay_line(sp_revsc *p, sp_revsc_dl *lp, int n) { SPFLOAT readPos; /* int i; */ /* calculate length of delay line */ lp->bufferSize = delay_line_max_samples(p->sampleRate, 1, n); lp->dummy = 0; lp->writePos = 0; /* set random seed */ lp->seedVal = (int) (reverbParams[n][3] + 0.5); /* set initial delay time */ readPos = (SPFLOAT) lp->seedVal * reverbParams[n][1] / 32768; readPos = reverbParams[n][0] + (readPos * (SPFLOAT) p->iPitchMod); readPos = (SPFLOAT) lp->bufferSize - (readPos * p->sampleRate); lp->readPos = (int) readPos; readPos = (readPos - (SPFLOAT) lp->readPos) * (SPFLOAT) DELAYPOS_SCALE; lp->readPosFrac = (int) (readPos + 0.5); /* initialise first random line segment */ next_random_lineseg(p, lp, n); /* clear delay line to zero */ lp->filterState = 0.0; memset(lp->buf, 0, sizeof(SPFLOAT) * lp->bufferSize); return SP_OK; }
static void init_delay_line(SC_REVERB *p, delayLine *lp, int32_t n) { double readPos; /* int32_t i; */ /* calculate length of delay line */ lp->bufferSize = delay_line_max_samples(p, n); lp->dummy = 0; lp->writePos = 0; /* set random seed */ lp->seedVal = (int32_t) (reverbParams[n][3] + 0.5); /* set initial delay time */ readPos = (double) lp->seedVal * reverbParams[n][1] / 32768; readPos = reverbParams[n][0] + (readPos * (double) *(p->iPitchMod)); readPos = (double) lp->bufferSize - (readPos * p->sampleRate); lp->readPos = (int32_t) readPos; readPos = (readPos - (double) lp->readPos) * (double) DELAYPOS_SCALE; lp->readPosFrac = (int32_t) (readPos + 0.5); /* initialise first random line segment */ next_random_lineseg(p, lp, n); /* clear delay line to zero */ lp->filterState = 0.0; memset(lp->buf, 0, sizeof(MYFLT)*lp->bufferSize); /* for (i = 0; i < lp->bufferSize; i++) */ /* lp->buf[i] = FL(0.0); */ }
static void init_delay_line(y_synth_t *synth, SC_REVERB *p, delayLine *lp, int n) { double readPos; /* delay line bufferSize and buffer address already set up */ lp->writePos = 0; /* set random seed */ lp->seedVal = (int) (reverbParams[n][3] + 0.5); /* set initial delay time */ readPos = (double) lp->seedVal * reverbParams[n][1] / 32768.0; /* was: readPos = reverbParams[n][0] + (readPos * (double) *(p->iPitchMod)); */ readPos = reverbParams[n][0] + (readPos * pitch_mod(synth)); readPos = (double) lp->bufferSize - (readPos * (double)synth->sample_rate); lp->readPos = (int) readPos; readPos = (readPos - (double) lp->readPos) * (double) DELAYPOS_SCALE; lp->readPosFrac = (int) (readPos + 0.5); /* initialise first random line segment */ next_random_lineseg(synth, p, lp, n); /* delay line already cleared to zero */ }
int sp_revsc_compute(sp_data *sp, sp_revsc *p, SPFLOAT *in1, SPFLOAT *in2, SPFLOAT *out1, SPFLOAT *out2) { SPFLOAT ainL, ainR, aoutL, aoutR; SPFLOAT vm1, v0, v1, v2, am1, a0, a1, a2, frac; sp_revsc_dl *lp; int readPos; uint32_t n; int bufferSize; /* Local copy */ SPFLOAT dampFact = p->dampFact; if (p->initDone <= 0) return SP_NOT_OK; /* calculate tone filter coefficient if frequency changed */ if (p->lpfreq != p->prv_LPFreq) { p->prv_LPFreq = p->lpfreq; dampFact = 2.0 - cos(p->prv_LPFreq * (2 * M_PI) / p->sampleRate); dampFact = p->dampFact = dampFact - sqrt(dampFact * dampFact - 1.0); } /* calculate "resultant junction pressure" and mix to input signals */ ainL = aoutL = aoutR = 0.0; for (n = 0; n < 8; n++) { ainL += p->delayLines[n].filterState; } ainL *= jpScale; ainR = ainL + *in2; ainL = ainL + *in1; /* loop through all delay lines */ for (n = 0; n < 8; n++) { lp = &p->delayLines[n]; bufferSize = lp->bufferSize; /* send input signal and feedback to delay line */ lp->buf[lp->writePos] = (SPFLOAT) ((n & 1 ? ainR : ainL) - lp->filterState); if (++lp->writePos >= bufferSize) { lp->writePos -= bufferSize; } /* read from delay line with cubic interpolation */ if (lp->readPosFrac >= DELAYPOS_SCALE) { lp->readPos += (lp->readPosFrac >> DELAYPOS_SHIFT); lp->readPosFrac &= DELAYPOS_MASK; } if (lp->readPos >= bufferSize) lp->readPos -= bufferSize; readPos = lp->readPos; frac = (SPFLOAT) lp->readPosFrac * (1.0 / (SPFLOAT) DELAYPOS_SCALE); /* calculate interpolation coefficients */ a2 = frac * frac; a2 -= 1.0; a2 *= (1.0 / 6.0); a1 = frac; a1 += 1.0; a1 *= 0.5; am1 = a1 - 1.0; a0 = 3.0 * a2; a1 -= a0; am1 -= a2; a0 -= frac; /* read four samples for interpolation */ if (readPos > 0 && readPos < (bufferSize - 2)) { vm1 = (SPFLOAT) (lp->buf[readPos - 1]); v0 = (SPFLOAT) (lp->buf[readPos]); v1 = (SPFLOAT) (lp->buf[readPos + 1]); v2 = (SPFLOAT) (lp->buf[readPos + 2]); } else { /* at buffer wrap-around, need to check index */ if (--readPos < 0) readPos += bufferSize; vm1 = (SPFLOAT) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v0 = (SPFLOAT) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v1 = (SPFLOAT) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v2 = (SPFLOAT) lp->buf[readPos]; } v0 = (am1 * vm1 + a0 * v0 + a1 * v1 + a2 * v2) * frac + v0; /* update buffer read position */ lp->readPosFrac += lp->readPosFrac_inc; /* apply feedback gain and lowpass filter */ v0 *= (SPFLOAT) p->feedback; v0 = (lp->filterState - v0) * dampFact + v0; lp->filterState = v0; /* mix to output */ if (n & 1) { aoutR += v0; }else{ aoutL += v0; } /* start next random line segment if current one has reached endpoint */ if (--(lp->randLine_cnt) <= 0) { next_random_lineseg(p, lp, n); } }
static int32_t sc_reverb_perf(CSOUND *csound, SC_REVERB *p) { double ainL, ainR, aoutL, aoutR; double vm1, v0, v1, v2, am1, a0, a1, a2, frac; delayLine *lp; int32_t readPos; uint32_t offset = p->h.insdshead->ksmps_offset; uint32_t early = p->h.insdshead->ksmps_no_end; uint32_t i, n, nsmps = CS_KSMPS; int32_t bufferSize; /* Local copy */ double dampFact = p->dampFact; if (UNLIKELY(p->initDone <= 0)) goto err1; /* calculate tone filter coefficient if frequency changed */ if (*(p->kLPFreq) != p->prv_LPFreq) { p->prv_LPFreq = *(p->kLPFreq); dampFact = 2.0 - cos(p->prv_LPFreq * TWOPI / p->sampleRate); dampFact = p->dampFact = dampFact - sqrt(dampFact * dampFact - 1.0); } if (UNLIKELY(offset)) { memset(p->aoutL, '\0', offset*sizeof(MYFLT)); memset(p->aoutR, '\0', offset*sizeof(MYFLT)); } if (UNLIKELY(early)) { nsmps -= early; memset(&p->aoutL[nsmps], '\0', early*sizeof(MYFLT)); memset(&p->aoutR[nsmps], '\0', early*sizeof(MYFLT)); } /* update delay lines */ for (i = offset; i < nsmps; i++) { /* calculate "resultant junction pressure" and mix to input signals */ ainL = aoutL = aoutR = 0.0; for (n = 0; n < 8; n++) ainL += p->delayLines[n]->filterState; ainL *= jpScale; ainR = ainL + (double) p->ainR[i]; ainL = ainL + (double) p->ainL[i]; /* loop through all delay lines */ for (n = 0; n < 8; n++) { lp = p->delayLines[n]; bufferSize = lp->bufferSize; /* send input signal and feedback to delay line */ lp->buf[lp->writePos] = (MYFLT) ((n & 1 ? ainR : ainL) - lp->filterState); if (UNLIKELY(++lp->writePos >= bufferSize)) lp->writePos -= bufferSize; /* read from delay line with cubic interpolation */ if (lp->readPosFrac >= DELAYPOS_SCALE) { lp->readPos += (lp->readPosFrac >> DELAYPOS_SHIFT); lp->readPosFrac &= DELAYPOS_MASK; } if (UNLIKELY(lp->readPos >= bufferSize)) lp->readPos -= bufferSize; readPos = lp->readPos; frac = (double) lp->readPosFrac * (1.0 / (double) DELAYPOS_SCALE); /* calculate interpolation coefficients */ a2 = frac * frac; a2 -= 1.0; a2 *= (1.0 / 6.0); a1 = frac; a1 += 1.0; a1 *= 0.5; am1 = a1 - 1.0; a0 = 3.0 * a2; a1 -= a0; am1 -= a2; a0 -= frac; /* read four samples for interpolation */ if (LIKELY(readPos > 0 && readPos < (bufferSize - 2))) { vm1 = (double) (lp->buf[readPos - 1]); v0 = (double) (lp->buf[readPos]); v1 = (double) (lp->buf[readPos + 1]); v2 = (double) (lp->buf[readPos + 2]); } else { /* at buffer wrap-around, need to check index */ if (--readPos < 0) readPos += bufferSize; vm1 = (double) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v0 = (double) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v1 = (double) lp->buf[readPos]; if (++readPos >= bufferSize) readPos -= bufferSize; v2 = (double) lp->buf[readPos]; } v0 = (am1 * vm1 + a0 * v0 + a1 * v1 + a2 * v2) * frac + v0; /* update buffer read position */ lp->readPosFrac += lp->readPosFrac_inc; /* apply feedback gain and lowpass filter */ v0 *= (double) *(p->kFeedBack); v0 = (lp->filterState - v0) * dampFact + v0; lp->filterState = v0; /* mix to output */ if (n & 1) aoutR += v0; else aoutL += v0; /* start next random line segment if current one has reached endpoint */ if (--(lp->randLine_cnt) <= 0) next_random_lineseg(p, lp, n); } p->aoutL[i] = (MYFLT) (aoutL * outputGain); p->aoutR[i] = (MYFLT) (aoutR * outputGain); }
void effect_screverb_process(y_synth_t *synth, unsigned long sample_count, LADSPA_Data *out_left, LADSPA_Data *out_right) { SC_REVERB *p = (SC_REVERB *)synth->effect_buffer; float wet, dry; double ainL, ainR, aoutL, aoutR, feedback; double vm1, v0, v1, v2, am1, a0, a1, a2, frac; delayLine *lp; int i, n, readPos; wet = *(synth->effect_mix); dry = 1.0f - wet; // *(synth->effect_param4) = kfblvl = kFeedBack // *(synth->effect_param5) = kfco = kLPFreq // *(synth->effect_param6) = ipitchm = iPitchMod /* calculate tone filter coefficient if frequency changed */ if (fabs(*(synth->effect_param5) - p->prv_LPFreq) > 1e-7f) { p->prv_LPFreq = *(synth->effect_param5); /* was: p->dampFact = 2.0 - cos(p->prv_LPFreq * TWOPI / p->sampleRate); */ p->dampFact = 2.0 - cos((double) p->prv_LPFreq * M_PI); p->dampFact = p->dampFact - sqrt(p->dampFact * p->dampFact - 1.0); } feedback = sqrt(*(synth->effect_param4)); /* update delay lines */ for (i = 0; i < sample_count; i++) { /* DC blocker */ synth->dc_block_l_ynm1 = synth->voice_bus_l[i] - synth->dc_block_l_xnm1 + synth->dc_block_r * synth->dc_block_l_ynm1; ainL = (double)synth->dc_block_l_ynm1; synth->dc_block_l_xnm1 = synth->voice_bus_l[i]; synth->dc_block_r_ynm1 = synth->voice_bus_r[i] - synth->dc_block_r_xnm1 + synth->dc_block_r * synth->dc_block_r_ynm1; ainR = (double)synth->dc_block_r_ynm1; synth->dc_block_r_xnm1 = synth->voice_bus_r[i]; /* calculate "resultant junction pressure" and mix to input signals */ aoutL = 0.0; for (n = 0; n < 8; n++) aoutL += p->delayLines[n].filterState; aoutL *= jpScale; ainR += aoutL; ainL += aoutL; aoutL = aoutR = 0.0; /* loop through all delay lines */ for (n = 0; n < 8; n++) { lp = &p->delayLines[n]; /* send input signal and feedback to delay line */ lp->buf[lp->writePos] = (float) ((n & 1 ? ainR : ainL) - lp->filterState); if (++lp->writePos >= lp->bufferSize) lp->writePos -= lp->bufferSize; /* read from delay line with cubic interpolation */ if (lp->readPosFrac >= DELAYPOS_SCALE) { lp->readPos += (lp->readPosFrac >> DELAYPOS_SHIFT); lp->readPosFrac &= DELAYPOS_MASK; } if (lp->readPos >= lp->bufferSize) lp->readPos -= lp->bufferSize; readPos = lp->readPos; frac = (double) lp->readPosFrac * (1.0 / (double) DELAYPOS_SCALE); /* calculate interpolation coefficients */ a2 = frac * frac; a2 -= 1.0; a2 *= (1.0 / 6.0); a1 = frac; a1 += 1.0; a1 *= 0.5; am1 = a1 - 1.0; a0 = 3.0 * a2; a1 -= a0; am1 -= a2; a0 -= frac; /* read four samples for interpolation */ if (readPos > 0 && readPos < (lp->bufferSize - 2)) { vm1 = (double) (lp->buf[readPos - 1]); v0 = (double) (lp->buf[readPos]); v1 = (double) (lp->buf[readPos + 1]); v2 = (double) (lp->buf[readPos + 2]); } else { /* at buffer wrap-around, need to check index */ if (--readPos < 0) readPos += lp->bufferSize; vm1 = (double) lp->buf[readPos]; if (++readPos >= lp->bufferSize) readPos -= lp->bufferSize; v0 = (double) lp->buf[readPos]; if (++readPos >= lp->bufferSize) readPos -= lp->bufferSize; v1 = (double) lp->buf[readPos]; if (++readPos >= lp->bufferSize) readPos -= lp->bufferSize; v2 = (double) lp->buf[readPos]; } v0 = (am1 * vm1 + a0 * v0 + a1 * v1 + a2 * v2) * frac + v0; /* update buffer read position */ lp->readPosFrac += lp->readPosFrac_inc; /* apply feedback gain and lowpass filter */ v0 *= feedback; v0 = (lp->filterState - v0) * p->dampFact + v0; lp->filterState = v0; /* mix to output */ if (n & 1) aoutR += v0; else aoutL += v0; /* start next random line segment if current one has reached endpoint */ if (--(lp->randLine_cnt) <= 0) next_random_lineseg(synth, p, lp, n); } out_left[i] = wet * (float) (aoutL * outputGain) + dry * synth->voice_bus_l[i]; out_right[i] = wet * (float) (aoutR * outputGain) + dry * synth->voice_bus_r[i]; }