From 49ec8db5f8ba9d386451487bb9e1698ab58346a0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 19 Jul 2022 22:04:49 -0400 Subject: [PATCH] audio: Generate the channel converter code from a program. --- build-scripts/gen_audio_channel_conversion.c | 450 ++++++ src/audio/SDL_audio_channel_converters.h | 1459 ++++++++++++++++++ src/audio/SDL_audiocvt.c | 1155 +------------- 3 files changed, 1911 insertions(+), 1153 deletions(-) create mode 100644 build-scripts/gen_audio_channel_conversion.c create mode 100644 src/audio/SDL_audio_channel_converters.h diff --git a/build-scripts/gen_audio_channel_conversion.c b/build-scripts/gen_audio_channel_conversion.c new file mode 100644 index 000000000..e74ed2674 --- /dev/null +++ b/build-scripts/gen_audio_channel_conversion.c @@ -0,0 +1,450 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +/* + +Built with: + +gcc -o genchancvt build-scripts/gen_audio_channel_conversion.c -lm && ./genchancvt > src/audio/SDL_audio_channel_converters.h + +*/ + +#define NUM_CHANNELS 8 + +static const char *layout_names[NUM_CHANNELS] = { + "Mono", "Stereo", "2.1", "Quad", "4.1", "5.1", "6.1", "7.1" +}; + +static const char *channel_names[NUM_CHANNELS][NUM_CHANNELS] = { + /* mono */ { "FC" }, + /* stereo */ { "FL", "FR" }, + /* 2.1 */ { "FL", "FR", "LFE" }, + /* quad */ { "FL", "FR", "BL", "BR" }, + /* 4.1 */ { "FL", "FR", "LFE", "BL", "BR" }, + /* 5.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR" }, + /* 6.1 */ { "FL", "FR", "FC", "LFE", "BC", "SL", "SR" }, + /* 7.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR", "SL", "SR" }, +}; + + +/* + * This table is from FAudio: + * + * https://raw.githubusercontent.com/FNA-XNA/FAudio/master/src/matrix_defaults.inl + */ +static const float channel_conversion_matrix[8][8][64] = { +{ + /* 1 x 1 */ + { 1.000000000f }, + /* 1 x 2 */ + { 1.000000000f, 1.000000000f }, + /* 1 x 3 */ + { 1.000000000f, 1.000000000f, 0.000000000f }, + /* 1 x 4 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 5 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 6 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 7 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 8 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 2 x 1 */ + { 0.500000000f, 0.500000000f }, + /* 2 x 2 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 2 x 3 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 4 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 3 x 1 */ + { 0.333333343f, 0.333333343f, 0.333333343f }, + /* 3 x 2 */ + { 0.800000012f, 0.000000000f, 0.200000003f, 0.000000000f, 0.800000012f, 0.200000003f }, + /* 3 x 3 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 3 x 4 */ + { 0.888888896f, 0.000000000f, 0.111111112f, 0.000000000f, 0.888888896f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f }, + /* 3 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 4 x 1 */ + { 0.250000000f, 0.250000000f, 0.250000000f, 0.250000000f }, + /* 4 x 2 */ + { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f }, + /* 4 x 3 */ + { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 4 x 4 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 4 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 5 x 1 */ + { 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f }, + /* 5 x 2 */ + { 0.374222219f, 0.000000000f, 0.111111112f, 0.319111109f, 0.195555553f, 0.000000000f, 0.374222219f, 0.111111112f, 0.195555553f, 0.319111109f }, + /* 5 x 3 */ + { 0.421000004f, 0.000000000f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.000000000f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 5 x 4 */ + { 0.941176474f, 0.000000000f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.941176474f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.941176474f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.000000000f, 0.941176474f }, + /* 5 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 5 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 5 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 5 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 6 x 1 */ + { 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f }, + /* 6 x 2 */ + { 0.294545442f, 0.000000000f, 0.208181813f, 0.090909094f, 0.251818180f, 0.154545456f, 0.000000000f, 0.294545442f, 0.208181813f, 0.090909094f, 0.154545456f, 0.251818180f }, + /* 6 x 3 */ + { 0.324000001f, 0.000000000f, 0.229000002f, 0.000000000f, 0.277000010f, 0.170000002f, 0.000000000f, 0.324000001f, 0.229000002f, 0.000000000f, 0.170000002f, 0.277000010f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 6 x 4 */ + { 0.558095276f, 0.000000000f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.558095276f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.558095276f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.000000000f, 0.558095276f }, + /* 6 x 5 */ + { 0.586000025f, 0.000000000f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f }, + /* 6 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 6 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 6 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 7 x 1 */ + { 0.143142849f, 0.143142849f, 0.143142849f, 0.142857149f, 0.143142849f, 0.143142849f, 0.143142849f }, + /* 7 x 2 */ + { 0.247384623f, 0.000000000f, 0.174461529f, 0.076923080f, 0.174461529f, 0.226153851f, 0.100615382f, 0.000000000f, 0.247384623f, 0.174461529f, 0.076923080f, 0.174461529f, 0.100615382f, 0.226153851f }, + /* 7 x 3 */ + { 0.268000007f, 0.000000000f, 0.188999996f, 0.000000000f, 0.188999996f, 0.245000005f, 0.108999997f, 0.000000000f, 0.268000007f, 0.188999996f, 0.000000000f, 0.188999996f, 0.108999997f, 0.245000005f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 7 x 4 */ + { 0.463679999f, 0.000000000f, 0.327360004f, 0.040000003f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.463679999f, 0.327360004f, 0.040000003f, 0.000000000f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.431039989f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.000000000f, 0.431039989f }, + /* 7 x 5 */ + { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.000000000f, 0.449000001f }, + /* 7 x 6 */ + { 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.568000019f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.000000000f, 0.568000019f }, + /* 7 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 7 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } +}, +{ + /* 8 x 1 */ + { 0.125125006f, 0.125125006f, 0.125125006f, 0.125000000f, 0.125125006f, 0.125125006f, 0.125125006f, 0.125125006f }, + /* 8 x 2 */ + { 0.211866662f, 0.000000000f, 0.150266662f, 0.066666670f, 0.181066677f, 0.111066669f, 0.194133341f, 0.085866667f, 0.000000000f, 0.211866662f, 0.150266662f, 0.066666670f, 0.111066669f, 0.181066677f, 0.085866667f, 0.194133341f }, + /* 8 x 3 */ + { 0.226999998f, 0.000000000f, 0.160999998f, 0.000000000f, 0.194000006f, 0.119000003f, 0.208000004f, 0.092000000f, 0.000000000f, 0.226999998f, 0.160999998f, 0.000000000f, 0.119000003f, 0.194000006f, 0.092000000f, 0.208000004f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 8 x 4 */ + { 0.466344833f, 0.000000000f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.466344833f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.466344833f, 0.000000000f, 0.433517247f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.000000000f, 0.466344833f, 0.000000000f, 0.433517247f }, + /* 8 x 5 */ + { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f }, + /* 8 x 6 */ + { 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f }, + /* 8 x 7 */ + { 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.287999988f, 0.287999988f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f }, + /* 8 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } +} +}; + +static char *remove_dots(const char *str) /* this is NOT robust. */ +{ + static char retval1[32]; + static char retval2[32]; + static int idx = 0; + char *retval = (idx++ & 1) ? retval1 : retval2; + char *ptr = retval; + while (*str) { + if (*str != '.') { + *(ptr++) = *str; + } + str++; + } + *ptr = '\0'; + return retval; +} + +static char *lowercase(const char *str) /* this is NOT robust. */ +{ + static char retval1[32]; + static char retval2[32]; + static int idx = 0; + char *retval = (idx++ & 1) ? retval1 : retval2; + char *ptr = retval; + while (*str) { + const char ch = *(str++); + *(ptr++) = ((ch >= 'A') && (ch <= 'Z')) ? (ch - ('A' - 'a')) : ch; + } + *ptr = '\0'; + return retval; +} + +static void write_converter(const int fromchans, const int tochans) +{ + const char *fromstr = layout_names[fromchans-1]; + const char *tostr = layout_names[tochans-1]; + const float *cvtmatrix = channel_conversion_matrix[fromchans-1][tochans-1]; + const float *fptr; + const int convert_backwards = (tochans > fromchans); + int input_channel_used[NUM_CHANNELS]; + int i, j; + + if (tochans == fromchans) { + return; /* nothing to convert, don't generate a converter. */ + } + + for (i = 0; i < fromchans; i++) { + input_channel_used[i] = 0; + } + + fptr = cvtmatrix; + for (j = 0; j < tochans; j++) { + for (i = 0; i < fromchans; i++) { + #if 0 + printf("to=%d, from=%d, coeff=%f\n", j, i, *fptr); + #endif + if (*(fptr++) != 0.0f) { + input_channel_used[i]++; + } + } + } + + 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)));\n", fromchans, tochans - 1); + 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(" int i;\n" + "\n" + " LOG_DEBUG_CONVERT(\"%s\", \"%s\");\n" + " SDL_assert(format == AUDIO_F32SYS);\n" + "\n", lowercase(fromstr), lowercase(tostr)); + + if (convert_backwards) { + 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); + fptr = cvtmatrix; + for (i = 0; i < fromchans; i++) { + if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ + printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); + } + } + + for (j = tochans - 1; j >= 0; j--) { + int has_input = 0; + fptr = cvtmatrix + (fromchans * j); + printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); + for (i = fromchans - 1; i >= 0; i--) { + const float coefficient = fptr[i]; + char srcname[32]; + if (coefficient == 0.0f) { + continue; + } else if (input_channel_used[i] > 1) { + snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); + } else { + snprintf(srcname, sizeof (srcname), "src[%d]", i); + } + + if (has_input) { + printf(" +"); + } + + has_input = 1; + + if (coefficient == 1.0f) { + printf(" %s", srcname); + } else { + printf(" (%s * %.9ff)", srcname, coefficient); + } + } + + if (!has_input) { + printf(" 0.0f"); + } + + printf(";\n"); + } + + printf(" }\n"); + } else { + printf(" for (i = cvt->len_cvt / (sizeof (float) * %d); i; i--, src += %d, dst += %d) {\n", fromchans, fromchans, tochans); + + fptr = cvtmatrix; + for (i = 0; i < fromchans; i++) { + if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ + printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); + } + } + + for (j = 0; j < tochans; j++) { + int has_input = 0; + fptr = cvtmatrix + (fromchans * j); + printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); + for (i = 0; i < fromchans; i++) { + const float coefficient = fptr[i]; + char srcname[32]; + if (coefficient == 0.0f) { + continue; + } else if (input_channel_used[i] > 1) { + snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); + } else { + snprintf(srcname, sizeof (srcname), "src[%d]", i); + } + + if (has_input) { + printf(" +"); + } + + has_input = 1; + + if (coefficient == 1.0f) { + printf(" %s", srcname); + } else { + printf(" (%s * %.9ff)", srcname, coefficient); + } + } + + if (!has_input) { + printf(" 0.0f"); + } + + printf(";\n"); + } + 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"); +} + +int main(void) +{ + int ini, outi; + + printf( + "/*\n" + " Simple DirectMedia Layer\n" + " Copyright (C) 1997-2022 Sam Lantinga \n" + "\n" + " This software is provided 'as-is', without any express or implied\n" + " warranty. In no event will the authors be held liable for any damages\n" + " arising from the use of this software.\n" + "\n" + " Permission is granted to anyone to use this software for any purpose,\n" + " including commercial applications, and to alter it and redistribute it\n" + " freely, subject to the following restrictions:\n" + "\n" + " 1. The origin of this software must not be misrepresented; you must not\n" + " claim that you wrote the original software. If you use this software\n" + " in a product, an acknowledgment in the product documentation would be\n" + " appreciated but is not required.\n" + " 2. Altered source versions must be plainly marked as such, and must not be\n" + " misrepresented as being the original software.\n" + " 3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "\n" + "/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c */\n" + "\n" + ); + + for (ini = 1; ini <= NUM_CHANNELS; ini++) { + for (outi = 1; outi <= NUM_CHANNELS; outi++) { + write_converter(ini, outi); + } + } + + printf("static const SDL_AudioFilter channel_converters[%d][%d] = { /* [from][to] */\n", NUM_CHANNELS, NUM_CHANNELS); + for (ini = 1; ini <= NUM_CHANNELS; ini++) { + const char *comma = ""; + printf(" {"); + for (outi = 1; outi <= NUM_CHANNELS; outi++) { + const char *fromstr = layout_names[ini-1]; + const char *tostr = layout_names[outi-1]; + if (ini == outi) { + printf("%s NULL", comma); + } else { + printf("%s SDL_Convert%sTo%s", comma, remove_dots(fromstr), remove_dots(tostr)); + } + comma = ","; + } + printf(" }%s\n", (ini == NUM_CHANNELS) ? "" : ","); + } + + printf("};\n\n"); + printf("/* vi: set ts=4 sw=4 expandtab: */\n\n"); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_audio_channel_converters.h b/src/audio/SDL_audio_channel_converters.h new file mode 100644 index 000000000..5794a1205 --- /dev/null +++ b/src/audio/SDL_audio_channel_converters.h @@ -0,0 +1,1459 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c */ + +static void SDLCALL +SDL_ConvertMonoToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 1))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 2) { + const float srcFC = src[0]; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 2))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 3) { + const float srcFC = src[0]; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 3))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 4) { + const float srcFC = src[0]; + dst[3] /* BR */ = 0.0f; + dst[2] /* BL */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 4))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 5) { + const float srcFC = src[0]; + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 5))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 6) { + const float srcFC = src[0]; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 7) { + const float srcFC = src[0]; + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertMonoTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 1) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 1); i; i--, src -= 1, dst -= 8) { + const float srcFC = src[0]; + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("stereo", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src += 2, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.500000000f) + (src[1] * 0.500000000f); + } + + cvt->len_cvt = cvt->len_cvt / 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 2))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 3) { + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 3))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 4) { + dst[3] /* BR */ = 0.0f; + dst[2] /* BL */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 4))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 5) { + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 5))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 6) { + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 7) { + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertStereoTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 2); i; i--, src -= 2, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("2.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src += 3, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.333333343f) + (src[1] * 0.333333343f) + (src[2] * 0.333333343f); + } + + cvt->len_cvt = cvt->len_cvt / 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("2.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src += 3, dst += 2) { + const float srcLFE = src[2]; + dst[0] /* FL */ = (src[0] * 0.800000012f) + (srcLFE * 0.200000003f); + dst[1] /* FR */ = (src[1] * 0.800000012f) + (srcLFE * 0.200000003f); + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 3) * 3))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src -= 3, dst -= 4) { + const float srcLFE = src[2]; + dst[3] /* BR */ = (srcLFE * 0.111111112f); + dst[2] /* BL */ = (srcLFE * 0.111111112f); + dst[1] /* FR */ = (srcLFE * 0.111111112f) + (src[1] * 0.888888896f); + dst[0] /* FL */ = (srcLFE * 0.111111112f) + (src[0] * 0.888888896f); + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 3) * 4))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src -= 3, dst -= 5) { + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 3) * 5))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src -= 3, dst -= 6) { + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 3) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src -= 3, dst -= 7) { + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert21To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 3) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 3); i; i--, src -= 3, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src += 4, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.250000000f) + (src[1] * 0.250000000f) + (src[2] * 0.250000000f) + (src[3] * 0.250000000f); + } + + cvt->len_cvt = cvt->len_cvt / 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src += 4, dst += 2) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src += 4, dst += 3) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + dst[2] /* LFE */ = 0.0f; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 4))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src -= 4, dst -= 5) { + dst[4] /* BR */ = src[3]; + dst[3] /* BL */ = src[2]; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 5))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src -= 4, dst -= 6) { + dst[5] /* BR */ = src[3]; + dst[4] /* BL */ = src[2]; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src -= 4, dst -= 7) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_ConvertQuadTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 4); i; i--, src -= 4, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[3]; + dst[4] /* BL */ = src[2]; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src += 5, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.200000003f) + (src[1] * 0.200000003f) + (src[2] * 0.200000003f) + (src[3] * 0.200000003f) + (src[4] * 0.200000003f); + } + + cvt->len_cvt = cvt->len_cvt / 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src += 5, dst += 2) { + const float srcLFE = src[2]; + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[0] /* FL */ = (src[0] * 0.374222219f) + (srcLFE * 0.111111112f) + (srcBL * 0.319111109f) + (srcBR * 0.195555553f); + dst[1] /* FR */ = (src[1] * 0.374222219f) + (srcLFE * 0.111111112f) + (srcBL * 0.195555553f) + (srcBR * 0.319111109f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src += 5, dst += 3) { + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + dst[2] /* LFE */ = src[2]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src += 5, dst += 4) { + const float srcLFE = src[2]; + dst[0] /* FL */ = (src[0] * 0.941176474f) + (srcLFE * 0.058823530f); + dst[1] /* FR */ = (src[1] * 0.941176474f) + (srcLFE * 0.058823530f); + dst[2] /* BL */ = (srcLFE * 0.058823530f) + (src[3] * 0.941176474f); + dst[3] /* BR */ = (srcLFE * 0.058823530f) + (src[4] * 0.941176474f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 5) * 5))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src -= 5, dst -= 6) { + dst[5] /* BR */ = src[4]; + dst[4] /* BL */ = src[3]; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 5) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src -= 5, dst -= 7) { + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert41To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 5) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 5); i; i--, src -= 5, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[4]; + dst[4] /* BL */ = src[3]; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src += 6, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.166666672f) + (src[1] * 0.166666672f) + (src[2] * 0.166666672f) + (src[3] * 0.166666672f) + (src[4] * 0.166666672f) + (src[5] * 0.166666672f); + } + + cvt->len_cvt = cvt->len_cvt / 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src += 6, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.294545442f) + (srcFC * 0.208181813f) + (srcLFE * 0.090909094f) + (srcBL * 0.251818180f) + (srcBR * 0.154545456f); + dst[1] /* FR */ = (src[1] * 0.294545442f) + (srcFC * 0.208181813f) + (srcLFE * 0.090909094f) + (srcBL * 0.154545456f) + (srcBR * 0.251818180f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src += 6, dst += 3) { + const float srcFC = src[2]; + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.324000001f) + (srcFC * 0.229000002f) + (srcBL * 0.277000010f) + (srcBR * 0.170000002f); + dst[1] /* FR */ = (src[1] * 0.324000001f) + (srcFC * 0.229000002f) + (srcBL * 0.170000002f) + (srcBR * 0.277000010f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src += 6, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + dst[0] /* FL */ = (src[0] * 0.558095276f) + (srcFC * 0.394285709f) + (srcLFE * 0.047619049f); + dst[1] /* FR */ = (src[1] * 0.558095276f) + (srcFC * 0.394285709f) + (srcLFE * 0.047619049f); + dst[2] /* BL */ = (srcLFE * 0.047619049f) + (src[4] * 0.558095276f); + dst[3] /* BR */ = (srcLFE * 0.047619049f) + (src[5] * 0.558095276f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src += 6, dst += 5) { + const float srcFC = src[2]; + dst[0] /* FL */ = (src[0] * 0.586000025f) + (srcFC * 0.414000005f); + dst[1] /* FR */ = (src[1] * 0.586000025f) + (srcFC * 0.414000005f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (src[4] * 0.586000025f); + dst[4] /* BR */ = (src[5] * 0.586000025f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 6) * 6))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 6; + int i; + + LOG_DEBUG_CONVERT("5.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src -= 6, dst -= 7) { + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = (src[2] * 0.939999998f); + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert51To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 6) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 6; + int i; + + LOG_DEBUG_CONVERT("5.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 6); i; i--, src -= 6, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[5]; + dst[4] /* BL */ = src[4]; + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.143142849f) + (src[1] * 0.143142849f) + (src[2] * 0.143142849f) + (src[3] * 0.142857149f) + (src[4] * 0.143142849f) + (src[5] * 0.143142849f) + (src[6] * 0.143142849f); + } + + cvt->len_cvt = cvt->len_cvt / 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.247384623f) + (srcFC * 0.174461529f) + (srcLFE * 0.076923080f) + (srcBC * 0.174461529f) + (srcSL * 0.226153851f) + (srcSR * 0.100615382f); + dst[1] /* FR */ = (src[1] * 0.247384623f) + (srcFC * 0.174461529f) + (srcLFE * 0.076923080f) + (srcBC * 0.174461529f) + (srcSL * 0.100615382f) + (srcSR * 0.226153851f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 3) { + const float srcFC = src[2]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.268000007f) + (srcFC * 0.188999996f) + (srcBC * 0.188999996f) + (srcSL * 0.245000005f) + (srcSR * 0.108999997f); + dst[1] /* FR */ = (src[1] * 0.268000007f) + (srcFC * 0.188999996f) + (srcBC * 0.188999996f) + (srcSL * 0.108999997f) + (srcSR * 0.245000005f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.463679999f) + (srcFC * 0.327360004f) + (srcLFE * 0.040000003f) + (srcSL * 0.168960005f); + dst[1] /* FR */ = (src[1] * 0.463679999f) + (srcFC * 0.327360004f) + (srcLFE * 0.040000003f) + (srcSR * 0.168960005f); + dst[2] /* BL */ = (srcLFE * 0.040000003f) + (srcBC * 0.327360004f) + (srcSL * 0.431039989f); + dst[3] /* BR */ = (srcLFE * 0.040000003f) + (srcBC * 0.327360004f) + (srcSR * 0.431039989f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 5) { + const float srcFC = src[2]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSL * 0.175999999f); + dst[1] /* FR */ = (src[1] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSR * 0.175999999f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (srcBC * 0.340999991f) + (srcSL * 0.449000001f); + dst[4] /* BR */ = (srcBC * 0.340999991f) + (srcSR * 0.449000001f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src += 7, dst += 6) { + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.611000001f) + (srcSL * 0.223000005f); + dst[1] /* FR */ = (src[1] * 0.611000001f) + (srcSR * 0.223000005f); + dst[2] /* FC */ = (src[2] * 0.611000001f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BL */ = (srcBC * 0.432000011f) + (srcSL * 0.568000019f); + dst[5] /* BR */ = (srcBC * 0.432000011f) + (srcSR * 0.568000019f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert61To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 7) * 7))); + const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 7; + int i; + + LOG_DEBUG_CONVERT("6.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof (float) * 7); i; i--, src -= 7, dst -= 8) { + const float srcBC = src[4]; + dst[7] /* SR */ = src[6]; + dst[6] /* SL */ = src[5]; + dst[5] /* BR */ = (srcBC * 0.707000017f); + dst[4] /* BL */ = (srcBC * 0.707000017f); + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.125125006f) + (src[1] * 0.125125006f) + (src[2] * 0.125125006f) + (src[3] * 0.125000000f) + (src[4] * 0.125125006f) + (src[5] * 0.125125006f) + (src[6] * 0.125125006f) + (src[7] * 0.125125006f); + } + + cvt->len_cvt = cvt->len_cvt / 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBL = src[4]; + const float srcBR = src[5]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.211866662f) + (srcFC * 0.150266662f) + (srcLFE * 0.066666670f) + (srcBL * 0.181066677f) + (srcBR * 0.111066669f) + (srcSL * 0.194133341f) + (srcSR * 0.085866667f); + dst[1] /* FR */ = (src[1] * 0.211866662f) + (srcFC * 0.150266662f) + (srcLFE * 0.066666670f) + (srcBL * 0.111066669f) + (srcBR * 0.181066677f) + (srcSL * 0.085866667f) + (srcSR * 0.194133341f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 3) { + const float srcFC = src[2]; + const float srcBL = src[4]; + const float srcBR = src[5]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.226999998f) + (srcFC * 0.160999998f) + (srcBL * 0.194000006f) + (srcBR * 0.119000003f) + (srcSL * 0.208000004f) + (srcSR * 0.092000000f); + dst[1] /* FR */ = (src[1] * 0.226999998f) + (srcFC * 0.160999998f) + (srcBL * 0.119000003f) + (srcBR * 0.194000006f) + (srcSL * 0.092000000f) + (srcSR * 0.208000004f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.466344833f) + (srcFC * 0.329241365f) + (srcLFE * 0.034482758f) + (srcSL * 0.169931039f); + dst[1] /* FR */ = (src[1] * 0.466344833f) + (srcFC * 0.329241365f) + (srcLFE * 0.034482758f) + (srcSR * 0.169931039f); + dst[2] /* BL */ = (srcLFE * 0.034482758f) + (src[4] * 0.466344833f) + (srcSL * 0.433517247f); + dst[3] /* BR */ = (srcLFE * 0.034482758f) + (src[5] * 0.466344833f) + (srcSR * 0.433517247f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 5) { + const float srcFC = src[2]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSL * 0.175999999f); + dst[1] /* FR */ = (src[1] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSR * 0.175999999f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (src[4] * 0.483000010f) + (srcSL * 0.449000001f); + dst[4] /* BR */ = (src[5] * 0.483000010f) + (srcSR * 0.449000001f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 6) { + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.518000007f) + (srcSL * 0.188999996f); + dst[1] /* FR */ = (src[1] * 0.518000007f) + (srcSR * 0.188999996f); + dst[2] /* FC */ = (src[2] * 0.518000007f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BL */ = (src[4] * 0.518000007f) + (srcSL * 0.481999993f); + dst[5] /* BR */ = (src[5] * 0.518000007f) + (srcSR * 0.481999993f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static void SDLCALL +SDL_Convert71To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *) cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof (float) * 8); i; i--, src += 8, dst += 7) { + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.541000009f); + dst[1] /* FR */ = (src[1] * 0.541000009f); + dst[2] /* FC */ = (src[2] * 0.541000009f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BC */ = (srcBL * 0.287999988f) + (srcBR * 0.287999988f); + dst[5] /* SL */ = (srcBL * 0.458999991f) + (src[6] * 0.541000009f); + dst[6] /* SR */ = (srcBR * 0.458999991f) + (src[7] * 0.541000009f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +static const SDL_AudioFilter channel_converters[8][8] = { /* [from][to] */ + { NULL, SDL_ConvertMonoToStereo, SDL_ConvertMonoTo21, SDL_ConvertMonoToQuad, SDL_ConvertMonoTo41, SDL_ConvertMonoTo51, SDL_ConvertMonoTo61, SDL_ConvertMonoTo71 }, + { SDL_ConvertStereoToMono, NULL, SDL_ConvertStereoTo21, SDL_ConvertStereoToQuad, SDL_ConvertStereoTo41, SDL_ConvertStereoTo51, SDL_ConvertStereoTo61, SDL_ConvertStereoTo71 }, + { SDL_Convert21ToMono, SDL_Convert21ToStereo, NULL, SDL_Convert21ToQuad, SDL_Convert21To41, SDL_Convert21To51, SDL_Convert21To61, SDL_Convert21To71 }, + { SDL_ConvertQuadToMono, SDL_ConvertQuadToStereo, SDL_ConvertQuadTo21, NULL, SDL_ConvertQuadTo41, SDL_ConvertQuadTo51, SDL_ConvertQuadTo61, SDL_ConvertQuadTo71 }, + { SDL_Convert41ToMono, SDL_Convert41ToStereo, SDL_Convert41To21, SDL_Convert41ToQuad, NULL, SDL_Convert41To51, SDL_Convert41To61, SDL_Convert41To71 }, + { SDL_Convert51ToMono, SDL_Convert51ToStereo, SDL_Convert51To21, SDL_Convert51ToQuad, SDL_Convert51To41, NULL, SDL_Convert51To61, SDL_Convert51To71 }, + { SDL_Convert61ToMono, SDL_Convert61ToStereo, SDL_Convert61To21, SDL_Convert61ToQuad, SDL_Convert61To41, SDL_Convert61To51, NULL, SDL_Convert61To71 }, + { SDL_Convert71ToMono, SDL_Convert71ToStereo, SDL_Convert71To21, SDL_Convert71ToQuad, SDL_Convert71To41, SDL_Convert71To51, SDL_Convert71To61, NULL } +}; + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 9927f6be5..8f4393ba2 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -22,9 +22,6 @@ /* Functions for audio drivers to perform runtime conversion of audio format */ -/* FIXME: Channel weights when converting from more channels to fewer may need to be adjusted, see https://msdn.microsoft.com/en-us/library/windows/desktop/ff819070(v=vs.85).aspx -*/ - #include "SDL.h" #include "SDL_audio.h" #include "SDL_audio_c.h" @@ -286,44 +283,6 @@ SDL_Convert51ToStereo_NEON(SDL_AudioCVT * cvt, SDL_AudioFormat format) #endif -/* Channel conversion is now mostly following this scheme, borrowed from FNA - (which is following the scheme of XNA)... - https://github.com/FNA-XNA/FAudio/blob/master/src/matrix_defaults.inl */ - -/* CONVERT FROM MONO... */ -/* Mono duplicates to stereo and all other channels are silenced. */ - -#define CVT_MONO_TO(toname, tonamestr, num_channels, zeroingcode) \ - static void SDLCALL SDL_ConvertMonoTo##toname(SDL_AudioCVT * cvt, SDL_AudioFormat format) { \ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 1; \ - float *dst = ((float *) (cvt->buf + cvt->len_cvt * num_channels)) - num_channels; \ - int i; \ - LOG_DEBUG_CONVERT("mono", tonamestr); \ - SDL_assert(format == AUDIO_F32SYS); \ - SDL_assert(num_channels >= 2); \ - for (i = cvt->len_cvt / sizeof (float); i; i--, src--, dst -= num_channels) { \ - dst[0] = dst[1] = *src; \ - zeroingcode; \ - } \ - cvt->len_cvt *= num_channels; \ - if (cvt->filters[++cvt->filter_index]) { \ - cvt->filters[cvt->filter_index] (cvt, format); \ - } \ - } -CVT_MONO_TO(Stereo, "stereo", 2, {}); -CVT_MONO_TO(21, "2.1", 3, { dst[2] = 0.0f; }); -CVT_MONO_TO(Quad, "quad", 4, { dst[2] = dst[3] = 0.0f; }); -CVT_MONO_TO(41, "4.1", 5, { dst[2] = dst[3] = dst[4] = 0.0f; }); -CVT_MONO_TO(51, "5.1", 6, { dst[2] = dst[3] = dst[4] = dst[5] = 0.0f; }); -CVT_MONO_TO(61, "6.1", 7, { dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = 0.0f; }); -CVT_MONO_TO(71, "7.1", 8, { dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = dst[7] = 0.0f; }); -#undef CVT_MONO_TO - - - -/* CONVERT FROM STEREO... */ -/* Stereo duplicates to two front speakers and all other channels are silenced. */ - #if HAVE_SSE3_INTRINSICS /* Convert from stereo to mono. Average left and right. */ static void SDLCALL @@ -358,1119 +317,9 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format) } #endif -/* Convert from stereo to mono. Average left and right. */ -static void SDLCALL -SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - LOG_DEBUG_CONVERT("stereo", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 2); i; --i, src += 2) { - *(dst++) = (src[0] + src[1]) * 0.5f; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -#define CVT_STEREO_TO(toname, tonamestr, num_channels, zeroingcode) \ - static void SDLCALL SDL_ConvertStereoTo##toname(SDL_AudioCVT * cvt, SDL_AudioFormat format) { \ - int i; \ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 2; \ - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 2) * num_channels))) - num_channels; \ - LOG_DEBUG_CONVERT("stereo", tonamestr); \ - SDL_assert(format == AUDIO_F32SYS); \ - SDL_assert(num_channels >= 3); \ - for (i = cvt->len_cvt / (sizeof (float) * 2); i; --i, dst -= num_channels, src -= 2) { \ - dst[0] = src[0]; \ - dst[1] = src[1]; \ - zeroingcode; \ - } \ - cvt->len_cvt = (cvt->len_cvt / 2) * num_channels; \ - if (cvt->filters[++cvt->filter_index]) { \ - cvt->filters[cvt->filter_index] (cvt, format); \ - } \ - } - -CVT_STEREO_TO(21, "2.1", 3, { dst[2] = 0.0f; }); -CVT_STEREO_TO(Quad, "quad", 4, { dst[2] = dst[3] = 0.0f; }); -CVT_STEREO_TO(41, "4.1", 5, { dst[2] = dst[3] = dst[4] = 0.0f; }); -CVT_STEREO_TO(51, "5.1", 6, { dst[2] = dst[3] = dst[4] = dst[5] = 0.0f; }); -CVT_STEREO_TO(61, "6.1", 7, { dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = 0.0f; }); -CVT_STEREO_TO(71, "7.1", 8, { dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = dst[7] = 0.0f; }); -#undef CVT_STEREO_TO - - - -/* CONVERT FROM 2.1... */ -/* 2.1 duplicates to two front speakers (and LFE when available) and all other channels are silenced. */ - -/* Convert from 2.1 to mono. Average left and right, drop LFE. */ -static void SDLCALL -SDL_Convert21ToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("2.1", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 2); i; --i, src += 3) { - *(dst++) = (src[0] + src[1]) * 0.5f; - } - - cvt->len_cvt /= 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -#define CVT_21_TO(toname, tonamestr, num_channels, customcode) \ - static void SDLCALL SDL_Convert21To##toname(SDL_AudioCVT * cvt, SDL_AudioFormat format) { \ - int i; \ - float lf, rf, lfe; \ - const float *src = (const float *) (cvt->buf + cvt->len_cvt); \ - float *dst = (float *) (cvt->buf + ((cvt->len_cvt / 3) * num_channels)); \ - LOG_DEBUG_CONVERT("2.1", tonamestr); \ - SDL_assert(format == AUDIO_F32SYS); \ - SDL_assert(num_channels >= 2); \ - for (i = cvt->len_cvt / (sizeof (float) * 3); i; --i) { \ - dst -= num_channels; \ - src -= 2; \ - lf = src[0]; \ - rf = src[1]; \ - lfe = src[2]; \ - dst[0] = lf; \ - dst[1] = rf; \ - customcode; \ - } \ - cvt->len_cvt = (cvt->len_cvt / 3) * num_channels; \ - if (cvt->filters[++cvt->filter_index]) { \ - cvt->filters[cvt->filter_index] (cvt, format); \ - } \ - } - -CVT_21_TO(Stereo, "stereo", 2, { (void) lfe; }); -CVT_21_TO(Quad, "quad", 4, { (void) lfe; dst[2] = dst[3] = 0.0f; }); -CVT_21_TO(41, "4.1", 5, { dst[2] = lfe; dst[3] = dst[4] = 0.0f; }); -CVT_21_TO(51, "5.1", 6, { dst[2] = 0.0f; dst[3] = lfe; dst[4] = dst[5] = 0.0f; }); -CVT_21_TO(61, "6.1", 7, { dst[2] = 0.0f; dst[3] = lfe; dst[4] = dst[5] = dst[6] = 0.0f; }); -CVT_21_TO(71, "7.1", 8, { dst[2] = 0.0f; dst[3] = lfe; dst[4] = dst[5] = dst[6] = dst[7] = 0.0f; }); -#undef CVT_21_TO - - -/* CONVERT FROM QUAD... */ - -static void SDLCALL -SDL_ConvertQuadToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("quad", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: could benefit from SIMD */ - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src += 4) { - *(dst++) = (src[0] + src[1] + src[3] + src[4]) * 0.25f; - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("quad", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: could benefit from SIMD */ - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src += 4) { - const float fl = src[0]; - const float fr = src[1]; - const float bl = src[2]; - const float br = src[3]; - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right)...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.421000004f) + (bl * 0.358999997f) + (br * 0.219999999f); - *(dst++) = (fr * 0.421000004f) + (br * 0.358999997f) + (bl * 0.219999999f); - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadTo21(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("quad", "2.1"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: could benefit from SIMD */ - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src += 4) { - const float fl = src[0]; - const float fr = src[1]; - const float bl = src[2]; - const float br = src[3]; - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right)...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.421000004f) + (bl * 0.358999997f) + (br * 0.219999999f); - *(dst++) = (fr * 0.421000004f) + (br * 0.358999997f) + (bl * 0.219999999f); - *(dst++) = 0.0f; /* lfe */ - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadTo41(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 5))) - 5; - int i; - - LOG_DEBUG_CONVERT("quad", "4.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src -= 4, dst -= 5) { - dst[4] = src[3]; - dst[3] = src[2]; - dst[2] = 0.0f; /* LFE */ - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 5; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 6))) - 6; - int i; - - LOG_DEBUG_CONVERT("quad", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src -= 4, dst -= 6) { - dst[5] = src[3]; - dst[4] = src[2]; - dst[3] = 0.0f; /* LFE */ - dst[2] = 0.0f; /* FC */ - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadTo61(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 7))) - 7; - int i; - - LOG_DEBUG_CONVERT("quad", "6.1"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: I'm skeptical XNA/FNA's conversion is right, here. */ - - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src -= 4, dst -= 7) { - const float bl = src[2]; - const float br = src[3]; - dst[6] = br * 0.796000004f; - dst[5] = bl * 0.796000004f; - dst[4] = (bl + br) * 0.5f; /* average BL+BR to BC */ - dst[3] = 0.0f; /* LFE */ - dst[2] = 0.0f; /* FC */ - dst[1] = src[1] * 0.939999998f; - dst[0] = src[0] * 0.939999998f; - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 7; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_ConvertQuadTo71(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 4; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 8))) - 8; - int i; - - LOG_DEBUG_CONVERT("quad", "7.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src -= 4, dst -= 8) { - dst[7] = 0.0f; /* SR */ - dst[6] = 0.0f; /* SL */ - dst[5] = src[3]; - dst[4] = src[2]; - dst[3] = 0.0f; /* LFE */ - dst[2] = 0.0f; /* FC */ - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 4) * 8; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* CONVERT FROM 4.1... */ - -static void SDLCALL -SDL_Convert41ToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("4.1", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src += 5) { - *(dst++) = (src[0] + src[1] + src[3] + src[4]) * 0.25f; - } - - cvt->len_cvt /= 5; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("4.1", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src += 5) { - const float fl = src[0]; - const float fr = src[1]; - const float bl = src[3]; - const float br = src[4]; - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.374222219f) + (bl * 0.319111109f) + (br * 0.195555553f); - *(dst++) = (fr * 0.374222219f) + (br * 0.319111109f) + (bl * 0.195555553f); - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41To21(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("4.1", "2.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src += 5) { - const float fl = src[0]; - const float fr = src[1]; - const float lfe = src[2]; - const float bl = src[3]; - const float br = src[4]; - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.374222219f) + (bl * 0.319111109f) + (br * 0.195555553f); - *(dst++) = (fr * 0.374222219f) + (br * 0.319111109f) + (bl * 0.195555553f); - *(dst++) = lfe; - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("4.1", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src += 5) { - /* !!! FIXME: FNA/XNA mixes a little of the LFE into every channel...but this can't possibly be right, right...? I just drop the LFE and copy the channels. */ - *(dst++) = src[0]; - *(dst++) = src[1]; - *(dst++) = src[3]; - *(dst++) = src[4]; - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41To51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 5) * 6))) - 6; - int i; - - LOG_DEBUG_CONVERT("4.1", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src -= 5, dst -= 6) { - dst[5] = src[4]; - dst[4] = src[3]; - dst[3] = src[2]; - dst[2] = 0.0f; /* FC */ - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41To61(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 4) * 7))) - 7; - int i; - - LOG_DEBUG_CONVERT("4.1", "6.1"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: I'm skeptical XNA/FNA's conversion is right, here. */ - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src -= 5, dst -= 7) { - const float bl = src[3]; - const float br = src[4]; - dst[6] = br * 0.796000004f; - dst[5] = bl * 0.796000004f; - dst[4] = (bl + br) * 0.5f; /* average BL+BR to BC */ - dst[3] = src[2]; - dst[2] = 0.0f; /* FC */ - dst[1] = src[1] * 0.939999998f; - dst[0] = src[0] * 0.939999998f; - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 7; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert41To71(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 5; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 5) * 8))) - 8; - int i; - - LOG_DEBUG_CONVERT("4.1", "7.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 5); i; --i, src -= 5, dst -= 8) { - dst[7] = 0.0f; /* SR */ - dst[6] = 0.0f; /* SL */ - dst[5] = src[4]; - dst[4] = src[3]; - dst[3] = src[2]; - dst[2] = 0.0f; /* FC */ - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 5) * 8; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - - -/* CONVERT FROM 5.1... */ - -static void SDLCALL -SDL_Convert51ToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6) { - *(dst++) = (src[0] + src[1] + src[2] + src[4] + src[5]) * 0.200000003f; - } - - cvt->len_cvt /= 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bl = src[4]; - const float br = src[5]; - const float extra = 0.090909094f / 4.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * (0.294545442f+extra)) + (fc * (0.208181813f+extra)) + (bl * (0.251818180f+extra)) + (br * (0.154545456f+extra)); - *(dst++) = (fr * (0.294545442f+extra)) + (fc * (0.208181813f+extra)) + (br * (0.251818180f+extra)) + (bl * (0.154545456f+extra)); - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51To21(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "2.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.324000001f) + (fc * 0.229000002f) + (bl * 0.277000010f) + (br * 0.170000002f); - *(dst++) = (fr * 0.324000001f) + (fc * 0.229000002f) + (br * 0.277000010f) + (bl * 0.170000002f); - *(dst++) = lfe; - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bl = src[4]; - const float br = src[5]; - const float extra = 0.047619049f / 2.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - *(dst++) = (fl * (0.558095276f+extra)) + (fc * (0.394285709f+extra)); - *(dst++) = (fr * (0.558095276f+extra)) + (fc * (0.394285709f+extra)); - *(dst++) = bl; /* !!! FIXME: XNA/FNA quiets the back speakers here to ~58%, but I'm copying them through. Not sure why they do it like that. */ - *(dst++) = br; /* !!! FIXME: XNA/FNA quiets the back speakers here to ~58%, but I'm copying them through. Not sure why they do it like that. */ - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51To41(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "4.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - *(dst++) = (fl * 0.586000025f) + (fc * 0.414000005f); - *(dst++) = (fr * 0.586000025f) + (fc * 0.414000005f); - *(dst++) = lfe; - *(dst++) = bl; /* !!! FIXME: XNA/FNA quiets the back speakers here to ~58%, but I'm copying them through. Not sure why they do it like that. */ - *(dst++) = br; /* !!! FIXME: XNA/FNA quiets the back speakers here to ~58%, but I'm copying them through. Not sure why they do it like that. */ - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 5; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 6; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 6) * 7))) - 7; - int i; - - LOG_DEBUG_CONVERT("5.1", "6.1"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: I'm skeptical XNA/FNA's conversion is right, here. Why is it quieting the back speakers instead of copying them through as-is? */ - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src -= 6, dst -= 7) { - const float bl = src[4]; - const float br = src[5]; - dst[6] = br * 0.796000004f; - dst[5] = bl * 0.796000004f; - dst[4] = (bl + br) * 0.5f; /* average BL+BR to BC */ - dst[3] = src[3]; - dst[2] = src[2] * 0.939999998f; - dst[1] = src[1] * 0.939999998f; - dst[0] = src[0] * 0.939999998f; - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 7; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 6; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 6) * 8))) - 8; - int i; - - LOG_DEBUG_CONVERT("5.1", "7.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src -= 6, dst -= 8) { - dst[7] = 0.0f; /* SR */ - dst[6] = 0.0f; /* SL */ - dst[5] = src[5]; - dst[4] = src[4]; - dst[3] = src[3]; - dst[2] = src[2]; - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 6) * 8; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - - -/* CONVERT FROM 6.1... */ - -static void SDLCALL -SDL_Convert61ToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - *(dst++) = (src[0] + src[1] + src[2] + src[4] + src[5] + src[6]) * 0.166666672f; - } - - cvt->len_cvt /= 7; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bc = src[4]; - const float sl = src[5]; - const float sr = src[6]; - const float extra = 0.076923080f / 5.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * (0.247384623f+extra)) + (fc * (0.174461529f+extra)) + (bc * (0.174461529f+extra)) + (sl * (0.226153851f+extra)) + (sr * (0.100615382f+extra)); - *(dst++) = (fr * (0.247384623f+extra)) + (fc * (0.174461529f+extra)) + (bc * (0.174461529f+extra)) + (sr * (0.226153851f+extra)) + (sl * (0.100615382f+extra)); - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61To21(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "2.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bc = src[4]; - const float sl = src[5]; - const float sr = src[6]; - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.247384623f) + (fc * 0.174461529f) + (bc * 0.174461529f) + (sl * 0.226153851f) + (sr * 0.100615382f); - *(dst++) = (fr * 0.247384623f) + (fc * 0.174461529f) + (bc * 0.174461529f) + (sr * 0.226153851f) + (sl * 0.100615382f); - *(dst++) = lfe; - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bc = src[4]; - const float sl = src[5]; - const float sr = src[6]; - const float extra = 0.040000003f / 3.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - const float extra2 = 0.040000003f / 2.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - *(dst++) = (fl * (0.463679999f+extra)) + (fc * (0.327360004f+extra)) + (sl * (0.168960005f+extra)); - *(dst++) = (fr * (0.463679999f+extra)) + (fc * (0.327360004f+extra)) + (sr * (0.168960005f+extra)); - *(dst++) = (bc * (0.327360004f+extra2)) + (sl * (0.431039989f+extra2)); - *(dst++) = (bc * (0.327360004f+extra2)) + (sr * (0.431039989f+extra2)); - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61To41(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "4.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bc = src[4]; - const float sl = src[5]; - const float sr = src[6]; - *(dst++) = (fl * 0.483000010f) + (fc * 0.340999991f) + (sl * 0.175999999f); - *(dst++) = (fr * 0.483000010f) + (fc * 0.340999991f) + (sr * 0.175999999f); - *(dst++) = lfe; - *(dst++) = (bc * 0.340999991f) + (sl * 0.449000001f); - *(dst++) = (bc * 0.340999991f) + (sr * 0.449000001f); - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 5; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("6.1", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bc = src[4]; - const float sl = src[5]; - const float sr = src[6]; - /* !!! FIXME: XNA/FNA quiets the front speakers a bunch, but leaves the back speakers at about the same volume. I'm not sure that's right. */ - *(dst++) = (fl * 0.611000001f) + (sl * 0.223000005f); - *(dst++) = (fr * 0.611000001f) + (sr * 0.223000005f); - *(dst++) = (fc * 0.611000001f); /* !!! FIXME: XNA/FNA silence the FC speaker to ~61%, but I'm not sure this is right. */ - *(dst++) = lfe; - *(dst++) = (bc * 0.432000011f) + (sl * 0.568000019f); - *(dst++) = (bc * 0.432000011f) + (sr * 0.568000019f); - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - 7; - float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / 7) * 8))) - 8; - int i; - - LOG_DEBUG_CONVERT("6.1", "7.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src -= 7, dst -= 8) { - const float bc = src[4]; - dst[7] = src[6]; - dst[6] = src[5]; - dst[5] = (bc * 0.707000017f); - dst[4] = (bc * 0.707000017f); - dst[3] = src[3]; - dst[2] = src[2]; - dst[1] = src[1]; - dst[0] = src[0]; - } - - cvt->len_cvt = (cvt->len_cvt / 7) * 8; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* CONVERT FROM 7.1... */ - -static void SDLCALL -SDL_Convert71ToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: we can probably SIMD this. */ - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - *(dst++) = (src[0] + src[1] + src[2] + src[4] + src[5] + src[6] + src[7]) * 0.143142849f; - } - - cvt->len_cvt /= 8; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: we can probably SIMD this. */ - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - const float extra = 0.066666670f / 6.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * (0.211866662f+extra)) + (fc * (0.150266662f+extra)) + (bl * (0.181066677f+extra)) + (br * (0.111066669f+extra)) + (sl * (0.194133341f+extra)) + (sr * (0.085866667f+extra)); - *(dst++) = (fr * (0.211866662f+extra)) + (fc * (0.150266662f+extra)) + (br * (0.181066677f+extra)) + (bl * (0.111066669f+extra)) + (sr * (0.194133341f+extra)) + (sl * (0.085866667f+extra)); - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71To21(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "2.1"); - SDL_assert(format == AUDIO_F32SYS); - - /* !!! FIXME: we can probably SIMD this. */ - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - - /* !!! FIXME: FNA/XNA mixes a little of the back right into the left (and back left into the right) and a little of the LFE...but this can't possibly be right, right...? */ - *(dst++) = (fl * 0.211866662f) + (fc * 0.150266662f) + (bl * 0.181066677f) + (br * 0.111066669f) + (sl * 0.194133341f) + (sr * 0.085866667f); - *(dst++) = (fr * 0.211866662f) + (fc * 0.150266662f) + (br * 0.181066677f) + (bl * 0.111066669f) + (sr * 0.194133341f) + (sl * 0.085866667f); - *(dst++) = lfe; - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - const float extra = 0.034482758f / 3.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - const float extra2 = 0.034482758f / 2.0f; /* this was the LFE distribution, we'll just split it between the other channels for now. */ - *(dst++) = (fl * (0.466344833f+extra)) + (fc * (0.329241365f+extra)) + (sl * (0.169931039f+extra)); - *(dst++) = (fr * (0.466344833f+extra)) + (fc * (0.329241365f+extra)) + (sr * (0.169931039f+extra)); - *(dst++) = (bl * (0.466344833f+extra2)) + (sl * (0.433517247f+extra2)); - *(dst++) = (br * (0.466344833f+extra2)) + (sr * (0.433517247f+extra2)); - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71To41(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "4.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - *(dst++) = (fl * 0.483000010f) + (fc * 0.340999991f) + (sl * 0.175999999f); - *(dst++) = (fr * 0.483000010f) + (fc * 0.340999991f) + (sr * 0.175999999f); - *(dst++) = lfe; - *(dst++) = (bl * 0.483000010f) + (sl * 0.449000001f); - *(dst++) = (br * 0.483000010f) + (sr * 0.449000001f); - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 5; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - /* !!! FIXME: XNA/FNA quiets the front speakers a bunch, but leaves the back speakers at about the same volume. I'm not sure that's right. */ - *(dst++) = (fl * 0.518000007f) + (sl * 0.188999996f); - *(dst++) = (fr * 0.518000007f) + (sr * 0.188999996f); - *(dst++) = (fc * 0.518000007f); /* !!! FIXME: XNA/FNA silence the FC speaker to ~51%, but I'm not sure this is right. */ - *(dst++) = lfe; - *(dst++) = (bl * 0.518000007f) + (sl * 0.188999996f); - *(dst++) = (br * 0.518000007f) + (sr * 0.188999996f); - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static void SDLCALL -SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "6.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8) { - const float fl = src[0]; - const float fr = src[1]; - const float fc = src[2]; - const float lfe = src[3]; - const float bl = src[4]; - const float br = src[5]; - const float sl = src[6]; - const float sr = src[7]; - /* !!! FIXME: XNA/FNA quiets the front speakers a bunch, but leaves the back speakers at about the same volume. I'm not sure that's right. */ - *(dst++) = (fl * 0.541000009f); - *(dst++) = (fr * 0.541000009f); - *(dst++) = (fc * 0.541000009f); /* !!! FIXME: XNA/FNA silence the FC speaker to ~61%, but I'm not sure this is right. */ - *(dst++) = lfe; - *(dst++) = (bl * 0.287999988f) + (br * 0.287999988f); - *(dst++) = (bl * 0.458999991f) + (sl * 0.541000009f); - *(dst++) = (br * 0.458999991f) + (sr * 0.541000009f); - } - - cvt->len_cvt = (cvt->len_cvt / 8) * 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -static const SDL_AudioFilter channel_converters[8][8] = { /* from][to] */ - { NULL, SDL_ConvertMonoToStereo, SDL_ConvertMonoTo21, SDL_ConvertMonoToQuad, SDL_ConvertMonoTo41, SDL_ConvertMonoTo51, SDL_ConvertMonoTo61, SDL_ConvertMonoTo71 }, - { SDL_ConvertStereoToMono, NULL, SDL_ConvertStereoTo21, SDL_ConvertStereoToQuad, SDL_ConvertStereoTo41, SDL_ConvertStereoTo51, SDL_ConvertStereoTo61, SDL_ConvertStereoTo71 }, - { SDL_Convert21ToMono, SDL_Convert21ToStereo, NULL, SDL_Convert21ToQuad, SDL_Convert21To41, SDL_Convert21To51, SDL_Convert21To61, SDL_Convert21To71 }, - { SDL_ConvertQuadToMono, SDL_ConvertQuadToStereo, SDL_ConvertQuadTo21, NULL, SDL_ConvertQuadTo41, SDL_ConvertQuadTo51, SDL_ConvertQuadTo61, SDL_ConvertQuadTo71 }, - { SDL_Convert41ToMono, SDL_Convert41ToStereo, SDL_Convert41To21, SDL_Convert41ToQuad, NULL, SDL_Convert41To51, SDL_Convert41To61, SDL_Convert41To71 }, - { SDL_Convert51ToMono, SDL_Convert51ToStereo, SDL_Convert51To21, SDL_Convert51ToQuad, SDL_Convert51To41, NULL, SDL_Convert51To61, SDL_Convert51To71 }, - { SDL_Convert61ToMono, SDL_Convert61ToStereo, SDL_Convert61To21, SDL_Convert61ToQuad, SDL_Convert61To41, SDL_Convert61To51, NULL, SDL_Convert61To71 }, - { SDL_Convert71ToMono, SDL_Convert71ToStereo, SDL_Convert71To21, SDL_Convert71ToQuad, SDL_Convert71To41, SDL_Convert71To51, SDL_Convert71To61, NULL } -}; +/* Include the autogenerated channel converters... */ +#include "SDL_audio_channel_converters.h"