configure.ac: Move OggVorbis Encoder to Encoder Plugins.
[mpd-mk.git] / src / pcm_channels.c
blob34e72ca4e48ec18259ac24ea651adb592dcc9c0a
1 /*
2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "config.h"
21 #include "pcm_channels.h"
22 #include "pcm_buffer.h"
24 #include <assert.h>
26 static void
27 pcm_convert_channels_16_1_to_2(int16_t *dest, const int16_t *src,
28 unsigned num_frames)
30 while (num_frames-- > 0) {
31 int16_t value = *src++;
33 *dest++ = value;
34 *dest++ = value;
38 static void
39 pcm_convert_channels_16_2_to_1(int16_t *dest, const int16_t *src,
40 unsigned num_frames)
42 while (num_frames-- > 0) {
43 int32_t a = *src++, b = *src++;
45 *dest++ = (a + b) / 2;
49 static void
50 pcm_convert_channels_16_n_to_2(int16_t *dest,
51 unsigned src_channels, const int16_t *src,
52 unsigned num_frames)
54 unsigned c;
56 assert(src_channels > 0);
58 while (num_frames-- > 0) {
59 int32_t sum = 0;
60 int16_t value;
62 for (c = 0; c < src_channels; ++c)
63 sum += *src++;
64 value = sum / (int)src_channels;
66 /* XXX this is actually only mono ... */
67 *dest++ = value;
68 *dest++ = value;
72 const int16_t *
73 pcm_convert_channels_16(struct pcm_buffer *buffer,
74 uint8_t dest_channels,
75 uint8_t src_channels, const int16_t *src,
76 size_t src_size, size_t *dest_size_r)
78 unsigned num_frames = src_size / src_channels / sizeof(*src);
79 unsigned dest_size = num_frames * dest_channels * sizeof(*src);
80 int16_t *dest = pcm_buffer_get(buffer, dest_size);
82 *dest_size_r = dest_size;
84 if (src_channels == 1 && dest_channels == 2)
85 pcm_convert_channels_16_1_to_2(dest, src, num_frames);
86 else if (src_channels == 2 && dest_channels == 1)
87 pcm_convert_channels_16_2_to_1(dest, src, num_frames);
88 else if (dest_channels == 2)
89 pcm_convert_channels_16_n_to_2(dest, src_channels, src,
90 num_frames);
91 else
92 return NULL;
94 return dest;
97 static void
98 pcm_convert_channels_24_1_to_2(int32_t *dest, const int32_t *src,
99 unsigned num_frames)
101 while (num_frames-- > 0) {
102 int32_t value = *src++;
104 *dest++ = value;
105 *dest++ = value;
109 static void
110 pcm_convert_channels_24_2_to_1(int32_t *dest, const int32_t *src,
111 unsigned num_frames)
113 while (num_frames-- > 0) {
114 int32_t a = *src++, b = *src++;
116 *dest++ = (a + b) / 2;
120 static void
121 pcm_convert_channels_24_n_to_2(int32_t *dest,
122 unsigned src_channels, const int32_t *src,
123 unsigned num_frames)
125 unsigned c;
127 assert(src_channels > 0);
129 while (num_frames-- > 0) {
130 int32_t sum = 0;
131 int32_t value;
133 for (c = 0; c < src_channels; ++c)
134 sum += *src++;
135 value = sum / (int)src_channels;
137 /* XXX this is actually only mono ... */
138 *dest++ = value;
139 *dest++ = value;
143 const int32_t *
144 pcm_convert_channels_24(struct pcm_buffer *buffer,
145 uint8_t dest_channels,
146 uint8_t src_channels, const int32_t *src,
147 size_t src_size, size_t *dest_size_r)
149 unsigned num_frames = src_size / src_channels / sizeof(*src);
150 unsigned dest_size = num_frames * dest_channels * sizeof(*src);
151 int32_t *dest = pcm_buffer_get(buffer, dest_size);
153 *dest_size_r = dest_size;
155 if (src_channels == 1 && dest_channels == 2)
156 pcm_convert_channels_24_1_to_2(dest, src, num_frames);
157 else if (src_channels == 2 && dest_channels == 1)
158 pcm_convert_channels_24_2_to_1(dest, src, num_frames);
159 else if (dest_channels == 2)
160 pcm_convert_channels_24_n_to_2(dest, src_channels, src,
161 num_frames);
162 else
163 return NULL;
165 return dest;
168 static void
169 pcm_convert_channels_32_1_to_2(int32_t *dest, const int32_t *src,
170 unsigned num_frames)
172 pcm_convert_channels_24_1_to_2(dest, src, num_frames);
175 static void
176 pcm_convert_channels_32_2_to_1(int32_t *dest, const int32_t *src,
177 unsigned num_frames)
179 while (num_frames-- > 0) {
180 int64_t a = *src++, b = *src++;
182 *dest++ = (a + b) / 2;
186 static void
187 pcm_convert_channels_32_n_to_2(int32_t *dest,
188 unsigned src_channels, const int32_t *src,
189 unsigned num_frames)
191 unsigned c;
193 assert(src_channels > 0);
195 while (num_frames-- > 0) {
196 int64_t sum = 0;
197 int32_t value;
199 for (c = 0; c < src_channels; ++c)
200 sum += *src++;
201 value = sum / (int64_t)src_channels;
203 /* XXX this is actually only mono ... */
204 *dest++ = value;
205 *dest++ = value;
209 const int32_t *
210 pcm_convert_channels_32(struct pcm_buffer *buffer,
211 uint8_t dest_channels,
212 uint8_t src_channels, const int32_t *src,
213 size_t src_size, size_t *dest_size_r)
215 unsigned num_frames = src_size / src_channels / sizeof(*src);
216 unsigned dest_size = num_frames * dest_channels * sizeof(*src);
217 int32_t *dest = pcm_buffer_get(buffer, dest_size);
219 *dest_size_r = dest_size;
221 if (src_channels == 1 && dest_channels == 2)
222 pcm_convert_channels_32_1_to_2(dest, src, num_frames);
223 else if (src_channels == 2 && dest_channels == 1)
224 pcm_convert_channels_32_2_to_1(dest, src, num_frames);
225 else if (dest_channels == 2)
226 pcm_convert_channels_32_n_to_2(dest, src_channels, src,
227 num_frames);
228 else
229 return NULL;
231 return dest;