]> git.sesse.net Git - ffmpeg/blob - libavfilter/af_aconvert_rematrix.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavfilter / af_aconvert_rematrix.c
1 /*
2  * Copyright (c) 2011 Mina Nagy Zaki
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * audio rematrixing functions, based on functions from libavcodec/resample.c
24  */
25
26 #if defined(FLOATING)
27 # define DIV2 /2
28 #else
29 # define DIV2 >>1
30 #endif
31
32 REMATRIX_FUNC_SIG(stereo_to_mono_packed)
33 {
34     while (nb_samples >= 4) {
35         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
36         outp[0][1] = (inp[0][2] + inp[0][3]) DIV2;
37         outp[0][2] = (inp[0][4] + inp[0][5]) DIV2;
38         outp[0][3] = (inp[0][6] + inp[0][7]) DIV2;
39         outp[0] += 4;
40         inp[0]  += 8;
41         nb_samples -= 4;
42     }
43     while (nb_samples--) {
44         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
45         outp[0]++;
46         inp[0] += 2;
47     }
48 }
49
50 REMATRIX_FUNC_SIG(stereo_downmix_packed)
51 {
52     while (nb_samples--) {
53         *outp[0]++ = inp[0][0];
54         *outp[0]++ = inp[0][1];
55         inp[0] += aconvert->in_nb_channels;
56     }
57 }
58
59 REMATRIX_FUNC_SIG(mono_to_stereo_packed)
60 {
61     while (nb_samples >= 4) {
62         outp[0][0] = outp[0][1] = inp[0][0];
63         outp[0][2] = outp[0][3] = inp[0][1];
64         outp[0][4] = outp[0][5] = inp[0][2];
65         outp[0][6] = outp[0][7] = inp[0][3];
66         outp[0] += 8;
67         inp[0]  += 4;
68         nb_samples -= 4;
69     }
70     while (nb_samples--) {
71         outp[0][0] = outp[0][1] = inp[0][0];
72         outp[0] += 2;
73         inp[0]  += 1;
74     }
75 }
76
77 /**
78  * This is for when we have more than 2 input channels, need to downmix to mono
79  * and do not have a conversion formula available.  We just use first two input
80  * channels - left and right. This is a placeholder until more conversion
81  * functions are written.
82  */
83 REMATRIX_FUNC_SIG(mono_downmix_packed)
84 {
85     while (nb_samples--) {
86         outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
87         inp[0] += aconvert->in_nb_channels;
88         outp[0]++;
89     }
90 }
91
92 REMATRIX_FUNC_SIG(mono_downmix_planar)
93 {
94     FMT_TYPE *out = outp[0];
95
96     while (nb_samples >= 4) {
97         out[0] = (inp[0][0] + inp[1][0]) DIV2;
98         out[1] = (inp[0][1] + inp[1][1]) DIV2;
99         out[2] = (inp[0][2] + inp[1][2]) DIV2;
100         out[3] = (inp[0][3] + inp[1][3]) DIV2;
101         out    += 4;
102         inp[0] += 4;
103         inp[1] += 4;
104         nb_samples -= 4;
105     }
106     while (nb_samples--) {
107         out[0] = (inp[0][0] + inp[1][0]) DIV2;
108         out++;
109         inp[0]++;
110         inp[1]++;
111     }
112 }
113
114 /* Stereo to 5.1 output */
115 REMATRIX_FUNC_SIG(stereo_to_surround_5p1_packed)
116 {
117     while (nb_samples--) {
118       outp[0][0] = inp[0][0];  /* left */
119       outp[0][1] = inp[0][1];  /* right */
120       outp[0][2] = (inp[0][0] + inp[0][1]) DIV2; /* center */
121       outp[0][3] = 0;          /* low freq */
122       outp[0][4] = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
123       outp[0][5] = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
124       inp[0]  += 2;
125       outp[0] += 6;
126     }
127 }
128
129 REMATRIX_FUNC_SIG(stereo_to_surround_5p1_planar)
130 {
131     while (nb_samples--) {
132       *outp[0]++ = *inp[0];    /* left */
133       *outp[1]++ = *inp[1];    /* right */
134       *outp[2]++ = (*inp[0] + *inp[1]) DIV2; /* center */
135       *outp[3]++ = 0;          /* low freq */
136       *outp[4]++ = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
137       *outp[5]++ = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
138       inp[0]++; inp[1]++;
139     }
140 }
141
142
143 /*
144 5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
145 - Left = front_left + rear_gain * rear_left + center_gain * center
146 - Right = front_right + rear_gain * rear_right + center_gain * center
147 Where rear_gain is usually around 0.5-1.0 and
148       center_gain is almost always 0.7 (-3 dB)
149 */
150 REMATRIX_FUNC_SIG(surround_5p1_to_stereo_packed)
151 {
152     while (nb_samples--) {
153         *outp[0]++ = inp[0][0] + (0.5 * inp[0][4]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
154         *outp[0]++ = inp[0][1] + (0.5 * inp[0][5]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
155
156         inp[0] += 6;
157     }
158 }
159
160 REMATRIX_FUNC_SIG(surround_5p1_to_stereo_planar)
161 {
162     while (nb_samples--) {
163         *outp[0]++ = *inp[0] + (0.5 * *inp[4]) + (0.7 * *inp[2]); //FIXME CLIPPING!
164         *outp[1]++ = *inp[1] + (0.5 * *inp[5]) + (0.7 * *inp[2]); //FIXME CLIPPING!
165
166         inp[0]++; inp[1]++; inp[2]++; inp[3]++; inp[4]++; inp[5]++;
167     }
168 }
169
170 #undef DIV2
171 #undef REMATRIX_FUNC_NAME
172 #undef FMT_TYPE