static int filter(int input, struct filter_state *fs) { float tmp, normal_output, led_output; switch (sound_use_filter) { case FILTER_MODEL_A500: fs->rc1 = a500e_filter1_a0 * input + (1 - a500e_filter1_a0) * fs->rc1 + DENORMAL_OFFSET; fs->rc2 = a500e_filter2_a0 * fs->rc1 + (1-a500e_filter2_a0) * fs->rc2; normal_output = fs->rc2; fs->rc3 = filter_a0 * normal_output + (1 - filter_a0) * fs->rc3; fs->rc4 = filter_a0 * fs->rc3 + (1 - filter_a0) * fs->rc4; fs->rc5 = filter_a0 * fs->rc4 + (1 - filter_a0) * fs->rc5; led_output = fs->rc5; break; case FILTER_MODEL_A1200: normal_output = input; fs->rc2 = filter_a0 * normal_output + (1 - filter_a0) * fs->rc2 + DENORMAL_OFFSET; fs->rc3 = filter_a0 * fs->rc2 + (1 - filter_a0) * fs->rc3; fs->rc4 = filter_a0 * fs->rc3 + (1 - filter_a0) * fs->rc4; led_output = fs->rc4; break; default: fprintf(stderr, "Unknown filter mode\n"); exit(-1); } return clamp_sample(gui_ledstate ? led_output : normal_output); }
void Resampler::clamp(Sample* Pdst, int n) { while (n > 0) { *Pdst = clamp_sample(*Pdst); ++Pdst; n--; } }
/* this interpolator performs BLEP mixing (bleps are shaped like integrated sinc * functions) with a type of BLEP that matches the filtering configuration. */ static void sample16si_sinc_handler (void) { int i, n; int const *winsinc; int datas[4]; if (sound_use_filter) { n = (sound_use_filter == FILTER_MODEL_A500) ? 0 : 2; if (gui_ledstate) n += 1; } else { n = 4; } winsinc = winsinc_integral[n]; for (i = 0; i < 4; i += 1) { int j; struct audio_channel_data *acd = &audio_channel[i]; /* The sum rings with harmonic components up to infinity... */ int sum = acd->output_state << 17; /* ...but we cancel them through mixing in BLEPs instead */ int offsetpos = acd->sinc_queue_head & (SINC_QUEUE_LENGTH - 1); for (j = 0; j < SINC_QUEUE_LENGTH; j += 1) { int age = acd->sinc_queue_time - acd->sinc_queue[offsetpos].time; if (age >= SINC_QUEUE_MAX_AGE) break; sum -= winsinc[age] * acd->sinc_queue[offsetpos].output; offsetpos = (offsetpos + 1) & (SINC_QUEUE_LENGTH - 1); } datas[i] = sum >> 16; } *(sndbufpt++) = clamp_sample(datas[0] + datas[3]); *(sndbufpt++) = clamp_sample(datas[1] + datas[2]); check_sound_buffers(); }
static inline void process_nibble(unsigned nibble, int* idelta, int* sample1, int* sample2, const ADPCMCOEFSET* coeff) { int sample; int snibble; /* nibble is in fact a signed 4 bit integer => propagate sign if needed */ snibble = (nibble & 0x08) ? (nibble - 16) : nibble; sample = ((*sample1 * coeff->iCoef1) + (*sample2 * coeff->iCoef2)) / 256 + snibble * *idelta; clamp_sample(&sample); *sample2 = *sample1; *sample1 = sample; *idelta = ((MS_Delta[nibble] * *idelta) / 256); if (*idelta < 16) *idelta = 16; }