libavfilter/af_aconvert_rematrix.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Mina Nagy Zaki
00003  *
00004  * This file is part of FFmpeg.
00005  *
00006  * FFmpeg is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * FFmpeg is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with FFmpeg; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00026 #if defined(FLOATING)
00027 # define DIV2 /2
00028 #else
00029 # define DIV2 >>1
00030 #endif
00031 
00032 REMATRIX_FUNC_SIG(stereo_to_mono_packed)
00033 {
00034     while (nb_samples >= 4) {
00035         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
00036         outp[0][1] = (inp[0][2] + inp[0][3]) DIV2;
00037         outp[0][2] = (inp[0][4] + inp[0][5]) DIV2;
00038         outp[0][3] = (inp[0][6] + inp[0][7]) DIV2;
00039         outp[0] += 4;
00040         inp[0]  += 8;
00041         nb_samples -= 4;
00042     }
00043     while (nb_samples--) {
00044         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
00045         outp[0]++;
00046         inp[0] += 2;
00047     }
00048 }
00049 
00050 REMATRIX_FUNC_SIG(stereo_downmix_packed)
00051 {
00052     while (nb_samples--) {
00053         *outp[0]++ = inp[0][0];
00054         *outp[0]++ = inp[0][1];
00055         inp[0] += aconvert->in_nb_channels;
00056     }
00057 }
00058 
00059 REMATRIX_FUNC_SIG(mono_to_stereo_packed)
00060 {
00061     while (nb_samples >= 4) {
00062         outp[0][0] = outp[0][1] = inp[0][0];
00063         outp[0][2] = outp[0][3] = inp[0][1];
00064         outp[0][4] = outp[0][5] = inp[0][2];
00065         outp[0][6] = outp[0][7] = inp[0][3];
00066         outp[0] += 8;
00067         inp[0]  += 4;
00068         nb_samples -= 4;
00069     }
00070     while (nb_samples--) {
00071         outp[0][0] = outp[0][1] = inp[0][0];
00072         outp[0] += 2;
00073         inp[0]  += 1;
00074     }
00075 }
00076 
00083 REMATRIX_FUNC_SIG(mono_downmix_packed)
00084 {
00085     while (nb_samples--) {
00086         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
00087         inp[0] += aconvert->in_nb_channels;
00088         outp[0]++;
00089     }
00090 }
00091 
00092 REMATRIX_FUNC_SIG(mono_downmix_planar)
00093 {
00094     FMT_TYPE *out = outp[0];
00095 
00096     while (nb_samples >= 4) {
00097         out[0] = (inp[0][0] + inp[1][0]) DIV2;
00098         out[1] = (inp[0][1] + inp[1][1]) DIV2;
00099         out[2] = (inp[0][2] + inp[1][2]) DIV2;
00100         out[3] = (inp[0][3] + inp[1][3]) DIV2;
00101         out    += 4;
00102         inp[0] += 4;
00103         inp[1] += 4;
00104         nb_samples -= 4;
00105     }
00106     while (nb_samples--) {
00107         out[0] = (inp[0][0] + inp[1][0]) DIV2;
00108         out++;
00109         inp[0]++;
00110         inp[1]++;
00111     }
00112 }
00113 
00114 /* Stereo to 5.1 output */
00115 REMATRIX_FUNC_SIG(stereo_to_surround_5p1_packed)
00116 {
00117     while (nb_samples--) {
00118       outp[0][0] = inp[0][0];  /* left */
00119       outp[0][1] = inp[0][1];  /* right */
00120       outp[0][2] = (inp[0][0] + inp[0][1]) DIV2; /* center */
00121       outp[0][3] = 0;          /* low freq */
00122       outp[0][4] = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
00123       outp[0][5] = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
00124       inp[0]  += 2;
00125       outp[0] += 6;
00126     }
00127 }
00128 
00129 REMATRIX_FUNC_SIG(stereo_to_surround_5p1_planar)
00130 {
00131     while (nb_samples--) {
00132       *outp[0]++ = *inp[0];    /* left */
00133       *outp[1]++ = *inp[1];    /* right */
00134       *outp[2]++ = (*inp[0] + *inp[1]) DIV2; /* center */
00135       *outp[3]++ = 0;          /* low freq */
00136       *outp[4]++ = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
00137       *outp[5]++ = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
00138       inp[0]++; inp[1]++;
00139     }
00140 }
00141 
00142 
00143 /*
00144 5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
00145 - Left = front_left + rear_gain * rear_left + center_gain * center
00146 - Right = front_right + rear_gain * rear_right + center_gain * center
00147 Where rear_gain is usually around 0.5-1.0 and
00148       center_gain is almost always 0.7 (-3 dB)
00149 */
00150 REMATRIX_FUNC_SIG(surround_5p1_to_stereo_packed)
00151 {
00152     while (nb_samples--) {
00153         *outp[0]++ = inp[0][0] + (0.5 * inp[0][4]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
00154         *outp[0]++ = inp[0][1] + (0.5 * inp[0][5]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
00155 
00156         inp[0] += 6;
00157     }
00158 }
00159 
00160 REMATRIX_FUNC_SIG(surround_5p1_to_stereo_planar)
00161 {
00162     while (nb_samples--) {
00163         *outp[0]++ = *inp[0] + (0.5 * *inp[4]) + (0.7 * *inp[2]); //FIXME CLIPPING!
00164         *outp[1]++ = *inp[1] + (0.5 * *inp[5]) + (0.7 * *inp[2]); //FIXME CLIPPING!
00165 
00166         inp[0]++; inp[1]++; inp[2]++; inp[3]++; inp[4]++; inp[5]++;
00167     }
00168 }
00169 
00170 #undef DIV2
00171 #undef REMATRIX_FUNC_NAME
00172 #undef FMT_TYPE