/* crossfm.c: Copyright (C) 2005 Francois Pinot This file is part of Csound. The Csound Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Csound is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Csound; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "csdl.h" #include "crossfm.h" #include int xfmset(CSOUND *csound, CROSSFM *p) { FUNC *ftp1 = csound->FTFind(csound, p->ifn1); FUNC *ftp2 = csound->FTFind(csound, p->ifn2); if (ftp1 == NULL || ftp2 == NULL) { return csound->InitError(csound, Str("crossfm: ftable not found")); } p->siz1 = (MYFLT)ftp1->flen; p->siz2 = (MYFLT)ftp2->flen; p->ftp1 = ftp1; p->ftp2 = ftp2; if (*p->iphs1 >= FL(0.0)) { p->phase1 = *p->iphs1; p->sig1 = FL(0.0); } if (*p->iphs2 >= FL(0.0)) { p->phase2 = *p->iphs2; p->sig2 = FL(0.0); } p->frq1adv = (XINARG1) ? 1 : 0; p->frq2adv = (XINARG2) ? 1 : 0; p->ndx1adv = (XINARG3) ? 1 : 0; p->ndx2adv = (XINARG4) ? 1 : 0; return OK; } int xfm(CSOUND *csound, CROSSFM *p) { MYFLT *out1, *out2; MYFLT *xfrq1, *xfrq2, *xndx1, *xndx2; MYFLT k, cps; MYFLT frq1, frq2, si1, si2; MYFLT siz1, siz2; MYFLT *tbl1, *tbl2; MYFLT phase1, phase2; MYFLT sig1, sig2; int i, n1, n2; out1 = p->aout1; out2 = p->aout2; xfrq1 = p->xfrq1; xfrq2 = p->xfrq2; xndx1 = p->xndx1; xndx2 = p->xndx2; siz1 = p->siz1; siz2 = p->siz2; tbl1 = p->ftp1->ftable; tbl2 = p->ftp2->ftable; cps = *p->kcps; k = FL(1.0) / csound->esr; phase1 = p->phase1; phase2 = p->phase2; sig1 = p->sig1; sig2 = p->sig2; for (i = 0; i < csound->ksmps; i++) { frq1 = *xfrq1 * cps; frq2 = *xfrq2 * cps; si1 = (frq1 + *xndx2 * frq2 * sig2) * k; si2 = (frq2 + *xndx1 * frq1 * sig1) * k; *out1++ = sig1; *out2++ = sig2; phase1 += si1; phase1 -= (MYFLT)floor(phase1); phase2 += si2; phase2 -= (MYFLT)floor(phase2); n1 = (int)(phase1 * siz1); n2 = (int)(phase2 * siz2); sig1 = tbl1[n1]; sig2 = tbl2[n2]; xfrq1 += p->frq1adv; xfrq2 += p->frq2adv; xndx1 += p->ndx1adv; xndx2 += p->ndx2adv; } p->phase1 = phase1; p->phase2 = phase2; p->sig1 = sig1; p->sig2 = sig2; return OK; } int xfmi(CSOUND *csound, CROSSFM *p) { MYFLT *out1, *out2; MYFLT *xfrq1, *xfrq2, *xndx1, *xndx2; MYFLT k, cps; MYFLT frq1, frq2, si1, si2; MYFLT siz1, siz2; MYFLT *tbl1, *tbl2; MYFLT phase1, phase2; MYFLT sig1, sig2; MYFLT x, y1, y2; int i, n1, n2; out1 = p->aout1; out2 = p->aout2; xfrq1 = p->xfrq1; xfrq2 = p->xfrq2; xndx1 = p->xndx1; xndx2 = p->xndx2; siz1 = p->siz1; siz2 = p->siz2; tbl1 = p->ftp1->ftable; tbl2 = p->ftp2->ftable; cps = *p->kcps; k = FL(1.0) / csound->esr; phase1 = p->phase1; phase2 = p->phase2; sig1 = p->sig1; sig2 = p->sig2; for (i = 0; i < csound->ksmps; i++) { frq1 = *xfrq1 * cps; frq2 = *xfrq2 * cps; si1 = (frq1 + *xndx2 * frq2 * sig2) * k; si2 = (frq2 + *xndx1 * frq1 * sig1) * k; *out1++ = sig1; *out2++ = sig2; phase1 += si1; phase1 -= (MYFLT)floor(phase1); phase2 += si2; phase2 -= (MYFLT)floor(phase2); x = phase1 * siz1; n1 = (int)x; y1 = tbl1[n1]; sig1 = (tbl1[n1+1]-y1) * (x - (MYFLT)floor(x)) + y1; x = phase2 * siz2; n2 = (int)x; y2 = tbl2[n2]; sig2 = (tbl2[n2+1]-y2) * (x - (MYFLT)floor(x)) + y2; xfrq1 += p->frq1adv; xfrq2 += p->frq2adv; xndx1 += p->ndx1adv; xndx2 += p->ndx2adv; } p->phase1 = phase1; p->phase2 = phase2; p->sig1 = sig1; p->sig2 = sig2; return OK; } #define S sizeof static OENTRY localops[] = { { "crossfm", S(CROSSFM), 5, "aa", "xxxxkiioo", (SUBR)xfmset, NULL, (SUBR)xfm }, { "crossfmi", S(CROSSFM), 5, "aa", "xxxxkiioo", (SUBR)xfmset, NULL, (SUBR)xfmi } }; LINKAGE