mirror of https://github.com/encounter/SDL.git
audio: Resampler now special-cases stereo and mono processing.
Turns out that iterating from 0 to channels-1 was a serious performance hit! These cases now tend to match or beat the original audio resampler's speed!
This commit is contained in:
parent
8ce6ddf125
commit
dad07f960b
|
@ -249,49 +249,115 @@ SDL_ResampleAudioSimple(const int chans, const double rate_incr,
|
|||
SDL_assert((dest_samples * framelen) <= outbuflen);
|
||||
SDL_assert((inbuflen % framelen) == 0);
|
||||
|
||||
if (rate_incr > 1.0) {
|
||||
if (rate_incr > 1.0) { /* upsample */
|
||||
float *target = (outbuf + chans);
|
||||
const float *earlier_sample = &inbuf[finalpos];
|
||||
float final_sample[8];
|
||||
dst = outbuf + (dest_samples * chans);
|
||||
idx = (double) total;
|
||||
|
||||
/* save this off so we can correctly maintain state between runs. */
|
||||
SDL_memcpy(final_sample, &inbuf[finalpos], framelen);
|
||||
|
||||
while (dst > target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
SDL_assert(pos >= 0.0);
|
||||
for (i = chans - 1; i >= 0; i--) {
|
||||
if (chans == 1) {
|
||||
const float final_sample = inbuf[finalpos];
|
||||
float earlier_sample = inbuf[finalpos];
|
||||
while (dst > target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
const float val = *(--src);
|
||||
*(--dst) = (val + earlier_sample[i]) * 0.5f;
|
||||
SDL_assert(pos >= 0.0);
|
||||
*(--dst) = (val + earlier_sample) * 0.5f;
|
||||
earlier_sample = val;
|
||||
idx -= src_incr;
|
||||
}
|
||||
earlier_sample = src;
|
||||
idx -= src_incr;
|
||||
/* do last sample, interpolated against previous run's state. */
|
||||
*(--dst) = (inbuf[0] + last_sample[0]) * 0.5f;
|
||||
*last_sample = final_sample;
|
||||
} else if (chans == 2) {
|
||||
const float final_sample2 = inbuf[finalpos+1];
|
||||
const float final_sample1 = inbuf[finalpos];
|
||||
float earlier_sample2 = inbuf[finalpos];
|
||||
float earlier_sample1 = inbuf[finalpos-1];
|
||||
while (dst > target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
const float val2 = *(--src);
|
||||
const float val1 = *(--src);
|
||||
SDL_assert(pos >= 0.0);
|
||||
*(--dst) = (val2 + earlier_sample2) * 0.5f;
|
||||
*(--dst) = (val1 + earlier_sample1) * 0.5f;
|
||||
earlier_sample2 = val2;
|
||||
earlier_sample1 = val1;
|
||||
idx -= src_incr;
|
||||
}
|
||||
/* do last sample, interpolated against previous run's state. */
|
||||
*(--dst) = (inbuf[1] + last_sample[1]) * 0.5f;
|
||||
*(--dst) = (inbuf[0] + last_sample[0]) * 0.5f;
|
||||
last_sample[1] = final_sample2;
|
||||
last_sample[0] = final_sample1;
|
||||
} else {
|
||||
const float *earlier_sample = &inbuf[finalpos];
|
||||
float final_sample[8];
|
||||
SDL_memcpy(final_sample, &inbuf[finalpos], framelen);
|
||||
while (dst > target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
SDL_assert(pos >= 0.0);
|
||||
for (i = chans - 1; i >= 0; i--) {
|
||||
const float val = *(--src);
|
||||
*(--dst) = (val + earlier_sample[i]) * 0.5f;
|
||||
}
|
||||
earlier_sample = src;
|
||||
idx -= src_incr;
|
||||
}
|
||||
/* do last sample, interpolated against previous run's state. */
|
||||
for (i = chans - 1; i >= 0; i--) {
|
||||
const float val = inbuf[i];
|
||||
*(--dst) = (val + last_sample[i]) * 0.5f;
|
||||
}
|
||||
SDL_memcpy(last_sample, final_sample, framelen);
|
||||
}
|
||||
|
||||
/* do last sample, interpolated against previous run's state. */
|
||||
for (i = chans - 1; i >= 0; i--) {
|
||||
const float val = inbuf[i];
|
||||
*(--dst) = (val + last_sample[i]) * 0.5f;
|
||||
}
|
||||
SDL_memcpy(last_sample, final_sample, framelen);
|
||||
dst = (outbuf + (dest_samples * chans)) - 1;
|
||||
} else {
|
||||
} else { /* downsample */
|
||||
float *target = (outbuf + (dest_samples * chans));
|
||||
dst = outbuf;
|
||||
idx = 0.0;
|
||||
while (dst < target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
SDL_assert(pos <= finalpos);
|
||||
for (i = 0; i < chans; i++) {
|
||||
const float val = *(src++);
|
||||
*(dst++) = (val + last_sample[i]) * 0.5f;
|
||||
last_sample[i] = val;
|
||||
if (chans == 1) {
|
||||
float last = *last_sample;
|
||||
while (dst < target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float val = inbuf[pos];
|
||||
SDL_assert(pos <= finalpos);
|
||||
*(dst++) = (val + last) * 0.5f;
|
||||
last = val;
|
||||
idx += src_incr;
|
||||
}
|
||||
*last_sample = last;
|
||||
} else if (chans == 2) {
|
||||
float last1 = last_sample[0];
|
||||
float last2 = last_sample[1];
|
||||
while (dst < target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float val1 = inbuf[pos];
|
||||
const float val2 = inbuf[pos+1];
|
||||
SDL_assert(pos <= finalpos);
|
||||
*(dst++) = (val1 + last1) * 0.5f;
|
||||
*(dst++) = (val2 + last2) * 0.5f;
|
||||
last1 = val1;
|
||||
last2 = val2;
|
||||
idx += src_incr;
|
||||
}
|
||||
last_sample[0] = last1;
|
||||
last_sample[1] = last2;
|
||||
} else {
|
||||
while (dst < target) {
|
||||
const int pos = ((int) idx) * chans;
|
||||
const float *src = &inbuf[pos];
|
||||
SDL_assert(pos <= finalpos);
|
||||
for (i = 0; i < chans; i++) {
|
||||
const float val = *(src++);
|
||||
*(dst++) = (val + last_sample[i]) * 0.5f;
|
||||
last_sample[i] = val;
|
||||
}
|
||||
idx += src_incr;
|
||||
}
|
||||
idx += src_incr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue