Add missing #include in libpcm codecs
[kugel-rb.git] / apps / codecs / libpcm / swf_adpcm.c
blob9acab5cb4bb12dd1e7e9a6ed43c1d80f91e90559
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Yoshihisa Uchida
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "codeclib.h"
22 #include "pcm_common.h"
23 #include "ima_adpcm_common.h"
24 #include "support_formats.h"
27 * Adobe SWF ADPCM
29 * References
30 * [1] Adobe, SWF File Format Specification Version 10, 2008
31 * [2] Jack Jansen, adpcm.c in adpcm.zip
32 * [3] ffmpeg source code, libavcodec/adpcm.c
35 /* step index table when bitspersample is 3.
36 * (when bitspersample is 2, 4, 5, step index table uses the table
37 * which is defined ima_adpcm_common.c.)
39 static const int index_table[4] ICONST_ATTR = {
40 -1, -1, 2, 4,
43 static int validity_bits = 8;
44 static bool first_block = true;
45 static int blockbits = 0;
46 static int lastbytebits = 0;
47 static bool after_seek = false;
49 static struct pcm_format *fmt;
51 static bool set_format(struct pcm_format *format)
53 fmt = format;
55 if (fmt->bitspersample < 2 || fmt->bitspersample > 5)
57 DEBUGF("CODEC_ERROR: swf adpcm must be 2, 3, 4 or 5 bitspersample: %d\n",
58 fmt->bitspersample);
59 return false;
62 if (fmt->samplesperblock == 0)
63 fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22)
64 / fmt->bitspersample + 1;
66 blockbits = ((fmt->samplesperblock - 1) * fmt->bitspersample + 22) * fmt->channels;
69 * chunksize = about 93 [ms] data (frequency:44.1kHz, 4096 [sample/block])
70 * chunksize changes depending upon the position of block.
72 fmt->chunksize = (blockbits + 9) >> 3;
74 /* initialize for ima adpcm common functions */
75 if (fmt->bitspersample == 3)
76 init_ima_adpcm_decoder(fmt->bitspersample, index_table);
77 else
78 init_ima_adpcm_decoder(fmt->bitspersample, NULL);
80 return true;
83 static struct pcm_pos *get_seek_pos(long seek_time,
84 uint8_t *(*read_buffer)(size_t *realsize))
86 static struct pcm_pos newpos;
87 uint32_t chunkbits = blockbits;
88 uint32_t seekbits = (((uint64_t)seek_time * ci->id3->frequency)
89 / (1000LL * fmt->samplesperblock)) * blockbits + 2;
91 (void)read_buffer;
93 newpos.pos = seekbits >> 3;
94 newpos.samples = (((uint64_t)seek_time * ci->id3->frequency)
95 / (1000LL * fmt->samplesperblock))
96 * fmt->samplesperblock;
98 if (newpos.pos == 0)
100 first_block = true;
101 lastbytebits = 0;
103 else
105 first_block = false;
106 lastbytebits = seekbits & 0x07;
107 if (lastbytebits != 0)
108 chunkbits -= (8 - lastbytebits);
111 /* calculates next read bytes */
112 fmt->chunksize = (chunkbits >> 3) + (((chunkbits & 0x07) > 0)?1:0)
113 + ((lastbytebits > 0)?1:0);
115 after_seek = true;
116 return &newpos;
119 static uint8_t get_data(const uint8_t **buf, int bit)
121 uint8_t res = 0;
122 uint8_t mask = (1 << bit) - 1;
124 if (validity_bits >= bit)
126 validity_bits -= bit;
127 return (**buf >> validity_bits) & mask;
130 if (validity_bits > 0)
131 res = **buf << (bit - validity_bits);
133 validity_bits += 8 - bit;
134 res = (res | (*(++(*buf)) >> validity_bits)) & mask;
135 return res;
138 static int decode(const uint8_t *inbuf, size_t inbufsize,
139 int32_t *outbuf, int *outbufcount)
141 int ch;
142 int adpcm_code_size;
143 int count = fmt->samplesperblock;
144 int32_t init_pcmdata[2];
145 int8_t init_index[2];
146 static uint8_t lastbyte = 0;
148 (void)inbufsize;
150 validity_bits = 8;
152 /* read block header */
153 ch = fmt->channels - 1;
154 if (first_block)
156 adpcm_code_size = get_data(&inbuf, 2) + 2;
157 if (fmt->bitspersample != adpcm_code_size)
159 DEBUGF("CODEC_ERROR: swf adpcm different adpcm code size=%d != %d\n",
160 adpcm_code_size, fmt->bitspersample);
161 return CODEC_ERROR;
163 init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
165 lastbytebits = 0;
166 first_block = false;
168 else
170 if (after_seek && lastbytebits > 0)
172 lastbyte = *inbuf++;
173 after_seek = false;
175 if (lastbytebits > 0)
176 init_pcmdata[0] = ((lastbyte << (8 + lastbytebits)) |
177 (get_data(&inbuf, 8) << lastbytebits) |
178 get_data(&inbuf, lastbytebits)) & 65535;
179 else
180 init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
182 after_seek = false;
184 init_index[0] = get_data(&inbuf, 6);
185 if (init_pcmdata[0] > 32767)
186 init_pcmdata[0] -= 65536;
188 if (ch > 0)
190 init_pcmdata[1] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
191 init_index[1] = get_data(&inbuf, 6);
192 if (init_pcmdata[1] > 32767)
193 init_pcmdata[1] -= 65536;
196 *outbuf++ = init_pcmdata[0] << 13;
197 if (ch > 0)
198 *outbuf++ = init_pcmdata[1] << 13;
200 set_decode_parameters(fmt->channels, init_pcmdata, init_index);
202 /* read block data */
203 while (--count > 0)
205 *outbuf++ = create_pcmdata(0, get_data(&inbuf, fmt->bitspersample)) << 13;
206 if (ch > 0)
207 *outbuf++ = create_pcmdata(ch, get_data(&inbuf, fmt->bitspersample)) << 13;
210 *outbufcount = fmt->samplesperblock;
212 lastbyte = *inbuf;
213 lastbytebits = (8 - validity_bits) & 0x07;
215 /* calculates next read bytes */
216 fmt->chunksize = (blockbits - validity_bits + 7) >> 3;
218 return CODEC_OK;
221 static const struct pcm_codec codec = {
222 set_format,
223 get_seek_pos,
224 decode,
227 const struct pcm_codec *get_swf_adpcm_codec(void)
229 first_block = true;
230 lastbytebits = 0;
231 after_seek = false;
233 return &codec;