diff options
Diffstat (limited to 'apps/codecs/libpcm')
-rw-r--r-- | apps/codecs/libpcm/SOURCES | 7 | ||||
-rw-r--r-- | apps/codecs/libpcm/adpcm_seek.c | 101 | ||||
-rw-r--r-- | apps/codecs/libpcm/adpcm_seek.h | 39 | ||||
-rw-r--r-- | apps/codecs/libpcm/dialogic_oki_adpcm.c | 183 | ||||
-rw-r--r-- | apps/codecs/libpcm/dvi_adpcm.c | 444 | ||||
-rw-r--r-- | apps/codecs/libpcm/ieee_float.c | 29 | ||||
-rw-r--r-- | apps/codecs/libpcm/ima_adpcm_common.c | 171 | ||||
-rw-r--r-- | apps/codecs/libpcm/ima_adpcm_common.h | 32 | ||||
-rw-r--r-- | apps/codecs/libpcm/itut_g711.c | 44 | ||||
-rw-r--r-- | apps/codecs/libpcm/linear_pcm.c | 39 | ||||
-rw-r--r-- | apps/codecs/libpcm/ms_adpcm.c | 166 | ||||
-rw-r--r-- | apps/codecs/libpcm/pcm_common.h | 77 | ||||
-rw-r--r-- | apps/codecs/libpcm/qt_ima_adpcm.c | 136 | ||||
-rw-r--r-- | apps/codecs/libpcm/support_formats.h | 21 | ||||
-rw-r--r-- | apps/codecs/libpcm/swf_adpcm.c | 233 | ||||
-rw-r--r-- | apps/codecs/libpcm/yamaha_adpcm.c | 245 |
16 files changed, 1681 insertions, 286 deletions
diff --git a/apps/codecs/libpcm/SOURCES b/apps/codecs/libpcm/SOURCES index 89be3452b1..356c9cdbb7 100644 --- a/apps/codecs/libpcm/SOURCES +++ b/apps/codecs/libpcm/SOURCES | |||
@@ -2,3 +2,10 @@ linear_pcm.c | |||
2 | itut_g711.c | 2 | itut_g711.c |
3 | dvi_adpcm.c | 3 | dvi_adpcm.c |
4 | ieee_float.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/apps/codecs/libpcm/adpcm_seek.c b/apps/codecs/libpcm/adpcm_seek.c new file mode 100644 index 0000000000..ce49d5fcd3 --- /dev/null +++ b/apps/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/apps/codecs/libpcm/adpcm_seek.h b/apps/codecs/libpcm/adpcm_seek.h new file mode 100644 index 0000000000..66ec390097 --- /dev/null +++ b/apps/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 <sys/types.h> | ||
25 | #include <stdbool.h> | ||
26 | #include <inttypes.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/apps/codecs/libpcm/dialogic_oki_adpcm.c b/apps/codecs/libpcm/dialogic_oki_adpcm.c new file mode 100644 index 0000000000..e12930057b --- /dev/null +++ b/apps/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 "pcm_common.h" | ||
23 | #include "adpcm_seek.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 | |||
48 | static struct pcm_format *fmt; | ||
49 | |||
50 | static bool set_format(struct pcm_format *format) | ||
51 | { | ||
52 | uint32_t max_chunk_count; | ||
53 | |||
54 | fmt = format; | ||
55 | |||
56 | if (fmt->bitspersample != 4) | ||
57 | { | ||
58 | DEBUGF("CODEC_ERROR: dialogic oki adpcm must be 4 bitspersample: %d\n", | ||
59 | fmt->bitspersample); | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | if (fmt->channels != 1) | ||
64 | { | ||
65 | DEBUGF("CODEC_ERROR: dialogic oki adpcm must be monaural\n"); | ||
66 | return false; | ||
67 | } | ||
68 | |||
69 | /* blockalign = 2 samples */ | ||
70 | fmt->blockalign = 1; | ||
71 | fmt->samplesperblock = 2; | ||
72 | |||
73 | /* chunksize = about 1/32[sec] data */ | ||
74 | fmt->chunksize = ci->id3->frequency >> 6; | ||
75 | |||
76 | max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency | ||
77 | / (2000LL * fmt->chunksize); | ||
78 | |||
79 | /* initialize seek table */ | ||
80 | init_seek_table(max_chunk_count); | ||
81 | /* add first data */ | ||
82 | add_adpcm_data(&cur_data); | ||
83 | |||
84 | return true; | ||
85 | } | ||
86 | |||
87 | static int16_t create_pcmdata(uint8_t nibble) | ||
88 | { | ||
89 | int16_t delta; | ||
90 | int16_t index = cur_data.step[0]; | ||
91 | int16_t step = step_table[index]; | ||
92 | |||
93 | delta = (step >> 3); | ||
94 | if (nibble & 4) delta += step; | ||
95 | if (nibble & 2) delta += (step >> 1); | ||
96 | if (nibble & 1) delta += (step >> 2); | ||
97 | |||
98 | if (nibble & 0x08) | ||
99 | cur_data.pcmdata[0] -= delta; | ||
100 | else | ||
101 | cur_data.pcmdata[0] += delta; | ||
102 | |||
103 | CLIP(cur_data.pcmdata[0], -2048, 2047); | ||
104 | |||
105 | index += index_table[nibble & 0x07]; | ||
106 | CLIP(index, 0, 48); | ||
107 | cur_data.step[0] = index; | ||
108 | |||
109 | return cur_data.pcmdata[0]; | ||
110 | } | ||
111 | |||
112 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
113 | int32_t *outbuf, int *outbufcount) | ||
114 | { | ||
115 | size_t nsamples = 0; | ||
116 | |||
117 | while (inbufsize) | ||
118 | { | ||
119 | *outbuf++ = create_pcmdata(*inbuf >> 4) << 17; | ||
120 | *outbuf++ = create_pcmdata(*inbuf ) << 17; | ||
121 | nsamples += 2; | ||
122 | |||
123 | inbuf++; | ||
124 | inbufsize--; | ||
125 | } | ||
126 | |||
127 | *outbufcount = nsamples; | ||
128 | add_adpcm_data(&cur_data); | ||
129 | |||
130 | return CODEC_OK; | ||
131 | } | ||
132 | |||
133 | static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize) | ||
134 | { | ||
135 | while (inbufsize) | ||
136 | { | ||
137 | create_pcmdata(*inbuf >> 4); | ||
138 | create_pcmdata(*inbuf ); | ||
139 | |||
140 | inbuf++; | ||
141 | inbufsize--; | ||
142 | } | ||
143 | |||
144 | add_adpcm_data(&cur_data); | ||
145 | |||
146 | return CODEC_OK; | ||
147 | } | ||
148 | |||
149 | static struct pcm_pos *get_seek_pos(long seek_time, | ||
150 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
151 | { | ||
152 | static struct pcm_pos newpos; | ||
153 | uint32_t seek_count = 0; | ||
154 | uint32_t new_count; | ||
155 | |||
156 | if (seek_time > 0) | ||
157 | seek_count = (uint64_t)seek_time * ci->id3->frequency | ||
158 | / (2000LL * fmt->chunksize); | ||
159 | |||
160 | new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek); | ||
161 | newpos.pos = new_count * fmt->chunksize; | ||
162 | newpos.samples = (newpos.pos / fmt->blockalign) * 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/apps/codecs/libpcm/dvi_adpcm.c b/apps/codecs/libpcm/dvi_adpcm.c index 3df5e901be..97ba017451 100644 --- a/apps/codecs/libpcm/dvi_adpcm.c +++ b/apps/codecs/libpcm/dvi_adpcm.c | |||
@@ -21,280 +21,282 @@ | |||
21 | ****************************************************************************/ | 21 | ****************************************************************************/ |
22 | #include "codeclib.h" | 22 | #include "codeclib.h" |
23 | #include "pcm_common.h" | 23 | #include "pcm_common.h" |
24 | #include "support_formats.h" | 24 | #include "ima_adpcm_common.h" |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Intel DVI ADPCM | 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 | ||
28 | */ | 36 | */ |
29 | 37 | ||
30 | static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = { | ||
31 | 7, 8, 9, 10, 11, 12, 13, 14, | ||
32 | 16, 17, 19, 21, 23, 25, 28, 31, | ||
33 | 34, 37, 41, 45, 50, 55, 60, 66, | ||
34 | 73, 80, 88, 97, 107, 118, 130, 143, | ||
35 | 157, 173, 190, 209, 230, 253, 279, 307, | ||
36 | 337, 371, 408, 449, 494, 544, 598, 658, | ||
37 | 724, 796, 876, 963, 1060, 1166, 1282, 1411, | ||
38 | 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, | ||
39 | 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, | ||
40 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | ||
41 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, | ||
42 | 32767 }; | ||
43 | |||
44 | static const int dvi_adpcm_indextab4[8] ICONST_ATTR = { | ||
45 | -1, -1, -1, -1, 2, 4, 6, 8 }; | ||
46 | |||
47 | static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 }; | ||
48 | |||
49 | static struct pcm_format *fmt; | 38 | static struct pcm_format *fmt; |
50 | 39 | ||
51 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | 40 | static bool set_format(struct pcm_format *format) |
52 | { | 41 | { |
53 | fmt = format; | 42 | fmt = format; |
54 | 43 | ||
55 | (void)fmtpos; | 44 | if (fmt->bitspersample < 2 || fmt->bitspersample > 5) |
56 | |||
57 | if (fmt->bitspersample != 4 && fmt->bitspersample != 3) | ||
58 | { | 45 | { |
59 | DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n"); | 46 | DEBUGF("CODEC_ERROR: dvi adpcm must be 2, 3, 4 or 5 bitspersample: %d\n", |
47 | fmt->bitspersample); | ||
60 | return false; | 48 | return false; |
61 | } | 49 | } |
62 | 50 | ||
63 | if (fmt->size < 2) { | 51 | fmt->chunksize = fmt->blockalign; |
64 | DEBUGF("CODEC_ERROR: dvi_adpcm is missing SamplesPerBlock value\n"); | ||
65 | return false; | ||
66 | } | ||
67 | |||
68 | /* chunksize is computed so that one chunk is about 1/50s. | ||
69 | * this make 4096 for 44.1kHz 16bits stereo. | ||
70 | * It also has to be a multiple of blockalign */ | ||
71 | fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign; | ||
72 | |||
73 | /* check that the output buffer is big enough (convert to samplespersec, | ||
74 | then round to the blockalign multiple below) */ | ||
75 | if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3) | ||
76 | /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE) | ||
77 | fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec | ||
78 | /((uint64_t)ci->id3->frequency * fmt->channels * 2 | ||
79 | * fmt->blockalign)) * fmt->blockalign; | ||
80 | 52 | ||
53 | init_ima_adpcm_decoder(fmt->bitspersample, NULL); | ||
81 | return true; | 54 | return true; |
82 | } | 55 | } |
83 | 56 | ||
84 | static uint32_t get_seek_pos(long seek_time) | 57 | static struct pcm_pos *get_seek_pos(long seek_time, |
58 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
85 | { | 59 | { |
86 | uint32_t newpos; | 60 | static struct pcm_pos newpos; |
61 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | ||
62 | / (1000LL * fmt->samplesperblock); | ||
87 | 63 | ||
88 | /* use avgbytespersec to round to the closest blockalign multiple, | 64 | (void)read_buffer; |
89 | add firstblockposn. 64-bit casts to avoid overflows. */ | 65 | newpos.pos = newblock * fmt->blockalign; |
90 | newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) | 66 | newpos.samples = newblock * fmt->samplesperblock; |
91 | / (1000LL*fmt->blockalign))*fmt->blockalign; | 67 | return &newpos; |
92 | return newpos; | ||
93 | } | 68 | } |
94 | 69 | ||
95 | static int decode_dvi_adpcm(const uint8_t *inbuf, size_t inbufsize, | 70 | static inline void decode_2bit(const uint8_t **inbuf, |
96 | int32_t *outbuf, size_t *outbufcount) | 71 | int32_t **outbuf, int *outbufcount) |
97 | { | 72 | { |
98 | size_t nsamples = 0; | 73 | int ch; |
99 | int sample[2]; | ||
100 | int samplecode[32][2]; | ||
101 | int i; | 74 | int i; |
102 | int stepindex[2]; | 75 | int32_t *pcmbuf; |
103 | int c; | 76 | int samples; |
104 | int diff; | ||
105 | int step; | ||
106 | int codem; | ||
107 | int code; | ||
108 | 77 | ||
109 | if (fmt->bitspersample != 4 && fmt->bitspersample != 3) { | 78 | samples = fmt->blockalign / (4 * fmt->channels) - 1; |
110 | DEBUGF("decode_dvi_adpcm: wrong bitspersample\n"); | 79 | *outbufcount += (samples << 4); |
111 | return CODEC_ERROR; | 80 | while (samples-- > 0) |
81 | { | ||
82 | for (ch = 0; ch < fmt->channels; ch++) | ||
83 | { | ||
84 | pcmbuf = *outbuf + ch; | ||
85 | for (i = 0; i < 4; i++) | ||
86 | { | ||
87 | *pcmbuf = create_pcmdata(ch, **inbuf ) << 13; | ||
88 | pcmbuf += fmt->channels; | ||
89 | *pcmbuf = create_pcmdata(ch, **inbuf >> 2) << 13; | ||
90 | pcmbuf += fmt->channels; | ||
91 | *pcmbuf = create_pcmdata(ch, **inbuf >> 4) << 13; | ||
92 | pcmbuf += fmt->channels; | ||
93 | *pcmbuf = create_pcmdata(ch, **inbuf >> 6) << 13; | ||
94 | pcmbuf += fmt->channels; | ||
95 | (*inbuf)++; | ||
96 | } | ||
97 | } | ||
98 | *outbuf += 16 * fmt->channels; | ||
112 | } | 99 | } |
100 | } | ||
113 | 101 | ||
114 | /* decode block header */ | 102 | static inline void decode_3bit(const uint8_t **inbuf, |
115 | for (c = 0; c < fmt->channels && inbufsize >= 4; c++) { | 103 | int32_t **outbuf, int *outbufcount) |
116 | /* decode + push first sample */ | 104 | { |
117 | sample[c] = (short)(inbuf[0]|(inbuf[1]<<8));/* need cast for sign-extend */ | 105 | const uint8_t *adpcmbuf; |
118 | outbuf[c] = sample[c] << 13; | 106 | uint32_t adpcms; |
119 | nsamples++; | 107 | int ch; |
120 | stepindex[c] = inbuf[2]; | 108 | int i; |
121 | /* check for step table index overflow */ | 109 | int32_t *pcmbuf; |
122 | if (stepindex[c] > 88) { | 110 | int samples; |
123 | DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]); | ||
124 | return CODEC_ERROR; | ||
125 | } | ||
126 | 111 | ||
127 | inbuf += 4; | 112 | samples = (fmt->blockalign - 4 * fmt->channels) / (12 * fmt->channels); |
128 | inbufsize -= 4; | 113 | *outbufcount += (samples << 5); |
129 | } | 114 | while (samples--) |
130 | if (fmt->bitspersample == 4) { | 115 | { |
131 | while (inbufsize >= (size_t)(fmt->channels*4) && | 116 | for (ch = 0; ch < fmt->channels; ch++) |
132 | (nsamples + (fmt->channels*8) <= *outbufcount)) | ||
133 | { | 117 | { |
134 | for (c = 0; c < fmt->channels; c++) | 118 | adpcmbuf = *inbuf + ch * 4; |
119 | pcmbuf = *outbuf + ch; | ||
120 | adpcms = *adpcmbuf++; | ||
121 | adpcms |= (*adpcmbuf++) << 8; | ||
122 | adpcms |= (*adpcmbuf++) << 16; | ||
123 | for (i = 0; i < 8; i++) | ||
135 | { | 124 | { |
136 | samplecode[0][c] = inbuf[0]&0xf; | 125 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13; |
137 | samplecode[1][c] = inbuf[0]>>4; | 126 | pcmbuf += fmt->channels; |
138 | samplecode[2][c] = inbuf[1]&0xf; | ||
139 | samplecode[3][c] = inbuf[1]>>4; | ||
140 | samplecode[4][c] = inbuf[2]&0xf; | ||
141 | samplecode[5][c] = inbuf[2]>>4; | ||
142 | samplecode[6][c] = inbuf[3]&0xf; | ||
143 | samplecode[7][c] = inbuf[3]>>4; | ||
144 | inbuf += 4; | ||
145 | inbufsize -= 4; | ||
146 | } | 127 | } |
128 | adpcms = *adpcmbuf++; | ||
129 | adpcmbuf += (fmt->channels - 1) * 4; | ||
130 | adpcms |= (*adpcmbuf++) << 8; | ||
131 | adpcms |= (*adpcmbuf++) << 16; | ||
147 | for (i = 0; i < 8; i++) | 132 | for (i = 0; i < 8; i++) |
148 | { | 133 | { |
149 | for (c = 0; c < fmt->channels; c++) | 134 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13; |
150 | { | 135 | pcmbuf += fmt->channels; |
151 | step = dvi_adpcm_steptab[stepindex[c]]; | ||
152 | codem = samplecode[i][c]; | ||
153 | code = codem & 0x07; | ||
154 | |||
155 | /* adjust the step table index */ | ||
156 | stepindex[c] += dvi_adpcm_indextab4[code]; | ||
157 | /* check for step table index overflow and underflow */ | ||
158 | if (stepindex[c] > 88) | ||
159 | stepindex[c] = 88; | ||
160 | else if (stepindex[c] < 0) | ||
161 | stepindex[c] = 0; | ||
162 | /* calculate the difference */ | ||
163 | #ifdef STRICT_IMA | ||
164 | diff = 0; | ||
165 | if (code & 4) | ||
166 | diff += step; | ||
167 | step = step >> 1; | ||
168 | if (code & 2) | ||
169 | diff += step; | ||
170 | step = step >> 1; | ||
171 | if (code & 1) | ||
172 | diff += step; | ||
173 | step = step >> 1; | ||
174 | diff += step; | ||
175 | #else | ||
176 | diff = ((code + code + 1) * step) >> 3; /* faster */ | ||
177 | #endif | ||
178 | /* check the sign bit */ | ||
179 | /* check for overflow and underflow errors */ | ||
180 | if (code != codem) | ||
181 | { | ||
182 | sample[c] -= diff; | ||
183 | if (sample[c] < -32768) | ||
184 | sample[c] = -32768; | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | sample[c] += diff; | ||
189 | if (sample[c] > 32767) | ||
190 | sample[c] = 32767; | ||
191 | } | ||
192 | /* output the new sample */ | ||
193 | outbuf[nsamples] = sample[c] << 13; | ||
194 | nsamples++; | ||
195 | } | ||
196 | } | 136 | } |
197 | } | 137 | adpcms = *adpcmbuf++; |
198 | } else { /* bitspersample == 3 */ | 138 | adpcms |= (*adpcmbuf++) << 8; |
199 | while (inbufsize >= (uint32_t)(fmt->channels*12) && | 139 | adpcmbuf += (fmt->channels - 1) * 4; |
200 | (nsamples + 32*fmt->channels) <= *outbufcount) { | 140 | adpcms |= (*adpcmbuf++) << 16; |
201 | for (c = 0; c < fmt->channels; c++) { | 141 | for (i = 0; i < 8; i++) |
202 | uint16_t bitstream = 0; | 142 | { |
203 | int bitsread = 0; | 143 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13; |
204 | for (i = 0; i < 32 && inbufsize > 0; i++) { | 144 | pcmbuf += fmt->channels; |
205 | if (bitsread < 3) { | ||
206 | /* read 8 more bits */ | ||
207 | bitstream |= inbuf[0]<<bitsread; | ||
208 | bitsread += 8; | ||
209 | inbufsize--; | ||
210 | inbuf++; | ||
211 | } | ||
212 | samplecode[i][c] = bitstream & 7; | ||
213 | bitstream = bitstream>>3; | ||
214 | bitsread -= 3; | ||
215 | } | ||
216 | if (bitsread != 0) { | ||
217 | /* 32*3 = 3 words, so we should end with bitsread==0 */ | ||
218 | DEBUGF("decode_dvi_adpcm: error in implementation\n"); | ||
219 | return CODEC_ERROR; | ||
220 | } | ||
221 | } | 145 | } |
222 | 146 | adpcms = *adpcmbuf++; | |
223 | for (i = 0; i < 32; i++) { | 147 | adpcms |= (*adpcmbuf++) << 8; |
224 | for (c = 0; c < fmt->channels; c++) { | 148 | adpcms |= (*adpcmbuf++) << 16; |
225 | step = dvi_adpcm_steptab[stepindex[c]]; | 149 | for (i = 0; i < 8; i++) |
226 | codem = samplecode[i][c]; | 150 | { |
227 | code = codem & 0x03; | 151 | *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13; |
228 | 152 | pcmbuf += fmt->channels; | |
229 | /* adjust the step table index */ | ||
230 | stepindex[c] += dvi_adpcm_indextab3[code]; | ||
231 | /* check for step table index overflow and underflow */ | ||
232 | if (stepindex[c] > 88) | ||
233 | stepindex[c] = 88; | ||
234 | else if (stepindex[c] < 0) | ||
235 | stepindex[c] = 0; | ||
236 | /* calculate the difference */ | ||
237 | #ifdef STRICT_IMA | ||
238 | diff = 0; | ||
239 | if (code & 2) | ||
240 | diff += step; | ||
241 | step = step >> 1; | ||
242 | if (code & 1) | ||
243 | diff += step; | ||
244 | step = step >> 1; | ||
245 | diff += step; | ||
246 | #else | ||
247 | diff = ((code + code + 1) * step) >> 3; /* faster */ | ||
248 | #endif | ||
249 | /* check the sign bit */ | ||
250 | /* check for overflow and underflow errors */ | ||
251 | if (code != codem) { | ||
252 | sample[c] -= diff; | ||
253 | if (sample[c] < -32768) | ||
254 | sample[c] = -32768; | ||
255 | } | ||
256 | else { | ||
257 | sample[c] += diff; | ||
258 | if (sample[c] > 32767) | ||
259 | sample[c] = 32767; | ||
260 | } | ||
261 | /* output the new sample */ | ||
262 | outbuf[nsamples] = sample[c] << 13; | ||
263 | nsamples++; | ||
264 | } | ||
265 | } | 153 | } |
266 | } | 154 | } |
155 | *outbuf += 32 * fmt->channels; | ||
156 | *inbuf += 12 * fmt->channels; | ||
267 | } | 157 | } |
158 | } | ||
268 | 159 | ||
269 | if (nsamples > *outbufcount) { | 160 | static inline void decode_4bit(const uint8_t **inbuf, |
270 | DEBUGF("decode_dvi_adpcm: output buffer overflow!\n"); | 161 | int32_t **outbuf, int *outbufcount) |
271 | return CODEC_ERROR; | 162 | { |
163 | int ch; | ||
164 | int i; | ||
165 | int32_t *pcmbuf; | ||
166 | int samples; | ||
167 | |||
168 | samples = fmt->blockalign / (4 * fmt->channels) - 1; | ||
169 | *outbufcount += (samples << 3); | ||
170 | while (samples-- > 0) | ||
171 | { | ||
172 | for (ch = 0; ch < fmt->channels; ch++) | ||
173 | { | ||
174 | pcmbuf = *outbuf + ch; | ||
175 | for (i = 0; i < 4; i++) | ||
176 | { | ||
177 | *pcmbuf = create_pcmdata_size4(ch, **inbuf ) << 13; | ||
178 | pcmbuf += fmt->channels; | ||
179 | *pcmbuf = create_pcmdata_size4(ch, **inbuf >> 4) << 13; | ||
180 | pcmbuf += fmt->channels; | ||
181 | (*inbuf)++; | ||
182 | } | ||
183 | } | ||
184 | *outbuf += 8 * fmt->channels; | ||
272 | } | 185 | } |
273 | *outbufcount = nsamples; | 186 | } |
274 | if (inbufsize != 0) { | 187 | |
275 | DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", (int)inbufsize); | 188 | static inline void decode_5bit(const uint8_t **inbuf, |
189 | int32_t **outbuf, int *outbufcount) | ||
190 | { | ||
191 | const uint8_t *adpcmbuf; | ||
192 | uint64_t adpcms; | ||
193 | int ch; | ||
194 | int i; | ||
195 | int32_t *pcmbuf; | ||
196 | int samples; | ||
197 | |||
198 | samples = (fmt->blockalign - 4 * fmt->channels) / (20 * fmt->channels); | ||
199 | *outbufcount += (samples << 5); | ||
200 | while (samples--) | ||
201 | { | ||
202 | for (ch = 0; ch < fmt->channels; ch++) | ||
203 | { | ||
204 | adpcmbuf = *inbuf + ch * 4; | ||
205 | pcmbuf = *outbuf + ch; | ||
206 | adpcms = *adpcmbuf++; | ||
207 | adpcms |= (*adpcmbuf++) << 8; | ||
208 | adpcms |= (*adpcmbuf++) << 16; | ||
209 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
210 | adpcmbuf += (fmt->channels - 1) * 4; | ||
211 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
212 | for (i = 0; i < 8; i++) | ||
213 | { | ||
214 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13; | ||
215 | pcmbuf += fmt->channels; | ||
216 | } | ||
217 | adpcms = *adpcmbuf++; | ||
218 | adpcms |= (*adpcmbuf++) << 8; | ||
219 | adpcms |= (*adpcmbuf++) << 16; | ||
220 | adpcmbuf += (fmt->channels - 1) * 4; | ||
221 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
222 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
223 | for (i = 0; i < 8; i++) | ||
224 | { | ||
225 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13; | ||
226 | pcmbuf += fmt->channels; | ||
227 | } | ||
228 | adpcms = *adpcmbuf++; | ||
229 | adpcms |= (*adpcmbuf++) << 8; | ||
230 | adpcmbuf += (fmt->channels - 1) * 4; | ||
231 | adpcms |= (*adpcmbuf++) << 16; | ||
232 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
233 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
234 | for (i = 0; i < 8; i++) | ||
235 | { | ||
236 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13; | ||
237 | pcmbuf += fmt->channels; | ||
238 | } | ||
239 | adpcms = *adpcmbuf++; | ||
240 | adpcmbuf += (fmt->channels - 1) * 4; | ||
241 | adpcms |= (*adpcmbuf++) << 8; | ||
242 | adpcms |= (*adpcmbuf++) << 16; | ||
243 | adpcms |= (uint64_t)(*adpcmbuf++) << 24; | ||
244 | adpcms |= (uint64_t)(*adpcmbuf++) << 32; | ||
245 | for (i = 0; i < 8; i++) | ||
246 | { | ||
247 | *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13; | ||
248 | pcmbuf += fmt->channels; | ||
249 | } | ||
250 | } | ||
251 | *outbuf += 32 * fmt->channels; | ||
252 | *inbuf += 20 * fmt->channels; | ||
276 | } | 253 | } |
277 | return CODEC_OK; | ||
278 | } | 254 | } |
279 | 255 | ||
280 | static int decode(const uint8_t *inbuf, size_t inbufsize, | 256 | static int decode(const uint8_t *inbuf, size_t inbufsize, |
281 | int32_t *outbuf, int *outbufsize) | 257 | int32_t *outbuf, int *outbufcount) |
282 | { | 258 | { |
259 | int ch; | ||
283 | unsigned int i; | 260 | unsigned int i; |
261 | int32_t init_pcmdata[2]; | ||
262 | int8_t init_index[2]; | ||
284 | unsigned int nblocks = fmt->chunksize / fmt->blockalign; | 263 | unsigned int nblocks = fmt->chunksize / fmt->blockalign; |
285 | 264 | ||
286 | (void)inbufsize; | 265 | (void)inbufsize; |
287 | 266 | ||
267 | *outbufcount = 0; | ||
288 | for (i = 0; i < nblocks; i++) | 268 | for (i = 0; i < nblocks; i++) |
289 | { | 269 | { |
290 | size_t decodedsize = fmt->samplesperblock * fmt->channels; | 270 | for (ch = 0; ch < fmt->channels; ch++) |
291 | if (decode_dvi_adpcm(inbuf + i * fmt->blockalign, fmt->blockalign, | 271 | { |
292 | outbuf + i * fmt->samplesperblock * fmt->channels, | 272 | init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); |
293 | &decodedsize) != CODEC_OK) { | 273 | if (init_pcmdata[ch] > 32767) |
294 | return CODEC_ERROR; | 274 | init_pcmdata[ch] -= 65536; |
275 | |||
276 | init_index[ch] = inbuf[2]; | ||
277 | if (init_index[ch] > 88 || init_index[ch] < 0) | ||
278 | { | ||
279 | DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n", | ||
280 | init_index[ch]); | ||
281 | return CODEC_ERROR; | ||
282 | } | ||
283 | inbuf += 4; | ||
284 | |||
285 | *outbuf++ = init_pcmdata[ch] << 13; | ||
295 | } | 286 | } |
287 | |||
288 | *outbufcount += 1; | ||
289 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); | ||
290 | |||
291 | if (fmt->bitspersample == 4) | ||
292 | decode_4bit(&inbuf, &outbuf, outbufcount); | ||
293 | else if (fmt->bitspersample == 3) | ||
294 | decode_3bit(&inbuf, &outbuf, outbufcount); | ||
295 | else if (fmt->bitspersample == 5) | ||
296 | decode_5bit(&inbuf, &outbuf, outbufcount); | ||
297 | else /* fmt->bitspersample == 2 */ | ||
298 | decode_2bit(&inbuf, &outbuf, outbufcount); | ||
296 | } | 299 | } |
297 | *outbufsize = nblocks * fmt->samplesperblock; | ||
298 | return CODEC_OK; | 300 | return CODEC_OK; |
299 | } | 301 | } |
300 | 302 | ||
diff --git a/apps/codecs/libpcm/ieee_float.c b/apps/codecs/libpcm/ieee_float.c index c0e91a46cb..0530993f31 100644 --- a/apps/codecs/libpcm/ieee_float.c +++ b/apps/codecs/libpcm/ieee_float.c | |||
@@ -28,33 +28,38 @@ | |||
28 | 28 | ||
29 | static struct pcm_format *fmt; | 29 | static struct pcm_format *fmt; |
30 | 30 | ||
31 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | 31 | static bool set_format(struct pcm_format *format) |
32 | { | 32 | { |
33 | fmt = format; | 33 | fmt = format; |
34 | 34 | ||
35 | (void)fmtpos; | ||
36 | |||
37 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) | 35 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) |
38 | { | 36 | { |
39 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample %d\n", fmt->bitspersample); | 37 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample: %d\n", |
38 | fmt->bitspersample); | ||
40 | return false; | 39 | return false; |
41 | } | 40 | } |
42 | 41 | ||
43 | fmt->bytespersample = fmt->bitspersample >> 3; | 42 | fmt->bytespersample = fmt->bitspersample >> 3; |
44 | fmt->blockalign = fmt->bytespersample; | 43 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); |
45 | 44 | ||
46 | /* chunksize is computed so that one chunk is about 1/50s. */ | 45 | /* chunksize = about 1/50[sec] data */ |
47 | fmt->chunksize = (ci->id3->frequency * fmt->channels / 50) * fmt->blockalign; | 46 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) |
47 | * fmt->blockalign; | ||
48 | 48 | ||
49 | return true; | 49 | return true; |
50 | } | 50 | } |
51 | 51 | ||
52 | static uint32_t get_seek_pos(long seek_time) | 52 | static struct pcm_pos *get_seek_pos(long seek_time, |
53 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
53 | { | 54 | { |
54 | uint32_t newpos; | 55 | static struct pcm_pos newpos; |
55 | 56 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | |
56 | newpos = ((uint64_t)(seek_time * ci->id3->frequency * fmt->channels / 1000LL))*fmt->blockalign; | 57 | / (1000LL * fmt->samplesperblock); |
57 | return newpos; | 58 | |
59 | (void)read_buffer; | ||
60 | newpos.pos = newblock * fmt->blockalign; | ||
61 | newpos.samples = newblock * fmt->samplesperblock; | ||
62 | return &newpos; | ||
58 | } | 63 | } |
59 | 64 | ||
60 | static int decode(const uint8_t *inbuf, size_t inbufsize, | 65 | static int decode(const uint8_t *inbuf, size_t inbufsize, |
diff --git a/apps/codecs/libpcm/ima_adpcm_common.c b/apps/codecs/libpcm/ima_adpcm_common.c new file mode 100644 index 0000000000..ff5051f166 --- /dev/null +++ b/apps/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 index[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 | index[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[index[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 | index[ch] += use_index_table[nibble & step_mask]; | ||
140 | CLIP(index[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[index[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 | index[ch] += use_index_table[nibble & 0x07]; | ||
166 | CLIP(index[ch], 0, 88); | ||
167 | |||
168 | CLIP(pcmdata[ch], -32768, 32767); | ||
169 | |||
170 | return (int16_t)pcmdata[ch]; | ||
171 | } | ||
diff --git a/apps/codecs/libpcm/ima_adpcm_common.h b/apps/codecs/libpcm/ima_adpcm_common.h new file mode 100644 index 0000000000..65cfefcfa3 --- /dev/null +++ b/apps/codecs/libpcm/ima_adpcm_common.h | |||
@@ -0,0 +1,32 @@ | |||
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 <sys/types.h> | ||
25 | #include <stdbool.h> | ||
26 | #include <inttypes.h> | ||
27 | |||
28 | void init_ima_adpcm_decoder(int bit, const int *index_table); | ||
29 | void set_decode_parameters(int channels, int32_t *init_pcmdata, int8_t *init_index); | ||
30 | int16_t create_pcmdata(int ch, uint8_t nibble); | ||
31 | int16_t create_pcmdata_size4(int ch, uint8_t nibble); | ||
32 | #endif | ||
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c index 520ca46a7a..9a38031882 100644 --- a/apps/codecs/libpcm/itut_g711.c +++ b/apps/codecs/libpcm/itut_g711.c | |||
@@ -109,49 +109,43 @@ static const int16_t ulaw2linear16[256] ICONST_ATTR = { | |||
109 | 109 | ||
110 | static struct pcm_format *fmt; | 110 | static struct pcm_format *fmt; |
111 | 111 | ||
112 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | 112 | static bool set_format(struct pcm_format *format) |
113 | { | 113 | { |
114 | fmt = format; | 114 | fmt = format; |
115 | 115 | ||
116 | (void)fmtpos; | ||
117 | |||
118 | if (fmt->bitspersample != 8) | 116 | if (fmt->bitspersample != 8) |
119 | { | 117 | { |
120 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); | 118 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n", |
119 | fmt->bitspersample); | ||
121 | return false; | 120 | return false; |
122 | } | 121 | } |
123 | 122 | ||
124 | if (fmt->totalsamples == 0) | 123 | if (fmt->totalsamples == 0) |
125 | { | 124 | { |
126 | fmt->bytespersample = fmt->channels; | 125 | fmt->bytespersample = 1; |
127 | fmt->totalsamples = fmt->numbytes/fmt->bytespersample; | 126 | fmt->totalsamples = fmt->numbytes / (fmt->bytespersample * fmt->channels); |
128 | } | 127 | } |
129 | 128 | ||
130 | /* chunksize is computed so that one chunk is about 1/50s. | 129 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); |
131 | * this make 4096 for 44.1kHz 16bits stereo. | ||
132 | * It also has to be a multiple of blockalign */ | ||
133 | fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign; | ||
134 | 130 | ||
135 | /* check that the output buffer is big enough (convert to samplespersec, | 131 | /* chunksize = about 1/50[sec] data */ |
136 | then round to the blockalign multiple below) */ | 132 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) |
137 | if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3) | 133 | * fmt->blockalign; |
138 | /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE) | ||
139 | fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec | ||
140 | /((uint64_t)ci->id3->frequency * fmt->channels * 2 | ||
141 | * fmt->blockalign)) * fmt->blockalign; | ||
142 | 134 | ||
143 | return true; | 135 | return true; |
144 | } | 136 | } |
145 | 137 | ||
146 | static uint32_t get_seek_pos(long seek_time) | 138 | static struct pcm_pos *get_seek_pos(long seek_time, |
139 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
147 | { | 140 | { |
148 | uint32_t newpos; | 141 | static struct pcm_pos newpos; |
149 | 142 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | |
150 | /* use avgbytespersec to round to the closest blockalign multiple, | 143 | / (1000LL * fmt->samplesperblock); |
151 | add firstblockposn. 64-bit casts to avoid overflows. */ | 144 | |
152 | newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) | 145 | (void)read_buffer; |
153 | / (1000LL*fmt->blockalign))*fmt->blockalign; | 146 | newpos.pos = newblock * fmt->blockalign; |
154 | return newpos; | 147 | newpos.samples = newblock * fmt->samplesperblock; |
148 | return &newpos; | ||
155 | } | 149 | } |
156 | 150 | ||
157 | static int decode_alaw(const uint8_t *inbuf, size_t inbufsize, | 151 | static int decode_alaw(const uint8_t *inbuf, size_t inbufsize, |
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c index 4db27ca2b3..5360d79901 100644 --- a/apps/codecs/libpcm/linear_pcm.c +++ b/apps/codecs/libpcm/linear_pcm.c | |||
@@ -29,12 +29,10 @@ | |||
29 | 29 | ||
30 | static struct pcm_format *fmt; | 30 | static struct pcm_format *fmt; |
31 | 31 | ||
32 | static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | 32 | static bool set_format(struct pcm_format *format) |
33 | { | 33 | { |
34 | fmt = format; | 34 | fmt = format; |
35 | 35 | ||
36 | (void)fmtpos; | ||
37 | |||
38 | if (fmt->bitspersample > 32) | 36 | if (fmt->bitspersample > 32) |
39 | { | 37 | { |
40 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | 38 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " |
@@ -42,33 +40,34 @@ static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) | |||
42 | return false; | 40 | return false; |
43 | } | 41 | } |
44 | 42 | ||
43 | fmt->bytespersample = fmt->bitspersample >> 3; | ||
44 | |||
45 | if (fmt->totalsamples == 0) | 45 | if (fmt->totalsamples == 0) |
46 | { | ||
47 | fmt->bytespersample = (((fmt->bitspersample - 1)/8 + 1)*fmt->channels); | ||
48 | fmt->totalsamples = fmt->numbytes/fmt->bytespersample; | 46 | fmt->totalsamples = fmt->numbytes/fmt->bytespersample; |
49 | } | ||
50 | 47 | ||
51 | /* chunksize is computed so that one chunk is about 1/50s. | 48 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); |
52 | * this make 4096 for 44.1kHz 16bits stereo. | 49 | |
53 | * It also has to be a multiple of blockalign */ | 50 | /* chunksize = about 1/50[sec] data */ |
54 | fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign; | 51 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) |
52 | * fmt->blockalign; | ||
55 | 53 | ||
56 | return true; | 54 | return true; |
57 | } | 55 | } |
58 | 56 | ||
59 | static uint32_t get_seek_pos(long seek_time) | 57 | static struct pcm_pos *get_seek_pos(long seek_time, |
58 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
60 | { | 59 | { |
61 | uint32_t newpos; | 60 | static struct pcm_pos newpos; |
62 | 61 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | |
63 | /* use avgbytespersec to round to the closest blockalign multiple, | 62 | / (1000LL * fmt->samplesperblock); |
64 | add firstblockposn. 64-bit casts to avoid overflows. */ | 63 | |
65 | newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) | 64 | (void)read_buffer; |
66 | / (1000LL*fmt->blockalign))*fmt->blockalign; | 65 | newpos.pos = newblock * fmt->blockalign; |
67 | return newpos; | 66 | newpos.samples = newblock * fmt->samplesperblock; |
67 | return &newpos; | ||
68 | } | 68 | } |
69 | 69 | ||
70 | static int decode(const uint8_t *inbuf, size_t inbufsize, | 70 | static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufsize) |
71 | int32_t *outbuf, int *outbufsize) | ||
72 | { | 71 | { |
73 | uint32_t i; | 72 | uint32_t i; |
74 | 73 | ||
diff --git a/apps/codecs/libpcm/ms_adpcm.c b/apps/codecs/libpcm/ms_adpcm.c new file mode 100644 index 0000000000..899ecc2045 --- /dev/null +++ b/apps/codecs/libpcm/ms_adpcm.c | |||
@@ -0,0 +1,166 @@ | |||
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 | |||
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(long seek_time, | ||
64 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
65 | { | ||
66 | static struct pcm_pos newpos; | ||
67 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | ||
68 | / (1000LL * fmt->samplesperblock); | ||
69 | |||
70 | (void)read_buffer; | ||
71 | newpos.pos = newblock * fmt->blockalign; | ||
72 | newpos.samples = newblock * fmt->samplesperblock; | ||
73 | return &newpos; | ||
74 | } | ||
75 | |||
76 | static int16_t create_pcmdata(int ch, uint8_t nibble) | ||
77 | { | ||
78 | int32_t pcmdata; | ||
79 | |||
80 | pcmdata = (sample[ch][0] * dec_coeff[ch][0] + | ||
81 | sample[ch][1] * dec_coeff[ch][1]) / 256; | ||
82 | pcmdata += (delta[ch] * (nibble - ((nibble & 0x8) << 1))); | ||
83 | |||
84 | CLIP(pcmdata, -32768, 32767); | ||
85 | |||
86 | sample[ch][1] = sample[ch][0]; | ||
87 | sample[ch][0] = pcmdata; | ||
88 | |||
89 | delta[ch] = (adaptation_table[nibble] * delta[ch]) >> 8; | ||
90 | if (delta[ch] < 16) | ||
91 | delta[ch] = 16; | ||
92 | |||
93 | return (int16_t)pcmdata; | ||
94 | } | ||
95 | |||
96 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
97 | int32_t *outbuf, int *outbufcount) | ||
98 | { | ||
99 | int ch; | ||
100 | size_t nsamples = 0; | ||
101 | int size = fmt->samplesperblock; | ||
102 | |||
103 | /* read block header */ | ||
104 | for (ch = 0; ch < fmt->channels; ch++) | ||
105 | { | ||
106 | if (*inbuf >= ADPCM_NUM_COEFF) | ||
107 | { | ||
108 | DEBUGF("CODEC_ERROR: microsoft adpcm illegal initial coeff=%d > 7\n", | ||
109 | *inbuf); | ||
110 | return CODEC_ERROR; | ||
111 | } | ||
112 | dec_coeff[ch][0] = fmt->coeffs[*inbuf][0]; | ||
113 | dec_coeff[ch][1] = fmt->coeffs[*inbuf][1]; | ||
114 | inbuf++; | ||
115 | } | ||
116 | |||
117 | for (ch = 0; ch < fmt->channels; ch++) | ||
118 | { | ||
119 | delta[ch] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
120 | inbuf += 2; | ||
121 | } | ||
122 | |||
123 | for (ch = 0; ch < fmt->channels; ch++) | ||
124 | { | ||
125 | sample[ch][0] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
126 | inbuf += 2; | ||
127 | } | ||
128 | |||
129 | for (ch = 0; ch < fmt->channels; ch++) | ||
130 | { | ||
131 | sample[ch][1] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
132 | inbuf += 2; | ||
133 | } | ||
134 | |||
135 | inbufsize -= 7 * fmt->channels; | ||
136 | ch = fmt->channels - 1; | ||
137 | |||
138 | while (size-- > 0) | ||
139 | { | ||
140 | *outbuf++ = create_pcmdata(0, *inbuf >> 4 ) << 13; | ||
141 | *outbuf++ = create_pcmdata(ch, *inbuf & 0xf) << 13; | ||
142 | nsamples += 2; | ||
143 | |||
144 | inbuf++; | ||
145 | inbufsize--; | ||
146 | if (inbufsize <= 0) | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | if (fmt->channels == 2) | ||
151 | nsamples >>= 1; | ||
152 | *outbufcount = nsamples; | ||
153 | |||
154 | return CODEC_OK; | ||
155 | } | ||
156 | |||
157 | static const struct pcm_codec codec = { | ||
158 | set_format, | ||
159 | get_seek_pos, | ||
160 | decode, | ||
161 | }; | ||
162 | |||
163 | const struct pcm_codec *get_ms_adpcm_codec(void) | ||
164 | { | ||
165 | return &codec; | ||
166 | } | ||
diff --git a/apps/codecs/libpcm/pcm_common.h b/apps/codecs/libpcm/pcm_common.h index 757d0ad5d9..d490a85e9f 100644 --- a/apps/codecs/libpcm/pcm_common.h +++ b/apps/codecs/libpcm/pcm_common.h | |||
@@ -18,8 +18,8 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #ifndef CODEC_LIBPCMS_PCM_COMMON_H | 21 | #ifndef CODEC_LIBPCM_PCM_COMMON_H |
22 | #define CODEC_LIBPCMS_PCM_COMMON_H | 22 | #define CODEC_LIBPCM_PCM_COMMON_H |
23 | 23 | ||
24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
25 | #include <stdbool.h> | 25 | #include <stdbool.h> |
@@ -38,6 +38,19 @@ | |||
38 | /* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */ | 38 | /* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */ |
39 | #define SFT(x) ((int32_t)x-0x80) | 39 | #define SFT(x) ((int32_t)x-0x80) |
40 | 40 | ||
41 | /* Macro that clipping data */ | ||
42 | #define CLIP(data, min, max) \ | ||
43 | if ((data) > (max)) data = max; \ | ||
44 | else if ((data) < (min)) data = min; | ||
45 | |||
46 | /* nums of msadpcm coeffs | ||
47 | * In many case, nNumCoef is 7. | ||
48 | * Depending upon the encoder, as for this value there is a possibility | ||
49 | * of increasing more. | ||
50 | * If you found the file where this value exceeds 7, please report. | ||
51 | */ | ||
52 | #define MSADPCM_NUM_COEFF 7 | ||
53 | |||
41 | struct pcm_format { | 54 | struct pcm_format { |
42 | /* | 55 | /* |
43 | * RIFF: wFormatTag (in 'fmt ' chunk) | 56 | * RIFF: wFormatTag (in 'fmt ' chunk) |
@@ -103,13 +116,67 @@ struct pcm_format { | |||
103 | * true: signed, false: unsigned | 116 | * true: signed, false: unsigned |
104 | */ | 117 | */ |
105 | bool is_signed; | 118 | bool is_signed; |
119 | |||
120 | /* the following values are format speciffic parameters */ | ||
121 | |||
122 | /* microsoft adpcm: aCoeff */ | ||
123 | int16_t coeffs[MSADPCM_NUM_COEFF][2]; | ||
124 | }; | ||
125 | |||
126 | struct pcm_pos { | ||
127 | uint32_t pos; | ||
128 | uint32_t samples; | ||
106 | }; | 129 | }; |
107 | 130 | ||
108 | struct pcm_codec { | 131 | struct pcm_codec { |
109 | bool (*set_format)(struct pcm_format *format, const unsigned char *fmtpos); | 132 | /* |
110 | uint32_t (*get_seek_pos)(long seek_time); | 133 | * sets the format speciffic RIFF/AIFF header information and checks the pcm_format. |
134 | * | ||
135 | * [In/Out] format | ||
136 | * the structure which supplies RIFF/AIFF header information. | ||
137 | * | ||
138 | * return | ||
139 | * true: RIFF/AIFF header check OK | ||
140 | * false: RIFF/AIFF header check NG | ||
141 | */ | ||
142 | bool (*set_format)(struct pcm_format *format); | ||
143 | |||
144 | /* | ||
145 | * get seek position | ||
146 | * | ||
147 | * [In] seek_time | ||
148 | * seek time [ms] | ||
149 | * | ||
150 | * [In] read_buffer | ||
151 | * the function which reads the data from the file (chunksize bytes read). | ||
152 | * | ||
153 | * return | ||
154 | * position after the seeking. | ||
155 | */ | ||
156 | struct pcm_pos *(*get_seek_pos)(long seek_time, | ||
157 | uint8_t *(*read_buffer)(size_t *realsize)); | ||
158 | |||
159 | /* | ||
160 | * decode wave data. | ||
161 | * | ||
162 | * [In] inbuf | ||
163 | * the start pointer of wave data buffer. | ||
164 | * | ||
165 | * [In] inbufsize | ||
166 | * wave data buffer size (bytes). | ||
167 | * | ||
168 | * [Out] outbuf | ||
169 | * the start pointer of the buffer which supplies decoded pcm data. | ||
170 | * | ||
171 | * [Out] outbufcount | ||
172 | * decoded pcm data count. | ||
173 | * | ||
174 | * return | ||
175 | * CODEC_OK: decode succeed. | ||
176 | * CODEC_ERROR: decode failure. | ||
177 | */ | ||
111 | int (*decode)(const uint8_t *inbuf, size_t inbufsize, | 178 | int (*decode)(const uint8_t *inbuf, size_t inbufsize, |
112 | int32_t *outbuf, int *outbufsize); | 179 | int32_t *outbuf, int *outbufcount); |
113 | }; | 180 | }; |
114 | 181 | ||
115 | struct pcm_entry { | 182 | struct pcm_entry { |
diff --git a/apps/codecs/libpcm/qt_ima_adpcm.c b/apps/codecs/libpcm/qt_ima_adpcm.c new file mode 100644 index 0000000000..a34e0e86cd --- /dev/null +++ b/apps/codecs/libpcm/qt_ima_adpcm.c | |||
@@ -0,0 +1,136 @@ | |||
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 | * 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(long seek_time, | ||
61 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
62 | { | ||
63 | static struct pcm_pos newpos; | ||
64 | uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) | ||
65 | / (1000LL * fmt->samplesperblock); | ||
66 | |||
67 | (void)read_buffer; | ||
68 | newpos.pos = newblock * fmt->blockalign; | ||
69 | newpos.samples = newblock * fmt->samplesperblock; | ||
70 | return &newpos; | ||
71 | } | ||
72 | |||
73 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
74 | int32_t *outbuf, int *outbufcount) | ||
75 | { | ||
76 | int ch; | ||
77 | size_t nsamples = 0; | ||
78 | int block_size; | ||
79 | int32_t *pcmbuf; | ||
80 | int32_t init_pcmdata; | ||
81 | int8_t init_index; | ||
82 | |||
83 | while (inbufsize > 0) | ||
84 | { | ||
85 | for (ch = 0; ch < fmt->channels; ch++) | ||
86 | { | ||
87 | /* read block header */ | ||
88 | init_pcmdata = (inbuf[0] << 8)|(inbuf[1] & 0x80); | ||
89 | if (init_pcmdata > 32767) | ||
90 | init_pcmdata -= 65536; | ||
91 | |||
92 | init_index = inbuf[1] & 0x7f; | ||
93 | if (init_index > 88) | ||
94 | { | ||
95 | DEBUGF("CODEC_ERROR: quicktime ima adpcm illegal step index=%d > 88\n", | ||
96 | init_index); | ||
97 | return CODEC_ERROR; | ||
98 | } | ||
99 | |||
100 | inbuf += 2; | ||
101 | inbufsize -= 2; | ||
102 | |||
103 | set_decode_parameters(1, &init_pcmdata, &init_index); | ||
104 | |||
105 | /* read block data */ | ||
106 | pcmbuf = outbuf + ch; | ||
107 | for (block_size = 32; block_size > 0 && inbufsize > 0; block_size--, inbufsize--) | ||
108 | { | ||
109 | *pcmbuf = create_pcmdata_size4(ch, *inbuf ) << 13; | ||
110 | pcmbuf += fmt->channels; | ||
111 | *pcmbuf = create_pcmdata_size4(ch, *inbuf >> 4) << 13; | ||
112 | pcmbuf += fmt->channels; | ||
113 | nsamples += 2; | ||
114 | inbuf++; | ||
115 | } | ||
116 | } | ||
117 | outbuf += 64 * fmt->channels; | ||
118 | } | ||
119 | |||
120 | if (fmt->channels == 2) | ||
121 | nsamples >>= 1; | ||
122 | *outbufcount = nsamples; | ||
123 | |||
124 | return CODEC_OK; | ||
125 | } | ||
126 | |||
127 | static const struct pcm_codec codec = { | ||
128 | set_format, | ||
129 | get_seek_pos, | ||
130 | decode, | ||
131 | }; | ||
132 | |||
133 | const struct pcm_codec *get_qt_ima_adpcm_codec(void) | ||
134 | { | ||
135 | return &codec; | ||
136 | } | ||
diff --git a/apps/codecs/libpcm/support_formats.h b/apps/codecs/libpcm/support_formats.h index 0a6ea339f4..b1e089e464 100644 --- a/apps/codecs/libpcm/support_formats.h +++ b/apps/codecs/libpcm/support_formats.h | |||
@@ -18,8 +18,8 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #ifndef CODEC_LIBPCMS_SUPPORT_FORMATS_H | 21 | #ifndef CODEC_LIBPCM_SUPPORT_FORMATS_H |
22 | #define CODEC_LIBPCMS_SUPPORT_FORMATS_H | 22 | #define CODEC_LIBPCM_SUPPORT_FORMATS_H |
23 | 23 | ||
24 | #include "pcm_common.h" | 24 | #include "pcm_common.h" |
25 | 25 | ||
@@ -32,9 +32,24 @@ const struct pcm_codec *get_itut_g711_alaw_codec(void); | |||
32 | /* ITU-T G.711 mu-law */ | 32 | /* ITU-T G.711 mu-law */ |
33 | const struct pcm_codec *get_itut_g711_mulaw_codec(void); | 33 | const struct pcm_codec *get_itut_g711_mulaw_codec(void); |
34 | 34 | ||
35 | /* Intel DVI ADPCM */ | 35 | /* Intel DVI ADPCM (IMA ADPCM) */ |
36 | const struct pcm_codec *get_dvi_adpcm_codec(void); | 36 | const struct pcm_codec *get_dvi_adpcm_codec(void); |
37 | 37 | ||
38 | /* IEEE float */ | 38 | /* IEEE float */ |
39 | const struct pcm_codec *get_ieee_float_codec(void); | 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); | ||
40 | #endif | 55 | #endif |
diff --git a/apps/codecs/libpcm/swf_adpcm.c b/apps/codecs/libpcm/swf_adpcm.c new file mode 100644 index 0000000000..456e1cdd4c --- /dev/null +++ b/apps/codecs/libpcm/swf_adpcm.c | |||
@@ -0,0 +1,233 @@ | |||
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 | * 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 | static bool set_format(struct pcm_format *format) | ||
51 | { | ||
52 | fmt = format; | ||
53 | |||
54 | if (fmt->bitspersample < 2 || fmt->bitspersample > 5) | ||
55 | { | ||
56 | DEBUGF("CODEC_ERROR: swf adpcm must be 2, 3, 4 or 5 bitspersample: %d\n", | ||
57 | fmt->bitspersample); | ||
58 | return false; | ||
59 | } | ||
60 | |||
61 | if (fmt->samplesperblock == 0) | ||
62 | fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22) | ||
63 | / fmt->bitspersample + 1; | ||
64 | |||
65 | blockbits = ((fmt->samplesperblock - 1) * fmt->bitspersample + 22) * fmt->channels; | ||
66 | |||
67 | /* | ||
68 | * chunksize = about 93 [ms] data (frequency:44.1kHz, 4096 [sample/block]) | ||
69 | * chunksize changes depending upon the position of block. | ||
70 | */ | ||
71 | fmt->chunksize = (blockbits + 9) >> 3; | ||
72 | |||
73 | /* initialize for ima adpcm common functions */ | ||
74 | if (fmt->bitspersample == 3) | ||
75 | init_ima_adpcm_decoder(fmt->bitspersample, index_table); | ||
76 | else | ||
77 | init_ima_adpcm_decoder(fmt->bitspersample, NULL); | ||
78 | |||
79 | return true; | ||
80 | } | ||
81 | |||
82 | static struct pcm_pos *get_seek_pos(long seek_time, | ||
83 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
84 | { | ||
85 | static struct pcm_pos newpos; | ||
86 | uint32_t chunkbits = blockbits; | ||
87 | uint32_t seekbits = (((uint64_t)seek_time * ci->id3->frequency) | ||
88 | / (1000LL * fmt->samplesperblock)) * blockbits + 2; | ||
89 | |||
90 | (void)read_buffer; | ||
91 | |||
92 | newpos.pos = seekbits >> 3; | ||
93 | newpos.samples = (((uint64_t)seek_time * ci->id3->frequency) | ||
94 | / (1000LL * fmt->samplesperblock)) | ||
95 | * fmt->samplesperblock; | ||
96 | |||
97 | if (newpos.pos == 0) | ||
98 | { | ||
99 | first_block = true; | ||
100 | lastbytebits = 0; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | first_block = false; | ||
105 | lastbytebits = seekbits & 0x07; | ||
106 | if (lastbytebits != 0) | ||
107 | chunkbits -= (8 - lastbytebits); | ||
108 | } | ||
109 | |||
110 | /* calculates next read bytes */ | ||
111 | fmt->chunksize = (chunkbits >> 3) + (((chunkbits & 0x07) > 0)?1:0) | ||
112 | + ((lastbytebits > 0)?1:0); | ||
113 | |||
114 | after_seek = true; | ||
115 | return &newpos; | ||
116 | } | ||
117 | |||
118 | static uint8_t get_data(const uint8_t **buf, int bit) | ||
119 | { | ||
120 | uint8_t res = 0; | ||
121 | uint8_t mask = (1 << bit) - 1; | ||
122 | |||
123 | if (validity_bits >= bit) | ||
124 | { | ||
125 | validity_bits -= bit; | ||
126 | return (**buf >> validity_bits) & mask; | ||
127 | } | ||
128 | |||
129 | if (validity_bits > 0) | ||
130 | res = **buf << (bit - validity_bits); | ||
131 | |||
132 | validity_bits += 8 - bit; | ||
133 | res = (res | (*(++(*buf)) >> validity_bits)) & mask; | ||
134 | return res; | ||
135 | } | ||
136 | |||
137 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
138 | int32_t *outbuf, int *outbufcount) | ||
139 | { | ||
140 | int ch; | ||
141 | int adpcm_code_size; | ||
142 | int count = fmt->samplesperblock; | ||
143 | int32_t init_pcmdata[2]; | ||
144 | int8_t init_index[2]; | ||
145 | static uint8_t lastbyte = 0; | ||
146 | |||
147 | (void)inbufsize; | ||
148 | |||
149 | validity_bits = 8; | ||
150 | |||
151 | /* read block header */ | ||
152 | ch = fmt->channels - 1; | ||
153 | if (first_block) | ||
154 | { | ||
155 | adpcm_code_size = get_data(&inbuf, 2) + 2; | ||
156 | if (fmt->bitspersample != adpcm_code_size) | ||
157 | { | ||
158 | DEBUGF("CODEC_ERROR: swf adpcm different adpcm code size=%d != %d\n", | ||
159 | adpcm_code_size, fmt->bitspersample); | ||
160 | return CODEC_ERROR; | ||
161 | } | ||
162 | init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
163 | |||
164 | lastbytebits = 0; | ||
165 | first_block = false; | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | if (after_seek && lastbytebits > 0) | ||
170 | { | ||
171 | lastbyte = *inbuf++; | ||
172 | after_seek = false; | ||
173 | } | ||
174 | if (lastbytebits > 0) | ||
175 | init_pcmdata[0] = ((lastbyte << (8 + lastbytebits)) | | ||
176 | (get_data(&inbuf, 8) << lastbytebits) | | ||
177 | get_data(&inbuf, lastbytebits)) & 65535; | ||
178 | else | ||
179 | init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
180 | } | ||
181 | after_seek = false; | ||
182 | |||
183 | init_index[0] = get_data(&inbuf, 6); | ||
184 | if (init_pcmdata[0] > 32767) | ||
185 | init_pcmdata[0] -= 65536; | ||
186 | |||
187 | if (ch > 0) | ||
188 | { | ||
189 | init_pcmdata[1] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8); | ||
190 | init_index[1] = get_data(&inbuf, 6); | ||
191 | if (init_pcmdata[1] > 32767) | ||
192 | init_pcmdata[1] -= 65536; | ||
193 | } | ||
194 | |||
195 | *outbuf++ = init_pcmdata[0] << 13; | ||
196 | if (ch > 0) | ||
197 | *outbuf++ = init_pcmdata[1] << 13; | ||
198 | |||
199 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); | ||
200 | |||
201 | /* read block data */ | ||
202 | while (--count > 0) | ||
203 | { | ||
204 | *outbuf++ = create_pcmdata(0, get_data(&inbuf, fmt->bitspersample)) << 13; | ||
205 | if (ch > 0) | ||
206 | *outbuf++ = create_pcmdata(ch, get_data(&inbuf, fmt->bitspersample)) << 13; | ||
207 | } | ||
208 | |||
209 | *outbufcount = fmt->samplesperblock; | ||
210 | |||
211 | lastbyte = *inbuf; | ||
212 | lastbytebits = (8 - validity_bits) & 0x07; | ||
213 | |||
214 | /* calculates next read bytes */ | ||
215 | fmt->chunksize = (blockbits - validity_bits + 7) >> 3; | ||
216 | |||
217 | return CODEC_OK; | ||
218 | } | ||
219 | |||
220 | static const struct pcm_codec codec = { | ||
221 | set_format, | ||
222 | get_seek_pos, | ||
223 | decode, | ||
224 | }; | ||
225 | |||
226 | const struct pcm_codec *get_swf_adpcm_codec(void) | ||
227 | { | ||
228 | first_block = true; | ||
229 | lastbytebits = 0; | ||
230 | after_seek = false; | ||
231 | |||
232 | return &codec; | ||
233 | } | ||
diff --git a/apps/codecs/libpcm/yamaha_adpcm.c b/apps/codecs/libpcm/yamaha_adpcm.c new file mode 100644 index 0000000000..6b3daa8f83 --- /dev/null +++ b/apps/codecs/libpcm/yamaha_adpcm.c | |||
@@ -0,0 +1,245 @@ | |||
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 "adpcm_seek.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->bitspersample != 4) | ||
86 | { | ||
87 | DEBUGF("CODEC_ERROR: yamaha adpcm must be 4 bitspersample: %d\n", | ||
88 | fmt->bitspersample); | ||
89 | return false; | ||
90 | } | ||
91 | |||
92 | /* check exists block header */ | ||
93 | if (fmt->blockalign == ((ci->id3->frequency / 60) + 4) * fmt->channels) | ||
94 | { | ||
95 | has_block_header = true; | ||
96 | |||
97 | /* chunksize = about 1/30 [sec] data */ | ||
98 | fmt->chunksize = fmt->blockalign; | ||
99 | blocksperchunk = 1; | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | uint32_t max_chunk_count; | ||
104 | |||
105 | has_block_header = false; | ||
106 | |||
107 | /* blockalign = 2 * channels samples */ | ||
108 | fmt->blockalign = fmt->channels; | ||
109 | fmt->samplesperblock = 2; | ||
110 | |||
111 | /* chunksize = about 1/32[sec] data */ | ||
112 | blocksperchunk = ci->id3->frequency >> 6; | ||
113 | fmt->chunksize = blocksperchunk * fmt->blockalign; | ||
114 | |||
115 | max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency | ||
116 | / (2000LL * fmt->chunksize / fmt->channels); | ||
117 | |||
118 | /* initialize seek table */ | ||
119 | init_seek_table(max_chunk_count); | ||
120 | /* add first data */ | ||
121 | add_adpcm_data(&cur_data); | ||
122 | } | ||
123 | |||
124 | return true; | ||
125 | } | ||
126 | |||
127 | static int16_t create_pcmdata(int ch, uint8_t nibble) | ||
128 | { | ||
129 | int32_t tmp_pcmdata = cur_data.pcmdata[ch]; | ||
130 | int32_t step = cur_data.step[ch]; | ||
131 | int32_t delta = step >> 3; | ||
132 | |||
133 | if (nibble & 4) delta += step; | ||
134 | if (nibble & 2) delta += (step >> 1); | ||
135 | if (nibble & 1) delta += (step >> 2); | ||
136 | |||
137 | if (nibble & 0x08) | ||
138 | tmp_pcmdata -= delta; | ||
139 | else | ||
140 | tmp_pcmdata += delta; | ||
141 | |||
142 | CLIP(tmp_pcmdata, -32768, 32767); | ||
143 | cur_data.pcmdata[ch] = tmp_pcmdata; | ||
144 | |||
145 | step = (step * amplification_table[nibble & 0x07]) >> 8; | ||
146 | CLIP(step, 127, 24576); | ||
147 | cur_data.step[ch] = step; | ||
148 | |||
149 | return cur_data.pcmdata[ch]; | ||
150 | } | ||
151 | |||
152 | static int decode(const uint8_t *inbuf, size_t inbufsize, | ||
153 | int32_t *outbuf, int *outbufcount) | ||
154 | { | ||
155 | int ch; | ||
156 | size_t nsamples = 0; | ||
157 | |||
158 | /* read block header */ | ||
159 | if (has_block_header) | ||
160 | { | ||
161 | for (ch = 0; ch < fmt->channels; ch++) | ||
162 | { | ||
163 | cur_data.pcmdata[ch] = inbuf[0] | (SE(inbuf[1]) << 8); | ||
164 | cur_data.step[ch] = inbuf[2] | (inbuf[3] << 8); | ||
165 | |||
166 | inbuf += 4; | ||
167 | inbufsize -= 4; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* read block data */ | ||
172 | ch = fmt->channels - 1; | ||
173 | while (inbufsize) | ||
174 | { | ||
175 | *outbuf++ = create_pcmdata(0, *inbuf ) << 13; | ||
176 | *outbuf++ = create_pcmdata(ch, *inbuf >> 4) << 13; | ||
177 | nsamples += 2; | ||
178 | |||
179 | inbuf++; | ||
180 | inbufsize--; | ||
181 | } | ||
182 | |||
183 | if (fmt->channels == 2) | ||
184 | nsamples >>= 1; | ||
185 | *outbufcount = nsamples; | ||
186 | |||
187 | if (!has_block_header) | ||
188 | add_adpcm_data(&cur_data); | ||
189 | |||
190 | return CODEC_OK; | ||
191 | } | ||
192 | |||
193 | static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize) | ||
194 | { | ||
195 | int ch = fmt->channels - 1; | ||
196 | |||
197 | while (inbufsize) | ||
198 | { | ||
199 | create_pcmdata(0, *inbuf ); | ||
200 | create_pcmdata(ch, *inbuf >> 4); | ||
201 | |||
202 | inbuf++; | ||
203 | inbufsize--; | ||
204 | } | ||
205 | |||
206 | add_adpcm_data(&cur_data); | ||
207 | |||
208 | return CODEC_OK; | ||
209 | } | ||
210 | |||
211 | static struct pcm_pos *get_seek_pos(long seek_time, | ||
212 | uint8_t *(*read_buffer)(size_t *realsize)) | ||
213 | { | ||
214 | static struct pcm_pos newpos; | ||
215 | uint32_t new_count= 0; | ||
216 | |||
217 | if (seek_time > 0) | ||
218 | new_count = ((uint64_t)seek_time * ci->id3->frequency | ||
219 | / (1000LL * fmt->samplesperblock)) / blocksperchunk; | ||
220 | |||
221 | if (!has_block_header) | ||
222 | { | ||
223 | new_count = seek(new_count, &cur_data, read_buffer, &decode_for_seek); | ||
224 | } | ||
225 | newpos.pos = new_count * fmt->chunksize; | ||
226 | newpos.samples = new_count * blocksperchunk * fmt->samplesperblock; | ||
227 | return &newpos; | ||
228 | } | ||
229 | |||
230 | static struct pcm_codec codec = { | ||
231 | set_format, | ||
232 | get_seek_pos, | ||
233 | decode, | ||
234 | }; | ||
235 | |||
236 | const struct pcm_codec *get_yamaha_adpcm_codec(void) | ||
237 | { | ||
238 | /* initialize first step, pcm data */ | ||
239 | cur_data.pcmdata[0] = 0; | ||
240 | cur_data.pcmdata[1] = 0; | ||
241 | cur_data.step[0] = 127; | ||
242 | cur_data.step[1] = 127; | ||
243 | |||
244 | return &codec; | ||
245 | } | ||