00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "audiooutputbase.h"
00020 #include "audiooutputdownmix.h"
00021
00022 #include "string.h"
00023
00024 #define LOC QString("Downmixer: ")
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 static const float m6db = 0.5;
00049 static const float m3db = 0.7071067811865476f;
00050 static const float mm3db = -0.7071067811865476f;
00051 static const float msqrt_1_3 = -0.577350269189626f;
00052 static const float sqrt_2_3 = 0.816496580927726f;
00053 static const float sqrt_2_3by3db = 0.577350269189626f;
00054 static const float msqrt_1_3bym3db = 0.408248290463863f;
00055
00056 int matrix[4][2] = { { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 } };
00057
00058 static const float stereo_matrix[8][8][2] =
00059 {
00060
00061 {
00062 { 1, 1 },
00063 },
00064
00065
00066 {
00067 { 1, 0 },
00068 { 0, 1 },
00069 },
00070
00071
00072 {
00073 { 1, 0 },
00074 { 0, 1 },
00075 { 1, 1 },
00076 },
00077
00078
00079 {
00080 { 1, 0 },
00081 { 0, 1 },
00082 { m3db, m3db },
00083 { mm3db, m3db },
00084 },
00085
00086
00087 {
00088 { 1, 0 },
00089 { 0, 1 },
00090 { m3db, m3db },
00091 { sqrt_2_3, msqrt_1_3 },
00092 { msqrt_1_3, sqrt_2_3 },
00093 },
00094
00095
00096 {
00097 { 1, 0 },
00098 { 0, 1 },
00099 { m3db, m3db },
00100 { 0, 0 },
00101 { sqrt_2_3, msqrt_1_3 },
00102 { msqrt_1_3, sqrt_2_3 },
00103 },
00104
00105
00106 {
00107 { 1, 0 },
00108 { 0, 1 },
00109 { m3db, m3db },
00110 { 0, 0 },
00111 { m6db, m6db },
00112 { sqrt_2_3, msqrt_1_3 },
00113 { msqrt_1_3, sqrt_2_3 },
00114 },
00115
00116
00117 {
00118 { 1, 0 },
00119 { 0, 1 },
00120 { m3db, m3db },
00121 { 0, 0 },
00122 { sqrt_2_3by3db, msqrt_1_3bym3db },
00123 { msqrt_1_3bym3db, sqrt_2_3by3db },
00124 { sqrt_2_3by3db, msqrt_1_3bym3db },
00125 { msqrt_1_3bym3db, sqrt_2_3by3db },
00126 }
00127 };
00128
00129 static const float s51_matrix[3][8][6] =
00130 {
00131
00132
00133 {
00134 { 1, 0, 0, 0, 0, 0 },
00135 { 0, 1, 0, 0, 0, 0 },
00136 { 0, 0, 1, 0, 0, 0 },
00137 { 0, 0, 0, 1, 0, 0 },
00138 { 0, 0, 0, 0, 1, 0 },
00139 { 0, 0, 0, 0, 0, 1 },
00140 },
00141
00142
00143
00144 {
00145 { 1, 0, 0, 0, 0, 0 },
00146 { 0, 1, 0, 0, 0, 0 },
00147 { 0, 0, 1, 0, 0, 0 },
00148 { 0, 0, 0, 1, 0, 0 },
00149 { 0, 0, 0, 0, m3db, m3db },
00150 { 0, 0, 0, 0, 1, 0 },
00151 { 0, 0, 0, 0, 0, 1 },
00152 },
00153
00154
00155 {
00156 { 1, 0, 0, 0, 0, 0 },
00157 { 0, 1, 0, 0, 0, 0 },
00158 { 0, 0, 1, 0, 0, 0 },
00159 { 0, 0, 0, 1, 0, 0 },
00160 { 0, 0, 0, 0, m3db, 0 },
00161 { 0, 0, 0, 0, 0, m3db },
00162 { 0, 0, 0, 0, m3db, 0 },
00163 { 0, 0, 0, 0, 0, m3db },
00164 }
00165 };
00166
00167 int AudioOutputDownmix::DownmixFrames(int channels_in, int channels_out,
00168 float *dst, float *src, int frames)
00169 {
00170 if (channels_in < channels_out)
00171 return -1;
00172
00173
00174
00175 if (channels_out == 2)
00176 {
00177 float tmp;
00178 int index = channels_in - 1;
00179 for (int n=0; n < frames; n++)
00180 {
00181 for (int i=0; i < channels_out; i++)
00182 {
00183 tmp = 0.0f;
00184 for (int j=0; j < channels_in; j++)
00185 tmp += src[j] * stereo_matrix[index][j][i];
00186 *dst++ = tmp;
00187 }
00188 src += channels_in;
00189 }
00190 }
00191 else if (channels_out == 6)
00192 {
00193 float tmp;
00194 int index = channels_in - 6;
00195 for (int n=0; n < frames; n++)
00196 {
00197 for (int i=0; i < channels_out; i++)
00198 {
00199 tmp = 0.0f;
00200 for (int j=0; j < channels_in; j++)
00201 tmp += src[j] * s51_matrix[index][j][i];
00202 *dst++ = tmp;
00203 }
00204 src += channels_in;
00205 }
00206 }
00207 else
00208 return -1;
00209
00210 return frames;
00211 }