home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / windows3 / mtlabsnd.zip / ECHO.C < prev    next >
Text File  |  1993-04-26  |  5KB  |  215 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. **     Echo effect. based on:
  13. **
  14. ** echoplex.c - echo generator
  15. **
  16. ** Copyright (C) 1989 by Jef Poskanzer.
  17. **
  18. ** Permission to use, copy, modify, and distribute this software and its
  19. ** documentation for any purpose and without fee is hereby granted, provided
  20. ** that the above copyright notice appear in all copies and that both that
  21. ** copyright notice and this permission notice appear in supporting
  22. ** documentation.  This software is provided "as is" without express or
  23. ** implied warranty.
  24. */
  25.  
  26. /*
  27.  * Sound Tools echo effect file.
  28.  */
  29.  
  30. #include "st.h"
  31. #include <math.h>
  32.  
  33. #define FADE_THRESH 10
  34. #define MYBUFSIZ 256
  35. #define DELAYBUFSIZ ( 50 * MAXRATE )
  36. #define MAXDELAYS 30
  37.  
  38. struct echoplex {
  39.     int    counter;            
  40.     int    numdelays;
  41.     long    *delaybuf;
  42.     float    delay[MAXDELAYS], atten[MAXDELAYS];
  43.     long    samples[MAXDELAYS], maxsamples;
  44.     long    pl, ppl, pppl;
  45. };
  46.  
  47. /* Private data for SKEL file */
  48. typedef struct echostuff {
  49.     struct    echoplex *echoplex;
  50. } *echo_t;
  51.  
  52. #define abs(a) ((a) >= 0 ? (a) : -(a))
  53.  
  54. long clip24();
  55.  
  56. double atof();
  57.  
  58. extern writing;
  59.  
  60. /*
  61.  * Process options
  62.  */
  63. echo_getopts(effp, n, argv) 
  64. eff_t effp;
  65. int n;
  66. char **argv;
  67. {
  68.     echo_t echo = (echo_t) effp->priv;
  69.     struct echoplex *e;
  70.     int i;
  71.  
  72.     echo->echoplex = (struct echoplex *) malloc(sizeof(struct echoplex));
  73.     e = echo->echoplex;
  74.     e->numdelays = 0;
  75.     e->maxsamples = 0;
  76.  
  77.     if ((n == 0) || (n & 1))
  78.         fail("Usage: echo delay attenuation [ delay attenuation ... ]");
  79.  
  80.     i = 0;
  81.     while (i < n) {
  82.         e->delay[e->numdelays] = atof( argv[i++] );
  83.         e->atten[e->numdelays] = atof( argv[i++] );
  84.         e->numdelays++;
  85.     }
  86. }
  87.  
  88. /*
  89.  * Prepare for processing.
  90.  */
  91. echo_start(effp)
  92. eff_t effp;
  93. {
  94.     echo_t echo = (echo_t) effp->priv;
  95.     struct    echoplex *e = echo->echoplex;
  96.     int i;
  97.  
  98.     for(i = 0; i < e->numdelays; i++) {
  99.         e->samples[i] = e->delay[i] * effp->ininfo.rate;
  100.         if ( e->samples[i] < 1 )
  101.             fail(" delay must positive, aye!");
  102.         if ( e->samples[i] > DELAYBUFSIZ )
  103.             fail("Echo: delay must be less than %g seconds",
  104.                 DELAYBUFSIZ / (float) effp->ininfo.rate );
  105.         if ( e->atten[i] < 0.0 )
  106.             fail("attenuation must positive, aye!\n" );
  107.         if ( e->samples[i] > e->maxsamples )
  108.             e->maxsamples = e->samples[i];
  109.     }
  110.     if (! (e->delaybuf = (long *) malloc(sizeof (long) * e->maxsamples)))
  111.         fail("Echo: Cannot malloc %d bytes\n", 
  112.             sizeof(long) * e->maxsamples);
  113.     for ( i = 0; i < e->maxsamples; ++i )
  114.         e->delaybuf[i] = 0;
  115.     e->pppl = e->ppl = e->pl = 0x7fffff;        /* fade-outs */
  116.     e->counter = 0;
  117. }
  118.  
  119. /*
  120.  * Processed signed long samples from ibuf to obuf.
  121.  * Return number of samples processed.
  122.  */
  123.  
  124. echo_flow(effp, ibuf, obuf, isamp, osamp)
  125. eff_t effp;
  126. long *ibuf, *obuf;
  127. int *isamp, *osamp;
  128. {
  129.     echo_t echo = (echo_t) effp->priv;
  130.     struct    echoplex *e = echo->echoplex;
  131.     int len, done;
  132.     int i, j;
  133.     
  134.     long l;
  135.  
  136.     i = e->counter;
  137.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  138.     for(done = 0; done < len; done++) {
  139.         /* Store delays as 24-bit signed longs */
  140.         l = *ibuf++ / 256;
  141.         for ( j = 0; j < e->numdelays; ++j )
  142.             l = l + 
  143. e->delaybuf[( i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  144.         l = clip24(l);
  145.         e->delaybuf[i] = l;
  146.         *obuf++ = l * 256;
  147.         i++;        /* XXX need a % maxsamples here ? */
  148.         i %= e->maxsamples;
  149.     }
  150.     e->counter = i;
  151.     /* processed all samples */
  152. }
  153.  
  154. /*
  155.  * Drain out echo lines. 
  156.  */
  157. echo_drain(effp, obuf, osamp)
  158. eff_t effp;
  159. long *obuf;
  160. long *osamp;
  161. {
  162.     echo_t echo = (echo_t) effp->priv;
  163.     struct    echoplex *e = echo->echoplex;
  164.     long l;
  165.     int i, j, done;
  166.  
  167.     i = e->counter;
  168.     done = 0;
  169.     /* drain out delay samples */
  170.     do {
  171.         l = 0;
  172.         for ( j = 0; j < e->numdelays; ++j )
  173.             l += 
  174. e->delaybuf[(i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  175.         l = clip24(l);
  176.         e->delaybuf[i] = l;
  177.         obuf[done++] = l * 256;
  178.         e->pppl = e->ppl;
  179.         e->ppl = e->pl;
  180.         e->pl = l;
  181.         i++;        /* need a % maxsamples here ? */
  182.         i %= e->maxsamples;
  183.     } while((done < *osamp) && 
  184.         ((abs(e->pl) + abs(e->ppl) + abs(e->pppl)) > FADE_THRESH));
  185.     e->counter = i;
  186.     *osamp = done;
  187.     /* drain will not be called again */
  188. }
  189.  
  190. /*
  191.  * Clean up echo effect.
  192.  */
  193. echo_stop(effp)
  194. eff_t effp;
  195. {
  196.     echo_t echo = (echo_t) effp->priv;
  197.  
  198.     free((char *) echo->echoplex);
  199.     echo->echoplex = (struct echoplex *) -1;   /* guaranteed core dump */
  200. }
  201.  
  202. long
  203. clip24(l)
  204. long l;
  205. {
  206.     if (l >= ((long)1 << 24))
  207.         return ((long)1 << 24) - 1;
  208.     else if (l <= -((long)1 << 24))
  209.         return -((long)1 << 24) + 1;
  210.     else
  211.         return l;
  212. }
  213.  
  214.  
  215.