
          




                  |\/\/\/|        Chris Ahlstrom
                  |      |        uucp ahlstrom%hei.uucp@usc.edu
                  |      |        GEnie KICKAHA; Compuserve 73340,26
                  | (.)(.)
                  C      _)  "Last name Simpson, first name Bart..."
                  | `___|
                  \   /           9950 Topanga Canyon Blvd
                  /____\          Chatsworth, CA   91311
                 /      \         (818) 998-0490

               File: V_CAL2.TXT
              Title: More Cakewalk Application Language (CAL) Programs
            Subject: Cakewalk Professional CAL Programs for
                     Swing Quantization
             Format: ASCII text file | PROFF text formatter
          Sequencer: Cakewalk 4.0 Professional
           Computer: 386 SX IBM PC clone (HD Systems; SVT motherboard)
               Date: 92.01.03




                       CAKEWALK PROFESSIONAL CAL PROGRAMS:
               A PREPOSTEROUS TREATISE ON THE QUANTIZATION QUANDARY

                                        or

                  WHY I REJECTED HEISENBERG & PLANCK IN FAVOR OF
                                 WAGNER AND MONK

                               Edition 2.0 92.01.03


          0. APOLOGIA 

               The fancy  title  comes  from  my  need  to  write  out a
          complete,  pompous  description  of  what  I intend to program
          before  I  program  it.   [Deep guy, but stupid... thinks he's
          the Harlan Ellison of MIDI].  



          1. INTRODUCTION 

               This set  of  CAL routines aids in the swing-quantization
          of  rhythm patterns.  Each CAL routine in Edition 2 implements
          a  different  type  of swing quantization.  Some guidelines on
          modifying  the  files  to  perform  other types of swing might
          also  provided, if the author gets ambitious enough.  A sample
          WRK  file  is  included,  showing the results of using some of
          the  swing-quantization  programs.  Finally, the theory behind


                                      - 1 -

          CAL Programs, Edition 2.0                             Ahlstrom



          all  the  swing-quantization  programs  is provided, for those
          who want to improve my code.  

               Feel free  to  use  and  modify these in whatever way you
          want.  You'll want to create your own routines.  

               Note that  only  the  "Professional"  version of Cakewalk
          supports the Cakewalk Application Language.  

               CAL programs described herein: 

          SWINGQ.CAL   The prototype swing-quantizer.  Copy it and
                       modify it to create new versions.  It
                       implements some examples of 32-quantization.

          12SHUFM.CAL  Shuffle rhythm.

          16LOPE.CAL   Another rhythm.

          16LURCH.CAL  Another rhythm.

               None of   these   programs   operate  on  pitch  bend  or
          controller  information;  they do not move them to where their
          respective notes moved.  

               Also, I  use  DOS  5.0,  and  have  a  configuration that
          allows  for  more  unused  memory  than  normal.   I hope this
          program  runs  on  your system.  If not, try stripping out all
          unnecessary characters.  




          2. GUIDELINES ON CREATING YOUR OWN SWINGS 

               Some of  the  following  discussion requires the insights
          gained  by  reading  the  "theory"  chapter.   The reader must
          understand  that  the main beat is broken into sub-beats.  For
          example, if the main beat is 4/4, the sub-beat can be 16/16.  

               The sub-beats   of   a   single  measure  have  a  number
          associated  with them.  That number tells the CAL program what
          to  do  with  notes  that fall in the domain of that sub-beat.
          If  all the numbers (qi's in the "theory" section) are 0, then
          there  is  no  swing quantization, just straight quantization,
          implemented  much faster with Cakewalk's built-in quantization
          command.   However,  if  some  of  the  numbers  are  non-zero
          (either  positive or negative), then notes that would normally
          be  quantized  to  the nearest sub-beat are now either delayed
          to  the next sub-beat, or moved sooner in time to the previous
          sub-beat.  



                                      - 2 -

          CAL Programs, Edition 2.0                             Ahlstrom



               The numbers  are  usually very small integers in units of
          sub-beats.   Take a look at SWINGQ.CAL's Prolog section.  Here
          is  where  we  define  the  swing of the sub-beats.  Each unit
          represents  one  sub-beat  of  temporal movement.  "1" and "2"
          represent  delaying  the  note  one or two sub-beats, and "-1"
          and  "-2" represent leading the note (pushing the note) one or
          two sub-beats.  

               It would   be   easy  to  modify  the  swing-quantization
          programs  to move the notes in units of ticks, or to include a
          "percentage-quantization"  factor,  but  we've  kept it simple
          for now.  



          3. THE SAMPLE WRK FILE 

               The sample  work-file  is  called  SWINGQ.CAL.  The first
          track  of  this  files is a few measures of 4/4 beats, and the
          next  nine  tracks  are  the  results  of applying various CAL
          swing programs to this track.  

               The 20th  track is a few measures of 8/8 beats, with some
          notes  missing,  for  effect.   The  next  nine tracks are the
          results  of  applying  various  CAL  swing  programs  to  this
          track.  

               Rather than  describe all this, I advise you to play with
          it.  



          4. THE THEORY 

               We'll be  taking  over  a  lot of functions ourselves, to
          make  this  set  of  CAL  routines  a lot more flexible, to do
          strange, non-integer-beat things.  

               In this  discussion,  there  are  two versions of some of
          the   equations.   Version  a  is  the  "musician's  version",
          wherein  values  are  counted  starting  from  1.  This is the
          version   used   in   the   discussion.    Version  b  is  the
          "C-programmer's  version", wherein values are counted starting
          from  0.   This  is the version used in the program, to reduce
          the  number  of  mathematical operations needed, and hence, to
          speed the programs up slightly.  

               Here is  a figure showing a time-line for events occuring
          during  a  single  measure  of  4/4 music, with a quantization
          value of 8 (eighth-note intervals): 




                                      - 3 -

          CAL Programs, Edition 2.0                             Ahlstrom




                      <------------------Tm------------------->
                      <----Tb--->
                         <Tq->

              time:   t--------->--------->--------->--------->
              beats:  o         o         o         o         o          
              beat:   1         2         3         4         1
              i:      1    2    3    4    5    6    7    8    9
              qi:     0    0    1    0   -1    0    0    0    0
              q's:    q-><-q-><-q-><-q-><-q-><-q-><-q-><-q-><-q
              notes:             x   Xy   z


               Here is  a figure showing a time-line for events occuring
          during  a  single  measure  of  3/4 music, with a quantization
          value of 8 (eighth-note intervals): 

                      <-------------Tm-------------->
                      <----Tb--->
                         <Tq->

              time:   t--------->--------->--------->
              beats:  o         o         o         o
              beat:   1         2         3         1
              i:      1    2    3    4    5    6    7
              qi:     0    0    1    0   -1    0    0
              q's:    q-><-q-><-q-><-q-><-q-><-q-><-q
              notes:             x   Xy   z


               Tm is  the  number of ticks per measure; Tb is the number
          of  ticks  per  beat;  and  Tq  is  the  number  of  ticks per
          quantization  interval.   Let  the meter be represented by the
          notation: 

                               Bm
                              ----                                [1]
                               B

          and let us adopt an expanded notation for quantization: 

                               Bm
                              -------, Bq > B                     [2]
                               B(Bq)

          where  Bm  is  the  numerator, or number of beats per measure,
          and  B  is the denominator, or size of the unit that comprises
          a  beat  (4, for quarter-notes, in the example above), and the
          unit   of   quantization   is  Bq  (called  the  "quantization
          interval",   or   "quantization   beat").   For  example,  the
          designation 


                                      - 4 -

          CAL Programs, Edition 2.0                             Ahlstrom




                               4
                              ------
                               4(16)

          means  that the meter is 4/4, and we want quantization on 16th
          notes.  

               In general,   B,  Bm,  and  Bq  are  all  interdependent.
          Normally,  we  will  choose  Bq to be some integer multiple of
          Bm.   For example, we might designate our quantization as 

                               3
                              ------
                               4(12)

          where  it's  easy  to  see  that  3x4=12.   I  will include an
          experiment  with  a strange set of values, though, to see what
          sort  of  weird  quantization  we  get.   See  the  "Examples"
          section of this document.  

               Then, the  above  quantities  are  given by the following
          formulae: 

                              Tb = TIMEBASE                       [3]

          where  TIMEBASE  is determined by the current configuration of
          Cakewalk.  We also have the number of ticks, Tm, per measure: 

                              Tm = Bm Tb                          [4]

          and 

                                    Tm
                              Tq = ----                           [5]
                                    Bq

          But  Tm  is given by Eq. 3, so, substituting Eq. 3 into Eq. 4,
          we have the ticks, Tq, per quantization beat: 

                                    Bm
                              Tq = ---- Tb                        [6]
                                    Bq


               The "beats"   and   "beat"  lines  represent  the  normal
          locations  of  quarter notes in the measure.  In this example,
          though, no note falls exactly at a quarter-note location.  

               "i" is  the  index of each quantization interval.  Rather
          than  using the C-convention of starting with 0, we start with
          1.   For  strict  quantization,  each  "q"  marking  denotes a


                                      - 5 -

          CAL Programs, Edition 2.0                             Ahlstrom



          location   to   which   notes   would  be  moved.   In  strict
          quantization,   all  notes  would  end  up  at  one  of  these
          locations.   Now,  the i's shown above assume that the measure
          is  the  first  measure.  For another measure, m, each i would
          be in the set 

                              (m-1)Bq < i <= m Bq                 [7a]

                              (m-1)Bq <= i < m Bq                 [7b]

          if  we  needed  to  count  all quantization intervals from the
          beginning  of  the  song.   We don't have to do this, however.
          We  need  to know only the i for the current measure, hence we
          restrict i to the following values 

                              0 < i <= Bq                         [8]

          Cakewalk  provides  a  way of determining the beat, the (beat)
          function.   Unfortunately,  getting the beat does not also get
          us   the  quantization  beat.   We  must  calculate  that  for
          ourselves.   Luckily,  the  equation  is pretty simple.  First
          divide  the current number of ticks at the current time by the
          number of ticks in a measure, and use the remainder.  

                                              Event.Time 
                              tm = remainder(------------)        [9]
                                                 Tm

                              tm = Event.Time % Tm                [10]

          where  "%"  is  the  mod  (remainder)  operator  of C and CAL.
          (Note  that  CAL is also an abbreviation for "C And Lisp", heh
          heh.)  This  tells  us  how  many  ticks,  tm, we are into the
          current  measure.   Then,  the quantization interval we are at
          is   this  time  divided  by  the  the  number  of  ticks  per
          quantization interval, plus 1, to start at 1 instead of 0: 

                                   tm
                              i = ---- + 1                        [11a]
                                   Tq

                                   tm
                              i = ----                            [11b]
                                   Tq

          Note  two  things:  (1)  integer division is used, so that the
          remainder  is  thrown  away;  (2)  "1"  is  added,  so  that i
          satisfies  Eq.  8, but, in the CAL programs, form 11b is used,
          to save some processing time.  

               We're not  finished  with  i  yet, however.  Eq. 11 would
          make  a note that lies just before a quantization beat fall on


                                      - 6 -

          CAL Programs, Edition 2.0                             Ahlstrom



          the  previous  quantization  beat.  We really need to round up
          to  the  next quantization beat.  To do this, we add (Tq/2) to
          the original number of ticks: 

                                         Tq
                                   tm + ----
                                         2
                              i = ----------- + 1                 [12a]
                                      Tq

          To save time in CAL, we will define 

                                     Tq
                              Tq2 = ----                          [13]
                                     2

          and,  for  the  C-programmer,  we  drop  the 1, so that Eq. 12
          becomes 

                                   tm + Tq2
                              i = ----------                      [12b]
                                     Tq



               We're still  not  finished  with  i yet, however! What if
          Eq.  12  gives  us  i  =  Bq + 1? The note belongs to the next
          measure.   In this case, we set a "nextm" (next measure) flag,
          and do 

                              i = i - Bq                          [14]


               Once we  have  determine  to  which quantization beat the
          note  belongs, we have to determine what is to be done to that
          note.   The  qi's  tell  CAL  what to do with that note.  Each
          "qi"  is  used to determine whether quantization at that point
          is  to  be  strict,  or  swing,  and  in which direction.  The
          values have the following meanings: 

               "0".  There  is  no swing; any note that falls within the
          range   of  this  q-value  will  be  placed  exactly  at  that
          q-value's time.  

               "1".  The  note  is  to be swung by delaying it until the
          next  quantization  interval  (the  next  "i").  Any note that
          falls  within  range  of the q-value will be placed exactly at
          the *next* q-value's time.  

               "-1".  The  note  is  to  be  swung  by leading it to the
          previous  quantization  interval (the previous "i").  Any note
          that  falls within range of the q-value will be placed exactly


                                      - 7 -

          CAL Programs, Edition 2.0                             Ahlstrom



          at the *previous* q-value's time.  

               "2", "-2",  etc.   Other values are possible, and specify
          the  number  of  quantization  intervals  the  note  is  to be
          moved.   In  the  case above, absolute values (|qi|) of two or
          greater  would  likely  not be used, since they would move the
          notes by a full quarter-note.  

               In the  example above, each of the notes at "x", "y", and
          "z"  would  be  moved to the location marked by "X".  Note "x"
          falls  within  the  purview  of  q3,  but q3 has a value of 1,
          indicating  the  note goes to the next interval, q4.  Note "y"
          falls  within  the  purview  of  q4,  and q4 has a value of 0,
          indicating  the  note  goes  to q4.  Note "z" falls within the
          purview  of  q5, but q5 has a value of -1, indicating the note
          goes to the previous interval, q4.  

               The qi  determines  the  actual qi to use.  So, the swing
          program performs a simple transformation: 

                              i2 = (i + qi)                       [15]

          Again,  if i2 > Bq, then we set the "nextm" flag, and  perform
          Eq. 14 to normalize i.  

               We now  perform  an  inverse  transformation to determine
          the  time  of this new i, and hence, the new time location for
          the  note.   First,  we determine the time of all the previous
          measures: 

                              Tp = Event.Time - tm                [16]

          Then,  if  the  "nextm" (next measure) flag is set, we add one
          more measure's worth of time.  

                              Tp = Tp + Tm                        [17]

          Then  we  determine  the  extra time needed to put the note at
          the right spot within the measure: 

                              tm2 = Tq * (i - 1)                  [18a]

                              tm2 = Tq * i                        [18b]

          And, finally, we have the final location of the note: 

                              tm2 = tm2 + Tp                      [19]

                              Event.Time = tm2                    [20]





                                      - 8 -

          CAL Programs, Edition 2.0                             Ahlstrom



          5. COMMENTS AS STRIPPED FROM THE CODE.  

               I probably  didn't  have  to  strip the comments from the
          code,  but  it  saves some space and time that might be needed
          later.  

               You'll probably   note   that   I  have  two  (switch  i)
          statements   where   one   longer  one  would  appear  to  do.
          Limitations  of the complexity of CAL expressions forced me to
          do  this;  I  could  not  get  any  good  results from setting
          CalMaxEvalStack=32.   No  big  problem,  just makes the code a
          little  slower  and  less elegant.  Besides, the second set of
          qi  variables  and  switch  statements  are  needed  only  for
          sub-beats of 32.  

               Here are  some  of  the  more important comments from the
          code: 

              (int ct 0)   ;note counter
              (int qi 0)   ;current i value for note

              (int q0 0)  (int q1 0) ...  (int q31 0)
                           ;the list of sub-beat swing-values

              (int Bm  4)  ;number of beat notes per measure
              (int B   4)  ;unit of the beats (quarter note by default)
              (int Bq 16)  ;number of quantizable intervals per measure
              (int Tb 0)   ;TIMEBASE
              (int Tm 0)   ;ticks per measure
              (int Tq 0)   ;ticks per quantization interval
              (int Tq2 0)  ;ticks per half-quantization interval
              (int Tp 0)   ;time of all previous measures

              (int i 0)    ;quantization interval number
              (int tm 0)   ;time of note in current measure
              (int nextm 0);1 if note goes in next measure




          6. GUIDELINES FOR SELECTING THE qi VALUES 

               I haven't   given   myself   much   time   to  play  with
          selections,  so  this  section  isn't  much.   Basically, I've
          noted  that you can force notes to cluster to a given point by
          setting  the  middle qi to 0, the left qi to +1, and the right
          qi  to -1.  Selecting satisfactory qi's is a bit of an art, so
          it's probably better that you play with this yourselves.  






                                      - 9 -

          CAL Programs, Edition 2.0                             Ahlstrom



          7.  PLAUSIBLE EXTENSIONS 

               Rather than  small  integer  values  of  qi, we could use
          tick  offsets,  at  the  expense of making everything a little
          more  complicated  for  the  user,  by making the user have to
          determine the timing scales.  

               I also  recommend  using  the  swing  routines on a small
          number  of  measures,  then  replicating the measures, to save
          time.  

               Twelve-Tone Systems  now  has  a disk of new CAL programs
          created  for  their  1991  CAL  Programming Contest.  (Dang, I
          didn't  get an earlier newsletter, so I missed out on a chance
          for  $500  smackers.) Call 1-800-234-1171 (be prepared to give
          your  Cakewalk  Professional  serial  number!) if you want the
          disk.   I  don't  think its too expensive (haven't called them
          myself  yet).  Among other things, it has a strum routine that
          sorts the notes before offsetting their start times.  



































                                      - 10 -

