--- SDL_audiotypecvt_old.c +++ SDL_audiotypecvt.c @@ -216,19 +216,31 @@ } } +/* Works a bit glitchy, need to more work on it for Arbitrary resapling! */ +#define TRY_INTERPOLATE_ARBITRARY +/* Without it sound is a bit "metallic" after up-sampling and some down-sampling, + but stable and no clicks and no clips */ + void SDL_Upsample_Arbitrary(SDL_AudioCVT *cvt, const int channels) { - const int srcsize = cvt->len_cvt - (64 * channels); - const int dstsize = (int) ((((double)(cvt->len_cvt/(channels*4))) * cvt->rate_incr)) * (channels*4); - register int eps = 0; - float *dst = ((float *) (cvt->buf + dstsize)) - channels; - const float *src = ((float *) (cvt->buf + cvt->len_cvt)) - channels; - const float *target = ((const float *) cvt->buf); - const size_t cpy = sizeof (float) * channels; + const size_t cpy = sizeof (float) * (size_t)channels; + const int s_size = cvt->len_cvt / (int)cpy; + const int d_size = (int)(((double)s_size) * cvt->rate_incr); + float *target = ((float *) cvt->buf); + float *dst = target + (d_size * channels) - channels; + const float *src = target + (s_size * channels) - channels; + + #ifdef TRY_INTERPOLATE_ARBITRARY + float last_sample[8]; + #endif float sample[8]; - float last_sample[8]; - int i; + #ifdef TRY_INTERPOLATE_ARBITRARY + int i; + #endif + + register double eps = 0.0; + double offset = 1.0 / cvt->rate_incr; #if DEBUG_CONVERT fprintf(stderr, "Upsample arbitrary (x%f), %d channels.\n", cvt->rate_incr, channels); @@ -236,17 +248,27 @@ SDL_assert(channels <= 8); + #ifndef TRY_INTERPOLATE_ARBITRARY + SDL_memcpy(sample, src, cpy); + #else for (i = 0; i < channels; i++) { - sample[i] = (float) ((((double) src[i]) + ((double) src[i - channels])) * 0.5); + sample[i] = (float) ((((double) src[i]) + ((double)(src - channels)[i])) * 0.5); } SDL_memcpy(last_sample, src, cpy); + #endif while (dst > target) { SDL_memcpy(dst, sample, cpy); dst -= channels; - eps += srcsize; - if ((eps << 1) >= dstsize) { + eps += offset; + if(eps >= 1.0) { + #ifndef TRY_INTERPOLATE_ARBITRARY if (src > target) { + src -= channels; + SDL_memcpy(sample, src, cpy); + } + #else + if(src > target) { src -= channels; for (i = 0; i < channels; i++) { sample[i] = (float) ((((double) src[i]) + ((double) last_sample[i])) * 0.5); @@ -255,11 +277,12 @@ } SDL_memcpy(last_sample, src, cpy); - eps -= dstsize; - } - } - - cvt->len_cvt = dstsize; + #endif + eps -= 1.0; + } + } + + cvt->len_cvt = d_size * (int)cpy; if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); } @@ -268,16 +291,20 @@ void SDL_Downsample_Arbitrary(SDL_AudioCVT *cvt, const int channels) { - const int srcsize = cvt->len_cvt - (64 * channels); - const int dstsize = (int) (((double)(cvt->len_cvt/(channels*4))) * cvt->rate_incr) * (channels*4); - register int eps = 0; - float *dst = (float *) cvt->buf; - const float *src = (float *) cvt->buf; - const float *target = (const float *) (cvt->buf + dstsize); - const size_t cpy = sizeof (float) * channels; + const size_t cpy = sizeof(float) * (size_t)channels; + const int s_size = cvt->len_cvt / (int)cpy; + const int d_size = (int)(((double)s_size) * cvt->rate_incr); + float *dst = (float *)cvt->buf; + const float *src = (float *)cvt->buf; + const float *target = src + (s_size * channels); + #ifdef TRY_INTERPOLATE_ARBITRARY float last_sample[8]; float sample[8]; int i; + #endif + + register double eps = 0.0; + double offset = cvt->rate_incr; #if DEBUG_CONVERT fprintf(stderr, "Downsample arbitrary (x%f), %d channels.\n", cvt->rate_incr, channels); @@ -285,24 +312,31 @@ SDL_assert(channels <= 8); + #ifdef TRY_INTERPOLATE_ARBITRARY SDL_memcpy(sample, src, cpy); SDL_memcpy(last_sample, src, cpy); - - while (dst < target) { + #endif + + while(dst < target) { src += channels; - eps += dstsize; - if ((eps << 1) >= srcsize) { + eps += offset; + if(eps >= 1.0) { + #ifndef TRY_INTERPOLATE_ARBITRARY + dst += channels; + SDL_memcpy(dst, src, cpy); + #else SDL_memcpy(dst, sample, cpy); dst += channels; for (i = 0; i < channels; i++) { sample[i] = (float) ((((double) src[i]) + ((double) last_sample[i])) * 0.5); } - SDL_memcpy(last_sample, src, cpy); - eps -= srcsize; - } - } - - cvt->len_cvt = dstsize; + SDL_memcpy(last_sample, sample, cpy); + #endif + eps -= 1.0; + } + } + + cvt->len_cvt = d_size * (int)cpy; if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); } @@ -312,13 +346,16 @@ SDL_Upsample_Multiple(SDL_AudioCVT *cvt, const int channels) { const int multiple = (int) cvt->rate_incr; - const int dstsize = cvt->len_cvt * multiple; - float *buf = (float *) cvt->buf; - float *dst = ((float *) (cvt->buf + dstsize)) - channels; - const float *src = ((float *) (cvt->buf + cvt->len_cvt)) - channels; - const float *target = buf + channels; - const size_t cpy = sizeof (float) * channels; + const size_t cpy = sizeof (float) * (size_t)channels; + const int s_size = cvt->len_cvt / (int)cpy; + const int d_size = s_size * multiple; + float *buf = ((float *)cvt->buf); + float *target = buf/*+ channels*/; + float *dst = buf + (d_size * channels) - channels; + const float *src = buf + (s_size * channels) - channels; + #ifdef TRY_INTERPOLATE_ARBITRARY float last_sample[8]; + #endif int i; #if DEBUG_CONVERT @@ -327,11 +364,14 @@ SDL_assert(channels <= 8); + #ifdef TRY_INTERPOLATE_ARBITRARY SDL_memcpy(last_sample, src, cpy); + #endif while (dst > target) { SDL_assert(src >= buf); + #ifdef TRY_INTERPOLATE_ARBITRARY for (i = 0; i < channels; i++) { dst[i] = (float) ((((double)src[i]) + ((double)last_sample[i])) * 0.5); } @@ -346,9 +386,16 @@ if (src > buf) { SDL_memcpy(last_sample, src - channels, cpy); } - } - - cvt->len_cvt = dstsize; + #else + for (i = 0; i < multiple; i++) { + SDL_memcpy(dst, src, cpy); + dst -= channels; + } + src -= channels; + #endif + } + + cvt->len_cvt = d_size * (int)cpy; if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); } @@ -358,32 +405,43 @@ SDL_Downsample_Multiple(SDL_AudioCVT *cvt, const int channels) { const int multiple = (int) (1.0 / cvt->rate_incr); - const int dstsize = cvt->len_cvt / multiple; - float *dst = (float *) cvt->buf; - const float *src = (float *) cvt->buf; - const float *target = (const float *) (cvt->buf + dstsize); - const size_t cpy = sizeof (float) * channels; + const size_t cpy = sizeof(float) * (size_t)channels; + const int s_size = cvt->len_cvt / (int)cpy; + const int d_size = s_size / multiple; + float *dst = (float *)cvt->buf; + const float *src = (float *)cvt->buf; + const float *target = src + (s_size * channels); + + #ifdef TRY_INTERPOLATE_ARBITRARY float last_sample[8]; int i; + #endif #if DEBUG_CONVERT fprintf(stderr, "Downsample (x%d), %d channels.\n", multiple, channels); #endif SDL_assert(channels <= 8); + #ifdef TRY_INTERPOLATE_ARBITRARY SDL_memcpy(last_sample, src, cpy); + #endif while (dst < target) { + #ifdef TRY_INTERPOLATE_ARBITRARY for (i = 0; i < channels; i++) { dst[i] = (float) ((((double)src[i]) + ((double)last_sample[i])) * 0.5); } dst += channels; - SDL_memcpy(last_sample, src, cpy); + #else + dst += channels; + SDL_memcpy(dst, src, cpy); + #endif + src += (channels * multiple); } - cvt->len_cvt = dstsize; + cvt->len_cvt = d_size * (int)cpy; if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); }