- 1. 算法原理
[cpp] view plaincopyprint?
- 合唱即多人一起唱歌,以下是算法的原理图:
[cpp] view plaincopyprint?
- /*
- *
- * * gain-in ___
- * ibuff -----+--------------------------------------------->| |
- * | _________ | |
- * | | | * level 1 | |
- * +---->| delay 1 |----------------------------->| |
- * | |_________| | |
- * | /|\ | |
- * : | | |
- * : +-----------------+ +--------------+ | + |
- * : | Delay control 1 |<--| mod. speed 1 | | |
- * : +-----------------+ +--------------+ | |
- * | _________ | |
- * | | | * level n | |
- * +---->| delay n |----------------------------->| |
- * |_________| | |
- * /|\ |___|
- * | |
- * +-----------------+ +--------------+ | * gain-out
- * | Delay control n |<--| mod. speed n | |
- * +-----------------+ +--------------+ +----->obuff
- *
- *
- */
2. 代码实现
[cpp] view plaincopyprint?
- void dsound_chorus_processmix(dsound_chorus_t* chorus, dsound_real_t *in,
- dsound_real_t *left_out, dsound_real_t *right_out)
- {
- int sample_index;
- int i;
- dsound_real_t d_in, d_out;
- for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {
- d_in = in[sample_index];
- d_out = 0.0f;
- # if 0
- /* Debug: Listen to the chorus signal only */
- left_out[sample_index]=0;
- right_out[sample_index]=0;
- #endif
- /* Write the current sample into the circular buffer */
- chorus->chorusbuf[chorus->counter] = d_in;
- for (i = 0; i < chorus->number_blocks; i++) {
- int ii;
- /* Calculate the delay in subsamples for the delay line of chorus block nr. */
- /* The value in the lookup table is so, that this expression
- * will always be positive. It will always include a number of
- * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
- * remain positive at all times. */
- int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
- - chorus->lookup_tab[chorus->phase[i]]);
- int pos_samples = pos_subsamples/INTERPOLATION_SUBSAMPLES;
- /* modulo divide by INTERPOLATION_SUBSAMPLES */
- pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
- for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){
- /* Add the delayed signal to the chorus sum d_out Note: The
- * delay in the delay line moves backwards for increasing
- * delay!*/
- /* The & in chorusbuf[...] is equivalent to a division modulo
- MAX_SAMPLES, only faster. */
- d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
- * chorus->sinc_table[ii][pos_subsamples];
- pos_samples--;
- };
- /* Cycle the phase of the modulating LFO */
- chorus->phase[i]++;
- chorus->phase[i] %= (chorus->modulation_period_samples);
- } /* foreach chorus block */
- d_out *= chorus->level;
- /* Add the chorus sum d_out to output */
- left_out[sample_index] += d_out;
- right_out[sample_index] += d_out;
- /* Move forward in circular buffer */
- chorus->counter++;
- chorus->counter %= MAX_SAMPLES;
- } /* foreach sample */
- }
合唱音效解释
时间: 2024-10-05 04:00:05