summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/aiff.c213
-rw-r--r--apps/codecs/codecs.make3
-rw-r--r--apps/codecs/libpcm/SOURCES3
-rwxr-xr-xapps/codecs/libpcm/dvi_adpcm.c309
-rw-r--r--apps/codecs/libpcm/itut_g711.c203
-rw-r--r--apps/codecs/libpcm/libpcm.make25
-rw-r--r--apps/codecs/libpcm/linear_pcm.c163
-rw-r--r--apps/codecs/libpcm/pcm_common.h120
-rw-r--r--apps/codecs/libpcm/support_formats.h37
-rw-r--r--apps/codecs/wav.c648
10 files changed, 1113 insertions, 611 deletions
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c
index 9a675415e2..1b8c2da920 100644
--- a/apps/codecs/aiff.c
+++ b/apps/codecs/aiff.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (c) 2005 Jvo Studer 10 * Copyright (c) 2005 Jvo Studer
11 * Copyright (c) 2009 Yoshihisa Uchida
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
@@ -21,48 +22,62 @@
21 22
22#include "codeclib.h" 23#include "codeclib.h"
23#include <inttypes.h> 24#include <inttypes.h>
25#include "codecs/libpcm/support_formats.h"
24 26
25CODEC_HEADER 27CODEC_HEADER
26 28
27/* Macro that sign extends an unsigned byte */ 29#define FOURCC(c1, c2, c3, c4) \
28#define SE(x) ((int32_t)((int8_t)(x))) 30((((uint32_t)c1)<<24)|(((uint32_t)c2)<<16)|(((uint32_t)c3)<<8)|((uint32_t)c4))
29 31
30/* This codec supports AIFF files with the following formats: 32/* This codec supports the following AIFC compressionType formats */
31 * - PCM, 8, 16 and 24 bits, mono or stereo 33enum {
32 */ 34 AIFC_FORMAT_PCM = FOURCC('N', 'O', 'N', 'E'), /* AIFC PCM Format (big endian) */
35 AIFC_FORMAT_ALAW = FOURCC('a', 'l', 'a', 'w'), /* AIFC ALaw compressed */
36 AIFC_FORMAT_MULAW = FOURCC('u', 'l', 'a', 'w'), /* AIFC uLaw compressed */
37};
33 38
34enum 39static const struct pcm_entry pcm_codecs[] = {
35{ 40 { AIFC_FORMAT_PCM, get_linear_pcm_codec },
36 AIFF_FORMAT_PCM = 0x0001, /* AIFF PCM Format (big endian) */ 41 { AIFC_FORMAT_ALAW, get_itut_g711_alaw_codec },
37 IEEE_FORMAT_FLOAT = 0x0003, /* IEEE Float */ 42 { AIFC_FORMAT_MULAW, get_itut_g711_mulaw_codec },
38 AIFF_FORMAT_ALAW = 0x0004, /* AIFC ALaw compressed */
39 AIFF_FORMAT_ULAW = 0x0005 /* AIFC uLaw compressed */
40}; 43};
41 44
42/* Maximum number of bytes to process in one iteration */ 45#define NUM_FORMATS 3
43/* for 44.1kHz stereo 16bits, this represents 0.023s ~= 1/50s */
44#define AIF_CHUNK_SIZE (1024*2)
45 46
46static int32_t samples[AIF_CHUNK_SIZE] IBSS_ATTR; 47static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR;
48
49static const struct pcm_codec *get_codec(uint32_t formattag)
50{
51 int i;
52
53 for (i = 0; i < NUM_FORMATS; i++)
54 {
55 if (pcm_codecs[i].format_tag == formattag)
56 {
57 if (pcm_codecs[i].get_codec)
58 return pcm_codecs[i].get_codec();
59 return 0;
60 }
61 }
62 return 0;
63}
47 64
48enum codec_status codec_main(void) 65enum codec_status codec_main(void)
49{ 66{
50 uint32_t numbytes, bytesdone; 67 int status = CODEC_OK;
51 uint16_t num_channels = 0; 68 struct pcm_format format;
69 uint32_t bytesdone, decodedbytes;
52 uint32_t num_sample_frames = 0; 70 uint32_t num_sample_frames = 0;
53 uint16_t sample_size = 0; 71 uint32_t i = CODEC_OK;
54 uint32_t sample_rate = 0;
55 uint32_t i;
56 size_t n; 72 size_t n;
57 int bufcount; 73 int bufcount;
58 int endofstream; 74 int endofstream;
59 unsigned char *buf; 75 unsigned char *buf;
60 uint8_t *aifbuf; 76 uint8_t *aifbuf;
61 long chunksize;
62 uint32_t offset2snd = 0; 77 uint32_t offset2snd = 0;
63 uint16_t block_size = 0;
64 uint32_t avgbytespersec = 0;
65 off_t firstblockposn; /* position of the first block in file */ 78 off_t firstblockposn; /* position of the first block in file */
79 bool is_aifc = false;
80 const struct pcm_codec *codec;
66 81
67 /* Generic codec initialisation */ 82 /* Generic codec initialisation */
68 ci->configure(DSP_SET_SAMPLE_DEPTH, 28); 83 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
@@ -84,45 +99,80 @@ next_track:
84 i = CODEC_ERROR; 99 i = CODEC_ERROR;
85 goto done; 100 goto done;
86 } 101 }
87 if ((memcmp(buf, "FORM", 4) != 0) || (memcmp(&buf[8], "AIFF", 4) != 0)) { 102
103 if (memcmp(buf, "FORM", 4) != 0)
104 {
105 DEBUGF("CODEC_ERROR: does not aiff format %c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
106 i = CODEC_ERROR;
107 goto done;
108 }
109 if (memcmp(&buf[8], "AIFF", 4) == 0)
110 is_aifc = false;
111 else if (memcmp(&buf[8], "AIFC", 4) == 0)
112 is_aifc = true;
113 else
114 {
115 DEBUGF("CODEC_ERROR: does not aiff format %c%c%c%c\n", buf[8], buf[9], buf[10], buf[11]);
88 i = CODEC_ERROR; 116 i = CODEC_ERROR;
89 goto done; 117 goto done;
90 } 118 }
91 119
92 buf += 12; 120 buf += 12;
93 n -= 12; 121 n -= 12;
94 numbytes = 0; 122
123 ci->memset(&format, 0, sizeof(struct pcm_format));
124 format.is_signed = true;
125 format.is_little_endian = false;
126
127 decodedbytes = 0;
128 codec = 0;
95 129
96 /* read until 'SSND' chunk, which typically is last */ 130 /* read until 'SSND' chunk, which typically is last */
97 while (numbytes == 0 && n >= 8) { 131 while (format.numbytes == 0 && n >= 8)
132 {
98 /* chunkSize */ 133 /* chunkSize */
99 i = ((buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7]); 134 i = ((buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7]);
100 if (memcmp(buf, "COMM", 4) == 0) { 135 if (memcmp(buf, "COMM", 4) == 0) {
101 if (i < 18) { 136 if ((!is_aifc && i < 18) || (is_aifc && i < 22))
102 DEBUGF("CODEC_ERROR: 'COMM' chunk size=%lu < 18\n", 137 {
103 (unsigned long)i); 138 DEBUGF("CODEC_ERROR: 'COMM' chunk size=%lu < %d\n",
139 (unsigned long)i, (is_aifc)?22:18);
104 i = CODEC_ERROR; 140 i = CODEC_ERROR;
105 goto done; 141 goto done;
106 } 142 }
107 /* num_channels */ 143 /* num_channels */
108 num_channels = ((buf[8]<<8)|buf[9]); 144 format.channels = ((buf[8]<<8)|buf[9]);
109 /* num_sample_frames */ 145 /* num_sample_frames */
110 num_sample_frames = ((buf[10]<<24)|(buf[11]<<16)|(buf[12]<<8) 146 num_sample_frames = ((buf[10]<<24)|(buf[11]<<16)|(buf[12]<<8)
111 |buf[13]); 147 |buf[13]);
112 /* sample_size */ 148 /* sample_size */
113 sample_size = ((buf[14]<<8)|buf[15]); 149 format.bitspersample = ((buf[14]<<8)|buf[15]);
114 /* sample_rate (don't use last 4 bytes, only integer fs) */ 150 /* sample_rate (don't use last 4 bytes, only integer fs) */
115 if (buf[16] != 0x40) { 151 if (buf[16] != 0x40) {
116 DEBUGF("CODEC_ERROR: weird sampling rate (no @)\n"); 152 DEBUGF("CODEC_ERROR: weird sampling rate (no @)\n");
117 i = CODEC_ERROR; 153 i = CODEC_ERROR;
118 goto done; 154 goto done;
119 } 155 }
120 sample_rate = ((buf[18]<<24)|(buf[19]<<16)|(buf[20]<<8)|buf[21])+1; 156 format.samplespersec = ((buf[18]<<24)|(buf[19]<<16)|(buf[20]<<8)|buf[21])+1;
121 sample_rate = sample_rate >> (16 + 14 - buf[17]); 157 format.samplespersec >>= (16 + 14 - buf[17]);
158 /* compressionType (AIFC only) */
159 if (is_aifc)
160 {
161 format.formattag = (buf[26]<<24)|(buf[27]<<16)|(buf[28]<<8)|buf[29];
162
163 /*
164 * aiff's sample_size is uncompressed sound data size.
165 * But format.bitspersample is compressed sound data size.
166 */
167 if (format.formattag == AIFC_FORMAT_ALAW || format.formattag == AIFC_FORMAT_MULAW)
168 format.bitspersample = 8;
169 }
170 else
171 format.formattag = AIFC_FORMAT_PCM;
122 /* calc average bytes per second */ 172 /* calc average bytes per second */
123 avgbytespersec = sample_rate*num_channels*sample_size/8; 173 format.avgbytespersec = format.samplespersec*format.channels*format.bitspersample/8;
124 } else if (memcmp(buf, "SSND", 4)==0) { 174 } else if (memcmp(buf, "SSND", 4)==0) {
125 if (sample_size == 0) { 175 if (format.bitspersample == 0) {
126 DEBUGF("CODEC_ERROR: unsupported chunk order\n"); 176 DEBUGF("CODEC_ERROR: unsupported chunk order\n");
127 i = CODEC_ERROR; 177 i = CODEC_ERROR;
128 goto done; 178 goto done;
@@ -130,11 +180,14 @@ next_track:
130 /* offset2snd */ 180 /* offset2snd */
131 offset2snd = (buf[8]<<24)|(buf[9]<<16)|(buf[10]<<8)|buf[11]; 181 offset2snd = (buf[8]<<24)|(buf[9]<<16)|(buf[10]<<8)|buf[11];
132 /* block_size */ 182 /* block_size */
133 block_size = (buf[12]<<24)|(buf[13]<<16)|(buf[14]<<8)|buf[15]; 183 format.blockalign = (buf[12]<<24)|(buf[13]<<16)|(buf[14]<<8)|buf[15];
134 if (block_size == 0) 184 if (format.blockalign == 0)
135 block_size = num_channels*sample_size; 185 format.blockalign = format.channels*format.bitspersample;
136 numbytes = i - 8 - offset2snd; 186 format.numbytes = i - 8 - offset2snd;
137 i = 8 + offset2snd; /* advance to the beginning of data */ 187 i = 8 + offset2snd; /* advance to the beginning of data */
188 } else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
189 /* Format Version Chunk (AIFC only chunk) */
190 /* skip this chunk */
138 } else { 191 } else {
139 DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n", 192 DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n",
140 buf[0], buf[1], buf[2], buf[3], (unsigned long)i); 193 buf[0], buf[1], buf[2], buf[3], (unsigned long)i);
@@ -151,28 +204,36 @@ next_track:
151 n -= i + 8; 204 n -= i + 8;
152 } /* while 'SSND' */ 205 } /* while 'SSND' */
153 206
154 if (num_channels == 0) { 207 if (format.channels == 0) {
155 DEBUGF("CODEC_ERROR: 'COMM' chunk not found or 0-channels file\n"); 208 DEBUGF("CODEC_ERROR: 'COMM' chunk not found or 0-channels file\n");
156 i = CODEC_ERROR; 209 i = CODEC_ERROR;
157 goto done; 210 goto done;
158 } 211 }
159 if (numbytes == 0) { 212 if (format.numbytes == 0) {
160 DEBUGF("CODEC_ERROR: 'SSND' chunk not found or has zero length\n"); 213 DEBUGF("CODEC_ERROR: 'SSND' chunk not found or has zero length\n");
161 i = CODEC_ERROR; 214 i = CODEC_ERROR;
162 goto done; 215 goto done;
163 } 216 }
164 if (sample_size > 24) { 217
165 DEBUGF("CODEC_ERROR: PCM with more than 24 bits per sample " 218 codec = get_codec(format.formattag);
166 "is unsupported\n"); 219 if (codec == 0)
220 {
221 DEBUGF("CODEC_ERROR: AIFC does not support compressionType: 0x%x\n", format.formattag);
222 i = CODEC_ERROR;
223 goto done;
224 }
225
226 if (!codec->set_format(&format, 0))
227 {
167 i = CODEC_ERROR; 228 i = CODEC_ERROR;
168 goto done; 229 goto done;
169 } 230 }
170 231
171 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 232 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
172 233
173 if (num_channels == 2) { 234 if (format.channels == 2) {
174 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); 235 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
175 } else if (num_channels == 1) { 236 } else if (format.channels == 1) {
176 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); 237 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
177 } else { 238 } else {
178 DEBUGF("CODEC_ERROR: more than 2 channels unsupported\n"); 239 DEBUGF("CODEC_ERROR: more than 2 channels unsupported\n");
@@ -187,18 +248,6 @@ next_track:
187 bytesdone = 0; 248 bytesdone = 0;
188 ci->set_elapsed(0); 249 ci->set_elapsed(0);
189 endofstream = 0; 250 endofstream = 0;
190 /* chunksize is computed so that one chunk is about 1/50s.
191 * this make 4096 for 44.1kHz 16bits stereo.
192 * It also has to be a multiple of blockalign */
193 chunksize = (1 + avgbytespersec/(50*block_size))*block_size;
194 /* check that the output buffer is big enough (convert to samplespersec,
195 then round to the block_size multiple below) */
196 if (((uint64_t)chunksize*ci->id3->frequency*num_channels*2)
197 /(uint64_t)avgbytespersec >= AIF_CHUNK_SIZE) {
198 chunksize = ((uint64_t)AIF_CHUNK_SIZE*avgbytespersec
199 /((uint64_t)ci->id3->frequency*num_channels*2
200 *block_size))*block_size;
201 }
202 251
203 while (!endofstream) { 252 while (!endofstream) {
204 ci->yield(); 253 ci->yield();
@@ -206,61 +255,39 @@ next_track:
206 break; 255 break;
207 256
208 if (ci->seek_time) { 257 if (ci->seek_time) {
209 uint32_t newpos; 258 uint32_t newpos = codec->get_seek_pos(ci->seek_time);
210 259 if (newpos > format.numbytes)
211 /* use avgbytespersec to round to the closest blockalign multiple,
212 add firstblockposn. 64-bit casts to avoid overflows. */
213 newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1))
214 /(1000LL*block_size))*block_size;
215 if (newpos > numbytes)
216 break; 260 break;
217 if (ci->seek_buffer(firstblockposn + newpos)) 261 if (ci->seek_buffer(firstblockposn + newpos))
218 bytesdone = newpos; 262 bytesdone = newpos;
219 ci->seek_complete(); 263 ci->seek_complete();
220 } 264 }
221 aifbuf = (uint8_t *)ci->request_buffer(&n, chunksize); 265 aifbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize);
222 266
223 if (n == 0) 267 if (n == 0)
224 break; /* End of stream */ 268 break; /* End of stream */
225 269
226 if (bytesdone + n > numbytes) { 270 if (bytesdone + n > format.numbytes) {
227 n = numbytes - bytesdone; 271 n = format.numbytes - bytesdone;
228 endofstream = 1; 272 endofstream = 1;
229 } 273 }
230 274
231 if (sample_size > 24) { 275 status = codec->decode(aifbuf, n, samples, &bufcount);
232 for (i = 0; i < n; i += 4) { 276 if (status == CODEC_ERROR)
233 samples[i/4] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) 277 {
234 |(aifbuf[i + 2]<<5)|(aifbuf[i + 3]>>3); 278 DEBUGF("codec error\n");
235 } 279 goto done;
236 bufcount = n >> 2;
237 } else if (sample_size > 16) {
238 for (i = 0; i < n; i += 3) {
239 samples[i/3] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13)
240 |(aifbuf[i + 2]<<5);
241 }
242 bufcount = n/3;
243 } else if (sample_size > 8) {
244 for (i = 0; i < n; i += 2)
245 samples[i/2] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13);
246 bufcount = n >> 1;
247 } else {
248 for (i = 0; i < n; i++)
249 samples[i] = SE(aifbuf[i]) << 21;
250 bufcount = n;
251 } 280 }
252 281
253 if (num_channels == 2)
254 bufcount >>= 1;
255
256 ci->pcmbuf_insert(samples, NULL, bufcount); 282 ci->pcmbuf_insert(samples, NULL, bufcount);
257 283
258 ci->advance_buffer(n); 284 ci->advance_buffer(n);
259 bytesdone += n; 285 bytesdone += n;
260 if (bytesdone >= numbytes) 286 decodedbytes += bufcount;
287 if (bytesdone >= format.numbytes)
261 endofstream = 1; 288 endofstream = 1;
262 289
263 ci->set_elapsed(bytesdone*1000LL/avgbytespersec); 290 ci->set_elapsed(decodedbytes*1000LL/ci->id3->frequency);
264 } 291 }
265 i = CODEC_OK; 292 i = CODEC_OK;
266 293
diff --git a/apps/codecs/codecs.make b/apps/codecs/codecs.make
index 391975d73c..9e1f909462 100644
--- a/apps/codecs/codecs.make
+++ b/apps/codecs/codecs.make
@@ -39,6 +39,7 @@ include $(APPSDIR)/codecs/libwma/libwma.make
39include $(APPSDIR)/codecs/libcook/libcook.make 39include $(APPSDIR)/codecs/libcook/libcook.make
40include $(APPSDIR)/codecs/librm/librm.make 40include $(APPSDIR)/codecs/librm/librm.make
41include $(APPSDIR)/codecs/libatrac/libatrac.make 41include $(APPSDIR)/codecs/libatrac/libatrac.make
42include $(APPSDIR)/codecs/libpcm/libpcm.make
42 43
43# compile flags for codecs 44# compile flags for codecs
44CODECFLAGS = $(filter-out -fno-strict-aliasing,$(CFLAGS)) -fstrict-aliasing \ 45CODECFLAGS = $(filter-out -fno-strict-aliasing,$(CFLAGS)) -fstrict-aliasing \
@@ -85,6 +86,8 @@ $(CODECDIR)/cook.codec : $(CODECDIR)/libcook.a $(CODECDIR)/librm.a
85$(CODECDIR)/raac.codec : $(CODECDIR)/libfaad.a $(CODECDIR)/librm.a 86$(CODECDIR)/raac.codec : $(CODECDIR)/libfaad.a $(CODECDIR)/librm.a
86$(CODECDIR)/a52_rm.codec : $(CODECDIR)/liba52.a $(CODECDIR)/librm.a 87$(CODECDIR)/a52_rm.codec : $(CODECDIR)/liba52.a $(CODECDIR)/librm.a
87$(CODECDIR)/atrac3_rm.codec : $(CODECDIR)/libatrac.a $(CODECDIR)/librm.a 88$(CODECDIR)/atrac3_rm.codec : $(CODECDIR)/libatrac.a $(CODECDIR)/librm.a
89$(CODECDIR)/aiff.codec : $(CODECDIR)/libpcm.a
90$(CODECDIR)/wav.codec : $(CODECDIR)/libpcm.a
88 91
89$(CODECS): $(CODECLIB) # this must be last in codec dependency list 92$(CODECS): $(CODECLIB) # this must be last in codec dependency list
90 93
diff --git a/apps/codecs/libpcm/SOURCES b/apps/codecs/libpcm/SOURCES
new file mode 100644
index 0000000000..e921584f7c
--- /dev/null
+++ b/apps/codecs/libpcm/SOURCES
@@ -0,0 +1,3 @@
1linear_pcm.c
2itut_g711.c
3dvi_adpcm.c
diff --git a/apps/codecs/libpcm/dvi_adpcm.c b/apps/codecs/libpcm/dvi_adpcm.c
new file mode 100755
index 0000000000..9118906a93
--- /dev/null
+++ b/apps/codecs/libpcm/dvi_adpcm.c
@@ -0,0 +1,309 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
12 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "codeclib.h"
23#include "pcm_common.h"
24
25/*
26 * Intel DVI ADPCM
27 */
28
29static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = {
30 7, 8, 9, 10, 11, 12, 13, 14,
31 16, 17, 19, 21, 23, 25, 28, 31,
32 34, 37, 41, 45, 50, 55, 60, 66,
33 73, 80, 88, 97, 107, 118, 130, 143,
34 157, 173, 190, 209, 230, 253, 279, 307,
35 337, 371, 408, 449, 494, 544, 598, 658,
36 724, 796, 876, 963, 1060, 1166, 1282, 1411,
37 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
38 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
39 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
40 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
41 32767 };
42
43static const int dvi_adpcm_indextab4[8] ICONST_ATTR = {
44 -1, -1, -1, -1, 2, 4, 6, 8 };
45
46static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 };
47
48static struct pcm_format *fmt;
49
50static bool set_format(struct pcm_format *format, const unsigned char *fmtpos)
51{
52 fmt = format;
53
54 (void)fmtpos;
55
56 if (fmt->bitspersample != 4 && fmt->bitspersample != 3)
57 {
58 DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n");
59 return false;
60 }
61
62 if (fmt->size < 2) {
63 DEBUGF("CODEC_ERROR: dvi_adpcm is missing SamplesPerBlock value\n");
64 return false;
65 }
66
67 /* chunksize is computed so that one chunk is about 1/50s.
68 * this make 4096 for 44.1kHz 16bits stereo.
69 * It also has to be a multiple of blockalign */
70 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
71
72 /* check that the output buffer is big enough (convert to samplespersec,
73 then round to the blockalign multiple below) */
74 if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3)
75 /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE)
76 fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec
77 /((uint64_t)ci->id3->frequency * fmt->channels * 2
78 * fmt->blockalign)) * fmt->blockalign;
79
80 return true;
81}
82
83static uint32_t get_seek_pos(long seek_time)
84{
85 uint32_t newpos;
86
87 /* use avgbytespersec to round to the closest blockalign multiple,
88 add firstblockposn. 64-bit casts to avoid overflows. */
89 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1))
90 / (1000LL*fmt->blockalign))*fmt->blockalign;
91 return newpos;
92}
93
94static int decode_dvi_adpcm(const uint8_t *inbuf, size_t inbufsize,
95 int32_t *outbuf, size_t *outbufcount)
96{
97 size_t nsamples = 0;
98 int sample[2];
99 int samplecode[32][2];
100 int i;
101 int stepindex[2];
102 int c;
103 int diff;
104 int step;
105 int codem;
106 int code;
107
108 if (fmt->bitspersample != 4 && fmt->bitspersample != 3) {
109 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n");
110 return CODEC_ERROR;
111 }
112
113 /* decode block header */
114 for (c = 0; c < fmt->channels && inbufsize >= 4; c++) {
115 /* decode + push first sample */
116 sample[c] = (short)(inbuf[0]|(inbuf[1]<<8));/* need cast for sign-extend */
117 outbuf[c] = sample[c] << 13;
118 nsamples++;
119 stepindex[c] = inbuf[2];
120 /* check for step table index overflow */
121 if (stepindex[c] > 88) {
122 DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]);
123 return CODEC_ERROR;
124 }
125
126 inbuf += 4;
127 inbufsize -= 4;
128 }
129 if (fmt->bitspersample == 4) {
130 while (inbufsize >= (size_t)(fmt->channels*4) &&
131 (nsamples + (fmt->channels*8) <= *outbufcount))
132 {
133 for (c = 0; c < fmt->channels; c++)
134 {
135 samplecode[0][c] = inbuf[0]&0xf;
136 samplecode[1][c] = inbuf[0]>>4;
137 samplecode[2][c] = inbuf[1]&0xf;
138 samplecode[3][c] = inbuf[1]>>4;
139 samplecode[4][c] = inbuf[2]&0xf;
140 samplecode[5][c] = inbuf[2]>>4;
141 samplecode[6][c] = inbuf[3]&0xf;
142 samplecode[7][c] = inbuf[3]>>4;
143 inbuf += 4;
144 inbufsize -= 4;
145 }
146 for (i = 0; i < 8; i++)
147 {
148 for (c = 0; c < fmt->channels; c++)
149 {
150 step = dvi_adpcm_steptab[stepindex[c]];
151 codem = samplecode[i][c];
152 code = codem & 0x07;
153
154 /* adjust the step table index */
155 stepindex[c] += dvi_adpcm_indextab4[code];
156 /* check for step table index overflow and underflow */
157 if (stepindex[c] > 88)
158 stepindex[c] = 88;
159 else if (stepindex[c] < 0)
160 stepindex[c] = 0;
161 /* calculate the difference */
162#ifdef STRICT_IMA
163 diff = 0;
164 if (code & 4)
165 diff += step;
166 step = step >> 1;
167 if (code & 2)
168 diff += step;
169 step = step >> 1;
170 if (code & 1)
171 diff += step;
172 step = step >> 1;
173 diff += step;
174#else
175 diff = ((code + code + 1) * step) >> 3; /* faster */
176#endif
177 /* check the sign bit */
178 /* check for overflow and underflow errors */
179 if (code != codem)
180 {
181 sample[c] -= diff;
182 if (sample[c] < -32768)
183 sample[c] = -32768;
184 }
185 else
186 {
187 sample[c] += diff;
188 if (sample[c] > 32767)
189 sample[c] = 32767;
190 }
191 /* output the new sample */
192 outbuf[nsamples] = sample[c] << 13;
193 nsamples++;
194 }
195 }
196 }
197 } else { /* bitspersample == 3 */
198 while (inbufsize >= (uint32_t)(fmt->channels*12) &&
199 (nsamples + 32*fmt->channels) <= *outbufcount) {
200 for (c = 0; c < fmt->channels; c++) {
201 uint16_t bitstream = 0;
202 int bitsread = 0;
203 for (i = 0; i < 32 && inbufsize > 0; i++) {
204 if (bitsread < 3) {
205 /* read 8 more bits */
206 bitstream |= inbuf[0]<<bitsread;
207 bitsread += 8;
208 inbufsize--;
209 inbuf++;
210 }
211 samplecode[i][c] = bitstream & 7;
212 bitstream = bitstream>>3;
213 bitsread -= 3;
214 }
215 if (bitsread != 0) {
216 /* 32*3 = 3 words, so we should end with bitsread==0 */
217 DEBUGF("decode_dvi_adpcm: error in implementation\n");
218 return CODEC_ERROR;
219 }
220 }
221
222 for (i = 0; i < 32; i++) {
223 for (c = 0; c < fmt->channels; c++) {
224 step = dvi_adpcm_steptab[stepindex[c]];
225 codem = samplecode[i][c];
226 code = codem & 0x03;
227
228 /* adjust the step table index */
229 stepindex[c] += dvi_adpcm_indextab3[code];
230 /* check for step table index overflow and underflow */
231 if (stepindex[c] > 88)
232 stepindex[c] = 88;
233 else if (stepindex[c] < 0)
234 stepindex[c] = 0;
235 /* calculate the difference */
236#ifdef STRICT_IMA
237 diff = 0;
238 if (code & 2)
239 diff += step;
240 step = step >> 1;
241 if (code & 1)
242 diff += step;
243 step = step >> 1;
244 diff += step;
245#else
246 diff = ((code + code + 1) * step) >> 3; /* faster */
247#endif
248 /* check the sign bit */
249 /* check for overflow and underflow errors */
250 if (code != codem) {
251 sample[c] -= diff;
252 if (sample[c] < -32768)
253 sample[c] = -32768;
254 }
255 else {
256 sample[c] += diff;
257 if (sample[c] > 32767)
258 sample[c] = 32767;
259 }
260 /* output the new sample */
261 outbuf[nsamples] = sample[c] << 13;
262 nsamples++;
263 }
264 }
265 }
266 }
267
268 if (nsamples > *outbufcount) {
269 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n");
270 return CODEC_ERROR;
271 }
272 *outbufcount = nsamples;
273 if (inbufsize != 0) {
274 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", (int)inbufsize);
275 }
276 return CODEC_OK;
277}
278
279static int decode(const uint8_t *inbuf, size_t inbufsize,
280 int32_t *outbuf, int *outbufsize)
281{
282 unsigned int i;
283 unsigned int nblocks = fmt->chunksize / fmt->blockalign;
284
285 (void)inbufsize;
286
287 for (i = 0; i < nblocks; i++)
288 {
289 size_t decodedsize = fmt->samplesperblock * fmt->channels;
290 if (decode_dvi_adpcm(inbuf + i * fmt->blockalign, fmt->blockalign,
291 outbuf + i * fmt->samplesperblock * fmt->channels,
292 &decodedsize) != CODEC_OK) {
293 return CODEC_ERROR;
294 }
295 }
296 *outbufsize = nblocks * fmt->samplesperblock;
297 return CODEC_OK;
298}
299
300static const struct pcm_codec codec = {
301 set_format,
302 get_seek_pos,
303 decode,
304 };
305
306const struct pcm_codec *get_dvi_adpcm_codec(void)
307{
308 return &codec;
309}
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c
new file mode 100644
index 0000000000..1f235943ad
--- /dev/null
+++ b/apps/codecs/libpcm/itut_g711.c
@@ -0,0 +1,203 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
12 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "codeclib.h"
23#include "pcm_common.h"
24
25/*
26 * ITU-T G.711 A-law mu-law
27 */
28
29static const int16_t alaw2linear16[256] ICONST_ATTR = {
30 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
31 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
32 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
33 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
34 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
35 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
36 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
37 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
38 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
39 -13568, -344, -328, -376, -360, -280, -264,
40 -312, -296, -472, -456, -504, -488, -408,
41 -392, -440, -424, -88, -72, -120, -104,
42 -24, -8, -56, -40, -216, -200, -248,
43 -232, -152, -136, -184, -168, -1376, -1312,
44 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
45 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
46 -688, -656, -752, -720, -560, -528, -624,
47 -592, -944, -912, -1008, -976, -816, -784,
48 -880, -848, 5504, 5248, 6016, 5760, 4480,
49 4224, 4992, 4736, 7552, 7296, 8064, 7808,
50 6528, 6272, 7040, 6784, 2752, 2624, 3008,
51 2880, 2240, 2112, 2496, 2368, 3776, 3648,
52 4032, 3904, 3264, 3136, 3520, 3392, 22016,
53 20992, 24064, 23040, 17920, 16896, 19968, 18944,
54 30208, 29184, 32256, 31232, 26112, 25088, 28160,
55 27136, 11008, 10496, 12032, 11520, 8960, 8448,
56 9984, 9472, 15104, 14592, 16128, 15616, 13056,
57 12544, 14080, 13568, 344, 328, 376, 360,
58 280, 264, 312, 296, 472, 456, 504,
59 488, 408, 392, 440, 424, 88, 72,
60 120, 104, 24, 8, 56, 40, 216,
61 200, 248, 232, 152, 136, 184, 168,
62 1376, 1312, 1504, 1440, 1120, 1056, 1248,
63 1184, 1888, 1824, 2016, 1952, 1632, 1568,
64 1760, 1696, 688, 656, 752, 720, 560,
65 528, 624, 592, 944, 912, 1008, 976,
66 816, 784, 880, 848
67};
68
69static const int16_t ulaw2linear16[256] ICONST_ATTR = {
70 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
71 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
72 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
73 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
74 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
75 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
76 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
77 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
78 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
79 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
80 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
81 -1052, -988, -924, -876, -844, -812, -780,
82 -748, -716, -684, -652, -620, -588, -556,
83 -524, -492, -460, -428, -396, -372, -356,
84 -340, -324, -308, -292, -276, -260, -244,
85 -228, -212, -196, -180, -164, -148, -132,
86 -120, -112, -104, -96, -88, -80, -72,
87 -64, -56, -48, -40, -32, -24, -16,
88 -8, 0, 32124, 31100, 30076, 29052, 28028,
89 27004, 25980, 24956, 23932, 22908, 21884, 20860,
90 19836, 18812, 17788, 16764, 15996, 15484, 14972,
91 14460, 13948, 13436, 12924, 12412, 11900, 11388,
92 10876, 10364, 9852, 9340, 8828, 8316, 7932,
93 7676, 7420, 7164, 6908, 6652, 6396, 6140,
94 5884, 5628, 5372, 5116, 4860, 4604, 4348,
95 4092, 3900, 3772, 3644, 3516, 3388, 3260,
96 3132, 3004, 2876, 2748, 2620, 2492, 2364,
97 2236, 2108, 1980, 1884, 1820, 1756, 1692,
98 1628, 1564, 1500, 1436, 1372, 1308, 1244,
99 1180, 1116, 1052, 988, 924, 876, 844,
100 812, 780, 748, 716, 684, 652, 620,
101 588, 556, 524, 492, 460, 428, 396,
102 372, 356, 340, 324, 308, 292, 276,
103 260, 244, 228, 212, 196, 180, 164,
104 148, 132, 120, 112, 104, 96, 88,
105 80, 72, 64, 56, 48, 40, 32,
106 24, 16, 8, 0
107};
108
109static struct pcm_format *fmt;
110
111static bool set_format(struct pcm_format *format, const unsigned char *fmtpos)
112{
113 fmt = format;
114
115 (void)fmtpos;
116
117 if (fmt->bitspersample != 8)
118 {
119 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n");
120 return false;
121 }
122
123 if (fmt->totalsamples == 0)
124 {
125 fmt->bytespersample = fmt->channels;
126 fmt->totalsamples = fmt->numbytes/fmt->bytespersample;
127 }
128
129 /* chunksize is computed so that one chunk is about 1/50s.
130 * this make 4096 for 44.1kHz 16bits stereo.
131 * It also has to be a multiple of blockalign */
132 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
133
134 /* check that the output buffer is big enough (convert to samplespersec,
135 then round to the blockalign multiple below) */
136 if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3)
137 /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE)
138 fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec
139 /((uint64_t)ci->id3->frequency * fmt->channels * 2
140 * fmt->blockalign)) * fmt->blockalign;
141
142 return true;
143}
144
145static uint32_t get_seek_pos(long seek_time)
146{
147 uint32_t newpos;
148
149 /* use avgbytespersec to round to the closest blockalign multiple,
150 add firstblockposn. 64-bit casts to avoid overflows. */
151 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1))
152 / (1000LL*fmt->blockalign))*fmt->blockalign;
153 return newpos;
154}
155
156static int decode_alaw(const uint8_t *inbuf, size_t inbufsize,
157 int32_t *outbuf, int *outbufsize)
158{
159 uint32_t i;
160
161 for (i = 0; i < inbufsize; i++)
162 outbuf[i] = alaw2linear16[inbuf[i]] << 13;
163
164 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
165
166 return CODEC_OK;
167}
168
169static int decode_mulaw(const uint8_t *inbuf, size_t inbufsize,
170 int32_t *outbuf, int *outbufsize)
171{
172 uint32_t i;
173
174 for (i = 0; i < inbufsize; i++)
175 outbuf[i] = ulaw2linear16[inbuf[i]] << 13;
176
177 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
178
179 return CODEC_OK;
180}
181
182static const struct pcm_codec alaw_codec = {
183 set_format,
184 get_seek_pos,
185 decode_alaw,
186 };
187
188static const struct pcm_codec mulaw_codec = {
189 set_format,
190 get_seek_pos,
191 decode_mulaw,
192 };
193
194const struct pcm_codec *get_itut_g711_alaw_codec(void)
195{
196 return &alaw_codec;
197}
198
199const struct pcm_codec *get_itut_g711_mulaw_codec(void)
200{
201 return &mulaw_codec;
202}
203
diff --git a/apps/codecs/libpcm/libpcm.make b/apps/codecs/libpcm/libpcm.make
new file mode 100644
index 0000000000..ce7b6b5083
--- /dev/null
+++ b/apps/codecs/libpcm/libpcm.make
@@ -0,0 +1,25 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10# libpcm
11PCMSLIB := $(CODECDIR)/libpcm.a
12PCMSLIB_SRC := $(call preprocess, $(APPSDIR)/codecs/libpcm/SOURCES)
13PCMSLIB_OBJ := $(call c2obj, $(PCMSLIB_SRC))
14OTHER_SRC += $(PCMSLIB_SRC)
15
16$(PCMSLIB): $(PCMSLIB_OBJ)
17 $(SILENT)$(shell rm -f $@)
18 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
19
20PCMSFLAGS = $(filter-out -O%,$(CODECFLAGS))
21PCMSFLAGS += -O1
22
23$(CODECDIR)/libpcm/%.o: $(ROOTDIR)/apps/codecs/libpcm/%.c
24 $(SILENT)mkdir -p $(dir $@)
25 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(PCMSFLAGS) -c $< -o $@
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c
new file mode 100644
index 0000000000..2c766bd741
--- /dev/null
+++ b/apps/codecs/libpcm/linear_pcm.c
@@ -0,0 +1,163 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
12 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "codeclib.h"
23#include "pcm_common.h"
24
25/*
26 * Linear PCM
27 */
28
29static struct pcm_format *fmt;
30
31static bool set_format(struct pcm_format *format, const unsigned char *fmtpos)
32{
33 fmt = format;
34
35 (void)fmtpos;
36
37 if (fmt->bitspersample > 32)
38 {
39 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
40 "is unsupported\n");
41 return false;
42 }
43
44 if (fmt->totalsamples == 0)
45 {
46 fmt->bytespersample = (((fmt->bitspersample - 1)/8 + 1)*fmt->channels);
47 fmt->totalsamples = fmt->numbytes/fmt->bytespersample;
48 }
49
50 /* chunksize is computed so that one chunk is about 1/50s.
51 * this make 4096 for 44.1kHz 16bits stereo.
52 * It also has to be a multiple of blockalign */
53 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
54
55 return true;
56}
57
58static uint32_t get_seek_pos(long seek_time)
59{
60 uint32_t newpos;
61
62 /* use avgbytespersec to round to the closest blockalign multiple,
63 add firstblockposn. 64-bit casts to avoid overflows. */
64 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1))
65 / (1000LL*fmt->blockalign))*fmt->blockalign;
66 return newpos;
67}
68
69static int decode(const uint8_t *inbuf, size_t inbufsize,
70 int32_t *outbuf, int *outbufsize)
71{
72 uint32_t i;
73
74 if (fmt->bitspersample > 24)
75 {
76 for (i = 0; i < inbufsize; i += 4)
77 {
78 if (fmt->is_little_endian)
79 {
80 if (fmt->is_signed)
81 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SE(inbuf[i+3])<<21);
82 else
83 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SFT(inbuf[i+3])<<21);
84 }
85 else
86 {
87 if (fmt->is_signed)
88 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
89 else
90 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
91 }
92 }
93 *outbufsize = inbufsize >> 2;
94 }
95 else if (fmt->bitspersample > 16)
96 {
97 for (i = 0; i < inbufsize; i += 3)
98 {
99 if (fmt->is_little_endian)
100 {
101 if (fmt->is_signed)
102 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i+2])<<21);
103 else
104 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i+2])<<21);
105 }
106 else
107 {
108 if (fmt->is_signed)
109 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
110 else
111 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
112 }
113 }
114 *outbufsize = inbufsize/3;
115 }
116 else if (fmt->bitspersample > 8)
117 {
118 for (i = 0; i < inbufsize; i += 2)
119 {
120 if (fmt->is_little_endian)
121 {
122 if (fmt->is_signed)
123 outbuf[i/2] = (inbuf[i]<<13)|(SE(inbuf[i+1])<<21);
124 else
125 outbuf[i/2] = (inbuf[i]<<13)|(SFT(inbuf[i+1])<<21);
126 }
127 else
128 {
129 if (fmt->is_signed)
130 outbuf[i/2] = (inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
131 else
132 outbuf[i/2] = (inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
133 }
134 }
135 *outbufsize = inbufsize >> 1;
136 }
137 else
138 {
139 for (i = 0; i < inbufsize; i++) {
140 if (fmt->is_signed)
141 outbuf[i] = SE(inbuf[i])<<21;
142 else
143 outbuf[i] = SFT(inbuf[i])<<21;
144 }
145 *outbufsize = inbufsize;
146 }
147
148 if (fmt->channels == 2)
149 *outbufsize >>= 1;
150
151 return CODEC_OK;
152}
153
154static const struct pcm_codec codec = {
155 set_format,
156 get_seek_pos,
157 decode,
158 };
159
160const struct pcm_codec *get_linear_pcm_codec(void)
161{
162 return &codec;
163}
diff --git a/apps/codecs/libpcm/pcm_common.h b/apps/codecs/libpcm/pcm_common.h
new file mode 100644
index 0000000000..757d0ad5d9
--- /dev/null
+++ b/apps/codecs/libpcm/pcm_common.h
@@ -0,0 +1,120 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CODEC_LIBPCMS_PCM_COMMON_H
22#define CODEC_LIBPCMS_PCM_COMMON_H
23
24#include <sys/types.h>
25#include <stdbool.h>
26#include <inttypes.h>
27
28/*
29 * PCM_CHUNK_SIZE has the size only of storing the sample at 1/50 seconds.
30 * But it might not be 1/50 seconds according to the format.
31 * Please confirm the source file of each format.
32 */
33#define PCM_CHUNK_SIZE (4096*2)
34
35/* Macro that sign extends an unsigned byte */
36#define SE(x) ((int32_t)((int8_t)(x)))
37
38/* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */
39#define SFT(x) ((int32_t)x-0x80)
40
41struct pcm_format {
42 /*
43 * RIFF: wFormatTag (in 'fmt ' chunk)
44 * AIFF: compressionType (in 'COMM' chunk)
45 */
46 uint32_t formattag;
47
48 /*
49 * RIFF: wChannels (in 'fmt ' chunk)
50 * AIFF: numChannels (in 'COMM' chunk)
51 */
52 uint16_t channels;
53
54 /*
55 * RIFF: dwSamplesPerSec (in 'fmt ' chunk)
56 * AIFF: sampleRate (in 'COMM' chunk)
57 */
58 uint32_t samplespersec;
59
60 /* RIFF: dwAvgBytesPerSec (in 'fmt ' chunk) */
61 uint32_t avgbytespersec;
62
63 /*
64 * RIFF: wBlockAlign (in 'fmt ' chunk)
65 * AIFF: blockSize (in 'SSND' chunk)
66 */
67 uint16_t blockalign;
68
69 /*
70 * RIFF: wBitsPerSample (in 'fmt ' chunk)
71 * AIFF: sampleSize (in 'COMM' chunk)
72 */
73 uint16_t bitspersample;
74
75 /* RIFF: wSize (in 'fmt ' chunk) */
76 uint16_t size;
77
78 /* RIFF: dSamplesPerBlock (in 'fmt ' chunk) */
79 uint16_t samplesperblock;
80
81 /* RIFF: wTotalSamples (in 'fact' chunk) */
82 uint16_t totalsamples;
83
84 /* the following values are not RIFF/AIFF chunk values */
85
86 /* bytes per sample */
87 int bytespersample;
88
89 /* chunk size */
90 long chunksize;
91
92 /* data size */
93 uint32_t numbytes;
94
95 /*
96 * data endian
97 * true: little endian, false: big endian
98 */
99 bool is_little_endian;
100
101 /*
102 * data signess
103 * true: signed, false: unsigned
104 */
105 bool is_signed;
106};
107
108struct pcm_codec {
109 bool (*set_format)(struct pcm_format *format, const unsigned char *fmtpos);
110 uint32_t (*get_seek_pos)(long seek_time);
111 int (*decode)(const uint8_t *inbuf, size_t inbufsize,
112 int32_t *outbuf, int *outbufsize);
113};
114
115struct pcm_entry {
116 uint32_t format_tag;
117 const struct pcm_codec *(*get_codec)(void);
118};
119
120#endif
diff --git a/apps/codecs/libpcm/support_formats.h b/apps/codecs/libpcm/support_formats.h
new file mode 100644
index 0000000000..9a1f4f764d
--- /dev/null
+++ b/apps/codecs/libpcm/support_formats.h
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CODEC_LIBPCMS_SUPPORT_FORMATS_H
22#define CODEC_LIBPCMS_SUPPORT_FORMATS_H
23
24#include "pcm_common.h"
25
26/* Linear PCM */
27const struct pcm_codec *get_linear_pcm_codec(void);
28
29/* ITU-T G.711 A-law */
30const struct pcm_codec *get_itut_g711_alaw_codec(void);
31
32/* ITU-T G.711 mu-law */
33const struct pcm_codec *get_itut_g711_mulaw_codec(void);
34
35/* Intel DVI ADPCM */
36const struct pcm_codec *get_dvi_adpcm_codec(void);
37#endif
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index b3efbc10ce..1f210a99bf 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2005 Dave Chapman 10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
@@ -21,16 +22,11 @@
21 22
22#include "codeclib.h" 23#include "codeclib.h"
23#include "inttypes.h" 24#include "inttypes.h"
25#include "codecs/libpcm/support_formats.h"
24 26
25CODEC_HEADER 27CODEC_HEADER
26 28
27/* Macro that sign extends an unsigned byte */ 29/* WAVE (RIFF) codec:
28#define SE(x) ((int32_t)((int8_t)(x)))
29
30/* This codec support WAVE files with the following formats:
31 * - PCM, up to 32 bits, supporting 32 bits playback when useful.
32 * - ALAW and MULAW (16 bits compressed on 8 bits).
33 * - DVI_ADPCM (16 bits compressed on 3 or 4 bits).
34 * 30 *
35 * For a good documentation on WAVE files, see: 31 * For a good documentation on WAVE files, see:
36 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html 32 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html
@@ -40,198 +36,74 @@ CODEC_HEADER
40 * For sample WAV files, see: 36 * For sample WAV files, see:
41 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html 37 * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html
42 * 38 *
43 * The most common formats seem to be PCM, ADPCM, DVI_ADPCM, IEEE_FLOAT,
44 * ALAW and MULAW
45 */ 39 */
46 40
47/* These constants are from RFC 2361. */ 41static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR;
42
43/* This codec support WAVE files with the following formats: */
48enum 44enum
49{ 45{
50 WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ 46 WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */
51 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ 47 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
52 WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
53 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
54 WAVE_FORMAT_VSELP = 0x0004, /* Compaq Computer's VSELP */
55 WAVE_FORMAT_IBM_CVSD = 0x0005, /* IBM CVSD */
56 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ 48 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
57 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ 49 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
58 WAVE_FORMAT_OKI_ADPCM = 0x0010, /* OKI ADPCM */
59 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ 50 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
60 WAVE_FORMAT_MEDIASPACE_ADPCM = 0x0012, /* Videologic's MediaSpace ADPCM */
61 WAVE_FORMAT_SIERRA_ADPCM = 0x0013, /* Sierra ADPCM */
62 WAVE_FORMAT_G723_ADPCM = 0x0014, /* G.723 ADPCM */
63 WAVE_FORMAT_DIGISTD = 0x0015, /* DSP Solutions' DIGISTD */
64 WAVE_FORMAT_DIGIFIX = 0x0016, /* DSP Solutions' DIGIFIX */
65 WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
66 WAVE_FORMAT_MEDIAVISION_ADPCM = 0x0018, /* MediaVision ADPCM */
67 WAVE_FORMAT_CU_CODEC = 0x0019, /* HP CU */
68 WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
69 WAVE_FORMAT_SONARC = 0x0021, /* Speech Compression's Sonarc */
70 WAVE_FORMAT_DSP_TRUESPEECH = 0x0022, /* DSP Group's True Speech */
71 WAVE_FORMAT_ECHOSC1 = 0x0023, /* Echo Speech's EchoSC1 */
72 WAVE_FORMAT_AUDIOFILE_AF36 = 0x0024, /* Audiofile AF36 */
73 WAVE_FORMAT_APTX = 0x0025, /* APTX */
74 WAVE_FORMAT_DOLBY_AC2 = 0x0030, /* Dolby AC2 */
75 WAVE_FORMAT_GSM610 = 0x0031, /* GSM610 */
76 WAVE_FORMAT_MSNAUDIO = 0x0032, /* MSNAudio */
77 WAVE_FORMAT_ANTEX_ADPCME = 0x0033, /* Antex ADPCME */
78
79 WAVE_FORMAT_MPEG = 0x0050, /* MPEG */
80 WAVE_FORMAT_MPEGLAYER3 = 0x0055, /* MPEG layer 3 */
81 WAVE_FORMAT_LUCENT_G723 = 0x0059, /* Lucent G.723 */
82 WAVE_FORMAT_G726_ADPCM = 0x0064, /* G.726 ADPCM */
83 WAVE_FORMAT_G722_ADPCM = 0x0065, /* G.722 ADPCM */
84
85 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */ 51 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
86 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */ 52 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
87 IBM_FORMAT_ADPCM = 0x0103,
88
89 WAVE_FORMAT_CREATIVE_ADPCM = 0x0200,
90
91 WAVE_FORMAT_EXTENSIBLE = 0xFFFE 53 WAVE_FORMAT_EXTENSIBLE = 0xFFFE
92}; 54};
93 55
94/* Maximum number of bytes to process in one iteration */ 56const struct pcm_entry wave_codecs[] = {
95/* for 44.1kHz stereo 16bits, this represents 0.023s ~= 1/50s */ 57 { WAVE_FORMAT_UNKNOWN, 0 },
96#define WAV_CHUNK_SIZE (1024*2) 58 { WAVE_FORMAT_PCM, get_linear_pcm_codec },
97 59 { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec },
98static const int16_t alaw2linear16[256] ICONST_ATTR = { 60 { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec },
99 -5504, -5248, -6016, -5760, -4480, -4224, -4992, 61 { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec },
100 -4736, -7552, -7296, -8064, -7808, -6528, -6272, 62 { IBM_FORMAT_MULAW, get_itut_g711_mulaw_codec },
101 -7040, -6784, -2752, -2624, -3008, -2880, -2240, 63 { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec },
102 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
103 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
104 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
105 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
106 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
107 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
108 -13568, -344, -328, -376, -360, -280, -264,
109 -312, -296, -472, -456, -504, -488, -408,
110 -392, -440, -424, -88, -72, -120, -104,
111 -24, -8, -56, -40, -216, -200, -248,
112 -232, -152, -136, -184, -168, -1376, -1312,
113 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
114 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
115 -688, -656, -752, -720, -560, -528, -624,
116 -592, -944, -912, -1008, -976, -816, -784,
117 -880, -848, 5504, 5248, 6016, 5760, 4480,
118 4224, 4992, 4736, 7552, 7296, 8064, 7808,
119 6528, 6272, 7040, 6784, 2752, 2624, 3008,
120 2880, 2240, 2112, 2496, 2368, 3776, 3648,
121 4032, 3904, 3264, 3136, 3520, 3392, 22016,
122 20992, 24064, 23040, 17920, 16896, 19968, 18944,
123 30208, 29184, 32256, 31232, 26112, 25088, 28160,
124 27136, 11008, 10496, 12032, 11520, 8960, 8448,
125 9984, 9472, 15104, 14592, 16128, 15616, 13056,
126 12544, 14080, 13568, 344, 328, 376, 360,
127 280, 264, 312, 296, 472, 456, 504,
128 488, 408, 392, 440, 424, 88, 72,
129 120, 104, 24, 8, 56, 40, 216,
130 200, 248, 232, 152, 136, 184, 168,
131 1376, 1312, 1504, 1440, 1120, 1056, 1248,
132 1184, 1888, 1824, 2016, 1952, 1632, 1568,
133 1760, 1696, 688, 656, 752, 720, 560,
134 528, 624, 592, 944, 912, 1008, 976,
135 816, 784, 880, 848
136}; 64};
137 65
138static const int16_t ulaw2linear16[256] ICONST_ATTR = { 66#define NUM_FORMATS 7
139 -32124, -31100, -30076, -29052, -28028, -27004, -25980, 67
140 -24956, -23932, -22908, -21884, -20860, -19836, -18812, 68static const struct pcm_codec *get_wave_codec(uint32_t formattag)
141 -17788, -16764, -15996, -15484, -14972, -14460, -13948, 69{
142 -13436, -12924, -12412, -11900, -11388, -10876, -10364, 70 int i;
143 -9852, -9340, -8828, -8316, -7932, -7676, -7420, 71
144 -7164, -6908, -6652, -6396, -6140, -5884, -5628, 72 for (i = 0; i < NUM_FORMATS; i++)
145 -5372, -5116, -4860, -4604, -4348, -4092, -3900, 73 {
146 -3772, -3644, -3516, -3388, -3260, -3132, -3004, 74 if (wave_codecs[i].format_tag == formattag)
147 -2876, -2748, -2620, -2492, -2364, -2236, -2108, 75 {
148 -1980, -1884, -1820, -1756, -1692, -1628, -1564, 76 if (wave_codecs[i].get_codec)
149 -1500, -1436, -1372, -1308, -1244, -1180, -1116, 77 return wave_codecs[i].get_codec();
150 -1052, -988, -924, -876, -844, -812, -780, 78 return 0;
151 -748, -716, -684, -652, -620, -588, -556, 79 }
152 -524, -492, -460, -428, -396, -372, -356, 80 }
153 -340, -324, -308, -292, -276, -260, -244, 81 return 0;
154 -228, -212, -196, -180, -164, -148, -132, 82}
155 -120, -112, -104, -96, -88, -80, -72,
156 -64, -56, -48, -40, -32, -24, -16,
157 -8, 0, 32124, 31100, 30076, 29052, 28028,
158 27004, 25980, 24956, 23932, 22908, 21884, 20860,
159 19836, 18812, 17788, 16764, 15996, 15484, 14972,
160 14460, 13948, 13436, 12924, 12412, 11900, 11388,
161 10876, 10364, 9852, 9340, 8828, 8316, 7932,
162 7676, 7420, 7164, 6908, 6652, 6396, 6140,
163 5884, 5628, 5372, 5116, 4860, 4604, 4348,
164 4092, 3900, 3772, 3644, 3516, 3388, 3260,
165 3132, 3004, 2876, 2748, 2620, 2492, 2364,
166 2236, 2108, 1980, 1884, 1820, 1756, 1692,
167 1628, 1564, 1500, 1436, 1372, 1308, 1244,
168 1180, 1116, 1052, 988, 924, 876, 844,
169 812, 780, 748, 716, 684, 652, 620,
170 588, 556, 524, 492, 460, 428, 396,
171 372, 356, 340, 324, 308, 292, 276,
172 260, 244, 228, 212, 196, 180, 164,
173 148, 132, 120, 112, 104, 96, 88,
174 80, 72, 64, 56, 48, 40, 32,
175 24, 16, 8, 0
176};
177 83
178static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = {
179 7, 8, 9, 10, 11, 12, 13, 14,
180 16, 17, 19, 21, 23, 25, 28, 31,
181 34, 37, 41, 45, 50, 55, 60, 66,
182 73, 80, 88, 97, 107, 118, 130, 143,
183 157, 173, 190, 209, 230, 253, 279, 307,
184 337, 371, 408, 449, 494, 544, 598, 658,
185 724, 796, 876, 963, 1060, 1166, 1282, 1411,
186 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
187 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
188 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
189 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
190 32767 };
191
192static const int dvi_adpcm_indextab4[8] ICONST_ATTR = {
193 -1, -1, -1, -1, 2, 4, 6, 8 };
194
195static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 };
196
197static int32_t samples[WAV_CHUNK_SIZE] IBSS_ATTR;
198
199static enum codec_status
200decode_dvi_adpcm(struct codec_api *ci,
201 const uint8_t *buf,
202 int n,
203 uint16_t channels, uint16_t bitspersample,
204 int32_t *pcmout,
205 size_t *pcmoutsize);
206 84
207/* this is the codec entry point */ 85/* this is the codec entry point */
208enum codec_status codec_main(void) 86enum codec_status codec_main(void)
209{ 87{
210 uint32_t numbytes, bytesdone; 88 int status = CODEC_OK;
211 uint32_t totalsamples = 0; 89 struct pcm_format format;
212 uint16_t channels = 0; 90 uint32_t bytesdone, decodedbytes;
213 uint16_t samplesperblock = 0;
214 int bytespersample = 0;
215 uint16_t bitspersample;
216 uint32_t i; 91 uint32_t i;
217 size_t n; 92 size_t n;
218 int bufcount; 93 int bufcount;
219 int endofstream; 94 int endofstream;
220 unsigned char *buf; 95 unsigned char *buf;
221 uint8_t *wavbuf; 96 uint8_t *wavbuf;
222 long chunksize;
223 uint16_t formattag = 0;
224 uint16_t blockalign = 0;
225 uint32_t avgbytespersec = 0;
226 off_t firstblockposn; /* position of the first block in file */ 97 off_t firstblockposn; /* position of the first block in file */
227 98 const struct pcm_codec *codec;
228 99
229 /* Generic codec initialisation */ 100 /* Generic codec initialisation */
230 ci->configure(DSP_SET_SAMPLE_DEPTH, 28); 101 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
231 102
232next_track: 103next_track:
233 if (codec_init()) { 104 if (codec_init()) {
234 i = CODEC_ERROR; 105 DEBUGF("codec_init() error\n");
106 status = CODEC_ERROR;
235 goto exit; 107 goto exit;
236 } 108 }
237 109
@@ -246,11 +118,12 @@ next_track:
246 /* get RIFF chunk header */ 118 /* get RIFF chunk header */
247 buf = ci->request_buffer(&n, 12); 119 buf = ci->request_buffer(&n, 12);
248 if (n < 12) { 120 if (n < 12) {
249 i = CODEC_ERROR; 121 DEBUGF("request_buffer error\n");
122 status = CODEC_ERROR;
250 goto done; 123 goto done;
251 } 124 }
252 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) { 125 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
253 i = CODEC_ERROR; 126 status = CODEC_ERROR;
254 goto done; 127 goto done;
255 } 128 }
256 129
@@ -258,17 +131,21 @@ next_track:
258 ci->advance_buffer(12); 131 ci->advance_buffer(12);
259 132
260 firstblockposn = 12; 133 firstblockposn = 12;
261 bitspersample = 0; 134 ci->memset(&format, 0, sizeof(struct pcm_format));
262 numbytes = 0; 135 format.is_signed = true;
263 totalsamples = 0; 136 format.is_little_endian = true;
137
138 decodedbytes = 0;
139 codec = 0;
264 140
265 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */ 141 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */
266 while (true) { 142 while (true) {
267 /* get WAVE chunk header */ 143 /* get WAVE chunk header */
268 buf = ci->request_buffer(&n, 1024); 144 buf = ci->request_buffer(&n, 1024);
269 if (n < 8) { 145 if (n < 8) {
146 DEBUGF("data chunk request_buffer error\n");
270 /* no more chunks, 'data' chunk must not have been found */ 147 /* no more chunks, 'data' chunk must not have been found */
271 i = CODEC_ERROR; 148 status = CODEC_ERROR;
272 goto done; 149 goto done;
273 } 150 }
274 151
@@ -278,54 +155,70 @@ next_track:
278 if (i < 16) { 155 if (i < 16) {
279 DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n", 156 DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n",
280 (unsigned long)i); 157 (unsigned long)i);
281 i = CODEC_ERROR; 158 status = CODEC_ERROR;
282 goto done; 159 goto done;
283 } 160 }
284 /* wFormatTag */ 161 /* wFormatTag */
285 formattag=buf[8]|(buf[9]<<8); 162 format.formattag=buf[8]|(buf[9]<<8);
286 /* wChannels */ 163 /* wChannels */
287 channels=buf[10]|(buf[11]<<8); 164 format.channels=buf[10]|(buf[11]<<8);
288 /* skipping dwSamplesPerSec */ 165 /* skipping dwSamplesPerSec */
289 /* dwAvgBytesPerSec */ 166 /* dwAvgBytesPerSec */
290 avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24); 167 format.avgbytespersec = buf[16]|(buf[17]<<8)|(buf[18]<<16)|(buf[19]<<24);
291 /* wBlockAlign */ 168 /* wBlockAlign */
292 blockalign=buf[20]|(buf[21]<<8); 169 format.blockalign=buf[20]|(buf[21]<<8);
293 /* wBitsPerSample */ 170 /* wBitsPerSample */
294 bitspersample=buf[22]|(buf[23]<<8); 171 format.bitspersample=buf[22]|(buf[23]<<8);
295 if (formattag != WAVE_FORMAT_PCM) { 172 if (format.formattag != WAVE_FORMAT_PCM) {
296 uint16_t size;
297 if (i < 18) { 173 if (i < 18) {
298 /* this is not a fatal error with some formats, 174 /* this is not a fatal error with some formats,
299 * we'll see later if we can't decode it */ 175 * we'll see later if we can't decode it */
300 DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) " 176 DEBUGF("CODEC_WARNING: non-PCM WAVE (formattag=0x%x) "
301 "doesn't have ext. fmt descr (chunksize=%ld<18).\n", 177 "doesn't have ext. fmt descr (chunksize=%ld<18).\n",
302 formattag, (long)i); 178 format.formattag, (long)i);
303 } 179 }
304 size = buf[24]|(buf[25]<<8); 180 else
305 if (formattag == WAVE_FORMAT_DVI_ADPCM) { 181 {
306 if (size < 2) { 182 format.size = buf[24]|(buf[25]<<8);
307 DEBUGF("CODEC_ERROR: dvi_adpcm is missing " 183 if (format.formattag != WAVE_FORMAT_EXTENSIBLE)
308 "SamplesPerBlock value\n"); 184 format.samplesperblock = buf[26]|(buf[27]<<8);
309 i = CODEC_ERROR; 185 else {
310 goto done; 186 if (format.size < 22) {
311 } 187 DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is "
312 samplesperblock = buf[26]|(buf[27]<<8); 188 "missing extension\n");
313 } else if (formattag == WAVE_FORMAT_EXTENSIBLE) { 189 status = CODEC_ERROR;
314 if (size < 22) { 190 goto done;
315 DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is " 191 }
316 "missing extension\n"); 192 /* wValidBitsPerSample */
317 i = CODEC_ERROR; 193 format.bitspersample = buf[26]|(buf[27]<<8);
318 goto done; 194 /* skipping dwChannelMask (4bytes) */
195 /* SubFormat (only get the first two bytes) */
196 format.formattag = buf[32]|(buf[33]<<8);
319 } 197 }
320 /* wValidBitsPerSample */
321 bitspersample = buf[26]|(buf[27]<<8);
322 /* skipping dwChannelMask (4bytes) */
323 /* SubFormat (only get the first two bytes) */
324 formattag = buf[32]|(buf[33]<<8);
325 } 198 }
326 } 199 }
200
201 /* get codec */
202 codec = get_wave_codec(format.formattag);
203 if (!codec)
204 {
205 DEBUGF("CODEC_ERROR: unsupport wave format %x\n", format.formattag);
206 status = CODEC_ERROR;
207 goto done;
208 }
209
210 /* riff 8bit linear pcm is unsigned */
211 if (format.formattag == WAVE_FORMAT_PCM && format.bitspersample == 8)
212 format.is_signed = false;
213
214 /* set format, parse codec specific tag, check format, and calculate chunk size */
215 if (!codec->set_format(&format, buf))
216 {
217 status = CODEC_ERROR;
218 goto done;
219 }
327 } else if (memcmp(buf, "data", 4) == 0) { 220 } else if (memcmp(buf, "data", 4) == 0) {
328 numbytes = i; 221 format.numbytes = i;
329 /* advance to start of data */ 222 /* advance to start of data */
330 ci->advance_buffer(8); 223 ci->advance_buffer(8);
331 firstblockposn += 8; 224 firstblockposn += 8;
@@ -333,7 +226,8 @@ next_track:
333 } else if (memcmp(buf, "fact", 4) == 0) { 226 } else if (memcmp(buf, "fact", 4) == 0) {
334 /* dwSampleLength */ 227 /* dwSampleLength */
335 if (i >= 4) 228 if (i >= 4)
336 totalsamples = (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24)); 229 format.totalsamples =
230 (buf[8]|(buf[9]<<8)|(buf[10]<<16)|(buf[11]<<24));
337 } else { 231 } else {
338 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", 232 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n",
339 buf[0], buf[1], buf[2], buf[3], (unsigned long)i); 233 buf[0], buf[1], buf[2], buf[3], (unsigned long)i);
@@ -346,71 +240,40 @@ next_track:
346 firstblockposn += i + 8; 240 firstblockposn += i + 8;
347 } 241 }
348 242
349 if (channels == 0) { 243 if (!codec)
350 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n"); 244 {
351 i = CODEC_ERROR; 245 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found\n");
246 status = CODEC_ERROR;
352 goto done; 247 goto done;
353 } 248 }
354 if (numbytes == 0) { 249
355 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); 250 /* common format check */
356 i = CODEC_ERROR; 251 if (format.channels == 0) {
357 goto done; 252 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
358 } 253 status = CODEC_ERROR;
359 if (formattag != WAVE_FORMAT_PCM && totalsamples == 0) {
360 /* This is non-fatal for some formats */
361 DEBUGF("CODEC_WARNING: non-PCM WAVE doesn't have a 'fact' chunk\n");
362 }
363 if (formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW ||
364 formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) {
365 if (bitspersample != 8) {
366 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n");
367 i = CODEC_ERROR;
368 goto done;
369 }
370 bytespersample = channels;
371 }
372 if (formattag == WAVE_FORMAT_DVI_ADPCM
373 && bitspersample != 4 && bitspersample != 3) {
374 DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n");
375 i = CODEC_ERROR;
376 goto done; 254 goto done;
377 } 255 }
378 if (formattag == WAVE_FORMAT_PCM && bitspersample > 32) { 256 if (format.numbytes == 0) {
379 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " 257 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
380 "is unsupported\n"); 258 status = CODEC_ERROR;
381 i = CODEC_ERROR;
382 goto done; 259 goto done;
383 } 260 }
384 261
385 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 262 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
386 if (channels == 2) { 263 if (format.channels == 2) {
387 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); 264 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
388 } else if (channels == 1) { 265 } else if (format.channels == 1) {
389 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); 266 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
390 } else { 267 } else {
391 DEBUGF("CODEC_ERROR: more than 2 channels\n"); 268 DEBUGF("CODEC_ERROR: more than 2 channels\n");
392 i = CODEC_ERROR; 269 status = CODEC_ERROR;
393 goto done; 270 goto done;
394 } 271 }
395 272
396 if (totalsamples == 0) {
397 if (formattag == WAVE_FORMAT_PCM ||
398 formattag == WAVE_FORMAT_ALAW || formattag == WAVE_FORMAT_MULAW ||
399 formattag == IBM_FORMAT_ALAW || formattag == IBM_FORMAT_MULAW) {
400 /* for PCM and derived formats only */
401 bytespersample = (((bitspersample - 1)/8 + 1)*channels);
402 totalsamples = numbytes/bytespersample;
403 } else {
404 DEBUGF("CODEC_ERROR: cannot compute totalsamples\n");
405 i = CODEC_ERROR;
406 goto done;
407 }
408 }
409
410 /* make sure we're at the correct offset */ 273 /* make sure we're at the correct offset */
411 if (bytesdone > (uint32_t) firstblockposn) { 274 if (bytesdone > (uint32_t) firstblockposn) {
412 /* Round down to previous block */ 275 /* Round down to previous block */
413 uint32_t offset = bytesdone - bytesdone % blockalign; 276 uint32_t offset = bytesdone - bytesdone % format.blockalign;
414 277
415 ci->advance_buffer(offset-firstblockposn); 278 ci->advance_buffer(offset-firstblockposn);
416 bytesdone = offset - firstblockposn; 279 bytesdone = offset - firstblockposn;
@@ -421,18 +284,6 @@ next_track:
421 284
422 /* The main decoder loop */ 285 /* The main decoder loop */
423 endofstream = 0; 286 endofstream = 0;
424 /* chunksize is computed so that one chunk is about 1/50s.
425 * this make 4096 for 44.1kHz 16bits stereo.
426 * It also has to be a multiple of blockalign */
427 chunksize = (1 + avgbytespersec / (50*blockalign))*blockalign;
428 /* check that the output buffer is big enough (convert to samplespersec,
429 then round to the blockalign multiple below) */
430 if (((uint64_t)chunksize*ci->id3->frequency*channels*2)
431 /(uint64_t)avgbytespersec >= WAV_CHUNK_SIZE) {
432 chunksize = ((uint64_t)WAV_CHUNK_SIZE*avgbytespersec
433 /((uint64_t)ci->id3->frequency*channels*2
434 *blockalign))*blockalign;
435 }
436 287
437 while (!endofstream) { 288 while (!endofstream) {
438 ci->yield(); 289 ci->yield();
@@ -441,286 +292,47 @@ next_track:
441 } 292 }
442 293
443 if (ci->seek_time) { 294 if (ci->seek_time) {
444 uint32_t newpos; 295 uint32_t newpos = codec->get_seek_pos(ci->seek_time);
445 296
446 /* use avgbytespersec to round to the closest blockalign multiple, 297 if (newpos > format.numbytes)
447 add firstblockposn. 64-bit casts to avoid overflows. */
448 newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1))
449 / (1000LL*blockalign))*blockalign;
450 if (newpos > numbytes)
451 break; 298 break;
452 if (ci->seek_buffer(firstblockposn + newpos)) 299 if (ci->seek_buffer(firstblockposn + newpos))
300 {
453 bytesdone = newpos; 301 bytesdone = newpos;
302 }
454 ci->seek_complete(); 303 ci->seek_complete();
455 } 304 }
456 wavbuf = (uint8_t *)ci->request_buffer(&n, chunksize);
457 305
306 wavbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize);
458 if (n == 0) 307 if (n == 0)
459 break; /* End of stream */ 308 break; /* End of stream */
460 309 if (bytesdone + n > format.numbytes) {
461 if (bytesdone + n > numbytes) { 310 n = format.numbytes - bytesdone;
462 n = numbytes - bytesdone;
463 endofstream = 1; 311 endofstream = 1;
464 } 312 }
465 313
466 if (formattag == WAVE_FORMAT_PCM) { 314 status = codec->decode(wavbuf, n, samples, &bufcount);
467 if (bitspersample > 24) { 315 if (status == CODEC_ERROR)
468 for (i = 0; i < n; i += 4) { 316 {
469 samples[i/4] = (wavbuf[i] >> 3)| 317 DEBUGF("codec error\n");
470 (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)|
471 (SE(wavbuf[i + 3])<<21);
472 }
473 bufcount = n >> 2;
474 } else if (bitspersample > 16) {
475 for (i = 0; i < n; i += 3) {
476 samples[i/3] = (wavbuf[i]<<5)|
477 (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21);
478 }
479 bufcount = n/3;
480 } else if (bitspersample > 8) {
481 for (i = 0; i < n; i += 2) {
482 samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21);
483 }
484 bufcount = n >> 1;
485 } else {
486 for (i = 0; i < n; i++) {
487 samples[i] = (wavbuf[i] - 0x80)<<21;
488 }
489 bufcount = n;
490 }
491
492 if (channels == 2)
493 bufcount >>= 1;
494 } else if (formattag == WAVE_FORMAT_ALAW
495 || formattag == IBM_FORMAT_ALAW) {
496 for (i = 0; i < n; i++)
497 samples[i] = alaw2linear16[wavbuf[i]] << 13;
498
499 bufcount = (channels == 2) ? (n >> 1) : n;
500 } else if (formattag == WAVE_FORMAT_MULAW
501 || formattag == IBM_FORMAT_MULAW) {
502 for (i = 0; i < n; i++)
503 samples[i] = ulaw2linear16[wavbuf[i]] << 13;
504
505 bufcount = (channels == 2) ? (n >> 1) : n;
506 }
507 else if (formattag == WAVE_FORMAT_DVI_ADPCM) {
508 unsigned int nblocks = chunksize/blockalign;
509
510 for (i = 0; i < nblocks; i++) {
511 size_t decodedsize = samplesperblock*channels;
512 if (decode_dvi_adpcm(ci, wavbuf + i*blockalign,
513 blockalign, channels, bitspersample,
514 samples + i*samplesperblock*channels,
515 &decodedsize) != CODEC_OK) {
516 i = CODEC_ERROR;
517 goto done;
518 }
519 }
520 bufcount = nblocks*samplesperblock;
521 } else {
522 DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag);
523 i = CODEC_ERROR;
524 goto done; 318 goto done;
525 } 319 }
526 320
527 ci->pcmbuf_insert(samples, NULL, bufcount); 321 ci->pcmbuf_insert(samples, NULL, bufcount);
528
529 ci->advance_buffer(n); 322 ci->advance_buffer(n);
530 bytesdone += n; 323 bytesdone += n;
531 if (bytesdone >= numbytes) 324 decodedbytes += bufcount;
325
326 if (bytesdone >= format.numbytes)
532 endofstream = 1; 327 endofstream = 1;
533 ci->set_elapsed(bytesdone*1000LL/avgbytespersec); 328 ci->set_elapsed(decodedbytes*1000LL/ci->id3->frequency);
534 } 329 }
535 i = CODEC_OK; 330 status = CODEC_OK;
536 331
537done: 332done:
538 if (ci->request_next_track()) 333 if (ci->request_next_track())
539 goto next_track; 334 goto next_track;
540 335
541exit: 336exit:
542 return i; 337 return status;
543} 338}
544
545static enum codec_status
546decode_dvi_adpcm(struct codec_api *ci,
547 const uint8_t *buf,
548 int n,
549 uint16_t channels, uint16_t bitspersample,
550 int32_t *pcmout,
551 size_t *pcmoutsize)
552{
553 size_t nsamples = 0;
554 int sample[2];
555 int samplecode[32][2];
556 int i;
557 int stepindex[2];
558 int c;
559 int diff;
560 int step;
561 int codem;
562 int code;
563
564 (void)ci;
565 if (bitspersample != 4 && bitspersample != 3) {
566 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n");
567 return CODEC_ERROR;
568 }
569
570 /* decode block header */
571 for (c = 0; c < channels && n >= 4; c++) {
572 /* decode + push first sample */
573 sample[c] = (short)(buf[0]|(buf[1]<<8));/* need cast for sign-extend */
574 pcmout[c] = sample[c] << 13;
575 nsamples++;
576 stepindex[c] = buf[2];
577 /* check for step table index overflow */
578 if (stepindex[c] > 88) {
579 DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]);
580 return CODEC_ERROR;
581 }
582
583 buf += 4;
584 n -= 4;
585 }
586 if (bitspersample == 4) {
587 while (n>= channels*4 && (nsamples + 8*channels) <= *pcmoutsize) {
588 for (c = 0; c < channels; c++) {
589 samplecode[0][c] = buf[0]&0xf;
590 samplecode[1][c] = buf[0]>>4;
591 samplecode[2][c] = buf[1]&0xf;
592 samplecode[3][c] = buf[1]>>4;
593 samplecode[4][c] = buf[2]&0xf;
594 samplecode[5][c] = buf[2]>>4;
595 samplecode[6][c] = buf[3]&0xf;
596 samplecode[7][c] = buf[3]>>4;
597 buf += 4;
598 n -= 4;
599 }
600 for (i = 0; i < 8; i++) {
601 for (c = 0; c < channels; c++) {
602 step = dvi_adpcm_steptab[stepindex[c]];
603 codem = samplecode[i][c];
604 code = codem & 0x07;
605
606 /* adjust the step table index */
607 stepindex[c] += dvi_adpcm_indextab4[code];
608 /* check for step table index overflow and underflow */
609 if (stepindex[c] > 88)
610 stepindex[c] = 88;
611 else if (stepindex[c] < 0)
612 stepindex[c] = 0;
613 /* calculate the difference */
614#ifdef STRICT_IMA
615 diff = 0;
616 if (code & 4)
617 diff += step;
618 step = step >> 1;
619 if (code & 2)
620 diff += step;
621 step = step >> 1;
622 if (code & 1)
623 diff += step;
624 step = step >> 1;
625 diff += step;
626#else
627 diff = ((code + code + 1) * step) >> 3; /* faster */
628#endif
629 /* check the sign bit */
630 /* check for overflow and underflow errors */
631 if (code != codem) {
632 sample[c] -= diff;
633 if (sample[c] < -32768)
634 sample[c] = -32768;
635 } else {
636 sample[c] += diff;
637 if (sample[c] > 32767)
638 sample[c] = 32767;
639 }
640 /* output the new sample */
641 pcmout[nsamples] = sample[c] << 13;
642 nsamples++;
643 }
644 }
645 }
646 } else { /* bitspersample == 3 */
647 while (n >= channels*12 && (nsamples + 32*channels) <= *pcmoutsize) {
648 for (c = 0; c < channels; c++) {
649 uint16_t bitstream = 0;
650 int bitsread = 0;
651 for (i = 0; i < 32 && n > 0; i++) {
652 if (bitsread < 3) {
653 /* read 8 more bits */
654 bitstream |= buf[0]<<bitsread;
655 bitsread += 8;
656 n--;
657 buf++;
658 }
659 samplecode[i][c] = bitstream & 7;
660 bitstream = bitstream>>3;
661 bitsread -= 3;
662 }
663 if (bitsread != 0) {
664 /* 32*3 = 3 words, so we should end with bitsread==0 */
665 DEBUGF("decode_dvi_adpcm: error in implementation\n");
666 return CODEC_ERROR;
667 }
668 }
669
670 for (i = 0; i < 32; i++) {
671 for (c = 0; c < channels; c++) {
672 step = dvi_adpcm_steptab[stepindex[c]];
673 codem = samplecode[i][c];
674 code = codem & 0x03;
675
676 /* adjust the step table index */
677 stepindex[c] += dvi_adpcm_indextab3[code];
678 /* check for step table index overflow and underflow */
679 if (stepindex[c] > 88)
680 stepindex[c] = 88;
681 else if (stepindex[c] < 0)
682 stepindex[c] = 0;
683 /* calculate the difference */
684#ifdef STRICT_IMA
685 diff = 0;
686 if (code & 2)
687 diff += step;
688 step = step >> 1;
689 if (code & 1)
690 diff += step;
691 step = step >> 1;
692 diff += step;
693#else
694 diff = ((code + code + 1) * step) >> 3; /* faster */
695#endif
696 /* check the sign bit */
697 /* check for overflow and underflow errors */
698 if (code != codem) {
699 sample[c] -= diff;
700 if (sample[c] < -32768)
701 sample[c] = -32768;
702 }
703 else {
704 sample[c] += diff;
705 if (sample[c] > 32767)
706 sample[c] = 32767;
707 }
708 /* output the new sample */
709 pcmout[nsamples] = sample[c] << 13;
710 nsamples++;
711 }
712 }
713 }
714 }
715
716 if (nsamples > *pcmoutsize) {
717 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n");
718 return CODEC_ERROR;
719 }
720 *pcmoutsize = nsamples;
721 if (n != 0) {
722 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", n);
723 }
724 return CODEC_OK;
725}
726