|
MythTV
0.26-pre
|
00001 /* 00002 Copyright (C) 2010-2011 Jean-Yves Avenard 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU General Public License 00006 as published by the Free Software Foundation; either version 2 00007 of the License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "audiooutputbase.h" 00020 #include "audiooutputdownmix.h" 00021 00022 #include "string.h" 00023 00024 #define LOC QString("Downmixer: ") 00025 00026 /* 00027 SMPTE channel layout 00028 DUAL-MONO L R 00029 DUAL-MONO-LFE L R LFE 00030 MONO M 00031 MONO-LFE M LFE 00032 STEREO L R 00033 STEREO-LFE L R LFE 00034 3F L R C 00035 3F-LFE L R C LFE 00036 2F1 L R S 00037 2F1-LFE L R LFE S 00038 3F1 L R C S 00039 3F1-LFE L R C LFE S 00040 2F2 L R LS RS 00041 2F2-LFE L R LFE LS RS 00042 3F2 L R C LS RS 00043 3F2-LFE L R C LFE LS RS 00044 3F3R-LFE L R C LFE BC LS RS 00045 3F4-LFE L R C LFE Rls Rrs LS RS 00046 */ 00047 00048 static const float m6db = 0.5; 00049 static const float m3db = 0.7071067811865476f; // 3dB = SQRT(2) 00050 static const float mm3db = -0.7071067811865476f; // -3dB = SQRT(1/2) 00051 static const float msqrt_1_3 = -0.577350269189626f; // -SQRT(1/3) 00052 static const float sqrt_2_3 = 0.816496580927726f; // SQRT(2/3) 00053 static const float sqrt_2_3by3db = 0.577350269189626f; // SQRT(2/3)*-3dB = SQRT(2/3)*SQRT(1/2)=SQRT(1/3) 00054 static const float msqrt_1_3bym3db = 0.408248290463863f; // -SQRT(1/3)*-3dB = -SQRT(1/3)*SQRT(1/2) = -SQRT(1/6) 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 //1F L R 00061 { 00062 { 1, 1 }, // M 00063 }, 00064 00065 //2F L R 00066 { 00067 { 1, 0 }, // L 00068 { 0, 1 }, // R 00069 }, 00070 00071 //3F L R 00072 { 00073 { 1, 0 }, // L 00074 { 0, 1 }, // R 00075 { 1, 1 }, // C 00076 }, 00077 00078 //3F1R L R 00079 { 00080 { 1, 0 }, // L 00081 { 0, 1 }, // R 00082 { m3db, m3db }, // C 00083 { mm3db, m3db }, // S 00084 }, 00085 00086 //3F2R L R 00087 { 00088 { 1, 0 }, // L 00089 { 0, 1 }, // R 00090 { m3db, m3db }, // C 00091 { sqrt_2_3, msqrt_1_3 }, // LS 00092 { msqrt_1_3, sqrt_2_3 }, // RS 00093 }, 00094 00095 //3F2R.1 L R 00096 { 00097 { 1, 0 }, // L 00098 { 0, 1 }, // R 00099 { m3db, m3db }, // C 00100 { 0, 0 }, // LFE 00101 { sqrt_2_3, msqrt_1_3 }, // LS 00102 { msqrt_1_3, sqrt_2_3 }, // RS 00103 }, 00104 00105 // 3F3R.1 L R 00106 { 00107 { 1, 0 }, // L 00108 { 0, 1 }, // R 00109 { m3db, m3db }, // C 00110 { 0, 0 }, // LFE 00111 { m6db, m6db }, // Cs 00112 { sqrt_2_3, msqrt_1_3 }, // LS 00113 { msqrt_1_3, sqrt_2_3 }, // RS 00114 }, 00115 00116 // 3F4R.1 L R 00117 { 00118 { 1, 0 }, // L 00119 { 0, 1 }, // R 00120 { m3db, m3db }, // C 00121 { 0, 0 }, // LFE 00122 { sqrt_2_3by3db, msqrt_1_3bym3db }, // Rls 00123 { msqrt_1_3bym3db, sqrt_2_3by3db }, // Rrs 00124 { sqrt_2_3by3db, msqrt_1_3bym3db }, // LS 00125 { msqrt_1_3bym3db, sqrt_2_3by3db }, // RS 00126 } 00127 }; 00128 00129 static const float s51_matrix[3][8][6] = 00130 { 00131 // 3F2R.1 in -> 3F2R.1 out 00132 // L R C LFE LS RS 00133 { 00134 { 1, 0, 0, 0, 0, 0 }, // L 00135 { 0, 1, 0, 0, 0, 0 }, // R 00136 { 0, 0, 1, 0, 0, 0 }, // C 00137 { 0, 0, 0, 1, 0, 0 }, // LFE 00138 { 0, 0, 0, 0, 1, 0 }, // LS 00139 { 0, 0, 0, 0, 0, 1 }, // RS 00140 }, 00141 // 3F3R.1 in -> 3F2R.1 out 00142 // Used coefficient found at http://www.yamahaproaudio.com/training/self_training/data/smqr_en.pdf 00143 // L R C LFE LS RS 00144 { 00145 { 1, 0, 0, 0, 0, 0 }, // L 00146 { 0, 1, 0, 0, 0, 0 }, // R 00147 { 0, 0, 1, 0, 0, 0 }, // C 00148 { 0, 0, 0, 1, 0, 0 }, // LFE 00149 { 0, 0, 0, 0, m3db, m3db }, // Cs 00150 { 0, 0, 0, 0, 1, 0 }, // LS 00151 { 0, 0, 0, 0, 0, 1 }, // RS 00152 }, 00153 // 3F4R.1 -> 3F2R.1 out 00154 // L R C LFE LS RS 00155 { 00156 { 1, 0, 0, 0, 0, 0 }, // L 00157 { 0, 1, 0, 0, 0, 0 }, // R 00158 { 0, 0, 1, 0, 0, 0 }, // C 00159 { 0, 0, 0, 1, 0, 0 }, // LFE 00160 { 0, 0, 0, 0, m3db, 0 }, // Rls 00161 { 0, 0, 0, 0, 0, m3db }, // Rrs 00162 { 0, 0, 0, 0, m3db, 0 }, // LS 00163 { 0, 0, 0, 0, 0, m3db }, // RS 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 //VBAUDIO(LOC + QString("Downmixing %1 frames (in:%2 out:%3)") 00174 // .arg(frames).arg(channels_in).arg(channels_out)); 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 }
1.7.6.1