/* ================ dmaHD_ResampleSfx resample / decimate to the current source rate ================ */ void dmaHD_ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data, qboolean compressed) { short* buffer; int (*dmaHD_GetSampleRaw)(int, int, byte*) = (inwidth == 2) ? dmaHD_GetSampleRaw_16bit : dmaHD_GetSampleRaw_8bit; float stepscale, idx_smp, sample, bsample; float lp_inva, lp_a, hp_a, lp_data, lp_last, hp_data, hp_last, hp_lastsample; int outcount, idx_hp, idx_lp; stepscale = (float)inrate/(float)dma.speed; outcount = (int)((float)sfx->soundLength / stepscale); // Create secondary buffer for bass sound while performing lowpass filter; buffer = dmaHD_AllocateSoundBuffer(outcount * 2); // Check if this is a weapon sound. sfx->weaponsound = (memcmp(sfx->soundName, "sound/weapons/", 14) == 0) ? qtrue : qfalse; // Get first sample from sound effect. idx_smp = -stepscale; sample = dmaHD_GetInterpolatedSample(idx_smp, sfx->soundLength, data, dmaHD_GetSampleRaw); bsample = dmaHD_GetNoInterpolationSample(idx_smp, sfx->soundLength, data, dmaHD_GetSampleRaw); idx_smp += stepscale; // Set up high pass filter. idx_hp = 0; hp_last = sample; hp_lastsample = sample; //buffer[idx_hp++] = sample; hp_a = 0.95f; // Set up Low pass filter. idx_lp = outcount; lp_last = bsample; lp_a = 0.03f; lp_inva = (1 - lp_a); // Now do actual high/low pass on actual data. for (;idx_hp < outcount; idx_hp++) { sample = dmaHD_GetInterpolatedSample(idx_smp, sfx->soundLength, data, dmaHD_GetSampleRaw); bsample = dmaHD_GetNoInterpolationSample(idx_smp, sfx->soundLength, data, dmaHD_GetSampleRaw); idx_smp += stepscale; // High pass. hp_data = hp_a * (hp_last + sample - hp_lastsample); buffer[idx_hp] = SMPCLAMP(hp_data); hp_last = hp_data; hp_lastsample = sample; // Low pass. lp_data = lp_a * (float)bsample + lp_inva * lp_last; //if ((idx_hp % 2) != 0) buffer[idx_lp++] = SMPCLAMP((lp_last + lp_data) / 2.0f); buffer[idx_lp++] = SMPCLAMP(lp_data); lp_last = lp_data; } sfx->soundData = (sndBuffer*)buffer; sfx->soundLength = outcount; }
// t must be a float between 0 and samples static int dmaHD_GetInterpolatedSampleCubic(float t, int samples, byte *data, int (*dmaHD_GetSampleRaw)(int, int, byte*)) { int x, val; t = dmaHD_NormalizeSamplePosition(t, samples); // Get points x = (int)t; // Interpolate val = (int)dmaHD_InterpolateCubic( (float)dmaHD_GetSampleRaw(x - 1, samples, data), (float)dmaHD_GetSampleRaw(x, samples, data), (float)dmaHD_GetSampleRaw(x + 1, samples, data), (float)dmaHD_GetSampleRaw(x + 2, samples, data), FLOAT_DECIMAL_PART(t)); // Clamp return SMPCLAMP(val); }