home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / windows3 / mtlabsnd.zip / RATE.C < prev    next >
Text File  |  1993-04-26  |  5KB  |  175 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12.  * Sound Tools rate change effect file.
  13.  */
  14.  
  15. #include "st.h"
  16. #include <math.h>
  17.  
  18. /*
  19.  * Least Common Multiple Linear Interpolation 
  20.  *
  21.  * Find least common multiple of the two sample rates.
  22.  * Construct the signal at the LCM by interpolating successive
  23.  * input samples as straight lines.  Pull output samples from
  24.  * this line at output rate.
  25.  *
  26.  * Of course, actually calculate only the output samples.
  27.  *
  28.  * LCM must be 32 bits or less.  Two prime number sample rates
  29.  * between 32768 and 65535 will yield a 32-bit LCM, so this is 
  30.  * stretching it.
  31.  */
  32.  
  33. /*
  34.  * Algorithm:
  35.  *  
  36.  *  Generate a master sample clock from the LCM of the two rates.
  37.  *  Interpolate linearly along it.  Count up input and output skips.
  38.  *
  39.  *  Input:   |inskip |       |       |       |       |
  40.  *                                                                      
  41.  *                                                                      
  42.  *                                                                      
  43.  *  LCM:     |   |   |   |   |   |   |   |   |   |   |
  44.  *                                                                      
  45.  *                                                                      
  46.  *                                                                      
  47.  *  Output:  |  outskip  |           |           | 
  48.  *
  49.  *                                                                      
  50.  */
  51.  
  52.  
  53. /* Private data for Lerp via LCM file */
  54. typedef struct ratestuff {
  55.     u_l    lcmrate;        /* least common multiple of rates */
  56.     u_l    inskip, outskip;    /* LCM increments for I & O rates */
  57.     u_l    total;
  58.     u_l    intot, outtot;        /* total samples in terms of LCM rate */
  59.     long    lastsamp;
  60. } *rate_t;
  61.  
  62. /*
  63.  * Process options
  64.  */
  65. rate_getopts(effp, n, argv) 
  66. eff_t effp;
  67. int n;
  68. char **argv;
  69. {
  70.     if (n)
  71.         fail("Rate effect takes no options.");
  72. }
  73.  
  74. /*
  75.  * Prepare processing.
  76.  */
  77. rate_start(effp)
  78. eff_t effp;
  79. {
  80.     rate_t rate = (rate_t) effp->priv;
  81.     extern long lcm();
  82.     
  83.     rate->lcmrate = lcm((long)effp->ininfo.rate, (long)effp->outinfo.rate);
  84.     /* Cursory check for LCM overflow.  
  85.      * If both rate are below 65k, there should be no problem.
  86.      * 16 bits x 16 bits = 32 bits, which we can handle.
  87.      */
  88.     rate->inskip = rate->lcmrate / effp->ininfo.rate;
  89.     rate->outskip = rate->lcmrate / effp->outinfo.rate; 
  90.     rate->total = rate->intot = rate->outtot = 0;
  91.     rate->lastsamp = 0;
  92. }
  93.  
  94. /*
  95.  * Processed signed long samples from ibuf to obuf.
  96.  * Return number of samples processed.
  97.  */
  98.  
  99. rate_flow(effp, ibuf, obuf, isamp, osamp)
  100. eff_t effp;
  101. long *ibuf, *obuf;
  102. int *isamp, *osamp;
  103. {
  104.     rate_t rate = (rate_t) effp->priv;
  105.     int len, done;
  106.     int skip;
  107.     long *istart = ibuf;
  108.     long last;
  109.     
  110.     char c;
  111.     unsigned char uc;
  112.     short s;
  113.     unsigned short us;
  114.     long l;
  115.     unsigned long ul;
  116.     float f;
  117.     double d;
  118.  
  119.     done = 0;
  120.     if (rate->total == 0) {
  121.         /* Emit first sample.  We know the fence posts meet. */
  122.         *obuf = *ibuf++;
  123.         /* Count up until have right input samples */
  124.             rate->lastsamp = *obuf++ >> 16;
  125.         done = 1;
  126.         rate->total = 1;
  127.         /* advance to second output */
  128.         rate->outtot += rate->outskip;
  129.         /* advance input range to span next output */
  130.         while ((rate->intot + rate->inskip) <= rate->outtot){
  131.             last = *ibuf++ / 65536;
  132.             rate->intot += rate->inskip;
  133.         }
  134.     }
  135.     /* number of output samples the input can feed */
  136.     len = (*isamp * rate->inskip) / rate->outskip;
  137.     if (len > *osamp)
  138.         len = *osamp;
  139.     last = rate->lastsamp;
  140.     for(; done < len; done++) {
  141.         *obuf = last;
  142.         *obuf += ((float)((*ibuf / 65536)  - last)* ((float)rate->outtot - 
  143.                 rate->intot))/rate->inskip;
  144.         *obuf *= 65536;
  145.         obuf++;
  146.         /* advance to next output */
  147.         rate->outtot += rate->outskip;
  148.         /* advance input range to span next output */
  149.         while ((rate->intot + rate->inskip) <= rate->outtot){
  150.             last = *ibuf++ >> 16;
  151.             rate->intot += rate->inskip;
  152.             if (ibuf - istart == *isamp)
  153.                 goto out;
  154.         }
  155.         /* long samples with high LCM's overrun counters! */
  156.         if (rate->outtot == rate->intot)
  157.             rate->outtot = rate->intot = 0;
  158.     }
  159. out:
  160.     *isamp = ibuf - istart;
  161.     *osamp = len;
  162.     rate->lastsamp = last;
  163. }
  164.  
  165. /*
  166.  * Do anything required when you stop reading samples.  
  167.  * Don't close input file! 
  168.  */
  169. rate_stop(effp)
  170. eff_t effp;
  171. {
  172.     /* nothing to do */
  173. }
  174.  
  175.