audio: Redesigned audio conversion code for SDL3.

- SDL_AudioCVT is gone, even internally.
- libsamplerate is gone (I suspect our resampler is finally Good Enough).
- Cleanups and improvements to audio conversion interfaces.
- SDL_AudioStream can change its input/output format/rate/channels on the fly!
This commit is contained in:
Ryan C. Gordon
2023-04-01 22:29:30 -04:00
parent 44bec9c01c
commit e5a6c24c82
20 changed files with 1434 additions and 2369 deletions

View File

@@ -261,27 +261,43 @@ static void write_converter(const int fromchans, const int tochans)
}
}
printf("static void SDLCALL\n"
"SDL_Convert%sTo%s(SDL_AudioCVT *cvt, SDL_AudioFormat format)\n"
"{\n", remove_dots(fromstr), remove_dots(tostr));
if (convert_backwards) { /* must convert backwards when growing the output in-place. */
printf(" float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / %d) * %d))) - %d;\n", fromchans, tochans, tochans);
printf(" const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - %d;\n", fromchans);
} else {
printf(" float *dst = (float *) cvt->buf;\n");
printf(" const float *src = dst;\n");
}
printf("static void SDL_Convert%sTo%s(float *dst, const float *src, int num_frames)\n{\n", remove_dots(fromstr), remove_dots(tostr));
printf(" int i;\n"
"\n"
" LOG_DEBUG_CONVERT(\"%s\", \"%s\");\n"
" SDL_assert(format == AUDIO_F32SYS);\n"
" LOG_DEBUG_AUDIO_CONVERT(\"%s\", \"%s\");\n"
"\n", lowercase(fromstr), lowercase(tostr));
if (convert_backwards) {
if (convert_backwards) { /* must convert backwards when growing the output in-place. */
printf(" /* convert backwards, since output is growing in-place. */\n");
printf(" for (i = cvt->len_cvt / (sizeof (float) * %d); i; i--, src -= %d, dst -= %d) {\n", fromchans, fromchans, tochans);
printf(" src += (num_frames-1)");
if (fromchans != 1) {
printf(" * %d", fromchans);
}
printf(";\n");
printf(" dst += (num_frames-1)");
if (tochans != 1) {
printf(" * %d", tochans);
}
printf(";\n");
printf(" for (i = num_frames");
if (fromchans > 1) {
printf(" * %d", fromchans);
}
printf("; i; i--, ");
if (fromchans == 1) {
printf("src--");
} else {
printf("src -= %d", fromchans);
}
printf(", ");
if (tochans == 1) {
printf("dst--");
} else {
printf("dst -= %d", tochans);
}
printf(") {\n");
fptr = cvtmatrix;
for (i = 0; i < fromchans; i++) {
if (input_channel_used[i] > 1) { /* don't read it from src more than once. */
@@ -326,7 +342,19 @@ static void write_converter(const int fromchans, const int tochans)
printf(" }\n");
} else {
printf(" for (i = cvt->len_cvt / (sizeof (float) * %d); i; i--, src += %d, dst += %d) {\n", fromchans, fromchans, tochans);
printf(" for (i = num_frames * %d; i; i--, ", fromchans);
if (fromchans == 1) {
printf("src++");
} else {
printf("src += %d", fromchans);
}
printf(", ");
if (tochans == 1) {
printf("dst++");
} else {
printf("dst += %d", tochans);
}
printf(") {\n");
fptr = cvtmatrix;
for (i = 0; i < fromchans; i++) {
@@ -372,20 +400,7 @@ static void write_converter(const int fromchans, const int tochans)
printf(" }\n");
}
printf("\n");
if ((fromchans > 1) && (tochans > 1)) {
printf(" cvt->len_cvt = (cvt->len_cvt / %d) * %d;\n", fromchans, tochans);
} else if (tochans == 1) {
printf(" cvt->len_cvt = cvt->len_cvt / %d;\n", fromchans);
} else /* if (fromchans == 1) */ {
printf(" cvt->len_cvt = cvt->len_cvt * %d;\n", tochans);
}
printf(" if (cvt->filters[++cvt->filter_index]) {\n"
" cvt->filters[cvt->filter_index] (cvt, format);\n"
" }\n"
"}\n\n");
printf("\n}\n\n");
}
int main(void)
@@ -416,6 +431,9 @@ int main(void)
"\n"
"/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c */\n"
"\n"
"\n"
"typedef void (*SDL_AudioChannelConverter)(float *dst, const float *src, int num_frames);\n"
"\n"
);
for (ini = 1; ini <= NUM_CHANNELS; ini++) {
@@ -424,7 +442,7 @@ int main(void)
}
}
printf("static const SDL_AudioFilter channel_converters[%d][%d] = { /* [from][to] */\n", NUM_CHANNELS, NUM_CHANNELS);
printf("static const SDL_AudioChannelConverter channel_converters[%d][%d] = { /* [from][to] */\n", NUM_CHANNELS, NUM_CHANNELS);
for (ini = 1; ini <= NUM_CHANNELS; ini++) {
const char *comma = "";
printf(" {");