Comment unused code in libmad. Clean up initialization and memset'ing of decoder...
[kugel-rb.git] / apps / codecs / libpcm / linear_pcm.c
blob5c3c140b8cb9952e408331179f16c87e116eb864
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include "codeclib.h"
23 #include "support_formats.h"
26 * Linear PCM
29 #define INC_DEPTH_8 (PCM_OUTPUT_DEPTH - 8)
30 #define INC_DEPTH_16 (PCM_OUTPUT_DEPTH - 16)
31 #define INC_DEPTH_24 (PCM_OUTPUT_DEPTH - 24)
32 #define DEC_DEPTH_32 (32 - PCM_OUTPUT_DEPTH)
35 static struct pcm_format *fmt;
37 static bool set_format(struct pcm_format *format)
39 fmt = format;
41 if (fmt->channels == 0)
43 DEBUGF("CODEC_ERROR: channels is 0\n");
44 return false;
47 if (fmt->bitspersample == 0)
49 DEBUGF("CODEC_ERROR: bitspersample is 0\n");
50 return false;
53 if (fmt->bitspersample > 32)
55 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
56 "is unsupported\n");
57 return false;
60 fmt->bytespersample = fmt->bitspersample >> 3;
62 if (fmt->blockalign == 0)
63 fmt->blockalign = fmt->bytespersample * fmt->channels;
65 fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels);
67 /* chunksize = about 1/50[sec] data */
68 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
69 * fmt->blockalign;
71 return true;
74 static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
75 uint8_t *(*read_buffer)(size_t *realsize))
77 static struct pcm_pos newpos;
78 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
79 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
80 / fmt->samplesperblock :
81 seek_val / fmt->blockalign;
83 (void)read_buffer;
84 newpos.pos = newblock * fmt->blockalign;
85 newpos.samples = newblock * fmt->samplesperblock;
86 return &newpos;
89 /* 8bit decode functions */
90 static inline void decode_s8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
92 size_t i = 0;
94 for ( ; i < inbufsize; i++)
95 outbuf[i] = SE(inbuf[i]) << INC_DEPTH_8;
98 static inline void decode_u8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
100 size_t i = 0;
102 for ( ; i < inbufsize; i++)
103 outbuf[i] = SFT(inbuf[i]) << INC_DEPTH_8;
106 /* 16bit decode functions */
107 static inline void decode_s16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
109 size_t i = 0;
111 for ( ; i < inbufsize; i += 2)
112 outbuf[i/2] = (inbuf[i] << INC_DEPTH_16)|(SE(inbuf[i+1]) << INC_DEPTH_8);
115 static inline void decode_u16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
117 size_t i = 0;
119 for ( ; i < inbufsize; i += 2)
120 outbuf[i/2] = (inbuf[i] << INC_DEPTH_16)|(SFT(inbuf[i+1]) << INC_DEPTH_8);
123 static inline void decode_s16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
125 size_t i = 0;
127 for ( ; i < inbufsize; i += 2)
128 outbuf[i/2] = (inbuf[i+1] << INC_DEPTH_16)|(SE(inbuf[i]) << INC_DEPTH_8);
131 static inline void decode_u16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
133 size_t i = 0;
135 for ( ; i < inbufsize; i += 2)
136 outbuf[i/2] = (inbuf[i+1] << INC_DEPTH_16)|(SFT(inbuf[i]) << INC_DEPTH_8);
139 /* 24bit decode functions */
140 static inline void decode_s24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
142 size_t i = 0;
144 for ( ; i < inbufsize; i += 3)
145 outbuf[i/3] = (inbuf[i] << INC_DEPTH_24)|(inbuf[i+1] << INC_DEPTH_16)|
146 (SE(inbuf[i+2]) << INC_DEPTH_8);
149 static inline void decode_u24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
151 size_t i = 0;
153 for ( ; i < inbufsize; i += 3)
154 outbuf[i/3] = (inbuf[i] << INC_DEPTH_24)|(inbuf[i+1] << INC_DEPTH_16)|
155 (SFT(inbuf[i+2]) << INC_DEPTH_8);
158 static inline void decode_s24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
160 size_t i = 0;
162 for ( ; i < inbufsize; i += 3)
163 outbuf[i/3] = (inbuf[i+2] << INC_DEPTH_24)|(inbuf[i+1] << INC_DEPTH_16)|
164 (SE(inbuf[i]) << INC_DEPTH_8);
167 static inline void decode_u24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
169 size_t i = 0;
171 for ( ; i < inbufsize; i += 3)
172 outbuf[i/3] = (inbuf[i+2] << INC_DEPTH_24)|(inbuf[i+1] << INC_DEPTH_16)|
173 (SFT(inbuf[i]) << INC_DEPTH_8);
176 /* 32bit decode functions */
177 static inline void decode_s32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
179 size_t i = 0;
181 for ( ; i < inbufsize; i += 4)
182 outbuf[i/4] = (inbuf[i] >> DEC_DEPTH_32)|(inbuf[i+1] << INC_DEPTH_24)|
183 (inbuf[i+2] << INC_DEPTH_16)|(SE(inbuf[i+3]) << INC_DEPTH_8);
186 static inline void decode_u32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
188 size_t i = 0;
190 for ( ; i < inbufsize; i += 4)
191 outbuf[i/4] = (inbuf[i] >> DEC_DEPTH_32)|(inbuf[i+1] << INC_DEPTH_24)|
192 (inbuf[i+2] << INC_DEPTH_16)|(SFT(inbuf[i+3]) << INC_DEPTH_8);
195 static inline void decode_s32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
197 size_t i = 0;
199 for ( ; i < inbufsize; i += 4)
200 outbuf[i/4] = (inbuf[i+3] >> DEC_DEPTH_32)|(inbuf[i+2] << INC_DEPTH_24)|
201 (inbuf[i+1] << INC_DEPTH_16)|(SE(inbuf[i]) << INC_DEPTH_8);
204 static inline void decode_u32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
206 size_t i = 0;
208 for ( ; i < inbufsize; i += 4)
209 outbuf[i/4] = (inbuf[i+3] >> DEC_DEPTH_32)|(inbuf[i+2] << INC_DEPTH_24)|
210 (inbuf[i+1] << INC_DEPTH_16)|(SFT(inbuf[i]) << INC_DEPTH_8);
213 static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufcount)
215 if (fmt->bitspersample > 24)
217 if (fmt->is_little_endian)
219 if (fmt->is_signed)
220 decode_s32le(inbuf, inbufsize, outbuf);
221 else
222 decode_u32le(inbuf, inbufsize, outbuf);
224 else
226 if (fmt->is_signed)
227 decode_s32be(inbuf, inbufsize, outbuf);
228 else
229 decode_u32be(inbuf, inbufsize, outbuf);
231 *outbufcount = inbufsize >> 2;
233 else if (fmt->bitspersample > 16)
235 if (fmt->is_little_endian)
237 if (fmt->is_signed)
238 decode_s24le(inbuf, inbufsize, outbuf);
239 else
240 decode_u24le(inbuf, inbufsize, outbuf);
242 else
244 if (fmt->is_signed)
245 decode_s24be(inbuf, inbufsize, outbuf);
246 else
247 decode_u24be(inbuf, inbufsize, outbuf);
249 *outbufcount = inbufsize / 3;
251 else if (fmt->bitspersample > 8)
253 if (fmt->is_little_endian)
255 if (fmt->is_signed)
256 decode_s16le(inbuf, inbufsize, outbuf);
257 else
258 decode_u16le(inbuf, inbufsize, outbuf);
260 else
262 if (fmt->is_signed)
263 decode_s16be(inbuf, inbufsize, outbuf);
264 else
265 decode_u16be(inbuf, inbufsize, outbuf);
267 *outbufcount = inbufsize >> 1;
269 else
271 if (fmt->is_signed)
272 decode_s8(inbuf, inbufsize, outbuf);
273 else
274 decode_u8(inbuf, inbufsize, outbuf);
276 *outbufcount = inbufsize;
279 if (fmt->channels == 2)
280 *outbufcount >>= 1;
282 return CODEC_OK;
285 static const struct pcm_codec codec = {
286 set_format,
287 get_seek_pos,
288 decode,
291 const struct pcm_codec *get_linear_pcm_codec(void)
293 return &codec;