configure.ac: Move OggVorbis Encoder to Encoder Plugins.
[mpd-mk.git] / src / pcm_format.c
blob3fd76a987107f4d4dad9810b202f93d88af1e685
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_format.h"
22 #include "pcm_dither.h"
23 #include "pcm_buffer.h"
24 #include "pcm_pack.h"
26 static void
27 pcm_convert_8_to_16(int16_t *out, const int8_t *in,
28 unsigned num_samples)
30 while (num_samples > 0) {
31 *out++ = *in++ << 8;
32 --num_samples;
36 static void
37 pcm_convert_24_to_16(struct pcm_dither *dither,
38 int16_t *out, const int32_t *in,
39 unsigned num_samples)
41 pcm_dither_24_to_16(dither, out, in, num_samples);
44 static void
45 pcm_convert_32_to_16(struct pcm_dither *dither,
46 int16_t *out, const int32_t *in,
47 unsigned num_samples)
49 pcm_dither_32_to_16(dither, out, in, num_samples);
52 static int32_t *
53 pcm_convert_24_to_24p32(struct pcm_buffer *buffer, const uint8_t *src,
54 unsigned num_samples)
56 int32_t *dest = pcm_buffer_get(buffer, num_samples * 4);
57 pcm_unpack_24(dest, src, num_samples, false);
58 return dest;
61 const int16_t *
62 pcm_convert_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
63 enum sample_format src_format, const void *src,
64 size_t src_size, size_t *dest_size_r)
66 unsigned num_samples;
67 int16_t *dest;
68 int32_t *dest32;
70 switch (src_format) {
71 case SAMPLE_FORMAT_UNDEFINED:
72 break;
74 case SAMPLE_FORMAT_S8:
75 num_samples = src_size;
76 *dest_size_r = src_size * sizeof(*dest);
77 dest = pcm_buffer_get(buffer, *dest_size_r);
79 pcm_convert_8_to_16(dest,
80 (const int8_t *)src,
81 num_samples);
82 return dest;
84 case SAMPLE_FORMAT_S16:
85 *dest_size_r = src_size;
86 return src;
88 case SAMPLE_FORMAT_S24:
89 /* convert to S24_P32 first */
90 num_samples = src_size / 3;
92 dest32 = pcm_convert_24_to_24p32(buffer, src, num_samples);
93 dest = (int16_t *)dest32;
95 /* convert to 16 bit in-place */
96 *dest_size_r = num_samples * sizeof(*dest);
97 pcm_convert_24_to_16(dither, dest, dest32,
98 num_samples);
99 return dest;
101 case SAMPLE_FORMAT_S24_P32:
102 num_samples = src_size / 4;
103 *dest_size_r = num_samples * sizeof(*dest);
104 dest = pcm_buffer_get(buffer, *dest_size_r);
106 pcm_convert_24_to_16(dither, dest,
107 (const int32_t *)src,
108 num_samples);
109 return dest;
111 case SAMPLE_FORMAT_S32:
112 num_samples = src_size / 4;
113 *dest_size_r = num_samples * sizeof(*dest);
114 dest = pcm_buffer_get(buffer, *dest_size_r);
116 pcm_convert_32_to_16(dither, dest,
117 (const int32_t *)src,
118 num_samples);
119 return dest;
122 return NULL;
125 static void
126 pcm_convert_8_to_24(int32_t *out, const int8_t *in,
127 unsigned num_samples)
129 while (num_samples > 0) {
130 *out++ = *in++ << 16;
131 --num_samples;
135 static void
136 pcm_convert_16_to_24(int32_t *out, const int16_t *in,
137 unsigned num_samples)
139 while (num_samples > 0) {
140 *out++ = *in++ << 8;
141 --num_samples;
145 static void
146 pcm_convert_32_to_24(int32_t *out, const int16_t *in,
147 unsigned num_samples)
149 while (num_samples > 0) {
150 *out++ = *in++ >> 8;
151 --num_samples;
155 const int32_t *
156 pcm_convert_to_24(struct pcm_buffer *buffer,
157 enum sample_format src_format, const void *src,
158 size_t src_size, size_t *dest_size_r)
160 unsigned num_samples;
161 int32_t *dest;
163 switch (src_format) {
164 case SAMPLE_FORMAT_UNDEFINED:
165 break;
167 case SAMPLE_FORMAT_S8:
168 num_samples = src_size;
169 *dest_size_r = src_size * sizeof(*dest);
170 dest = pcm_buffer_get(buffer, *dest_size_r);
172 pcm_convert_8_to_24(dest, (const int8_t *)src,
173 num_samples);
174 return dest;
176 case SAMPLE_FORMAT_S16:
177 num_samples = src_size / 2;
178 *dest_size_r = num_samples * sizeof(*dest);
179 dest = pcm_buffer_get(buffer, *dest_size_r);
181 pcm_convert_16_to_24(dest, (const int16_t *)src,
182 num_samples);
183 return dest;
185 case SAMPLE_FORMAT_S24:
186 num_samples = src_size / 3;
187 *dest_size_r = num_samples * sizeof(*dest);
189 return pcm_convert_24_to_24p32(buffer, src, num_samples);
191 case SAMPLE_FORMAT_S24_P32:
192 *dest_size_r = src_size;
193 return src;
195 case SAMPLE_FORMAT_S32:
196 num_samples = src_size / 4;
197 *dest_size_r = num_samples * sizeof(*dest);
198 dest = pcm_buffer_get(buffer, *dest_size_r);
200 pcm_convert_32_to_24(dest, (const int16_t *)src,
201 num_samples);
202 return dest;
205 return NULL;
208 static void
209 pcm_convert_8_to_32(int32_t *out, const int8_t *in,
210 unsigned num_samples)
212 while (num_samples > 0) {
213 *out++ = *in++ << 24;
214 --num_samples;
218 static void
219 pcm_convert_16_to_32(int32_t *out, const int16_t *in,
220 unsigned num_samples)
222 while (num_samples > 0) {
223 *out++ = *in++ << 16;
224 --num_samples;
228 static void
229 pcm_convert_24_to_32(int32_t *out, const int32_t *in,
230 unsigned num_samples)
232 while (num_samples > 0) {
233 *out++ = *in++ << 8;
234 --num_samples;
238 const int32_t *
239 pcm_convert_to_32(struct pcm_buffer *buffer,
240 enum sample_format src_format, const void *src,
241 size_t src_size, size_t *dest_size_r)
243 unsigned num_samples;
244 int32_t *dest;
246 switch (src_format) {
247 case SAMPLE_FORMAT_UNDEFINED:
248 break;
250 case SAMPLE_FORMAT_S8:
251 num_samples = src_size;
252 *dest_size_r = src_size * sizeof(*dest);
253 dest = pcm_buffer_get(buffer, *dest_size_r);
255 pcm_convert_8_to_32(dest, (const int8_t *)src,
256 num_samples);
257 return dest;
259 case SAMPLE_FORMAT_S16:
260 num_samples = src_size / 2;
261 *dest_size_r = num_samples * sizeof(*dest);
262 dest = pcm_buffer_get(buffer, *dest_size_r);
264 pcm_convert_16_to_32(dest, (const int16_t *)src,
265 num_samples);
266 return dest;
268 case SAMPLE_FORMAT_S24:
269 /* convert to S24_P32 first */
270 num_samples = src_size / 3;
272 dest = pcm_convert_24_to_24p32(buffer, src, num_samples);
274 /* convert to 32 bit in-place */
275 *dest_size_r = num_samples * sizeof(*dest);
276 pcm_convert_24_to_32(dest, dest, num_samples);
277 return dest;
279 case SAMPLE_FORMAT_S24_P32:
280 num_samples = src_size / 4;
281 *dest_size_r = num_samples * sizeof(*dest);
282 dest = pcm_buffer_get(buffer, *dest_size_r);
284 pcm_convert_24_to_32(dest, (const int32_t *)src,
285 num_samples);
286 return dest;
288 case SAMPLE_FORMAT_S32:
289 *dest_size_r = src_size;
290 return src;
293 return NULL;