- /* determine peak's value and position */
- for (i = 0; i < length / 2; i++, ip++) {
- int val = ABS(*ip);
- if (val > peak) {
- peak = val;
- pos = i;
- }
- }
- pcd->peaks[pcd->pn] = peak;
- for (i = 0; i < pcd->conf->buckets_arg; i++) {
- if (pcd->peaks[i] > peak) {
- peak = pcd->peaks[i];
- pos = 0;
- }
- }
- /* determine target gain */
- gn = (1 << GAINSHIFT) * pcd->conf->target_level_arg / peak;
- if (gn < (1 << GAINSHIFT))
- gn = 1 << GAINSHIFT;
- pcd->target_gain = (pcd->target_gain * ((1 << pcd->conf->gain_smooth_arg) - 1) + gn)
- >> pcd->conf->gain_smooth_arg;
- /* give it an extra insignificant nudge to counteract possible
- * rounding error
- */
- if (gn < pcd->target_gain)
- pcd->target_gain--;
- else if (gn > pcd->target_gain)
- pcd->target_gain++;
- if (pcd->target_gain > pcd->conf->gain_max_arg << GAINSHIFT)
- pcd->target_gain = pcd->conf->gain_max_arg << GAINSHIFT;
- /* see if a peak is going to clip */
- gn = (1 << GAINSHIFT) * 32768 / peak;
- if (gn < pcd->target_gain) {
- pcd->target_gain = gn;
- if (pcd->conf->anticlip_given)
- pos = 0;
- } else
- /* we're ramping up, so draw it out over the whole frame */
- pos = length;
- /* determine gain rate necessary to make target */
- if (!pos)
- pos = 1;
- gr = ((pcd->target_gain - pcd->current_gain) << 16) / pos;
- gf = pcd->current_gain << 16;
- ip = audio;
- op = (int16_t *)(fn->buf + fn->loaded);