diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libpcm | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libpcm')
-rw-r--r-- | lib/rbcodec/codecs/libpcm/SOURCES | 11 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/adpcm_seek.c | 101 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/adpcm_seek.h | 39 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/dialogic_oki_adpcm.c | 183 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/dvi_adpcm.c | 308 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/ieee_float.c | 165 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/ima_adpcm_common.c | 171 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/ima_adpcm_common.h | 33 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/itut_g711.c | 204 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/libpcm.make | 18 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/linear_pcm.c | 294 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/ms_adpcm.c | 168 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/pcm_common.h | 190 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/qt_ima_adpcm.c | 138 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/support_formats.h | 55 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/swf_adpcm.c | 236 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libpcm/yamaha_adpcm.c | 250 |
17 files changed, 2564 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libpcm/SOURCES b/lib/rbcodec/codecs/libpcm/SOURCES new file mode 100644 index 0000000000..356c9cdbb7 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/SOURCES | |||
@@ -0,0 +1,11 @@ | |||
1 | linear_pcm.c | ||
2 | itut_g711.c | ||
3 | dvi_adpcm.c | ||
4 | ieee_float.c | ||
5 | adpcm_seek.c | ||
6 | dialogic_oki_adpcm.c | ||
7 | ms_adpcm.c | ||
8 | yamaha_adpcm.c | ||
9 | ima_adpcm_common.c | ||
10 | qt_ima_adpcm.c | ||
11 | swf_adpcm.c | ||
diff --git a/lib/rbcodec/codecs/libpcm/adpcm_seek.c b/lib/rbcodec/codecs/libpcm/adpcm_seek.c new file mode 100644 index 0000000000..ce49d5fcd3 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/adpcm_seek.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "adpcm_seek.h" | ||
22 | #include "codeclib.h" | ||
23 | |||
24 | /* | ||
25 | * The helper functions in order to seek for the adpcm codec | ||
26 | * which does not include the header each the data block. | ||
27 | */ | ||
28 | |||
29 | #define MAX_STORE_COUNT 1000 | ||
30 | |||
31 | static struct adpcm_data seek_table[MAX_STORE_COUNT]; | ||
32 | static int seek_count; | ||
33 | static int cur_count; | ||
34 | static int max_ratio; | ||
35 | static int cur_ratio; | ||
36 | |||
37 | void init_seek_table(uint32_t max_count) | ||
38 | { | ||
39 | int i = 0; | ||
40 | |||
41 | for ( ; i < MAX_STORE_COUNT; i++) | ||
42 | { | ||
43 | seek_table[i].is_valid = false; | ||
44 | } | ||
45 | seek_count = max_count / MAX_STORE_COUNT + 1; | ||
46 | max_ratio = max_count / seek_count + 1; | ||
47 | cur_count = 0; | ||
48 | cur_ratio = -1; | ||
49 | } | ||
50 | |||
51 | void add_adpcm_data(struct adpcm_data *data) | ||
52 | { | ||
53 | if (--cur_count <= 0) | ||
54 | { | ||
55 | cur_count = seek_count; | ||
56 | if (++cur_ratio >= max_ratio) | ||
57 | cur_ratio = max_ratio - 1; | ||
58 | |||
59 | if (!seek_table[cur_ratio].is_valid) | ||
60 | { | ||
61 | seek_table[cur_ratio].pcmdata[0] = data->pcmdata[0]; | ||
62 | seek_table[cur_ratio].pcmdata[1] = data->pcmdata[1]; | ||
63 | seek_table[cur_ratio].step[0] = data->step[0]; | ||
64 | seek_table[cur_ratio].step[1] = data->step[1]; | ||
65 | seek_table[cur_ratio].is_valid = true; | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | uint32_t seek(uint32_t count, struct adpcm_data *seek_data, | ||
71 | uint8_t *(*read_buffer)(size_t *realsize), | ||
72 | int (*decode)(const uint8_t *inbuf, size_t inbufsize)) | ||
73 | { | ||
74 | int new_ratio = count / seek_count; | ||
75 | |||
76 | if (new_ratio >= max_ratio) | ||
77 | new_ratio = max_ratio - 1; | ||
78 | |||
79 | if (!seek_table[new_ratio].is_valid) | ||
80 | { | ||
81 | uint8_t *buffer; | ||
82 | size_t n; | ||
83 | |||
84 | do | ||
85 | { | ||
86 | buffer = read_buffer(&n); | ||
87 | if (n == 0) | ||
88 | break; | ||
89 | decode(buffer, n); | ||
90 | } while (cur_ratio < new_ratio); | ||
91 | } | ||
92 | |||
93 | seek_data->pcmdata[0] = seek_table[new_ratio].pcmdata[0]; | ||
94 | seek_data->pcmdata[1] = seek_table[new_ratio].pcmdata[1]; | ||
95 | seek_data->step[0] = seek_table[new_ratio].step[0]; | ||
96 | seek_data->step[1] = seek_table[new_ratio].step[1]; | ||
97 | |||
98 | cur_ratio = new_ratio; | ||
99 | cur_count = seek_count; | ||
100 | return cur_ratio * seek_count; | ||
101 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/adpcm_seek.h b/lib/rbcodec/codecs/libpcm/adpcm_seek.h new file mode 100644 index 0000000000..2dd3f000b1 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/adpcm_seek.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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_LIBPCM_ADPCM_SEEK_H | ||
22 | #define CODEC_LIBPCM_ADPCM_SEEK_H | ||
23 | |||
24 | #include <stdbool.h> | ||
25 | #include <inttypes.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | struct adpcm_data { | ||
29 | int16_t pcmdata[2]; | ||
30 | uint16_t step[2]; | ||
31 | bool is_valid; | ||
32 | }; | ||
33 | |||
34 | void init_seek_table(uint32_t max_count); | ||
35 | void add_adpcm_data(struct adpcm_data *data); | ||
36 | uint32_t seek(uint32_t seek_time, struct adpcm_data *seek_data, | ||
37 | uint8_t *(*read_buffer)(size_t *realsize), | ||
38 | int (*decode)(const uint8_t *inbuf, size_t inbufsize)); | ||
39 | #endif | ||
diff --git a/lib/rbcodec/codecs/libpcm/dialogic_oki_adpcm.c b/lib/rbcodec/codecs/libpcm/dialogic_oki_adpcm.c new file mode 100644 index 0000000000..60090aaa89 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/dialogic_oki_adpcm.c | |||
@@ -0,0 +1,183 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "adpcm_seek.h" | ||
23 | #include "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * Dialogic OKI ADPCM | ||
27 | * | ||
28 | * References | ||
29 | * [1] Dialogic Corporation, Dialogic ADPCM Algorithm, 1988 | ||
30 | * [2] MultimediaWiki, Dialogic IMA ADPCM, URL:http://wiki.multimedia.cx/index.php?title=Dialogic_IMA_ADPCM | ||
31 | * [3] sox source code, src/adpcms.c | ||
32 | * [4] Tetsuya Isaki, NetBSD:/sys/dev/audio.c, http://www.tri-tree.gr.jp/~isaki/NetBSD/src/sys/dev/ic/msm6258.c.html | ||
33 | */ | ||
34 | |||
35 | static const uint16_t step_table[] ICONST_ATTR = { | ||
36 | 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, | ||
37 | 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, | ||
38 | 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | ||
39 | 876, 963, 1060, 1166, 1282, 1411, 1552, | ||
40 | }; | ||
41 | |||
42 | static const int index_table[] ICONST_ATTR = { | ||
43 | -1, -1, -1, -1, 2, 4, 6, 8 | ||
44 | }; | ||
45 | |||
46 | static struct adpcm_data cur_data; | ||
47 | static int blocksperchunk; | ||
48 | |||
49 | static struct pcm_format *fmt; | ||
50 | |||
51 | static bool set_format(struct pcm_format *format) | ||
52 | { | ||
53 | uint32_t max_chunk_count; | ||
54 | |||
55 | fmt = format; | ||
56 | |||
57 | if (fmt->bitspersample != 4) | ||
58 | { | ||
59 | DEBUGF("CODEC_ERROR: dialogic oki adpcm must be 4 bitspersample: %d\n", | ||
60 | fmt->bitspersample); | ||
61 | return false; | ||
62 | } | ||
63 | |||
64 | if (fmt->channels != 1) | ||
65 | { | ||
66 | DEBUGF("CODEC_ERROR: dialogic oki adpcm must be monaural\n"); | ||
67 | return false; | ||
68 | } | ||
69 | |||
70 | /* blockalign = 2 samples */ | ||
71 | fmt->blockalign = 1; | ||
72 | fmt->samplesperblock = 2; | ||
73 | |||
74 | /* chunksize = about 1/32[sec] data */ | ||
75 | blocksperchunk = ci->id3->frequency >> 6; | ||
76 | fmt->chunksize = blocksperchunk * fmt->blockalign; | ||
77 | |||
78 | max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency | ||
79 | / (2000LL * fmt->chunksize); | ||
80 | |||
81 | /* initialize seek table */ | ||
82 | init_seek_table(max_chunk_count); | ||
83 | /* add first data */ | ||
84 | add_adpcm_data(&cur_data); | ||
85 | |||
86 | return true; | ||
87 | } | ||
88 | |||
89 | static int16_t create_pcmdata(uint8_t nibble) | ||
90 | { | ||
91 | int16_t delta; | ||
92 | int16_t index = cur_data.step[0]; | ||
93 | int16_t step = step_table[index]; | ||
94 | |||
95 | delta = (step >> 3); | ||
96 | if (nibble & 4) delta += step; | ||
97 | if (nibble & 2) delta += (step >> 1); | ||
98 | if (nibble & 1) delta += (step >> 2); | ||
99 | |||
100 | if (nibble & 0x08) | ||
101 | cur_data.pcmdata[0] -= delta; | ||
102 | else | ||
103 | cur_data.pcmdata[0] += delta; | ||
104 | |||
105 | CLIP(cur_data.pcmdata[0], -2048, 2047); | ||
106 | |||
107 | index += index_table[nibble & 0x07]; | ||
108 | CLIP(index, 0, 48); | ||
109 | cur_data.step[0] = index; | ||
110 | |||
111 | return cur_data.pcmdata[0]; | ||
112 | } | ||
113 | |||
114 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
115 | int32_t *outbuf, int *outbufcount) | ||
116 | { | ||
117 | size_t nsamples = 0; | ||
118 | |||
119 | while (inbufsize) | ||
120 | { | ||
121 | *outbuf++ = create_pcmdata(*inbuf >> 4) << (PCM_OUTPUT_DEPTH - 12); | ||
122 | *outbuf++ = create_pcmdata(*inbuf ) << (PCM_OUTPUT_DEPTH - 12); | ||
123 | nsamples += 2; | ||
124 | |||
125 | inbuf++; | ||
126 | inbufsize--; | ||
127 | } | ||
128 | |||
129 | *outbufcount = nsamples; | ||
130 | add_adpcm_data(&cur_data); | ||
131 | |||
132 | return CODEC_OK; | ||
133 | } | ||
134 | |||
135 | static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize) | ||
136 | { | ||
137 | while (inbufsize) | ||
138 | { | ||
139 | create_pcmdata(*inbuf >> 4); | ||
140 | create_pcmdata(*inbuf ); | ||
141 | |||
142 | inbuf++; | ||
143 | inbufsize--; | ||
144 | } | ||
145 | |||
146 | add_adpcm_data(&cur_data); | ||
147 | |||
148 | return CODEC_OK; | ||
149 | } | ||
150 | |||
151 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
152 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
153 | { | ||
154 | static struct pcm_pos newpos; | ||
155 | uint32_t seek_count = (seek_mode == PCM_SEEK_TIME)? | ||
156 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
157 | / (blocksperchunk * fmt->samplesperblock) : | ||
158 | seek_val / (unsigned long)fmt->chunksize; | ||
159 | uint32_t new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek); | ||
160 | |||
161 | newpos.pos = new_count * fmt->chunksize; | ||
162 | newpos.samples = new_count * blocksperchunk * fmt->samplesperblock; | ||
163 | return &newpos; | ||
164 | } | ||
165 | |||
166 | static const struct pcm_codec codec = { | ||
167 | set_format, | ||
168 | get_seek_pos, | ||
169 | decode, | ||
170 | }; | ||
171 | |||
172 | const struct pcm_codec *get_dialogic_oki_adpcm_codec(void) | ||
173 | { | ||
174 | /* | ||
175 | * initialize first pcm data, step index | ||
176 | * because the dialogic oki adpcm is always monaural, | ||
177 | * pcmdata[1], step[1] do not use. | ||
178 | */ | ||
179 | cur_data.pcmdata[0] = 0; | ||
180 | cur_data.step[0] = 0; | ||
181 | |||
182 | return &codec; | ||
183 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/dvi_adpcm.c b/lib/rbcodec/codecs/libpcm/dvi_adpcm.c new file mode 100644 index 0000000000..2e702ca394 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/dvi_adpcm.c | |||
@@ -0,0 +1,308 @@ | |||
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 "ima_adpcm_common.h" | ||
24 | #include "support_formats.h" | ||
25 | |||
26 | /* | ||
27 | * Intel DVI ADPCM (IMA ADPCM) | ||
28 | * | ||
29 | * References | ||
30 | * [1] The IMA Digital Audio Focus and Technical Working Groups, | ||
31 | * Recommended Practices for Enhancing Digital Audio Compatibility | ||
32 | * in Multimedia Systems Revision 3.00, 1992 | ||
33 | * [2] Microsoft Corporation, New Multimedia Data Types and Data Techniques, | ||
34 | * Revision:3.0, 1994 | ||
35 | * [3] ffmpeg source code, libavcodec/adpcm.c | ||
36 | */ | ||
37 | |||
38 | static struct pcm_format *fmt; | ||
39 | |||
40 | static bool set_format(struct pcm_format *format) | ||
41 | { | ||
42 | fmt = format; | ||
43 | |||
44 | if (fmt->bitspersample < 2 || fmt->bitspersample > 5) | ||
45 | { | ||
46 | DEBUGF("CODEC_ERROR: dvi adpcm must be 2, 3, 4 or 5 bitspersample: %d\n", | ||
47 | fmt->bitspersample); | ||
48 | return false; | ||
49 | } | ||
50 | |||
51 | fmt->chunksize = fmt->blockalign; | ||
52 | |||
53 | init_ima_adpcm_decoder(fmt->bitspersample, NULL); | ||
54 | return true; | ||
55 | } | ||
56 | |||
57 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
58 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
59 | { | ||
60 | static struct pcm_pos newpos; | ||
61 | uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ? | ||
62 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
63 | / fmt->samplesperblock : | ||
64 | seek_val / fmt->blockalign; | ||
65 | |||
66 | (void)read_buffer; | ||
67 | newpos.pos = newblock * fmt->blockalign; | ||
68 | newpos.samples = newblock * fmt->samplesperblock; | ||
69 | return &newpos; | ||
70 | } | ||
71 | |||
72 | static inline void decode_2bit(const uint8_t **inbuf, size_t inbufsize, | ||
73 | int32_t **outbuf, int *outbufcount) | ||
74 | { | ||
75 | int ch; | ||
76 | int i; | ||
77 | int32_t *pcmbuf; | ||
78 | int samples; | ||
79 | |||
80 | samples = inbufsize / (4 * fmt->channels) - 1; | ||
81 | *outbufcount += (samples << 4); | ||
82 | while (samples-- > 0) | ||
83 | { | ||
84 | for (ch = 0; ch < fmt->channels; ch++) | ||
85 | { | ||
86 | pcmbuf = *outbuf + ch; | ||
87 | for (i = 0; i < 4; i++) | ||
88 | { | ||
89 | *pcmbuf = create_pcmdata(ch, **inbuf ) << IMA_ADPCM_INC_DEPTH; | ||
90 | pcmbuf += fmt->channels; | ||
91 | *pcmbuf = create_pcmdata(ch, **inbuf >> 2) << IMA_ADPCM_INC_DEPTH; | ||
92 | pcmbuf += fmt->channels; | ||
93 | *pcmbuf = create_pcmdata(ch, **inbuf >> 4) << IMA_ADPCM_INC_DEPTH; | ||
94 | pcmbuf += fmt->channels; | ||
95 | *pcmbuf = create_pcmdata(ch, **inbuf >> 6) << IMA_ADPCM_INC_DEPTH; | ||
96 | pcmbuf += fmt->channels; | ||
97 | (*inbuf)++; | ||
98 | } | ||
99 | } | ||
100 | *outbuf += 16 * fmt->channels; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static inline void decode_3bit(const uint8_t **inbuf, size_t inbufsize, | ||
105 | int32_t **outbuf, int *outbufcount) | ||
106 | { | ||
107 | const uint8_t *adpcmbuf; | ||
108 | uint32_t adpcms; | ||
109 | int ch; | ||
110 | int i; | ||
111 | int32_t *pcmbuf; | ||
112 | int samples; | ||
113 | |||
114 | samples = (inbufsize - 4 * fmt->channels) / (12 * fmt->channels); | ||
115 | *outbufcount += (samples << 5); | ||
116 | while (samples--) | ||
117 | { | ||
118 | for (ch = 0; ch < fmt->channels; ch++) | ||
119 | { | ||
120 | adpcmbuf = *inbuf + ch * 4; | ||
121 | pcmbuf = *outbuf + ch; | ||
122 | adpcms = *adpcmbuf++; | ||
123 | adpcms |= (*adpcmbuf++) << 8; | ||
124 | adpcms |= (*adpcmbuf++) << 16; | ||
125 | for (i = 0; i < 8; i++) | ||
126 | { | ||
127 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << IMA_ADPCM_INC_DEPTH; | ||
128 | pcmbuf += fmt->channels; | ||
129 | } | ||
130 | adpcms = *adpcmbuf++; | ||
131 | adpcmbuf += (fmt->channels - 1) * 4; | ||
132 | adpcms |= (*adpcmbuf++) << 8; | ||
133 | adpcms |= (*adpcmbuf++) << 16; | ||
134 | for (i = 0; i < 8; i++) | ||
135 | { | ||
136 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << IMA_ADPCM_INC_DEPTH; | ||
137 | pcmbuf += fmt->channels; | ||
138 | } | ||
139 | adpcms = *adpcmbuf++; | ||
140 | adpcms |= (*adpcmbuf++) << 8; | ||
141 | adpcmbuf += (fmt->channels - 1) * 4; | ||
142 | adpcms |= (*adpcmbuf++) << 16; | ||
143 | for (i = 0; i < 8; i++) | ||
144 | { | ||
145 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << IMA_ADPCM_INC_DEPTH; | ||
146 | pcmbuf += fmt->channels; | ||
147 | } | ||
148 | adpcms = *adpcmbuf++; | ||
149 | adpcms |= (*adpcmbuf++) << 8; | ||
150 | adpcms |= (*adpcmbuf++) << 16; | ||
151 | for (i = 0; i < 8; i++) | ||
152 | { | ||
153 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << IMA_ADPCM_INC_DEPTH; | ||
154 | pcmbuf += fmt->channels; | ||
155 | } | ||
156 | } | ||
157 | *outbuf += 32 * fmt->channels; | ||
158 | *inbuf += 12 * fmt->channels; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static inline void decode_4bit(const uint8_t **inbuf, size_t inbufsize, | ||
163 | int32_t **outbuf, int *outbufcount) | ||
164 | { | ||
165 | int ch; | ||
166 | int i; | ||
167 | int32_t *pcmbuf; | ||
168 | int samples; | ||
169 | |||
170 | samples = inbufsize / (4 * fmt->channels) - 1; | ||
171 | *outbufcount += (samples << 3); | ||
172 | while (samples-- > 0) | ||
173 | { | ||
174 | for (ch = 0; ch < fmt->channels; ch++) | ||
175 | { | ||
176 | pcmbuf = *outbuf + ch; | ||
177 | for (i = 0; i < 4; i++) | ||
178 | { | ||
179 | *pcmbuf = create_pcmdata_size4(ch, **inbuf ) << IMA_ADPCM_INC_DEPTH; | ||
180 | pcmbuf += fmt->channels; | ||
181 | *pcmbuf = create_pcmdata_size4(ch, **inbuf >> 4) << IMA_ADPCM_INC_DEPTH; | ||
182 | pcmbuf += fmt->channels; | ||
183 | (*inbuf)++; | ||
184 | } | ||
185 | } | ||
186 | *outbuf += 8 * fmt->channels; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static inline void decode_5bit(const uint8_t **inbuf, size_t inbufsize, | ||
191 | int32_t **outbuf, int *outbufcount) | ||
192 | { | ||
193 | const uint8_t *adpcmbuf; | ||
194 | uint64_t adpcms; | ||
195 | int ch; | ||
196 | int i; | ||
197 | int32_t *pcmbuf; | ||
198 | int samples; | ||
199 | |||
200 | samples = (inbufsize - 4 * fmt->channels) / (20 * fmt->channels); | ||
201 | *outbufcount += (samples << 5); | ||
202 | while (samples--) | ||
203 | { | ||
204 | for (ch = 0; ch < fmt->channels; ch++) | ||
205 | { | ||
206 | adpcmbuf = *inbuf + ch * 4; | ||
207 | pcmbuf = *outbuf + ch; | ||
208 | adpcms = *adpcmbuf++; | ||
209 | adpcms |= (*adpcmbuf++) << 8; | ||
210 | adpcms |= (*adpcmbuf++) << 16; | ||
211 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
212 | adpcmbuf += (fmt->channels - 1) * 4; | ||
213 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
214 | for (i = 0; i < 8; i++) | ||
215 | { | ||
216 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << IMA_ADPCM_INC_DEPTH; | ||
217 | pcmbuf += fmt->channels; | ||
218 | } | ||
219 | adpcms = *adpcmbuf++; | ||
220 | adpcms |= (*adpcmbuf++) << 8; | ||
221 | adpcms |= (*adpcmbuf++) << 16; | ||
222 | adpcmbuf += (fmt->channels - 1) * 4; | ||
223 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
224 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
225 | for (i = 0; i < 8; i++) | ||
226 | { | ||
227 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << IMA_ADPCM_INC_DEPTH; | ||
228 | pcmbuf += fmt->channels; | ||
229 | } | ||
230 | adpcms = *adpcmbuf++; | ||
231 | adpcms |= (*adpcmbuf++) << 8; | ||
232 | adpcmbuf += (fmt->channels - 1) * 4; | ||
233 | adpcms |= (*adpcmbuf++) << 16; | ||
234 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
235 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
236 | for (i = 0; i < 8; i++) | ||
237 | { | ||
238 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << IMA_ADPCM_INC_DEPTH; | ||
239 | pcmbuf += fmt->channels; | ||
240 | } | ||
241 | adpcms = *adpcmbuf++; | ||
242 | adpcmbuf += (fmt->channels - 1) * 4; | ||
243 | adpcms |= (*adpcmbuf++) << 8; | ||
244 | adpcms |= (*adpcmbuf++) << 16; | ||
245 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
246 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
247 | for (i = 0; i < 8; i++) | ||
248 | { | ||
249 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << IMA_ADPCM_INC_DEPTH; | ||
250 | pcmbuf += fmt->channels; | ||
251 | } | ||
252 | } | ||
253 | *outbuf += 32 * fmt->channels; | ||
254 | *inbuf += 20 * fmt->channels; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
259 | int32_t *outbuf, int *outbufcount) | ||
260 | { | ||
261 | int ch; | ||
262 | int32_t init_pcmdata[2]; | ||
263 | int8_t init_index[2]; | ||
264 | |||
265 | *outbufcount = 0; | ||
266 | for (ch = 0; ch < fmt->channels; ch++) | ||
267 | { | ||
268 | init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); | ||
269 | if (init_pcmdata[ch] > 32767) | ||
270 | init_pcmdata[ch] -= 65536; | ||
271 | |||
272 | init_index[ch] = inbuf[2]; | ||
273 | if (init_index[ch] > 88 || init_index[ch] < 0) | ||
274 | { | ||
275 | DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n", | ||
276 | init_index[ch]); | ||
277 | return CODEC_ERROR; | ||
278 | } | ||
279 | inbuf += 4; | ||
280 | |||
281 | *outbuf++ = init_pcmdata[ch] << IMA_ADPCM_INC_DEPTH; | ||
282 | } | ||
283 | |||
284 | *outbufcount += 1; | ||
285 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); | ||
286 | |||
287 | if (fmt->bitspersample == 4) | ||
288 | decode_4bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
289 | else if (fmt->bitspersample == 3) | ||
290 | decode_3bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
291 | else if (fmt->bitspersample == 5) | ||
292 | decode_5bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
293 | else /* fmt->bitspersample == 2 */ | ||
294 | decode_2bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
295 | |||
296 | return CODEC_OK; | ||
297 | } | ||
298 | |||
299 | static const struct pcm_codec codec = { | ||
300 | set_format, | ||
301 | get_seek_pos, | ||
302 | decode, | ||
303 | }; | ||
304 | |||
305 | const struct pcm_codec *get_dvi_adpcm_codec(void) | ||
306 | { | ||
307 | return &codec; | ||
308 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/ieee_float.c b/lib/rbcodec/codecs/libpcm/ieee_float.c new file mode 100644 index 0000000000..639390bcd5 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/ieee_float.c | |||
@@ -0,0 +1,165 @@ | |||
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 | #include "codeclib.h" | ||
22 | #include "pcm_common.h" | ||
23 | #include "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * IEEE float | ||
27 | */ | ||
28 | |||
29 | static struct pcm_format *fmt; | ||
30 | |||
31 | static bool set_format(struct pcm_format *format) | ||
32 | { | ||
33 | fmt = format; | ||
34 | |||
35 | if (fmt->channels == 0) | ||
36 | { | ||
37 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
38 | return false; | ||
39 | } | ||
40 | |||
41 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) | ||
42 | { | ||
43 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample: %d\n", | ||
44 | fmt->bitspersample); | ||
45 | return false; | ||
46 | } | ||
47 | |||
48 | fmt->bytespersample = fmt->bitspersample >> 3; | ||
49 | |||
50 | if (fmt->blockalign == 0) | ||
51 | fmt->blockalign = fmt->bytespersample * fmt->channels; | ||
52 | |||
53 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); | ||
54 | |||
55 | /* chunksize = about 1/50[sec] data */ | ||
56 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) | ||
57 | * fmt->blockalign; | ||
58 | |||
59 | return true; | ||
60 | } | ||
61 | |||
62 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
63 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
64 | { | ||
65 | static struct pcm_pos newpos; | ||
66 | uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ? | ||
67 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
68 | / fmt->samplesperblock : | ||
69 | seek_val / fmt->blockalign; | ||
70 | |||
71 | (void)read_buffer; | ||
72 | newpos.pos = newblock * fmt->blockalign; | ||
73 | newpos.samples = newblock * fmt->samplesperblock; | ||
74 | return &newpos; | ||
75 | } | ||
76 | |||
77 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
78 | int32_t *outbuf, int *outbufsize) | ||
79 | { | ||
80 | uint32_t i; | ||
81 | int32_t pcm; | ||
82 | int16_t exp; | ||
83 | int sgn; | ||
84 | |||
85 | if (fmt->bitspersample == 32) | ||
86 | { | ||
87 | for (i = 0; i < inbufsize; i += 4) | ||
88 | { | ||
89 | if (fmt->is_little_endian) | ||
90 | { | ||
91 | pcm = (inbuf[0]<<5)|(inbuf[1]<<13)|((inbuf[2]|0x80)<<21); | ||
92 | exp = ((inbuf[2]>>7)|((inbuf[3]&0x7f)<<1)) - 127; | ||
93 | sgn = inbuf[3] & 0x80; | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | pcm = (inbuf[3]<<5)|(inbuf[2]<<13)|((inbuf[1]|0x80)<<21); | ||
98 | exp = ((inbuf[1]>>7)|((inbuf[0]&0x7f)<<1)) - 127; | ||
99 | sgn = inbuf[0] & 0x80; | ||
100 | } | ||
101 | if (exp > -29 && exp < 0) | ||
102 | { | ||
103 | pcm >>= -exp; | ||
104 | if (sgn) | ||
105 | pcm = -pcm; | ||
106 | } | ||
107 | else if (exp < -28) | ||
108 | pcm = 0; | ||
109 | else | ||
110 | pcm = (sgn)?-(1<<28):(1<<28)-1; | ||
111 | |||
112 | outbuf[i/4] = pcm; | ||
113 | inbuf += 4; | ||
114 | } | ||
115 | *outbufsize = inbufsize >> 2; | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | for (i = 0; i < inbufsize; i += 8) | ||
120 | { | ||
121 | if (fmt->is_little_endian) | ||
122 | { | ||
123 | pcm = inbuf[3]|(inbuf[4]<<8)|(inbuf[5]<<16)|(((inbuf[6]&0x0f)|0x10)<<24); | ||
124 | exp = (((inbuf[6]&0xf0)>>4)|((inbuf[7]&0x7f)<<4)) - 1023; | ||
125 | sgn = inbuf[7] & 0x80; | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | pcm = inbuf[4]|(inbuf[3]<<8)|(inbuf[2]<<16)|(((inbuf[1]&0x0f)|0x10)<<24); | ||
130 | exp = (((inbuf[1]&0xf0)>>4)|((inbuf[0]&0x7f)<<4)) - 1023; | ||
131 | sgn = inbuf[0] & 0x80; | ||
132 | } | ||
133 | if (exp > -29 && exp < 0) | ||
134 | { | ||
135 | pcm >>= -exp; | ||
136 | if (sgn) | ||
137 | pcm = -pcm; | ||
138 | } | ||
139 | else if (exp < -28) | ||
140 | pcm = 0; | ||
141 | else | ||
142 | pcm = (sgn)?-(1<<28):(1<<28)-1; | ||
143 | |||
144 | outbuf[i/8] = pcm; | ||
145 | inbuf += 8; | ||
146 | } | ||
147 | *outbufsize = inbufsize >> 3; | ||
148 | } | ||
149 | |||
150 | if (fmt->channels == 2) | ||
151 | *outbufsize >>= 1; | ||
152 | |||
153 | return CODEC_OK; | ||
154 | } | ||
155 | |||
156 | static const struct pcm_codec codec = { | ||
157 | set_format, | ||
158 | get_seek_pos, | ||
159 | decode, | ||
160 | }; | ||
161 | |||
162 | const struct pcm_codec *get_ieee_float_codec(void) | ||
163 | { | ||
164 | return &codec; | ||
165 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/ima_adpcm_common.c b/lib/rbcodec/codecs/libpcm/ima_adpcm_common.c new file mode 100644 index 0000000000..724cce31b0 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/ima_adpcm_common.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "pcm_common.h" | ||
23 | #include "ima_adpcm_common.h" | ||
24 | |||
25 | /* | ||
26 | * Functions for IMA ADPCM and IMA ADPCM series format | ||
27 | * | ||
28 | * References | ||
29 | * [1] The IMA Digital Audio Focus and Technical Working Groups, | ||
30 | * Recommended Practices for Enhancing Digital Audio Compatibility | ||
31 | * in Multimedia Systems Revision 3.00, 1992 | ||
32 | * [2] Microsoft Corporation, New Multimedia Data Types and Data Techniques, | ||
33 | * Revision:3.0, 1994 | ||
34 | * [3] ffmpeg source code, libavcodec/adpcm.c | ||
35 | */ | ||
36 | |||
37 | /* step table */ | ||
38 | static const uint16_t step_table[89] ICONST_ATTR = { | ||
39 | 7, 8, 9, 10, 11, 12, 13, 14, | ||
40 | 16, 17, 19, 21, 23, 25, 28, 31, | ||
41 | 34, 37, 41, 45, 50, 55, 60, 66, | ||
42 | 73, 80, 88, 97, 107, 118, 130, 143, | ||
43 | 157, 173, 190, 209, 230, 253, 279, 307, | ||
44 | 337, 371, 408, 449, 494, 544, 598, 658, | ||
45 | 724, 796, 876, 963, 1060, 1166, 1282, 1411, | ||
46 | 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, | ||
47 | 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, | ||
48 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | ||
49 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, | ||
50 | 32767 | ||
51 | }; | ||
52 | |||
53 | /* step index tables */ | ||
54 | static const int index_tables[4][16] ICONST_ATTR = { | ||
55 | /* adpcm data size is 2 */ | ||
56 | { -1, 2 }, | ||
57 | /* adpcm data size is 3 */ | ||
58 | { -1, -1, 1, 2 }, | ||
59 | /* adpcm data size is 4 */ | ||
60 | { -1, -1, -1, -1, 2, 4, 6, 8 }, | ||
61 | /* adpcm data size is 5 */ | ||
62 | { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }, | ||
63 | }; | ||
64 | |||
65 | static int32_t pcmdata[2]; | ||
66 | static int8_t indices[2]; | ||
67 | |||
68 | static int adpcm_data_size; | ||
69 | static uint8_t step_mask; | ||
70 | static uint8_t step_sign_mask; | ||
71 | static int8_t step_shift; | ||
72 | static const int *use_index_table; | ||
73 | |||
74 | /* | ||
75 | * Before first decoding, this function must be executed. | ||
76 | * | ||
77 | * params | ||
78 | * bit: adpcm data size (2 <= bit <= 5). | ||
79 | * index_table: step index table | ||
80 | * if index_table is null, then step index table | ||
81 | * is used index_tables[bit-2]. | ||
82 | */ | ||
83 | void init_ima_adpcm_decoder(int bit, const int *index_table) | ||
84 | { | ||
85 | adpcm_data_size = bit; | ||
86 | step_sign_mask = 1 << (adpcm_data_size - 1); | ||
87 | step_mask = step_sign_mask - 1; | ||
88 | step_shift = adpcm_data_size - 2; | ||
89 | if (index_table) | ||
90 | use_index_table = index_table; | ||
91 | else | ||
92 | use_index_table = index_tables[adpcm_data_size - 2]; | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * When starting decoding for each block, this function must be executed. | ||
97 | * | ||
98 | * params | ||
99 | * channels: channel count | ||
100 | * init_pcmdata: array of init pcmdata | ||
101 | * init_index: array of init step indexes | ||
102 | */ | ||
103 | void set_decode_parameters(int channels, int32_t *init_pcmdata, int8_t *init_index) | ||
104 | { | ||
105 | int ch; | ||
106 | |||
107 | for (ch = 0; ch < channels; ch++) | ||
108 | { | ||
109 | pcmdata[ch] = init_pcmdata[ch]; | ||
110 | indices[ch] = init_index[ch]; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * convert ADPCM to PCM for any adpcm data size. | ||
116 | * | ||
117 | * If adpcm_data_size is 4, then you use create_pcmdata_size4() | ||
118 | * in place of this functon. | ||
119 | */ | ||
120 | int16_t create_pcmdata(int ch, uint8_t nibble) | ||
121 | { | ||
122 | int check_bit = 1 << step_shift; | ||
123 | int32_t delta = 0; | ||
124 | int16_t step = step_table[indices[ch]]; | ||
125 | |||
126 | do { | ||
127 | if (nibble & check_bit) | ||
128 | delta += step; | ||
129 | step >>= 1; | ||
130 | check_bit >>= 1; | ||
131 | } while (check_bit); | ||
132 | delta += step; | ||
133 | |||
134 | if (nibble & step_sign_mask) | ||
135 | pcmdata[ch] -= delta; | ||
136 | else | ||
137 | pcmdata[ch] += delta; | ||
138 | |||
139 | indices[ch] += use_index_table[nibble & step_mask]; | ||
140 | CLIP(indices[ch], 0, 88); | ||
141 | |||
142 | CLIP(pcmdata[ch], -32768, 32767); | ||
143 | |||
144 | return (int16_t)pcmdata[ch]; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * convert ADPCM to PCM when adpcm data size is 4. | ||
149 | */ | ||
150 | int16_t create_pcmdata_size4(int ch, uint8_t nibble) | ||
151 | { | ||
152 | int32_t delta; | ||
153 | int16_t step = step_table[indices[ch]]; | ||
154 | |||
155 | delta = (step >> 3); | ||
156 | if (nibble & 4) delta += step; | ||
157 | if (nibble & 2) delta += (step >> 1); | ||
158 | if (nibble & 1) delta += (step >> 2); | ||
159 | |||
160 | if (nibble & 0x08) | ||
161 | pcmdata[ch] -= delta; | ||
162 | else | ||
163 | pcmdata[ch] += delta; | ||
164 | |||
165 | indices[ch] += use_index_table[nibble & 0x07]; | ||
166 | CLIP(indices[ch], 0, 88); | ||
167 | |||
168 | CLIP(pcmdata[ch], -32768, 32767); | ||
169 | |||
170 | return (int16_t)pcmdata[ch]; | ||
171 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/ima_adpcm_common.h b/lib/rbcodec/codecs/libpcm/ima_adpcm_common.h new file mode 100644 index 0000000000..46fd6083ec --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/ima_adpcm_common.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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_LIBPCM_IMA_ADPCM_COMMON_H | ||
22 | #define CODEC_LIBPCM_IMA_ADPCM_COMMON_H | ||
23 | |||
24 | #include <stdbool.h> | ||
25 | #include <inttypes.h> | ||
26 | |||
27 | #define IMA_ADPCM_INC_DEPTH (PCM_OUTPUT_DEPTH - 16) | ||
28 | |||
29 | void init_ima_adpcm_decoder(int bit, const int *index_table); | ||
30 | void set_decode_parameters(int channels, int32_t *init_pcmdata, int8_t *init_index); | ||
31 | int16_t create_pcmdata(int ch, uint8_t nibble); | ||
32 | int16_t create_pcmdata_size4(int ch, uint8_t nibble); | ||
33 | #endif | ||
diff --git a/lib/rbcodec/codecs/libpcm/itut_g711.c b/lib/rbcodec/codecs/libpcm/itut_g711.c new file mode 100644 index 0000000000..88ff5f59e6 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/itut_g711.c | |||
@@ -0,0 +1,204 @@ | |||
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 "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * ITU-T G.711 A-law mu-law | ||
27 | */ | ||
28 | |||
29 | static 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 | |||
69 | static 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 | |||
109 | static struct pcm_format *fmt; | ||
110 | |||
111 | static bool set_format(struct pcm_format *format) | ||
112 | { | ||
113 | fmt = format; | ||
114 | |||
115 | if (fmt->channels == 0) | ||
116 | { | ||
117 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
118 | return false; | ||
119 | } | ||
120 | |||
121 | if (fmt->bitspersample != 8) | ||
122 | { | ||
123 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n", | ||
124 | fmt->bitspersample); | ||
125 | return false; | ||
126 | } | ||
127 | |||
128 | fmt->bytespersample = 1; | ||
129 | |||
130 | if (fmt->blockalign == 0) | ||
131 | fmt->blockalign = fmt->channels; | ||
132 | |||
133 | fmt->samplesperblock = fmt->blockalign / fmt->channels; | ||
134 | |||
135 | /* chunksize = about 1/50[sec] data */ | ||
136 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) | ||
137 | * fmt->blockalign; | ||
138 | |||
139 | return true; | ||
140 | } | ||
141 | |||
142 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
143 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
144 | { | ||
145 | static struct pcm_pos newpos; | ||
146 | uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ? | ||
147 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
148 | / fmt->samplesperblock : | ||
149 | seek_val / fmt->blockalign; | ||
150 | |||
151 | (void)read_buffer; | ||
152 | newpos.pos = newblock * fmt->blockalign; | ||
153 | newpos.samples = newblock * fmt->samplesperblock; | ||
154 | return &newpos; | ||
155 | } | ||
156 | |||
157 | static int decode_alaw(const uint8_t *inbuf, size_t inbufsize, | ||
158 | int32_t *outbuf, int *outbufsize) | ||
159 | { | ||
160 | uint32_t i; | ||
161 | |||
162 | for (i = 0; i < inbufsize; i++) | ||
163 | outbuf[i] = alaw2linear16[inbuf[i]] << (PCM_OUTPUT_DEPTH - 16); | ||
164 | |||
165 | *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize; | ||
166 | |||
167 | return CODEC_OK; | ||
168 | } | ||
169 | |||
170 | static int decode_mulaw(const uint8_t *inbuf, size_t inbufsize, | ||
171 | int32_t *outbuf, int *outbufsize) | ||
172 | { | ||
173 | uint32_t i; | ||
174 | |||
175 | for (i = 0; i < inbufsize; i++) | ||
176 | outbuf[i] = ulaw2linear16[inbuf[i]] << (PCM_OUTPUT_DEPTH - 16); | ||
177 | |||
178 | *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize; | ||
179 | |||
180 | return CODEC_OK; | ||
181 | } | ||
182 | |||
183 | static const struct pcm_codec alaw_codec = { | ||
184 | set_format, | ||
185 | get_seek_pos, | ||
186 | decode_alaw, | ||
187 | }; | ||
188 | |||
189 | static const struct pcm_codec mulaw_codec = { | ||
190 | set_format, | ||
191 | get_seek_pos, | ||
192 | decode_mulaw, | ||
193 | }; | ||
194 | |||
195 | const struct pcm_codec *get_itut_g711_alaw_codec(void) | ||
196 | { | ||
197 | return &alaw_codec; | ||
198 | } | ||
199 | |||
200 | const struct pcm_codec *get_itut_g711_mulaw_codec(void) | ||
201 | { | ||
202 | return &mulaw_codec; | ||
203 | } | ||
204 | |||
diff --git a/lib/rbcodec/codecs/libpcm/libpcm.make b/lib/rbcodec/codecs/libpcm/libpcm.make new file mode 100644 index 0000000000..15c23bedf2 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/libpcm.make | |||
@@ -0,0 +1,18 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | # libpcm | ||
11 | PCMSLIB := $(CODECDIR)/libpcm.a | ||
12 | PCMSLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libpcm/SOURCES) | ||
13 | PCMSLIB_OBJ := $(call c2obj, $(PCMSLIB_SRC)) | ||
14 | OTHER_SRC += $(PCMSLIB_SRC) | ||
15 | |||
16 | $(PCMSLIB): $(PCMSLIB_OBJ) | ||
17 | $(SILENT)$(shell rm -f $@) | ||
18 | $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null | ||
diff --git a/lib/rbcodec/codecs/libpcm/linear_pcm.c b/lib/rbcodec/codecs/libpcm/linear_pcm.c new file mode 100644 index 0000000000..5c3c140b8c --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/linear_pcm.c | |||
@@ -0,0 +1,294 @@ | |||
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 "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * Linear PCM | ||
27 | */ | ||
28 | |||
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) | ||
33 | |||
34 | |||
35 | static struct pcm_format *fmt; | ||
36 | |||
37 | static bool set_format(struct pcm_format *format) | ||
38 | { | ||
39 | fmt = format; | ||
40 | |||
41 | if (fmt->channels == 0) | ||
42 | { | ||
43 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
44 | return false; | ||
45 | } | ||
46 | |||
47 | if (fmt->bitspersample == 0) | ||
48 | { | ||
49 | DEBUGF("CODEC_ERROR: bitspersample is 0\n"); | ||
50 | return false; | ||
51 | } | ||
52 | |||
53 | if (fmt->bitspersample > 32) | ||
54 | { | ||
55 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | ||
56 | "is unsupported\n"); | ||
57 | return false; | ||
58 | } | ||
59 | |||
60 | fmt->bytespersample = fmt->bitspersample >> 3; | ||
61 | |||
62 | if (fmt->blockalign == 0) | ||
63 | fmt->blockalign = fmt->bytespersample * fmt->channels; | ||
64 | |||
65 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); | ||
66 | |||
67 | /* chunksize = about 1/50[sec] data */ | ||
68 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) | ||
69 | * fmt->blockalign; | ||
70 | |||
71 | return true; | ||
72 | } | ||
73 | |||
74 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
75 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
76 | { | ||
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; | ||
82 | |||
83 | (void)read_buffer; | ||
84 | newpos.pos = newblock * fmt->blockalign; | ||
85 | newpos.samples = newblock * fmt->samplesperblock; | ||
86 | return &newpos; | ||
87 | } | ||
88 | |||
89 | /* 8bit decode functions */ | ||
90 | static inline void decode_s8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
91 | { | ||
92 | size_t i = 0; | ||
93 | |||
94 | for ( ; i < inbufsize; i++) | ||
95 | outbuf[i] = SE(inbuf[i]) << INC_DEPTH_8; | ||
96 | } | ||
97 | |||
98 | static inline void decode_u8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
99 | { | ||
100 | size_t i = 0; | ||
101 | |||
102 | for ( ; i < inbufsize; i++) | ||
103 | outbuf[i] = SFT(inbuf[i]) << INC_DEPTH_8; | ||
104 | } | ||
105 | |||
106 | /* 16bit decode functions */ | ||
107 | static inline void decode_s16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
108 | { | ||
109 | size_t i = 0; | ||
110 | |||
111 | for ( ; i < inbufsize; i += 2) | ||
112 | outbuf[i/2] = (inbuf[i] << INC_DEPTH_16)|(SE(inbuf[i+1]) << INC_DEPTH_8); | ||
113 | } | ||
114 | |||
115 | static inline void decode_u16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
116 | { | ||
117 | size_t i = 0; | ||
118 | |||
119 | for ( ; i < inbufsize; i += 2) | ||
120 | outbuf[i/2] = (inbuf[i] << INC_DEPTH_16)|(SFT(inbuf[i+1]) << INC_DEPTH_8); | ||
121 | } | ||
122 | |||
123 | static inline void decode_s16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
124 | { | ||
125 | size_t i = 0; | ||
126 | |||
127 | for ( ; i < inbufsize; i += 2) | ||
128 | outbuf[i/2] = (inbuf[i+1] << INC_DEPTH_16)|(SE(inbuf[i]) << INC_DEPTH_8); | ||
129 | } | ||
130 | |||
131 | static inline void decode_u16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
132 | { | ||
133 | size_t i = 0; | ||
134 | |||
135 | for ( ; i < inbufsize; i += 2) | ||
136 | outbuf[i/2] = (inbuf[i+1] << INC_DEPTH_16)|(SFT(inbuf[i]) << INC_DEPTH_8); | ||
137 | } | ||
138 | |||
139 | /* 24bit decode functions */ | ||
140 | static inline void decode_s24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
141 | { | ||
142 | size_t i = 0; | ||
143 | |||
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); | ||
147 | } | ||
148 | |||
149 | static inline void decode_u24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
150 | { | ||
151 | size_t i = 0; | ||
152 | |||
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); | ||
156 | } | ||
157 | |||
158 | static inline void decode_s24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
159 | { | ||
160 | size_t i = 0; | ||
161 | |||
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); | ||
165 | } | ||
166 | |||
167 | static inline void decode_u24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
168 | { | ||
169 | size_t i = 0; | ||
170 | |||
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); | ||
174 | } | ||
175 | |||
176 | /* 32bit decode functions */ | ||
177 | static inline void decode_s32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
178 | { | ||
179 | size_t i = 0; | ||
180 | |||
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); | ||
184 | } | ||
185 | |||
186 | static inline void decode_u32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
187 | { | ||
188 | size_t i = 0; | ||
189 | |||
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); | ||
193 | } | ||
194 | |||
195 | static inline void decode_s32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
196 | { | ||
197 | size_t i = 0; | ||
198 | |||
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); | ||
202 | } | ||
203 | |||
204 | static inline void decode_u32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf) | ||
205 | { | ||
206 | size_t i = 0; | ||
207 | |||
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); | ||
211 | } | ||
212 | |||
213 | static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufcount) | ||
214 | { | ||
215 | if (fmt->bitspersample > 24) | ||
216 | { | ||
217 | if (fmt->is_little_endian) | ||
218 | { | ||
219 | if (fmt->is_signed) | ||
220 | decode_s32le(inbuf, inbufsize, outbuf); | ||
221 | else | ||
222 | decode_u32le(inbuf, inbufsize, outbuf); | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | if (fmt->is_signed) | ||
227 | decode_s32be(inbuf, inbufsize, outbuf); | ||
228 | else | ||
229 | decode_u32be(inbuf, inbufsize, outbuf); | ||
230 | } | ||
231 | *outbufcount = inbufsize >> 2; | ||
232 | } | ||
233 | else if (fmt->bitspersample > 16) | ||
234 | { | ||
235 | if (fmt->is_little_endian) | ||
236 | { | ||
237 | if (fmt->is_signed) | ||
238 | decode_s24le(inbuf, inbufsize, outbuf); | ||
239 | else | ||
240 | decode_u24le(inbuf, inbufsize, outbuf); | ||
241 | } | ||
242 | else | ||
243 | { | ||
244 | if (fmt->is_signed) | ||
245 | decode_s24be(inbuf, inbufsize, outbuf); | ||
246 | else | ||
247 | decode_u24be(inbuf, inbufsize, outbuf); | ||
248 | } | ||
249 | *outbufcount = inbufsize / 3; | ||
250 | } | ||
251 | else if (fmt->bitspersample > 8) | ||
252 | { | ||
253 | if (fmt->is_little_endian) | ||
254 | { | ||
255 | if (fmt->is_signed) | ||
256 | decode_s16le(inbuf, inbufsize, outbuf); | ||
257 | else | ||
258 | decode_u16le(inbuf, inbufsize, outbuf); | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | if (fmt->is_signed) | ||
263 | decode_s16be(inbuf, inbufsize, outbuf); | ||
264 | else | ||
265 | decode_u16be(inbuf, inbufsize, outbuf); | ||
266 | } | ||
267 | *outbufcount = inbufsize >> 1; | ||
268 | } | ||
269 | else | ||
270 | { | ||
271 | if (fmt->is_signed) | ||
272 | decode_s8(inbuf, inbufsize, outbuf); | ||
273 | else | ||
274 | decode_u8(inbuf, inbufsize, outbuf); | ||
275 | |||
276 | *outbufcount = inbufsize; | ||
277 | } | ||
278 | |||
279 | if (fmt->channels == 2) | ||
280 | *outbufcount >>= 1; | ||
281 | |||
282 | return CODEC_OK; | ||
283 | } | ||
284 | |||
285 | static const struct pcm_codec codec = { | ||
286 | set_format, | ||
287 | get_seek_pos, | ||
288 | decode, | ||
289 | }; | ||
290 | |||
291 | const struct pcm_codec *get_linear_pcm_codec(void) | ||
292 | { | ||
293 | return &codec; | ||
294 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/ms_adpcm.c b/lib/rbcodec/codecs/libpcm/ms_adpcm.c new file mode 100644 index 0000000000..a385d6c99f --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/ms_adpcm.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "support_formats.h" | ||
23 | |||
24 | /* | ||
25 | * Microsoft ADPCM | ||
26 | * | ||
27 | * References | ||
28 | * [1] Microsoft, New Multimedia Data Types and Data Techniques Revision 3.0, 1994 | ||
29 | * [2] MulitimediaWiki, Microsoft ADPCM, 2006 | ||
30 | * (http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM) | ||
31 | * [3] ffmpeg source code, libavcodec/adpcm.c | ||
32 | */ | ||
33 | |||
34 | #define ADPCM_NUM_COEFF 7 | ||
35 | |||
36 | static int16_t dec_coeff[2][2]; | ||
37 | static uint16_t delta[2]; | ||
38 | static int16_t sample[2][2]; | ||
39 | |||
40 | static struct pcm_format *fmt; | ||
41 | |||
42 | static const int16_t adaptation_table[] ICONST_ATTR = { | ||
43 | 230, 230, 230, 230, 307, 409, 512, 614, | ||
44 | 768, 614, 512, 409, 307, 230, 230, 230 | ||
45 | }; | ||
46 | |||
47 | static bool set_format(struct pcm_format *format) | ||
48 | { | ||
49 | fmt = format; | ||
50 | |||
51 | if (fmt->bitspersample != 4) | ||
52 | { | ||
53 | DEBUGF("CODEC_ERROR: microsoft adpcm must be 4 bitspersample: %d\n", | ||
54 | fmt->bitspersample); | ||
55 | return false; | ||
56 | } | ||
57 | |||
58 | fmt->chunksize = fmt->blockalign; | ||
59 | |||
60 | return true; | ||
61 | } | ||
62 | |||
63 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
64 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
65 | { | ||
66 | static struct pcm_pos newpos; | ||
67 | uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ? | ||
68 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
69 | / fmt->samplesperblock : | ||
70 | seek_val / fmt->blockalign; | ||
71 | |||
72 | (void)read_buffer; | ||
73 | newpos.pos = newblock * fmt->blockalign; | ||
74 | newpos.samples = newblock * fmt->samplesperblock; | ||
75 | return &newpos; | ||
76 | } | ||
77 | |||
78 | static int16_t create_pcmdata(int ch, uint8_t nibble) | ||
79 | { | ||
80 | int32_t pcmdata; | ||
81 | |||
82 | pcmdata = (sample[ch][0] * dec_coeff[ch][0] + | ||
83 | sample[ch][1] * dec_coeff[ch][1]) / 256; | ||
84 | pcmdata += (delta[ch] * (nibble - ((nibble & 0x8) << 1))); | ||
85 | |||
86 | CLIP(pcmdata, -32768, 32767); | ||
87 | |||
88 | sample[ch][1] = sample[ch][0]; | ||
89 | sample[ch][0] = pcmdata; | ||
90 | |||
91 | delta[ch] = (adaptation_table[nibble] * delta[ch]) >> 8; | ||
92 | if (delta[ch] < 16) | ||
93 | delta[ch] = 16; | ||
94 | |||
95 | return (int16_t)pcmdata; | ||
96 | } | ||
97 | |||
98 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
99 | int32_t *outbuf, int *outbufcount) | ||
100 | { | ||
101 | int ch; | ||
102 | size_t nsamples = 0; | ||
103 | int size = fmt->samplesperblock; | ||
104 | |||
105 | /* read block header */ | ||
106 | for (ch = 0; ch < fmt->channels; ch++) | ||
107 | { | ||
108 | if (*inbuf >= ADPCM_NUM_COEFF) | ||
109 | { | ||
110 | DEBUGF("CODEC_ERROR: microsoft adpcm illegal initial coeff=%d > 7\n", | ||
111 | *inbuf); | ||
112 | return CODEC_ERROR; | ||
113 | } | ||
114 | dec_coeff[ch][0] = fmt->coeffs[*inbuf][0]; | ||
115 | dec_coeff[ch][1] = fmt->coeffs[*inbuf][1]; | ||
116 | inbuf++; | ||
117 | } | ||
118 | |||
119 | for (ch = 0; ch < fmt->channels; ch++) | ||
120 | { | ||
121 | delta[ch] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
122 | inbuf += 2; | ||
123 | } | ||
124 | |||
125 | for (ch = 0; ch < fmt->channels; ch++) | ||
126 | { | ||
127 | sample[ch][0] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
128 | inbuf += 2; | ||
129 | } | ||
130 | |||
131 | for (ch = 0; ch < fmt->channels; ch++) | ||
132 | { | ||
133 | sample[ch][1] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
134 | inbuf += 2; | ||
135 | } | ||
136 | |||
137 | inbufsize -= 7 * fmt->channels; | ||
138 | ch = fmt->channels - 1; | ||
139 | |||
140 | while (size-- > 0) | ||
141 | { | ||
142 | *outbuf++ = create_pcmdata(0, *inbuf >> 4 ) << (PCM_OUTPUT_DEPTH - 16); | ||
143 | *outbuf++ = create_pcmdata(ch, *inbuf & 0xf) << (PCM_OUTPUT_DEPTH - 16); | ||
144 | nsamples += 2; | ||
145 | |||
146 | inbuf++; | ||
147 | inbufsize--; | ||
148 | if (inbufsize <= 0) | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | if (fmt->channels == 2) | ||
153 | nsamples >>= 1; | ||
154 | *outbufcount = nsamples; | ||
155 | |||
156 | return CODEC_OK; | ||
157 | } | ||
158 | |||
159 | static const struct pcm_codec codec = { | ||
160 | set_format, | ||
161 | get_seek_pos, | ||
162 | decode, | ||
163 | }; | ||
164 | |||
165 | const struct pcm_codec *get_ms_adpcm_codec(void) | ||
166 | { | ||
167 | return &codec; | ||
168 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/pcm_common.h b/lib/rbcodec/codecs/libpcm/pcm_common.h new file mode 100644 index 0000000000..90e29c98ee --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/pcm_common.h | |||
@@ -0,0 +1,190 @@ | |||
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_LIBPCM_PCM_COMMON_H | ||
22 | #define CODEC_LIBPCM_PCM_COMMON_H | ||
23 | |||
24 | #include <stdbool.h> | ||
25 | #include <inttypes.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | /* decoded pcm sample depth (sample 28bit + sign 1bit) */ | ||
29 | #define PCM_OUTPUT_DEPTH 29 | ||
30 | |||
31 | /* Macro that sign extends an unsigned byte */ | ||
32 | #define SE(x) ((int32_t)((int8_t)(x))) | ||
33 | |||
34 | /* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */ | ||
35 | #define SFT(x) ((int32_t)x-0x80) | ||
36 | |||
37 | /* Macro that clipping data */ | ||
38 | #define CLIP(data, min, max) \ | ||
39 | if ((data) > (max)) data = max; \ | ||
40 | else if ((data) < (min)) data = min; | ||
41 | |||
42 | /* nums of msadpcm coeffs | ||
43 | * In many case, nNumCoef is 7. | ||
44 | * Depending upon the encoder, as for this value there is a possibility | ||
45 | * of increasing more. | ||
46 | * If you found the file where this value exceeds 7, please report. | ||
47 | */ | ||
48 | #define MSADPCM_NUM_COEFF 7 | ||
49 | |||
50 | struct pcm_format { | ||
51 | /* | ||
52 | * RIFF: wFormatTag (in 'fmt ' chunk) | ||
53 | * AIFF: compressionType (in 'COMM' chunk) | ||
54 | */ | ||
55 | uint32_t formattag; | ||
56 | |||
57 | /* | ||
58 | * RIFF: wChannels (in 'fmt ' chunk) | ||
59 | * AIFF: numChannels (in 'COMM' chunk) | ||
60 | */ | ||
61 | uint16_t channels; | ||
62 | |||
63 | /* | ||
64 | * RIFF: dwSamplesPerSec (in 'fmt ' chunk) | ||
65 | * AIFF: sampleRate (in 'COMM' chunk) | ||
66 | */ | ||
67 | uint32_t samplespersec; | ||
68 | |||
69 | /* RIFF: dwAvgBytesPerSec (in 'fmt ' chunk) */ | ||
70 | uint32_t avgbytespersec; | ||
71 | |||
72 | /* | ||
73 | * RIFF: wBlockAlign (in 'fmt ' chunk) | ||
74 | * AIFF: blockSize (in 'SSND' chunk) | ||
75 | */ | ||
76 | uint16_t blockalign; | ||
77 | |||
78 | /* | ||
79 | * RIFF: wBitsPerSample (in 'fmt ' chunk) | ||
80 | * AIFF: sampleSize (in 'COMM' chunk) | ||
81 | */ | ||
82 | uint16_t bitspersample; | ||
83 | |||
84 | /* RIFF: wSize (in 'fmt ' chunk) */ | ||
85 | uint16_t size; | ||
86 | |||
87 | /* RIFF: dSamplesPerBlock (in 'fmt ' chunk) */ | ||
88 | uint16_t samplesperblock; | ||
89 | |||
90 | /* RIFF: wTotalSamples (in 'fact' chunk) */ | ||
91 | uint16_t totalsamples; | ||
92 | |||
93 | /* the following values are not RIFF/AIFF chunk values */ | ||
94 | |||
95 | /* bytes per sample */ | ||
96 | int bytespersample; | ||
97 | |||
98 | /* chunk size */ | ||
99 | long chunksize; | ||
100 | |||
101 | /* data size */ | ||
102 | uint32_t numbytes; | ||
103 | |||
104 | /* | ||
105 | * data endian | ||
106 | * true: little endian, false: big endian | ||
107 | */ | ||
108 | bool is_little_endian; | ||
109 | |||
110 | /* | ||
111 | * data signess | ||
112 | * true: signed, false: unsigned | ||
113 | */ | ||
114 | bool is_signed; | ||
115 | |||
116 | /* the following values are format speciffic parameters */ | ||
117 | |||
118 | /* microsoft adpcm: aCoeff */ | ||
119 | int16_t coeffs[MSADPCM_NUM_COEFF][2]; | ||
120 | }; | ||
121 | |||
122 | struct pcm_pos { | ||
123 | uint32_t pos; | ||
124 | uint32_t samples; | ||
125 | }; | ||
126 | |||
127 | #define PCM_SEEK_TIME 0 | ||
128 | #define PCM_SEEK_POS 1 | ||
129 | |||
130 | struct pcm_codec { | ||
131 | /* | ||
132 | * sets the format speciffic RIFF/AIFF header information and checks the pcm_format. | ||
133 | * | ||
134 | * [In/Out] format | ||
135 | * the structure which supplies RIFF/AIFF header information. | ||
136 | * | ||
137 | * return | ||
138 | * true: RIFF/AIFF header check OK | ||
139 | * false: RIFF/AIFF header check NG | ||
140 | */ | ||
141 | bool (*set_format)(struct pcm_format *format); | ||
142 | |||
143 | /* | ||
144 | * get seek position | ||
145 | * | ||
146 | * [In] seek_val | ||
147 | * seek time [ms] or seek position | ||
148 | * | ||
149 | * [In] seek_mode | ||
150 | * if seek_mode sets PCM_SEEK_TIME, then seek_val means the seek time. | ||
151 | * if seek_mode sets PCM_SEEK_POS, then seek_val means the seek position. | ||
152 | * | ||
153 | * [In] read_buffer | ||
154 | * the function which reads the data from the file (chunksize bytes read). | ||
155 | * | ||
156 | * return | ||
157 | * position after the seeking. | ||
158 | */ | ||
159 | struct pcm_pos *(*get_seek_pos)(uint32_t seek_val, int seek_mode, | ||
160 | uint8_t *(*read_buffer)(size_t *realsize)); | ||
161 | |||
162 | /* | ||
163 | * decode wave data. | ||
164 | * | ||
165 | * [In] inbuf | ||
166 | * the start pointer of wave data buffer. | ||
167 | * | ||
168 | * [In] inbufsize | ||
169 | * wave data buffer size (bytes). | ||
170 | * | ||
171 | * [Out] outbuf | ||
172 | * the start pointer of the buffer which supplies decoded pcm data. | ||
173 | * | ||
174 | * [Out] outbufcount | ||
175 | * decoded pcm data count. | ||
176 | * | ||
177 | * return | ||
178 | * CODEC_OK: decode succeed. | ||
179 | * CODEC_ERROR: decode failure. | ||
180 | */ | ||
181 | int (*decode)(const uint8_t *inbuf, size_t inbufsize, | ||
182 | int32_t *outbuf, int *outbufcount); | ||
183 | }; | ||
184 | |||
185 | struct pcm_entry { | ||
186 | uint32_t format_tag; | ||
187 | const struct pcm_codec *(*get_codec)(void); | ||
188 | }; | ||
189 | |||
190 | #endif | ||
diff --git a/lib/rbcodec/codecs/libpcm/qt_ima_adpcm.c b/lib/rbcodec/codecs/libpcm/qt_ima_adpcm.c new file mode 100644 index 0000000000..d7b3360eb3 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/qt_ima_adpcm.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "ima_adpcm_common.h" | ||
23 | #include "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * Apple QuickTime IMA ADPCM | ||
27 | * | ||
28 | * References | ||
29 | * [1] Multimedia Wiki, Apple QuickTime IMA ADPCM | ||
30 | * URL:http://wiki.multimedia.cx/index.php?title=Apple_QuickTime_IMA_ADPCM | ||
31 | * [2] Apple Inc., Technical Note TN1081 Understanding the Differences Between | ||
32 | * Apple and Windows IMA-ADPCM Compressed Sound Files, 1996 | ||
33 | * [3] ffmpeg source code, libavcodec/adpcm.c | ||
34 | */ | ||
35 | |||
36 | static struct pcm_format *fmt; | ||
37 | |||
38 | static bool set_format(struct pcm_format *format) | ||
39 | { | ||
40 | fmt = format; | ||
41 | |||
42 | if (fmt->bitspersample != 4) | ||
43 | { | ||
44 | DEBUGF("CODEC_ERROR: quicktime ima adpcm must be 4 bitspersample: %d\n", | ||
45 | fmt->bitspersample); | ||
46 | return false; | ||
47 | } | ||
48 | |||
49 | fmt->blockalign = 34 * fmt->channels; | ||
50 | fmt->samplesperblock = 64; | ||
51 | |||
52 | /* chunksize = about 1/50[s] data */ | ||
53 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) | ||
54 | * fmt->blockalign; | ||
55 | |||
56 | init_ima_adpcm_decoder(4, NULL); | ||
57 | return true; | ||
58 | } | ||
59 | |||
60 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
61 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
62 | { | ||
63 | static struct pcm_pos newpos; | ||
64 | uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ? | ||
65 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
66 | / fmt->samplesperblock : | ||
67 | seek_val / fmt->blockalign; | ||
68 | |||
69 | (void)read_buffer; | ||
70 | newpos.pos = newblock * fmt->blockalign; | ||
71 | newpos.samples = newblock * fmt->samplesperblock; | ||
72 | return &newpos; | ||
73 | } | ||
74 | |||
75 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
76 | int32_t *outbuf, int *outbufcount) | ||
77 | { | ||
78 | int ch; | ||
79 | size_t nsamples = 0; | ||
80 | int block_size; | ||
81 | int32_t *pcmbuf; | ||
82 | int32_t init_pcmdata; | ||
83 | int8_t init_index; | ||
84 | |||
85 | while (inbufsize > 0) | ||
86 | { | ||
87 | for (ch = 0; ch < fmt->channels; ch++) | ||
88 | { | ||
89 | /* read block header */ | ||
90 | init_pcmdata = (inbuf[0] << 8)|(inbuf[1] & 0x80); | ||
91 | if (init_pcmdata > 32767) | ||
92 | init_pcmdata -= 65536; | ||
93 | |||
94 | init_index = inbuf[1] & 0x7f; | ||
95 | if (init_index > 88) | ||
96 | { | ||
97 | DEBUGF("CODEC_ERROR: quicktime ima adpcm illegal step index=%d > 88\n", | ||
98 | init_index); | ||
99 | return CODEC_ERROR; | ||
100 | } | ||
101 | |||
102 | inbuf += 2; | ||
103 | inbufsize -= 2; | ||
104 | |||
105 | set_decode_parameters(1, &init_pcmdata, &init_index); | ||
106 | |||
107 | /* read block data */ | ||
108 | pcmbuf = outbuf + ch; | ||
109 | for (block_size = 32; block_size > 0 && inbufsize > 0; block_size--, inbufsize--) | ||
110 | { | ||
111 | *pcmbuf = create_pcmdata_size4(ch, *inbuf ) << IMA_ADPCM_INC_DEPTH; | ||
112 | pcmbuf += fmt->channels; | ||
113 | *pcmbuf = create_pcmdata_size4(ch, *inbuf >> 4) << IMA_ADPCM_INC_DEPTH; | ||
114 | pcmbuf += fmt->channels; | ||
115 | nsamples += 2; | ||
116 | inbuf++; | ||
117 | } | ||
118 | } | ||
119 | outbuf += 64 * fmt->channels; | ||
120 | } | ||
121 | |||
122 | if (fmt->channels == 2) | ||
123 | nsamples >>= 1; | ||
124 | *outbufcount = nsamples; | ||
125 | |||
126 | return CODEC_OK; | ||
127 | } | ||
128 | |||
129 | static const struct pcm_codec codec = { | ||
130 | set_format, | ||
131 | get_seek_pos, | ||
132 | decode, | ||
133 | }; | ||
134 | |||
135 | const struct pcm_codec *get_qt_ima_adpcm_codec(void) | ||
136 | { | ||
137 | return &codec; | ||
138 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/support_formats.h b/lib/rbcodec/codecs/libpcm/support_formats.h new file mode 100644 index 0000000000..b1e089e464 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/support_formats.h | |||
@@ -0,0 +1,55 @@ | |||
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_LIBPCM_SUPPORT_FORMATS_H | ||
22 | #define CODEC_LIBPCM_SUPPORT_FORMATS_H | ||
23 | |||
24 | #include "pcm_common.h" | ||
25 | |||
26 | /* Linear PCM */ | ||
27 | const struct pcm_codec *get_linear_pcm_codec(void); | ||
28 | |||
29 | /* ITU-T G.711 A-law */ | ||
30 | const struct pcm_codec *get_itut_g711_alaw_codec(void); | ||
31 | |||
32 | /* ITU-T G.711 mu-law */ | ||
33 | const struct pcm_codec *get_itut_g711_mulaw_codec(void); | ||
34 | |||
35 | /* Intel DVI ADPCM (IMA ADPCM) */ | ||
36 | const struct pcm_codec *get_dvi_adpcm_codec(void); | ||
37 | |||
38 | /* IEEE float */ | ||
39 | const struct pcm_codec *get_ieee_float_codec(void); | ||
40 | |||
41 | /* Microsoft ADPCM */ | ||
42 | const struct pcm_codec *get_ms_adpcm_codec(void); | ||
43 | |||
44 | /* Dialogic OKI ADPCM */ | ||
45 | const struct pcm_codec *get_dialogic_oki_adpcm_codec(void); | ||
46 | |||
47 | /* YAMAHA ADPCM */ | ||
48 | const struct pcm_codec *get_yamaha_adpcm_codec(void); | ||
49 | |||
50 | /* Apple QuickTime IMA ADPCM */ | ||
51 | const struct pcm_codec *get_qt_ima_adpcm_codec(void); | ||
52 | |||
53 | /* Adobe SWF ADPCM */ | ||
54 | const struct pcm_codec *get_swf_adpcm_codec(void); | ||
55 | #endif | ||
diff --git a/lib/rbcodec/codecs/libpcm/swf_adpcm.c b/lib/rbcodec/codecs/libpcm/swf_adpcm.c new file mode 100644 index 0000000000..c440fd1303 --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/swf_adpcm.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "ima_adpcm_common.h" | ||
23 | #include "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * Adobe SWF ADPCM | ||
27 | * | ||
28 | * References | ||
29 | * [1] Adobe, SWF File Format Specification Version 10, 2008 | ||
30 | * [2] Jack Jansen, adpcm.c in adpcm.zip | ||
31 | * [3] ffmpeg source code, libavcodec/adpcm.c | ||
32 | */ | ||
33 | |||
34 | /* step index table when bitspersample is 3. | ||
35 | * (when bitspersample is 2, 4, 5, step index table uses the table | ||
36 | * which is defined ima_adpcm_common.c.) | ||
37 | */ | ||
38 | static const int index_table[4] ICONST_ATTR = { | ||
39 | -1, -1, 2, 4, | ||
40 | }; | ||
41 | |||
42 | static int validity_bits = 8; | ||
43 | static bool first_block = true; | ||
44 | static int blockbits = 0; | ||
45 | static int lastbytebits = 0; | ||
46 | static bool after_seek = false; | ||
47 | |||
48 | static struct pcm_format *fmt; | ||
49 | |||
50 | #define GET_SAMPLE_COUNT(s) ((((s) << 3) / fmt->channels - 22) / fmt->bitspersample + 1) | ||
51 | |||
52 | static bool set_format(struct pcm_format *format) | ||
53 | { | ||
54 | fmt = format; | ||
55 | |||
56 | if (fmt->bitspersample < 2 || fmt->bitspersample > 5) | ||
57 | { | ||
58 | DEBUGF("CODEC_ERROR: swf adpcm must be 2, 3, 4 or 5 bitspersample: %d\n", | ||
59 | fmt->bitspersample); | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | if (fmt->samplesperblock == 0) | ||
64 | fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22) | ||
65 | / fmt->bitspersample + 1; | ||
66 | |||
67 | blockbits = ((fmt->samplesperblock - 1) * fmt->bitspersample + 22) * fmt->channels; | ||
68 | |||
69 | /* | ||
70 | * chunksize = about 93 [ms] data (frequency:44.1kHz, 4096 [sample/block]) | ||
71 | * chunksize changes depending upon the position of block. | ||
72 | */ | ||
73 | fmt->chunksize = (blockbits + 9) >> 3; | ||
74 | |||
75 | /* initialize for ima adpcm common functions */ | ||
76 | if (fmt->bitspersample == 3) | ||
77 | init_ima_adpcm_decoder(fmt->bitspersample, index_table); | ||
78 | else | ||
79 | init_ima_adpcm_decoder(fmt->bitspersample, NULL); | ||
80 | |||
81 | return true; | ||
82 | } | ||
83 | |||
84 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
85 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
86 | { | ||
87 | static struct pcm_pos newpos; | ||
88 | uint32_t chunkbits = blockbits; | ||
89 | uint32_t seekblocks = (seek_mode == PCM_SEEK_TIME)? | ||
90 | ((uint64_t)seek_val * ci->id3->frequency) | ||
91 | / (1000LL * fmt->samplesperblock) : | ||
92 | ((seek_val << 3) - 2) / blockbits; | ||
93 | uint32_t seekbits = seekblocks * blockbits + 2; | ||
94 | |||
95 | (void)read_buffer; | ||
96 | |||
97 | newpos.pos = seekbits >> 3; | ||
98 | newpos.samples = seekblocks * fmt->samplesperblock; | ||
99 | |||
100 | if (newpos.pos == 0) | ||
101 | { | ||
102 | first_block = true; | ||
103 | lastbytebits = 0; | ||
104 | } | ||
105 | else | ||
106 | { | ||
107 | first_block = false; | ||
108 | lastbytebits = seekbits & 0x07; | ||
109 | if (lastbytebits != 0) | ||
110 | chunkbits -= (8 - lastbytebits); | ||
111 | } | ||
112 | |||
113 | /* calculates next read bytes */ | ||
114 | fmt->chunksize = (chunkbits >> 3) + (((chunkbits & 0x07) > 0)?1:0) | ||
115 | + ((lastbytebits > 0)?1:0); | ||
116 | |||
117 | after_seek = true; | ||
118 | return &newpos; | ||
119 | } | ||
120 | |||
121 | static uint8_t get_data(const uint8_t **buf, int bit) | ||
122 | { | ||
123 | uint8_t res = 0; | ||
124 | uint8_t mask = (1 << bit) - 1; | ||
125 | |||
126 | if (validity_bits >= bit) | ||
127 | { | ||
128 | validity_bits -= bit; | ||
129 | return (**buf >> validity_bits) & mask; | ||
130 | } | ||
131 | |||
132 | if (validity_bits > 0) | ||
133 | res = **buf << (bit - validity_bits); | ||
134 | |||
135 | validity_bits += 8 - bit; | ||
136 | res = (res | (*(++(*buf)) >> validity_bits)) & mask; | ||
137 | return res; | ||
138 | } | ||
139 | |||
140 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
141 | int32_t *outbuf, int *outbufcount) | ||
142 | { | ||
143 | int ch; | ||
144 | int adpcm_code_size; | ||
145 | int count = ((size_t)fmt->chunksize == inbufsize) ? fmt->samplesperblock : | ||
146 | GET_SAMPLE_COUNT(inbufsize); | ||
147 | int32_t init_pcmdata[2]; | ||
148 | int8_t init_index[2]; | ||
149 | static uint8_t lastbyte = 0; | ||
150 | |||
151 | validity_bits = 8; | ||
152 | *outbufcount = count; | ||
153 | |||
154 | /* read block header */ | ||
155 | ch = fmt->channels - 1; | ||
156 | if (first_block) | ||
157 | { | ||
158 | adpcm_code_size = get_data(&inbuf, 2) + 2; | ||
159 | if (fmt->bitspersample != adpcm_code_size) | ||
160 | { | ||
161 | DEBUGF("CODEC_ERROR: swf adpcm different adpcm code size=%d != %d\n", | ||
162 | adpcm_code_size, fmt->bitspersample); | ||
163 | return CODEC_ERROR; | ||
164 | } | ||
165 | init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
166 | |||
167 | lastbytebits = 0; | ||
168 | first_block = false; | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | if (after_seek && lastbytebits > 0) | ||
173 | { | ||
174 | lastbyte = *inbuf++; | ||
175 | after_seek = false; | ||
176 | } | ||
177 | if (lastbytebits > 0) | ||
178 | init_pcmdata[0] = ((lastbyte << (8 + lastbytebits)) | | ||
179 | (get_data(&inbuf, 8) << lastbytebits) | | ||
180 | get_data(&inbuf, lastbytebits)) & 65535; | ||
181 | else | ||
182 | init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
183 | } | ||
184 | after_seek = false; | ||
185 | |||
186 | init_index[0] = get_data(&inbuf, 6); | ||
187 | if (init_pcmdata[0] > 32767) | ||
188 | init_pcmdata[0] -= 65536; | ||
189 | |||
190 | if (ch > 0) | ||
191 | { | ||
192 | init_pcmdata[1] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
193 | init_index[1] = get_data(&inbuf, 6); | ||
194 | if (init_pcmdata[1] > 32767) | ||
195 | init_pcmdata[1] -= 65536; | ||
196 | } | ||
197 | |||
198 | *outbuf++ = init_pcmdata[0] << IMA_ADPCM_INC_DEPTH; | ||
199 | if (ch > 0) | ||
200 | *outbuf++ = init_pcmdata[1] << IMA_ADPCM_INC_DEPTH; | ||
201 | |||
202 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); | ||
203 | |||
204 | /* read block data */ | ||
205 | while (--count > 0) | ||
206 | { | ||
207 | *outbuf++ = create_pcmdata(0, get_data(&inbuf, fmt->bitspersample)) | ||
208 | << IMA_ADPCM_INC_DEPTH; | ||
209 | if (ch > 0) | ||
210 | *outbuf++ = create_pcmdata(ch, get_data(&inbuf, fmt->bitspersample)) | ||
211 | << IMA_ADPCM_INC_DEPTH; | ||
212 | } | ||
213 | |||
214 | lastbyte = *inbuf; | ||
215 | lastbytebits = (8 - validity_bits) & 0x07; | ||
216 | |||
217 | /* calculates next read bytes */ | ||
218 | fmt->chunksize = (blockbits - validity_bits + 7) >> 3; | ||
219 | |||
220 | return CODEC_OK; | ||
221 | } | ||
222 | |||
223 | static const struct pcm_codec codec = { | ||
224 | set_format, | ||
225 | get_seek_pos, | ||
226 | decode, | ||
227 | }; | ||
228 | |||
229 | const struct pcm_codec *get_swf_adpcm_codec(void) | ||
230 | { | ||
231 | first_block = true; | ||
232 | lastbytebits = 0; | ||
233 | after_seek = false; | ||
234 | |||
235 | return &codec; | ||
236 | } | ||
diff --git a/lib/rbcodec/codecs/libpcm/yamaha_adpcm.c b/lib/rbcodec/codecs/libpcm/yamaha_adpcm.c new file mode 100644 index 0000000000..c67fe7524a --- /dev/null +++ b/lib/rbcodec/codecs/libpcm/yamaha_adpcm.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 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 | #include "codeclib.h" | ||
22 | #include "adpcm_seek.h" | ||
23 | #include "support_formats.h" | ||
24 | |||
25 | /* | ||
26 | * YAMAHA ADPCM | ||
27 | * | ||
28 | * References | ||
29 | * [1] YAMAHA, YAMAHA ADPCM ACM Driver Version 1.0.0.0, 2005 | ||
30 | * [2] BlendWorks, YM2608 ADPCM, | ||
31 | * http://web.archive.org/web/20050208190547/www.memb.jp/~dearna/ma/ym2608/adpcm.html | ||
32 | * [3] Naoyuki Sawa, ADPCM no shikumi #1, | ||
33 | * http://www.piece-me.org/piece-lab/adpcm/adpcm1.html | ||
34 | * [4] ffmpeg source code, libavcodec/adpcm.c | ||
35 | */ | ||
36 | |||
37 | /* ADPCM data block layout | ||
38 | * | ||
39 | * when the block header exists. (for example, encoding by YAMAHA ADPCM ACM Driver) | ||
40 | * blockAlign = (frequency / 60 + 4) * channels. | ||
41 | * | ||
42 | * block | ||
43 | * <Mono> (channels = 1) | ||
44 | * int16_t first value (Little endian) | ||
45 | * uint16_t first predictor (Little endian) | ||
46 | * uint8_t ADPCM data (1st data: 0-3 bit, 2nd data: 4-7 bit) | ||
47 | * .... | ||
48 | * | ||
49 | * <Stereo> (channels = 2) | ||
50 | * int16_t Left channel first value (Little endian) | ||
51 | * uint16_t Left channel first predictor (Little endian) | ||
52 | * int16_t Right channel first value (Little endian) | ||
53 | * uint16_t Right channel first predictor (Little endian) | ||
54 | * uint8_t ADPCM data (Left channel: 0-3 bit, Right channel: 4-7 bit) | ||
55 | * .... | ||
56 | * | ||
57 | * when the block header does not exist. (for example, encoding by ffmpeg) | ||
58 | * blockAlign = 8000 | ||
59 | * | ||
60 | * block | ||
61 | * <Mono> (channels = 1) | ||
62 | * uint8_t ADPCM data (1st data: 0-3 bit, 2nd data: 4-7 bit) | ||
63 | * .... | ||
64 | * | ||
65 | * <Stereo> (channels = 2) | ||
66 | * uint8_t ADPCM data (Left channel: 0-3 bit, Right channel: 4-7 bit) | ||
67 | * .... | ||
68 | */ | ||
69 | |||
70 | static const int32_t amplification_table[] ICONST_ATTR = { | ||
71 | 230, 230, 230, 230, 307, 409, 512, 614, 230, 230, 230, 230, 307, 409, 512, 614 | ||
72 | }; | ||
73 | |||
74 | static bool has_block_header = false; | ||
75 | |||
76 | static struct adpcm_data cur_data; | ||
77 | static int blocksperchunk; | ||
78 | |||
79 | static struct pcm_format *fmt; | ||
80 | |||
81 | static bool set_format(struct pcm_format *format) | ||
82 | { | ||
83 | fmt = format; | ||
84 | |||
85 | if (fmt->channels == 0) | ||
86 | { | ||
87 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
88 | return false; | ||
89 | } | ||
90 | |||
91 | if (fmt->bitspersample != 4) | ||
92 | { | ||
93 | DEBUGF("CODEC_ERROR: yamaha adpcm must be 4 bitspersample: %d\n", | ||
94 | fmt->bitspersample); | ||
95 | return false; | ||
96 | } | ||
97 | |||
98 | /* check exists block header */ | ||
99 | if (fmt->blockalign == ((ci->id3->frequency / 60) + 4) * fmt->channels) | ||
100 | { | ||
101 | has_block_header = true; | ||
102 | |||
103 | /* chunksize = about 1/30 [sec] data */ | ||
104 | fmt->chunksize = fmt->blockalign; | ||
105 | blocksperchunk = 1; | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | uint32_t max_chunk_count; | ||
110 | |||
111 | has_block_header = false; | ||
112 | |||
113 | /* blockalign = 2 * channels samples */ | ||
114 | fmt->blockalign = fmt->channels; | ||
115 | fmt->samplesperblock = 2; | ||
116 | |||
117 | /* chunksize = about 1/32[sec] data */ | ||
118 | blocksperchunk = ci->id3->frequency >> 6; | ||
119 | fmt->chunksize = blocksperchunk * fmt->blockalign; | ||
120 | |||
121 | max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency | ||
122 | / (2000LL * fmt->chunksize / fmt->channels); | ||
123 | |||
124 | /* initialize seek table */ | ||
125 | init_seek_table(max_chunk_count); | ||
126 | /* add first data */ | ||
127 | add_adpcm_data(&cur_data); | ||
128 | } | ||
129 | |||
130 | return true; | ||
131 | } | ||
132 | |||
133 | static int16_t create_pcmdata(int ch, uint8_t nibble) | ||
134 | { | ||
135 | int32_t tmp_pcmdata = cur_data.pcmdata[ch]; | ||
136 | int32_t step = cur_data.step[ch]; | ||
137 | int32_t delta = step >> 3; | ||
138 | |||
139 | if (nibble & 4) delta += step; | ||
140 | if (nibble & 2) delta += (step >> 1); | ||
141 | if (nibble & 1) delta += (step >> 2); | ||
142 | |||
143 | if (nibble & 0x08) | ||
144 | tmp_pcmdata -= delta; | ||
145 | else | ||
146 | tmp_pcmdata += delta; | ||
147 | |||
148 | CLIP(tmp_pcmdata, -32768, 32767); | ||
149 | cur_data.pcmdata[ch] = tmp_pcmdata; | ||
150 | |||
151 | step = (step * amplification_table[nibble & 0x07]) >> 8; | ||
152 | CLIP(step, 127, 24576); | ||
153 | cur_data.step[ch] = step; | ||
154 | |||
155 | return cur_data.pcmdata[ch]; | ||
156 | } | ||
157 | |||
158 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
159 | int32_t *outbuf, int *outbufcount) | ||
160 | { | ||
161 | int ch; | ||
162 | size_t nsamples = 0; | ||
163 | |||
164 | /* read block header */ | ||
165 | if (has_block_header) | ||
166 | { | ||
167 | for (ch = 0; ch < fmt->channels; ch++) | ||
168 | { | ||
169 | cur_data.pcmdata[ch] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
170 | cur_data.step[ch] = inbuf[2] | (inbuf[3] << 8); | ||
171 | |||
172 | inbuf += 4; | ||
173 | inbufsize -= 4; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /* read block data */ | ||
178 | ch = fmt->channels - 1; | ||
179 | while (inbufsize) | ||
180 | { | ||
181 | *outbuf++ = create_pcmdata(0, *inbuf ) << (PCM_OUTPUT_DEPTH - 16); | ||
182 | *outbuf++ = create_pcmdata(ch, *inbuf >> 4) << (PCM_OUTPUT_DEPTH - 16); | ||
183 | nsamples += 2; | ||
184 | |||
185 | inbuf++; | ||
186 | inbufsize--; | ||
187 | } | ||
188 | |||
189 | if (fmt->channels == 2) | ||
190 | nsamples >>= 1; | ||
191 | *outbufcount = nsamples; | ||
192 | |||
193 | if (!has_block_header) | ||
194 | add_adpcm_data(&cur_data); | ||
195 | |||
196 | return CODEC_OK; | ||
197 | } | ||
198 | |||
199 | static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize) | ||
200 | { | ||
201 | int ch = fmt->channels - 1; | ||
202 | |||
203 | while (inbufsize) | ||
204 | { | ||
205 | create_pcmdata(0, *inbuf ); | ||
206 | create_pcmdata(ch, *inbuf >> 4); | ||
207 | |||
208 | inbuf++; | ||
209 | inbufsize--; | ||
210 | } | ||
211 | |||
212 | add_adpcm_data(&cur_data); | ||
213 | |||
214 | return CODEC_OK; | ||
215 | } | ||
216 | |||
217 | static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode, | ||
218 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
219 | { | ||
220 | static struct pcm_pos newpos; | ||
221 | uint32_t new_count = (seek_mode == PCM_SEEK_TIME)? | ||
222 | ((uint64_t)seek_val * ci->id3->frequency / 1000LL) | ||
223 | / (blocksperchunk * fmt->samplesperblock) : | ||
224 | seek_val / (unsigned long)fmt->chunksize; | ||
225 | |||
226 | if (!has_block_header) | ||
227 | { | ||
228 | new_count = seek(new_count, &cur_data, read_buffer, &decode_for_seek); | ||
229 | } | ||
230 | newpos.pos = new_count * fmt->chunksize; | ||
231 | newpos.samples = new_count * blocksperchunk * fmt->samplesperblock; | ||
232 | return &newpos; | ||
233 | } | ||
234 | |||
235 | static struct pcm_codec codec = { | ||
236 | set_format, | ||
237 | get_seek_pos, | ||
238 | decode, | ||
239 | }; | ||
240 | |||
241 | const struct pcm_codec *get_yamaha_adpcm_codec(void) | ||
242 | { | ||
243 | /* initialize first step, pcm data */ | ||
244 | cur_data.pcmdata[0] = 0; | ||
245 | cur_data.pcmdata[1] = 0; | ||
246 | cur_data.step[0] = 127; | ||
247 | cur_data.step[1] = 127; | ||
248 | |||
249 | return &codec; | ||
250 | } | ||