예제 #1
0
int tablew_audio(CSOUND *csound, TABL *p) {
  int ndx, len = p->len, n, nsmps = CS_KSMPS;
  int mask = p->ftp->lenmask;
  MYFLT *sig = p->sig;
  MYFLT *ndx_f = p->ndx;
  MYFLT *func = p->ftp->ftable;
  MYFLT offset = *p->offset;
  MYFLT mul = p->mul;
  int32 iwrap = p->iwrap;
  uint32_t    koffset = p->h.insdshead->ksmps_offset;
  uint32_t    early  = p->h.insdshead->ksmps_no_end;

 if (UNLIKELY(early)) nsmps -= early;

 for (n=koffset; n < nsmps; n++) {
   ndx = MYFLOOR((ndx_f[n] + offset)*mul + (iwrap==2 ? 0.5:0));
   if (iwrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
   func[ndx] = sig[n];
   if (iwrap==2 && ndx == 0) func[len] = func[ndx];
}
  return OK;
}
예제 #2
0
int tabler_audio(CSOUND *csound, TABL *p)
{
    int ndx, len = p->len, n, nsmps = CS_KSMPS;
    int mask = p->ftp->lenmask;
    MYFLT *sig = p->sig;
    MYFLT *ndx_f = p->ndx;
    MYFLT *func = p->ftp->ftable;
    MYFLT offset = *p->offset;
    MYFLT mul = p->mul;
    int32 iwrap = p->iwrap;
    uint32_t    koffset = p->h.insdshead->ksmps_offset;
    uint32_t    early  = p->h.insdshead->ksmps_no_end;

    if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
    }

    for (n=koffset; n < nsmps; n++) {
      ndx = MYFLOOR((ndx_f[n] + offset)*mul);
      if (iwrap) {
        if (p->np2) {
          while(ndx >= len) ndx -= len;
          while(ndx < 0)  ndx += len;
        }
        else ndx &= mask;
      } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
      }
      p->sig[n] = func[ndx];
    }
    return OK;
}
예제 #3
0
int tableir_kontrol(CSOUND *csound, TABL *p) {
  int ndx, len = p->len;
  int mask = p->ftp->lenmask;
  MYFLT tmp, frac;
  MYFLT x1, x2;
  IGN(csound);

  tmp = (*p->ndx + *p->offset)*p->mul;
  ndx = MYFLOOR(tmp);
  frac = tmp - ndx;

  if (p->iwrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  x1 = p->ftp->ftable[ndx];
  x2 = p->ftp->ftable[ndx+1];
  *p->sig = x1 + (x2 - x1)*frac;
  return OK;
}
예제 #4
0
int pktabl3(CSOUND *csound, TABLE   *p)
{
    FUNC        *ftp;
    int32        indx, length;
    MYFLT       v1, v2, fract, ndx;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;
    ndx = *p->xndx;
    length = ftp->flen;
    /* Multiply ndx by denormalisation factor.
     * xbmul is 1 or table length depending on state of ixmode.
     * Add in the offset, which has already been denormalised by
     * tblchk().  */

    ndx    = (ndx * p->xbmul) + p->offset;
    indx = (int32) MYFLOOR((double)ndx);

    /* We need to generate a fraction - How much above indx is ndx?
     * It will be between 0 and just below 1.0.  */
    fract = ndx - indx;

    if (!p->wrap) {
      if (UNLIKELY(ndx >= length)) {
        indx  = length - 1;
        fract = FL(1.0);
      }
      else if (UNLIKELY(ndx < 0)) {
        indx  = 0L;
        fract = FL(0.0);
      }
    }
    /* We are in wrap mode, so do the wrap function.  */
    else if (indx>=length) indx %= length;
    else if (indx<0) indx = length - (-indx)%length;

    /* interpolate with cubic if we can, else linear */
    if (UNLIKELY(indx<1 || indx==length-2 || length <4)) {
      v1 = *(ftp->ftable + indx);
      v2 = *(ftp->ftable + indx + 1);
      *p->rslt = v1 + (v2 - v1) * fract;
    }
    else {
      MYFLT *tab = ftp->ftable;
      MYFLT ym1 = tab[indx-1], y0 = tab[indx];
      MYFLT y1 = tab[indx+1], y2 = tab[indx+2];
      MYFLT frsq = fract*fract;
      MYFLT frcu = frsq*ym1;
      MYFLT t1 = y2 + y0+y0+y0;
      *p->rslt = y0 + FL(0.5)*frcu
        + fract*(y1 - frcu/FL(6.0) - t1/FL(6.0) - ym1/FL(3.0))
        + frsq*fract*(t1/FL(6.0) - FL(0.5)*y1) + frsq*(FL(0.5)* y1 - y0);
    }
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("ptable3(krate): not initialised"));
}
예제 #5
0
int table3r_init(CSOUND *csound, TABL *p) {

  int ndx, len;
  int mask;
  MYFLT tmp, frac;
  MYFLT x0, x1, x2, x3;
  MYFLT fracub, fracsq, temp1;
  MYFLT *func;

  if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
      return csound->InitError(csound,
                               Str("table: could not find ftable %d"),
                               (int) *p->ftable);
  mask = p->ftp->lenmask;
  p->np2 = mask ? 0 : 1;
  len = p->ftp->flen;
  func  =p->ftp->ftable;

  if (*p->mode)
      p->mul = len;
    else
      p->mul = 1;

  tmp = (*p->ndx + *p->offset)*p->mul;
  ndx = MYFLOOR(tmp);
  frac = tmp - ndx;

  if (*p->wrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
    x1 = func[ndx];
    x2 = func[ndx+1];
    *p->sig = x1 + (x2 - x1)*frac;
  } else {
    x0 = func[ndx-1];
    x1 = func[ndx];
    x2 = func[ndx+1];
    x3 = func[ndx+2];
    fracsq = frac*frac;
    fracub = fracsq*x0;
    temp1 = x3+FL(3.0)*x1;
    *p->sig =  x1 + FL(0.5)*fracub +
      frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
      frac*fracsq*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
  }
  return OK;
}
예제 #6
0
int table3r_audio(CSOUND *csound, TABL *p)
{
    int ndx, len = p->len, n, nsmps = CS_KSMPS;
    int mask = p->ftp->lenmask;
    MYFLT *sig = p->sig;
    MYFLT *ndx_f = p->ndx;
    MYFLT *func = p->ftp->ftable;
    MYFLT offset = *p->offset;
    MYFLT mul = p->mul, tmp, frac;
    int32 iwrap = p->iwrap;
    uint32_t    koffset = p->h.insdshead->ksmps_offset;
    uint32_t    early  = p->h.insdshead->ksmps_no_end;

    if (UNLIKELY(koffset)) memset(sig, '\0', koffset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&sig[nsmps], '\0', early*sizeof(MYFLT));
    }

    for (n=koffset; n < nsmps; n++) {
      MYFLT x0,x1,x2,x3,temp1,fracub,fracsq;
      tmp = (ndx_f[n] + offset)*mul;
      ndx = MYFLOOR(tmp);
      frac = tmp - ndx;
      if (iwrap) {
        if (p->np2) {
          while(ndx >= len) ndx -= len;
          while(ndx < 0)  ndx += len;
        }
        else ndx &= mask;
      } else {
        if (UNLIKELY(ndx >= len)) ndx = len - 1;
        else if (UNLIKELY(ndx < 0)) ndx = 0;
      }

      if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
        x1 = func[ndx];
        x2 = func[ndx+1];
        p->sig[n] = x1 + (x2 - x1)*frac;
      } else {
        x0 = func[ndx-1];
        x1 = func[ndx];
        x2 = func[ndx+1];
        x3 = func[ndx+2];
        fracsq = frac*frac;
        fracub = fracsq*x0;
        temp1 = x3+x1+x1+x1;
        p->sig[n] =  x1 + FL(0.5)*fracub +
          frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
          fracsq*frac*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
      }
    }
    return OK;
}
예제 #7
0
int ptablefn(CSOUND *csound, TABLE *p)
{
    FUNC        *ftp;
    MYFLT       *rslt, *pxndx, *tab;
    int32       indx, length;
    uint32_t koffset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT       ndx, xbmul, offset;
    int         wrap = p->wrap;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;            /* RWD fix */
    rslt = p->rslt;
    if (koffset) memset(rslt, '\0', koffset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
    }
    length = ftp->flen;
    pxndx = p->xndx;
    xbmul = (MYFLT)p->xbmul;
    offset = p->offset;
    //mask = ftp->lenmask;
    tab = ftp->ftable;
    for (n=koffset; n<nsmps; n++) {
      /* Read in the next raw index and increment the pointer ready
       * for the next cycle.
       *
       * Then multiply the ndx by the denormalising factor and add in
       * the offset.  */

      ndx = (pxndx[n] * xbmul) + offset;
      indx = (int32) MYFLOOR((double)ndx);

      /* Limit = non-wrap.  Limits to 0 and (length - 1), or does the
       * wrap code.  See notes above in ktable().  */
      if (!wrap) {
        if (UNLIKELY(indx >= length))
          indx = length - 1;
        else if (UNLIKELY(indx < (int32)0))
          indx = (int32)0;
      }
      /* do the wrap code only if we are not doing the non-wrap code.  */
      else if (indx >= length) indx %= length;
      else if (indx < 0) indx = length - (-indx)%length;
      rslt[n] = tab[indx];
    }
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("table: not initialised"));
}
예제 #8
0
int tablew_init(CSOUND *csound, TABL *p) {

  int ndx, len;
  int mask;
  MYFLT *func;
  int32 iwrap = *p->wrap;

  if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
      return csound->InitError(csound,
                               Str("table: could not find ftable %d"),
                               (int) *p->ftable);
  func = p->ftp->ftable;
  mask = p->ftp->lenmask;
  p->np2 = mask ? 0 : 1;
  len = p->ftp->flen;

  if (*p->mode)
      p->mul = len;
    else
      p->mul = 1;

  ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul  + (iwrap==2 ? 0.5:0));
  if (iwrap) {
    ndx = iwrap == 2 ? MYFLOOR(ndx+0.5) : ndx;
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  p->ftp->ftable[ndx] = *p->sig;
  if (ndx == 0 && iwrap==2) func[len] = func[ndx];
  return OK;
}
예제 #9
0
int pktabli(CSOUND *csound, TABLE   *p)
{
    FUNC        *ftp;
    int32       indx, length;
    MYFLT       v1, v2, fract, ndx;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;
    ndx = *p->xndx;
    length = ftp->flen;
    /* Multiply ndx by denormalisation factor.
     * xbmul is 1 or table length depending on state of ixmode.
     * Add in the offset, which has already been denormalised by
     * tblchk().  */

    ndx    = (ndx * p->xbmul) + p->offset;
    indx = (int32) MYFLOOR((double)ndx);

    /* We need to generate a fraction - How much above indx is ndx?
     * It will be between 0 and just below 1.0.  */
    fract = ndx - indx;

    if (!p->wrap) {
      if (UNLIKELY(ndx >= length)) {
        indx  = length - 1;
        fract = FL(1.0);
      }
      else if (UNLIKELY(ndx < 0)) {
        indx  = 0L;
        fract = FL(0.0);
      }
    }
    /* We are in wrap mode, so do the wrap function.  */
    else if (indx>=length) indx %= length;
    else if (indx<0) indx = length - (-indx)%length;

    /* Now read the value at indx and the one beyond */
    v1 = *(ftp->ftable + indx);
    indx++;
    if (indx>=length) indx -= length;
    v2 = *(ftp->ftable + indx);
    *p->rslt = v1 + (v2 - v1) * fract;
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("ptablei(krate): not initialised"));
}
예제 #10
0
int tabler_kontrol(CSOUND *csound, TABL *p) {
  int ndx, len = p->len;
  int mask = p->ftp->lenmask;
  IGN(csound);

  ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul);
  if (p->iwrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  *p->sig = p->ftp->ftable[ndx];
  return OK;
}
예제 #11
0
int table3r_kontrol(CSOUND *csound, TABL *p) {
  int ndx, len = p->len;
  int mask = p->ftp->lenmask;
  MYFLT tmp, frac;
  MYFLT x0, x1, x2, x3;
  MYFLT *func  =p->ftp->ftable;
  MYFLT fracub, fracsq, temp1;

  IGN(csound);

  tmp = (*p->ndx + *p->offset)*p->mul;
  ndx = MYFLOOR(tmp);
  frac = tmp - ndx;

  if (p->iwrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  if (UNLIKELY(ndx<1 || ndx==len-1 || len <4)) {
    x1 = func[ndx];
    x2 = func[ndx+1];
    *p->sig = x1 + (x2 - x1)*frac;
  } else {
    x0 = func[ndx-1];
    x1 = func[ndx];
    x2 = func[ndx+1];
    x3 = func[ndx+2];
    fracsq = frac*frac;
    fracub = fracsq*x0;
    temp1 = x3+FL(3.0)*x1;
    *p->sig =  x1 + FL(0.5)*fracub +
      frac*(x2 - fracub/FL(6.0) - temp1/FL(6.0) - x0/FL(3.0)) +
      frac*fracsq*(temp1/FL(6.0) - FL(0.5)*x2) + fracsq*(FL(0.5)*x2 - x1);
  }
  return OK;
}
예제 #12
0
int tableir_init(CSOUND *csound, TABL *p) {

  int ndx, len;
  int mask;
  MYFLT tmp, frac;
  MYFLT x1, x2;

  if (UNLIKELY((p->ftp = csound->FTnp2Find(csound, p->ftable)) == NULL))
      return csound->InitError(csound,
                               Str("table: could not find ftable %d"),
                               (int) *p->ftable);
  mask = p->ftp->lenmask;
  p->np2 = mask ? 0 : 1;
  len = p->ftp->flen;

  if (*p->mode)
      p->mul = len;
    else
      p->mul = 1;

  tmp = (*p->ndx + *p->offset)*p->mul;
  ndx = MYFLOOR(tmp);
  frac = tmp - ndx;

  if (*p->wrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  x1 = p->ftp->ftable[ndx];
  x2 = p->ftp->ftable[ndx+1];
  *p->sig = x1 + (x2 - x1)*frac;
  return OK;
}
예제 #13
0
int tablew_kontrol(CSOUND *csound, TABL *p) {
  int ndx, len = p->len;
  int mask = p->ftp->lenmask;
  MYFLT *func = p->ftp->ftable;
  int32 iwrap = p->iwrap;
  IGN(csound);

  ndx = MYFLOOR((*p->ndx + *p->offset)*p->mul + (iwrap==2 ? 0.5:0));
  if (iwrap) {
    if (p->np2) {
      while(ndx >= len) ndx -= len;
      while(ndx < 0)  ndx += len;
    }
    else ndx &= mask;
  } else {
    if (UNLIKELY(ndx >= len)) ndx = len - 1;
    else if (UNLIKELY(ndx < 0)) ndx = 0;
  }
  func[ndx] = *p->sig;
  if (ndx == 0 && iwrap==2) func[len] = func[ndx];
  return OK;
}
예제 #14
0
int table_mix(CSOUND *csound, TABLMIX *p) {
  int32 np2, np21, np22;
  FUNC *ftp, *ftp1, *ftp2;
  int32 len, len1, len2, flen;
  MYFLT g1, g2, *func, *func1, *func2;
  int32 off, off1, off2;

  if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->tab)) == NULL)) {
    csound->Warning(csound,
                    Str("table: could not find ftable %d"), (int) *p->tab);
    return NOTOK;
  }
  np2 = ftp->lenmask ? 0 : 1;

  if (UNLIKELY((ftp1 = csound->FTnp2Find(csound, p->tab1)) == NULL)) {
    csound->Warning(csound,
                    Str("table: could not find ftable %d"), (int) *p->tab1);
    return NOTOK;
  }
  np21 = ftp1->lenmask ? 0 : 1;

  if (UNLIKELY((ftp2 = csound->FTnp2Find(csound, p->tab2)) == NULL)) {
    csound->Warning(csound,
                    Str("table: could not find ftable %d"), (int) *p->tab2);
    return NOTOK;
  }
  np22 = ftp2->lenmask ? 0 : 1;

  len = MYFLOOR(*p->len);
  flen = ftp->flen;
  len1 = ftp1->flen;
  len2 = ftp2->flen;
  func = ftp->ftable;
  func1 = ftp1->ftable;
  func2 = ftp2->ftable;
  off = *p->off;
  off1 = *p->off1;
  off2 = *p->off2;
  g1 = *p->g1;
  g2 = *p->g2;

  if (len>0) {
    int i, p0, p1, p2;
    for (i=0; i < len; i++) {
      p0 = i+off;
      p1 = i+off1;
      p2 = i+off2;
      if (np2) {
        while(p0 < 0) p0 += flen;
        while(p0 >= len1) p0 -= flen;
      }
      else p0 &= ftp->lenmask;
      if (np21) {
        while(p1 < 0) p1 += len1;
        while(p1 >= len1) p1 -= len1;
      }
      else p1 &= ftp1->lenmask;
      if (np22) {
        while(p2 < 0) p2 += len2;
        while(p2 >= len2) p1 -= len2;
      }
      else p2 &= ftp2->lenmask;
      func[p0] = func1[p1]*g1 + func2[p2]*g2;
    }
  } else {
    int i, p0, p1, p2;
    for (i=0; i > len; i--) {
      p0 = i+off;
      p1 = i+off1;
      p2 = i+off2;
      if (np2) {
        while(p0 < 0) p0 += flen;
        while(p0 >= len1) p0 -= flen;
      }
      else p0 &= ftp->lenmask;
      if (np21) {
        while(p1 < 0) p1 += len1;
        while(p1 >= len1) p1 -= len1;
      }
      else p1 &= ftp1->lenmask;
      if (np22) {
        while(p2 < 0) p2 += len2;
        while(p2 >= len2) p2 -= len2;
      }
      else p2 &= ftp2->lenmask;
      func[p0] = func1[p1]*g1 + func2[p2]*g2;
    }
  }
  return OK;
}
예제 #15
0
int ptabli(CSOUND *csound, TABLE   *p)
{
    FUNC        *ftp;
    int32       indx, length;
    uint32_t koffset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT       *rslt, *pxndx, *tab;
    MYFLT       fract, v1, v2, ndx, xbmul, offset;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;
    rslt   = p->rslt;
    if (koffset) memset(rslt, '\0', koffset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
    }
    length = ftp->flen;
    pxndx  = p->xndx;
    xbmul  = (MYFLT)p->xbmul;
    offset = p->offset;
    //mask   = ftp->lenmask;
    tab    = ftp->ftable;
    /* As for ktabli() code to handle non wrap mode, and wrap mode.  */
    if (!p->wrap) {
      for (n=koffset; n<nsmps; n++) {
        /* Read in the next raw index and increment the pointer ready
         * for the next cycle.
         * Then multiply the ndx by the denormalising factor and add in
         * the offset.  */
        ndx = (pxndx[n] * xbmul) + offset;
        indx = (int32) ndx;
        if (UNLIKELY(ndx <= FL(0.0))) {
          rslt[n] = tab[0];
          continue;
        }
        if (UNLIKELY(indx >= length)) {
          rslt[n] = tab[length-1];
          continue;
        }
        /* We need to generate a fraction - How much above indx is ndx?
         * It will be between 0 and just below 1.0.  */
        fract = ndx - indx;
        /* As for ktabli(), read two values and interpolate between
         * them.  */
        v1 = tab[indx];
        indx++;
        if (indx>=length) indx = length-1;
        v2 = tab[indx];
        rslt[n] = v1 + (v2 - v1)*fract;
      }
    }
    else {                      /* wrap mode */
      for (n=koffset; n<nsmps; n++) {
        int j;
        /* Read in the next raw index and increment the pointer ready
         * for the next cycle.
         * Then multiply the ndx by the denormalising factor and add in
         * the offset.  */
        ndx = (pxndx[n] * xbmul) + offset;
        indx = (int32) MYFLOOR(ndx);
        /* We need to generate a fraction - How much above indx is ndx?
         * It will be between 0 and just below 1.0.  */
        fract = ndx - indx;
        if (indx >= length) indx %= length;
        else if (indx<0) indx = length-(-indx)%length;
        /* As for ktabli(), read two values and interpolate between
         * them.  */
        v1 = tab[indx];
        j = indx + 1;
        if (j >= length) j -= length;
        v2 = tab[j];
        rslt[n] = v1 + (v2 - v1)*fract;
      }
    }
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("ptablei: not initialised"));
}
예제 #16
0
int ptabl3(CSOUND *csound, TABLE *p)     /* Like ptabli but cubic interpolation */
{
    FUNC        *ftp;
    int32       indx, length;
    uint32_t    koffset = p->h.insdshead->ksmps_offset;
    uint32_t    early  = p->h.insdshead->ksmps_no_end;
    uint32_t    n, nsmps = CS_KSMPS;
    MYFLT       *rslt, *pxndx, *tab;
    MYFLT       fract, v1, v2, ndx, xbmul, offset;
    int         wrap = p->wrap;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;
    rslt = p->rslt;
    if (koffset) memset(rslt, '\0', koffset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&rslt[nsmps], '\0', early*sizeof(MYFLT));
    }
    length = ftp->flen;
    pxndx = p->xndx;
    xbmul = (MYFLT)p->xbmul;
    offset = p->offset;
    tab = ftp->ftable;
    for (n=koffset; n<nsmps; n++) {
      /* Read in the next raw index and increment the pointer ready
       * for the next cycle.
       * Then multiply the ndx by the denormalising factor and add in
       * the offset.  */

      ndx = (pxndx[n] * xbmul) + offset;
      indx = (int32) MYFLOOR((double)ndx);

      /* We need to generate a fraction - How much above indx is ndx?
       * It will be between 0 and just below 1.0.  */
      fract = ndx - indx;
      /* As for pktabli() code to handle non wrap mode, and wrap mode.  */
      if (!wrap) {
        if (UNLIKELY(ndx >= length)) {
          indx  = length - 1;
          fract = FL(1.0);
        }
        else if (UNLIKELY(ndx < 0)) {
          indx  = 0L;
          fract = FL(0.0);
        }
      }
      else if (UNLIKELY(indx>=length)) indx %= length;
      else if (UNLIKELY(indx<0)) indx = length-(-indx)%length;
      /* interpolate with cubic if we can */
      if (UNLIKELY(indx <1 || indx == length-2 || length<4)) {
        /* Too short or at ends */
        v1 = tab[indx];
        v2 = tab[indx + 1];
        rslt[n] = v1 + (v2 - v1)*fract;
      }
      else {
        MYFLT ym1 = tab[indx-1], y0 = tab[indx];
        int j = (indx+1<length ? indx+1 : indx+1-length);
        int k = (indx+2<length ? indx+2 : indx+2-length);
        MYFLT y1 = tab[j], y2 = tab[k];
        MYFLT frsq = fract*fract;
        MYFLT frcu = frsq*ym1;
        MYFLT t1 = y2 + y0+y0+y0;
        rslt[n] = y0 + FL(0.5)*frcu +
          fract*(y1 - frcu/FL(6.0) - t1/FL(6.0) - ym1/FL(3.0)) +
          frsq*fract*(t1/FL(6.0) - FL(0.5)*y1) + frsq*(FL(0.5)* y1 - y0);
      }
    }
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("ptable3: not initialised"));
}
예제 #17
0
int pktablew(CSOUND *csound, TABLEW   *p)
{
/* Pointer to data structure for accessing the table we will be
 * writing to.
 */
    FUNC        *ftp;
    int32        indx, length;
    MYFLT       ndx;            /*  for calculating index of read.  */
    MYFLT       *ptab;          /* Where we will write */

    /*-----------------------------------*/
    /* Assume that TABLEW has been set up correctly.  */

    ftp    = p->ftp;
    ndx    = *p->xndx;
    length = ftp->flen;
    /* Multiply ndx by denormalisation factor.  and add in the
     * offset - already denormalised - by tblchkw().
     * xbmul = 1 or table length depending on state of ixmode.  */

    ndx = (ndx * p->xbmul) + p->offset;

    /* ndx now includes the offset and is ready to address the table.
     * However we have three modes to consider:
     * igwm = 0     Limit mode.
     *        1     Wrap mode.
     *        2     Guardpoint mode.
     */
    if (p->iwgm == 0) {
      /* Limit mode - when igmode = 0.
       *
       * Limit the final index to 0 and the last location in the table.
       */
      indx = (int32) MYFLOOR(ndx); /* Limit to (table length - 1) */
      if (UNLIKELY(indx > length - 1))
        indx = length - 1;      /* Limit the high values. */
      else if (UNLIKELY(indx < 0L)) indx = 0L; /* limit negative values to zero. */
    }
    /* Wrap and guard point mode.
     * In guard point mode only, add 0.5 to the index. */
    else {
      if (p->iwgm == 2) ndx += FL(0.5);
      indx = (int32) MYFLOOR(ndx);

      /* Both wrap and guard point mode.
       * The following code uses an AND with an integer like 0000 0111 to wrap
       * the current index within the range of the table. */
      if (UNLIKELY(indx>=length)) indx %= length;
      else if (UNLIKELY(indx<0)) indx = length-(-indx)%length;
    }
                                /* Calculate the address of where we
                                 * want to write to, from indx and the
                                 * starting address of the table.
                                 */
    ptab = ftp->ftable + indx;
    *ptab = *p->xsig;           /* Write the input value to the table. */
                                /* If this is guard point mode and we
                                 * have just written to location 0,
                                 * then also write to the guard point.
                                 */
    if ((p->iwgm == 2) && indx == 0) { /* Fix -- JPff 2000/1/5 */
      ptab += ftp->flen;
      *ptab = *p->xsig;
    }
    return OK;
}
예제 #18
0
/* tablew() is similar to ktablew()  above, except that it processes
 * two arrays of input values and indexes.  These arrays are ksmps long. */
int ptablew(CSOUND *csound, TABLEW *p)
{
    FUNC        *ftp;   /* Pointer to function table data structure. */
    MYFLT       *psig;  /* Array of input values to be written to table. */
    MYFLT       *pxndx; /* Array of input index values */
    MYFLT       *ptab;  /* Pointer to start of table we will write. */
    MYFLT       *pwrite;/* Pointer to location in table where we will write */
    int32        indx;   /* Used to read table. */
    int32        length; /* Length of table */
    int         liwgm;          /* Local copy of iwgm for speed */
    uint32_t koffset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT       ndx, xbmul, offset;
                                /*-----------------------------------*/
    /* Assume that TABLEW has been set up correctly. */

    ftp    = p->ftp;
    psig   = p->xsig;
    pxndx  = p->xndx;
    ptab   = ftp->ftable;
    length = ftp->flen;
    liwgm  = p->iwgm;
    xbmul  = (MYFLT)p->xbmul;
    offset = p->offset;
                /* Main loop - for the number of a samples in a k cycle. */
    nsmps -= early;
    for (n=koffset; n<nsmps; n++) {
      /* Read in the next raw index and increment the pointer ready for the
         next cycle.  Then multiply the ndx by the denormalising factor and
         add in the offset.  */
      ndx = (pxndx[n] * xbmul) + offset;
      if (liwgm == 0) {         /* Limit mode - when igmode = 0. */
        indx = (int32) MYFLOOR(ndx);
        if (UNLIKELY(indx > length - 1)) indx = length - 1;
        else if (UNLIKELY(indx < 0L)) indx = 0L;
      }
      else {
        if (liwgm == 2) ndx += FL(0.5);
        indx = (int32) MYFLOOR(ndx);
        /* Both wrap and guard point mode. */
        if (UNLIKELY(indx>=length)) indx %= length;
        else if (UNLIKELY(indx<0)) indx = length-(-indx)%length;
      }
      pwrite = ptab + indx;
      *pwrite = psig[n];
                                        /* If this is guard point mode and we
                                         * have just written to location 0,
                                         * then also write to the guard point.
                                         */
      if ((liwgm == 2) && indx == 0) {  /* Fix -- JPff 2000/1/5 */
                                        /* Note that since pwrite is a pointer
                                         * to a float, adding length to it
                                         * adds (4 * length) to its value since
                                         * the length of a float is 4 bytes.
                                         */
        pwrite += length;
                                        /* Decrement psig to make it point
                                         * to the same input value.
                                         * Write to guard point.
                                         */
        *pwrite = psig[n];
      }
    }
    return OK;
}
예제 #19
0
파일: lfomodule.c 프로젝트: razorboy73/pyo
static void
LFO_generates_ii(LFO *self) {
    MYFLT val, inc, freq, sharp, pointer, numh;
    MYFLT v1, v2, inc2, fade;
    int i, maxHarms;

    freq = PyFloat_AS_DOUBLE(self->freq);
    if (freq <= 0) {
        return;
    }
    sharp = PyFloat_AS_DOUBLE(self->sharp);
    if (sharp < 0.0)
        sharp = 0.0;
    else if (sharp > 1.0)
        sharp = 1.0;
    inc = freq / self->sr;

    switch (self->wavetype) {
        case 0: /* Saw up */
            maxHarms = (int)(self->srOverFour/freq);
            numh = sharp * 46.0 + 4.0;
            if (numh > maxHarms)
                numh = maxHarms;
            for (i=0; i<self->bufsize; i++) {
                pointer = self->pointerPos * 2.0 - 1.0;
                val = pointer - MYTANH(numh * pointer) / MYTANH(numh);
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 1: /* Saw down */
            maxHarms = (int)(self->srOverFour/freq);
            numh = sharp * 46.0 + 4.0;
            if (numh > maxHarms)
                numh = maxHarms;
            for (i=0; i<self->bufsize; i++) {
                pointer = self->pointerPos * 2.0 - 1.0;
                val = -(pointer - MYTANH(numh * pointer) / MYTANH(numh));
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 2: /* Square */
            maxHarms = (int)(self->srOverEight/freq);
            numh = sharp * 46.0 + 4.0;
            if (numh > maxHarms)
                numh = maxHarms;
            for (i=0; i<self->bufsize; i++) {
                val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 3: /* Triangle */
            maxHarms = (int)(self->srOverFour/freq);
            if ((sharp * 36.0) > maxHarms)
                numh = (MYFLT)(maxHarms / 36.0);
            else
                numh = sharp;
            for (i=0; i<self->bufsize; i++) {
                v1 = MYTAN(MYSIN(TWOPI*self->pointerPos)) * self->oneOverPiOverTwo;
                pointer = self->pointerPos + 0.25;
                if (pointer > 1.0)
                    pointer -= 1.0;
                v2 = 4.0 * (0.5 - MYFABS(pointer - 0.5)) - 1.0;
                val = v1 * (1 - numh) + v2 * numh;
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 4: /* Pulse */
            maxHarms = (int)(self->srOverEight/freq);
            numh = MYFLOOR(sharp * 46.0 + 4.0);
            if (numh > maxHarms)
                numh = maxHarms;
            if (MYFMOD(numh, 2.0) == 0.0)
                numh += 1.0;
            for (i=0; i<self->bufsize; i++) {
                val = MYTAN(MYPOW(MYFABS(MYSIN(TWOPI*self->pointerPos)), numh));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 5: /* Bi-Pulse */
            maxHarms = (int)(self->srOverEight/freq);
            numh = MYFLOOR(sharp * 46.0 + 4.0);
            if (numh > maxHarms)
                numh = maxHarms;
            if (MYFMOD(numh, 2.0) == 0.0)
                numh += 1.0;
            for (i=0; i<self->bufsize; i++) {
                val = MYTAN(MYPOW(MYSIN(TWOPI*self->pointerPos), numh));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 6: /* SAH */
            numh = 1.0 - sharp;
            inc2 = 1.0 / (int)(1.0 / inc * numh);
            for (i=0; i<self->bufsize; i++) {
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1) {
                    self->pointerPos -= 1.0;
                    self->sahPointerPos = 0.0;
                    self->sahLastValue = self->sahCurrentValue;
                    self->sahCurrentValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
                }
                if (self->sahPointerPos < 1.0) {
                    fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
                    val = self->sahCurrentValue * (1.0 - fade) + self->sahLastValue * fade;
                    self->sahPointerPos += inc2;
                }
                else {
                    val = self->sahCurrentValue;
                }
                self->data[i] = val;
            }
            break;
        case 7: /* Sine-mod */
            inc2 = inc * sharp;
            for (i=0; i<self->bufsize; i++) {
                self->modPointerPos += inc2;
                if (self->modPointerPos < 0)
                    self->modPointerPos += 1.0;
                else if (self->modPointerPos >= 1)
                    self->modPointerPos -= 1.0;
                val = (0.5 * MYCOS(TWOPI*self->modPointerPos) + 0.5) * MYSIN(TWOPI*self->pointerPos);
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        default:
            break;
    }
}
예제 #20
0
파일: lfomodule.c 프로젝트: belangeo/pyo
static void
LFO_generates_aa(LFO *self) {
    MYFLT val, inc, freq, sharp, pointer, numh;
    MYFLT v1, v2, inc2, fade;
    MYFLT sharp2 = 0.0;
    int i, maxHarms;

    MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
    MYFLT *sh = Stream_getData((Stream *)self->sharp_stream);

    switch (self->wavetype) {
        case 0: /* Saw up */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverFour/freq);
                numh = sharp * 46.0 + 4.0;
                if (numh > maxHarms)
                    numh = maxHarms;
                pointer = self->pointerPos * 2.0 - 1.0;
                val = pointer - MYTANH(numh * pointer) / MYTANH(numh);
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 1: /* Saw down */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverFour/freq);
                numh = sharp * 46.0 + 4.0;
                if (numh > maxHarms)
                    numh = maxHarms;
                pointer = self->pointerPos * 2.0 - 1.0;
                val = -(pointer - MYTANH(numh * pointer) / MYTANH(numh));
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 2: /* Square */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverEight/freq);
                numh = sharp * 46.0 + 4.0;
                if (numh > maxHarms)
                    numh = maxHarms;
                val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 3: /* Triangle */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverFour/freq);
                if ((sharp * 36.0) > maxHarms)
                    numh = (MYFLT)(maxHarms / 36.0);
                else
                    numh = sharp;
                v1 = MYTAN(MYSIN(TWOPI*self->pointerPos)) * self->oneOverPiOverTwo;
                pointer = self->pointerPos + 0.25;
                if (pointer > 1.0)
                    pointer -= 1.0;
                v2 = 4.0 * (0.5 - MYFABS(pointer - 0.5)) - 1.0;
                val = v1 * (1 - numh) + v2 * numh;
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 4: /* Pulse */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverEight/freq);
                numh = MYFLOOR(sharp * 46.0 + 4.0);
                if (numh > maxHarms)
                    numh = maxHarms;
                if (MYFMOD(numh, 2.0) == 0.0)
                    numh += 1.0;
                val = MYTAN(MYPOW(MYFABS(MYSIN(TWOPI*self->pointerPos)), numh));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 5: /* Bi-Pulse */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                maxHarms = (int)(self->srOverEight/freq);
                numh = MYFLOOR(sharp * 46.0 + 4.0);
                if (numh > maxHarms)
                    numh = maxHarms;
                if (MYFMOD(numh, 2.0) == 0.0)
                    numh += 1.0;
                val = MYTAN(MYPOW(MYSIN(TWOPI*self->pointerPos), numh));
                self->data[i] = val * self->oneOverPiOverTwo;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        case 6: /* SAH */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                numh = 1.0 - sharp;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                inc2 = 1.0 / (int)(1.0 / inc * numh);
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1) {
                    self->pointerPos -= 1.0;
                    self->sahPointerPos = 0.0;
                    self->sahLastValue = self->sahCurrentValue;
                    self->sahCurrentValue = RANDOM_UNIFORM * 2.0 - 1.0;
                }
                if (self->sahPointerPos < 1.0) {
                    fade = 0.5 * MYSIN(PI * (self->sahPointerPos+0.5)) + 0.5;
                    val = self->sahCurrentValue * (1.0 - fade) + self->sahLastValue * fade;
                    self->sahPointerPos += inc2;
                }
                else {
                    val = self->sahCurrentValue;
                }
                self->data[i] = val;
            }
            break;
        case 7: /* Sine-mod */
            for (i=0; i<self->bufsize; i++) {
                sharp = sh[i];
                if (sharp < 0.0)
                    sharp = 0.0;
                else if (sharp > 1.0)
                    sharp = 1.0;
                freq = fr[i];
                if (freq < 0.00001)
                    freq = 0.00001;
                else if (freq > self->srOverFour)
                    freq = self->srOverFour;
                inc = freq * self->oneOverSr;
                inc2 = inc * sharp * 0.99;
                sharp2 = sharp * 0.5;
                self->modPointerPos += inc2;
                if (self->modPointerPos < 0)
                    self->modPointerPos += 1.0;
                else if (self->modPointerPos >= 1)
                    self->modPointerPos -= 1.0;
                val = ((sharp2 * MYCOS(TWOPI*self->modPointerPos) + sharp2) + (1.0 - sharp)) * MYSIN(TWOPI*self->pointerPos);
                self->data[i] = val;
                self->pointerPos += inc;
                if (self->pointerPos < 0)
                    self->pointerPos += 1.0;
                else if (self->pointerPos >= 1)
                    self->pointerPos -= 1.0;
            }
            break;
        default:
            break;
    }
}
예제 #21
0
int pktable(CSOUND *csound, TABLE   *p)
{
    FUNC        *ftp;
    int32        indx, length;
    MYFLT       ndx;

    ftp = p->ftp;
    if (UNLIKELY(ftp==NULL)) goto err1;            /* RWD fix */
    ndx = *p->xndx;
    length = ftp->flen;
    /* Multiply ndx by denormalisation factor, and add in the offset
     * - already denormalised - by tblchk().
     * xbmul = 1 or table length depending on state of ixmode.  */

    ndx = ( ndx * p->xbmul) + p->offset;

    /* ndx now includes the offset and is ready to address the table.
     *
     * The original code was:
     *  indx = (long) (ndx + p->offset);
     *
     * This is a problem, causes problems with negative numbers.
     *
     */
     indx = (int32) MYFLOOR((double)ndx);

    /* Now for "limit mode" - the "non-wrap" function, depending on
     * iwrap.
     *
     * The following section of code limits the final index to 0 and
     * the last location in the table.
     *
     * It is only used when wrap is OFF.  The wrapping is achieved by
     * code after this - when this code is not run.  */
    if (!p->wrap) {
      /* Previously this code limited the upper range of the indx to
       * the table length - for instance 8.  Then the result was ANDed
       * with a mask (for instance 7).
       *
       * This meant that when the input index was 8 or above, it got
       * reduced to 0.  What we want is for it to stick at the index
       * which reads the last value from the table - in this example
       * from location 7.
       *
       * So instead of limiting to the table length, we limit to
       * (table length - 1).  */
      if (UNLIKELY(indx > length - 1))
        indx = length - 1;

      /* Now limit negative values to zero.  */
      else if (UNLIKELY(indx < 0L))
        indx = 0L;
    }
    /* The following code used to use an AND with an integer like 0000 0111
     * to wrap the current index within the range of the table.  In
     * the original version, this code always ran, but with the new
     * (length - 1) code above, it would have no effect, so it is now
     * an else operation - running only when iwrap = 1.  This may save
     * half a usec or so.  */
    /* Now safe against non power-of-2 tables */
    else if (indx>=length) indx = indx % length;
    else if (indx<0) indx = length - (-indx)%length;

    /* Now find the address of the start of the table, add it to the
     * index, read the value from there and write it to the
     * destination.  */
    *p->rslt = *(ftp->ftable + indx);
    return OK;
 err1:
    return csound->PerfError(csound, p->h.insdshead,
                             Str("ptable(krate): not initialised"));
}