Re: Question on Statement

From: John Lazzaro (lazzaro@cs.berkeley.edu)
Date: Sun Nov 26 2000 - 13:27:59 EST


#if 0

Hi Michael,

At the moment, sfront does not support i-rate statements in
kopcodes, or i-rate and k-rate statements in aopcodes --
this is the root source of the problem you posted.
As I mentioned on the list a while ago, the exact semantics
of what "slower rate" statements in user-defined opcodes
should do is presently not nailed down in the spec, and so
until the corrigenda comes out which does nail it down,
sfront takes the most conservative approach -- simply making
it illegal to do so. This has the benefit that any code you
write today within this restrictive semantics will still do
exactly what you expect it to post-corrigenda -- if I
implemented some sort of provisional behavior in sfront
while waiting for the corrigenda to come out, code you would
write that depended on the provisional behavior might break once
the corrigenda semantics get defined.

I rewrote (and tested -- note that this email message will be a
legal SAOL file if you use -cpp -gcc options in sfront :-) the code
you posted, obeying the "no slower statements" criteria, it is appended
below -- note its pretty simple, an iopcode that only does i-rate stuff,
a kopcode that only does k-rate stuff, and i-rate variables in the test
instrument that communicate between the two.

Also note that there is a related set of sfront error messages that
are "too conservative" and will be going away with the corrigenda --
an a-rate assignment statement that has, on its right-hand side, a
call to a user-define kopcode. Right now, this is flagged with a
similiar sort of warning message -- but once the corrigenda specs out
the correct semantics in this case, these restrictive error messages
will go away, and sfront will implement what is standardized.

I am hoping these issues will be cleared up soon -- once there is
a corrigenda, I am planning on revising sfront and the MP4-SA book
as soon as possible thereafter ... so hopefully these issues will
be behind us soon.

P.S. It is tricky writing prose without the single quote
ASCII symbol -- for this code to pass the pre-processor, I could
not use them :-).

#endif

global {
srate 44100;
}

#define ENVSEG(start, length, end) (kline(start, length, end))

iopcode eg_setup(table rts, table lvs, ivar rscale,
                  ivar s0, ivar s1, ivar s2, ivar s3,
                  ivar r0, ivar r1, ivar r2, ivar r3)

{

 s0 = tableread(lvs, 0);
 s1 = tableread(lvs, 1);
 s2 = tableread(lvs, 2);
 s3 = tableread(lvs, 3);
 r0 = tableread(rts, 0) * rscale;
 r1 = tableread(rts, 1) * rscale;
 r2 = tableread(rts, 2) * rscale;
 r3 = tableread(rts, 3) * rscale;
}

kopcode eg(ksig rel, ivar s0, ivar s1, ivar s2, ivar s3,
                     ivar r0, ivar r1, ivar r2, ivar r3)

{
 ksig kinit; // init flag
 ksig expire; // stage expire time
 ksig triggered; // final stage init
 ksig stage; // stage counter, 0-based
 ksig eg; // the envelope signal
 ksig fin; // the final envelope starting level

 if (!kinit)
   {
     kinit = 1;
     expire = r0;
   }
 if (!rel && !triggered)
   {
     if (stage == 0)
       {
         eg = ENVSEG(s3, r0, s0);
         if (itime >= expire)
           {
             stage = stage + 1;
             expire = expire + r1;
           }
       }
     if (stage == 1)
       {
         eg = ENVSEG(s0, r1, s1);
         if (itime >= expire)
           {
             stage = stage + 1;
             expire = expire + r2;
           }
       }
     if (stage == 2)
       {
         eg = ENVSEG(s1, r2, s2);
         if (itime >= expire)
           {
             stage = stage + 1;
             eg = s2;
           }
       }
   }
 else
   {
     if (!triggered)
       {
         triggered = 1;
         expire = itime + r3;
         fin = eg;
       }
     if (itime < expire)
       {
         eg = ENVSEG(s2, r3, s3);
       }
     else
       {
         eg = s3;
       }
   }

 return(eg);

}

instr tone()

{
  ivar s0, s1, s2, s3;
  ivar r0, r1, r2, r3;
  ivar rscale;
  ksig env;
  table lvs(data, 4, 0, 0.5, 1, 0);
  table rts(data, 4, 0.25, 0.5, 0.25, 0.5);
  table sineout(harm, 128, 0.5);

  // i-rate

  rscale = 1;
  
  eg_setup(rts, lvs, rscale, s0, s1, s2, s3, r0, r1, r2, r3);

  // k-rate

  env = eg(0, s0, s1, s2, s3, r0, r1, r2, r3);

  // a-rate

  output(env*oscil(sineout, 1000));

}



This archive was generated by hypermail 2b29 : Mon Jan 28 2002 - 11:46:41 EST