您的位置:首页 > 其它

合唱音效解释

2014-06-14 01:00 155 查看
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 */

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: