Implementation methods
Approximation
Examples
Csound
5
oscil
Oops/ugens2.c function osckk
int osckk(CSOUND *csound, OSC *p)
{
FUNC *ftp;
MYFLT amp, *ar, *ftbl;
int32 phs, inc, lobits;
int n, nsmps=csound->ksmps;
ftp = p->ftp;
if (UNLIKELY(ftp==NULL)) goto err1;
ftbl = ftp->ftable;
phs = p->lphs;
inc = MYFLT2LONG(*p->xcps * csound->sicvt);
lobits = ftp->lobits;
amp = *p->xamp;
ar = p->sr;
for (n=0;n<nsmps;n++) {
ar[n] = ftbl[phs >> lobits] * amp;
/* phs += inc; */
/* phs &= PHMASK; */
phs = (phs+inc)&PHMASK;
}
p->lphs = phs;
return OK;
err1:
return csound->PerfError(csound, Str("oscil: not initialised"));
}
poscil
static int posckk(CSOUND *csound, POSC *p)
{
FUNC *ftp = p->ftp;
MYFLT *out = p->out, *ft;
MYFLT *curr_samp, fract;
double phs = p->phs;
double si = *p->freq * p->tablenUPsr; /* gab c3 */
int32 n,nsmps = csound->ksmps;
MYFLT amp = *p->amp;
if (UNLIKELY(ftp==NULL))
return csound->PerfError(csound, Str("poscil: not initialised"));
ft = p->ftp->ftable;
for (n=0; n<nsmps; n++) {
curr_samp = ft + (int32)phs;
fract = (MYFLT)(phs - (int32)phs);
out[n] = amp * (*curr_samp +(*(curr_samp+1)-*curr_samp)*fract);
phs += si;
while (UNLIKELY(phs >= p->tablen))
phs -= p->tablen;
while (UNLIKELY(phs < 0.0 ))
phs += p->tablen;
}
p->phs = phs;
return OK;
}
6
Addition of offsets for start and end for sample accurate timing
int osckk(CSOUND *csound, OSC *p)
{
FUNC *ftp;
MYFLT amp, *ar, *ftbl;
int32 phs, inc, lobits;
uint32_t offset = p->h.insdshead->ksmps_offset;
uint32_t early = p->h.insdshead->ksmps_no_end;
uint32_t n, nsmps = CS_KSMPS;
ftp = p->ftp;
if (UNLIKELY(ftp==NULL)) goto err1;
ftbl = ftp->ftable;
phs = p->lphs;
inc = MYFLT2LONG(*p->xcps * csound->sicvt);
lobits = ftp->lobits;
amp = *p->xamp;
ar = p->sr;
if (offset) memset(ar, '\0', offset*sizeof(MYFLT));
if (early) {
nsmps -= early;
memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
}
for (n=offset;n<nsmps;n++) {
ar[n] = ftbl[phs >> lobits] * amp;
/* phs += inc; */
/* phs &= PHMASK; */
phs = (phs+inc)&PHMASK;
}
p->lphs = phs;
return OK;
err1:
return csound->PerfError(csound, Str("oscil: not initialised"));
}
SC
Ringing filter
FSinOsc Ugen
void FSinOsc_Ctor(FSinOsc *unit)
{
SETCALC(FSinOsc_next);
unit->m_freq = ZIN0(0);
float iphase = ZIN0(1);
float w = unit->m_freq * unit->mRate->mRadiansPerSample;
unit->m_b1 = 2. * cos(w);
unit->m_y1 = sin(iphase);
unit->m_y2 = sin(iphase - w);
ZOUT0(0) = unit->m_y1;
}
void FSinOsc_next(FSinOsc *unit, int inNumSamples)
{
float *out = ZOUT(0);
double freq = ZIN0(0);
double b1;
if (freq != unit->m_freq) {
unit->m_freq = freq;
double w = freq * unit->mRate->mRadiansPerSample;
unit->m_b1 = b1 = 2.f * cos(w);
} else {
b1 = unit->m_b1;
}
double y0;
double y1 = unit->m_y1;
double y2 = unit->m_y2;
//Print("y %g %g b1 %g\n", y1, y2, b1);
//Print("%d %d\n", unit->mRate->mFilterLoops, unit->mRate->mFilterRemain);
LOOP(unit->mRate->mFilterLoops,
ZXP(out) = y0 = b1 * y1 - y2;
ZXP(out) = y2 = b1 * y0 - y1;
ZXP(out) = y1 = b1 * y2 - y0;
);
LOOP(unit->mRate->mFilterRemain,
ZXP(out) = y0 = b1 * y1 - y2;
y2 = y1;
y1 = y0;
);
//Print("y %g %g b1 %g\n", y1, y2, b1);
unit->m_y1 = y1;
unit->m_y2 = y2;
unit->m_b1 = b1;
}
Gamma
RSin Class
RSin& set(const T& frq, const T& phs, const T& amp=T(1)){
// printf("%g %g %g\n", frq, phs, amp);
mFreq = frq;
mAmp = amp;
mPhase = phs;
T f=frq*M_2PI, p=phs*M_2PI;
mul = 2 * cos(f);
val2 = sin(p - f * T(2))*amp;
val = sin(p - f )*amp;
// printf("%g %g %g\n", freq(), phase(), this->amp());
return *this;
}