合唱音效解释

  1. 1. 算法原理   
  1. 合唱即多人一起唱歌,以下是算法的原理图:  
  1. /* 
  2.  * 
  3.  *        * gain-in                                           ___ 
  4.  * ibuff -----+--------------------------------------------->|   | 
  5.  *            |      _________                               |   | 
  6.  *            |     |         |                   * level 1  |   | 
  7.  *            +---->| delay 1 |----------------------------->|   | 
  8.  *            |     |_________|                              |   | 
  9.  *            |        /|\                                   |   | 
  10.  *            :         |                                    |   | 
  11.  *            : +-----------------+   +--------------+       | + | 
  12.  *            : | Delay control 1 |<--| mod. speed 1 |       |   | 
  13.  *            : +-----------------+   +--------------+       |   | 
  14.  *            |      _________                               |   | 
  15.  *            |     |         |                   * level n  |   | 
  16.  *            +---->| delay n |----------------------------->|   | 
  17.  *                  |_________|                              |   | 
  18.  *                     /|\                                   |___| 
  19.  *                      |                                      | 
  20.  *              +-----------------+   +--------------+         | * gain-out 
  21.  *              | Delay control n |<--| mod. speed n |         | 
  22.  *              +-----------------+   +--------------+         +----->obuff 
  23.  * 
  24.  * 
  25.  */  

2. 代码实现

 

  1. void dsound_chorus_processmix(dsound_chorus_t* chorus, dsound_real_t *in,  
  2.                 dsound_real_t *left_out, dsound_real_t *right_out)  
  3. {  
  4.   int sample_index;  
  5.   int i;  
  6.   dsound_real_t d_in, d_out;  
  7.   
  8.   for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {  
  9.   
  10.     d_in = in[sample_index];  
  11.     d_out = 0.0f;  
  12.   
  13. # if 0  
  14.     /* Debug: Listen to the chorus signal only */  
  15.     left_out[sample_index]=0;  
  16.     right_out[sample_index]=0;  
  17. #endif  
  18.   
  19.     /* Write the current sample into the circular buffer */  
  20.     chorus->chorusbuf[chorus->counter] = d_in;  
  21.   
  22.     for (i = 0; i < chorus->number_blocks; i++) {  
  23.       int ii;  
  24.       /* Calculate the delay in subsamples for the delay line of chorus block nr. */  
  25.   
  26.       /* The value in the lookup table is so, that this expression 
  27.        * will always be positive.  It will always include a number of 
  28.        * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to 
  29.        * remain positive at all times. */  
  30.       int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter  
  31.                 - chorus->lookup_tab[chorus->phase[i]]);  
  32.   
  33.       int pos_samples = pos_subsamples/INTERPOLATION_SUBSAMPLES;  
  34.   
  35.       /* modulo divide by INTERPOLATION_SUBSAMPLES */  
  36.       pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;  
  37.   
  38.       for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){  
  39.     /* Add the delayed signal to the chorus sum d_out Note: The 
  40.      * delay in the delay line moves backwards for increasing 
  41.      * delay!*/  
  42.   
  43.     /* The & in chorusbuf[...] is equivalent to a division modulo 
  44.        MAX_SAMPLES, only faster. */  
  45.     d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]  
  46.       * chorus->sinc_table[ii][pos_subsamples];  
  47.   
  48.     pos_samples--;  
  49.       };  
  50.       /* Cycle the phase of the modulating LFO */  
  51.       chorus->phase[i]++;  
  52.       chorus->phase[i] %= (chorus->modulation_period_samples);  
  53.     } /* foreach chorus block */  
  54.   
  55.     d_out *= chorus->level;  
  56.   
  57.     /* Add the chorus sum d_out to output */  
  58.     left_out[sample_index] += d_out;  
  59.     right_out[sample_index] += d_out;  
  60.   
  61.     /* Move forward in circular buffer */  
  62.     chorus->counter++;  
  63.     chorus->counter %= MAX_SAMPLES;  
  64.   
  65.   } /* foreach sample */  
  66. }  
posted @ 2014-06-14 01:00  腐烂的翅膀  阅读(340)  评论(0编辑  收藏  举报