home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Sound / SoX / Source / vibro.c < prev    next >
C/C++ Source or Header  |  1999-07-18  |  3KB  |  138 lines

  1. /*
  2.  * Sound Tools Vibro effect file.
  3.  *
  4.  * Modeled on world-famous Fender(TM) Amp Vibro knobs.
  5.  * 
  6.  * Algorithm: generate a sine wave ranging from
  7.  * 0 + depth to 1.0, where signal goes from -1.0 to 1.0.
  8.  * Multiply signal with sine wave.  I think.
  9.  *
  10.  * July 5, 1991
  11.  * Copyright 1991 Lance Norskog And Sundry Contributors
  12.  * This source code is freely redistributable and may be used for
  13.  * any purpose.  This copyright notice must be maintained. 
  14.  * Lance Norskog And Sundry Contributors are not responsible for 
  15.  * the consequences of using this software.
  16.  *
  17.  * April 28, 1998 - Chris Bagwell (cbagwell@sprynet.com)
  18.  *
  19.  *  Rearranged some functions so that they are declared before they are
  20.  *  used.  Clears up some compiler warnings.  Because this functions passed
  21.  *  foats, it helped out some dump compilers pass stuff on the stack
  22.  *  correctly.
  23.  *
  24.  */
  25.  
  26.  
  27. #include <math.h>
  28. #include <stdlib.h>
  29. #ifdef HAVE_MALLOC_H
  30. #include <malloc.h>
  31. #endif
  32. #include "st.h"
  33.  
  34. /* Private data for Vibro effect */
  35. typedef struct vibrostuff {
  36.     float         speed;
  37.     float         depth;
  38.     short        *sinetab;        /* sine wave to apply */
  39.     int        mult;            /* multiplier */
  40.     unsigned    length;            /* length of table */
  41.     int        counter;        /* current counter */
  42. } *vibro_t;
  43.  
  44. /*
  45.  * Process options
  46.  */
  47. void vibro_getopts(effp, n, argv) 
  48. eff_t effp;
  49. int n;
  50. char **argv;
  51. {
  52.     vibro_t vibro = (vibro_t) effp->priv;
  53.  
  54.     vibro->depth = 0.5;
  55.     if ((n == 0) || !sscanf(argv[0], "%f", &vibro->speed) ||
  56.         ((n == 2) && !sscanf(argv[1], "%f", &vibro->depth)))
  57.         fail("Usage: vibro speed [ depth ]");
  58.     if ((vibro->speed <= 0.001) || (vibro->speed > 30.0) || 
  59.             (vibro->depth < 0.0) || (vibro->depth > 1.0))
  60.         fail("Vibro: speed must be < 30.0, 0.0 < depth < 1.0");
  61. }
  62.  
  63. /* This was very painful.  We need a sine library. */
  64.  
  65. void sine(buf, len, depth)
  66. short *buf;
  67. int len;
  68. float depth;
  69. {
  70.     int i;
  71.     int scale = depth * 128;
  72.     int base = (1.0 - depth) * 128;
  73.     double val;
  74.  
  75.     for (i = 0; i < len; i++) {
  76.         val = sin((float)i/(float)len * 2.0 * M_PI);
  77.         buf[i] = (val + 1.0) * scale + base * 2;
  78.     }
  79. }
  80.  
  81. /*
  82.  * Prepare processing.
  83.  */
  84. void vibro_start(effp)
  85. eff_t effp;
  86. {
  87.     vibro_t vibro = (vibro_t) effp->priv;
  88.  
  89.     vibro->length = effp->ininfo.rate / vibro->speed;
  90.     if (! (vibro->sinetab = (short*) malloc(vibro->length * sizeof(short))))
  91.         fail("Vibro: Cannot malloc %d bytes",
  92.             vibro->length * sizeof(short));
  93.  
  94.     sine(vibro->sinetab, vibro->length, vibro->depth);
  95.     vibro->counter = 0;
  96. }
  97.  
  98. /*
  99.  * Processed signed long samples from ibuf to obuf.
  100.  * Return number of samples processed.
  101.  */
  102.  
  103. void vibro_flow(effp, ibuf, obuf, isamp, osamp)
  104. eff_t effp;
  105. LONG *ibuf, *obuf;
  106. int *isamp, *osamp;
  107. {
  108.     vibro_t vibro = (vibro_t) effp->priv;
  109.     register int counter, tablen;
  110.     int len, done;
  111.     short *sinetab;
  112.     LONG l;
  113.  
  114.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  115.  
  116.     sinetab = vibro->sinetab;
  117.     counter = vibro->counter;
  118.     tablen = vibro->length;
  119.     for(done = 0; done < len; done++) {
  120.         l = *ibuf++;
  121.         /* 24x8 gives 32-bit result */
  122.         *obuf++ = ((l / 256) * sinetab[counter++ % tablen]);
  123.     }
  124.     vibro->counter = counter;
  125.     /* processed all samples */
  126. }
  127.  
  128. /*
  129.  * Do anything required when you stop reading samples.  
  130.  * Don't close input file! 
  131.  */
  132. void vibro_stop(effp)
  133. eff_t effp;
  134. {
  135.     /* nothing to do */
  136. }
  137.  
  138.