summaryrefslogtreecommitdiff
path: root/apps/codecs/libpcm/ima_adpcm_common.c
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-02-20 02:04:56 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-02-20 02:04:56 +0000
commit3716abba9274f544dd31cdf4e6c83a845bf2a801 (patch)
tree07bca7cdd3e40bb176e938fcb5ea8eb2f7c3e9cb /apps/codecs/libpcm/ima_adpcm_common.c
parent93caf52db5e0afe826278c148936bdfa563724f1 (diff)
downloadrockbox-3716abba9274f544dd31cdf4e6c83a845bf2a801.tar.gz
rockbox-3716abba9274f544dd31cdf4e6c83a845bf2a801.zip
commit FS#10424 and FS#10425
- wav(RIFF) supports Microsoft ADPCM, Dialogic OKI ADPCM, YAMAHA ADPCM, Adobe SWF ADPCM. - AIFF supports QuickTime IMA ADPCM. - DVI ADPCM(IMA ADPCM) reworks. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24782 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libpcm/ima_adpcm_common.c')
-rw-r--r--apps/codecs/libpcm/ima_adpcm_common.c171
1 files changed, 171 insertions, 0 deletions
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 */
38static 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 */
54static 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
65static int32_t pcmdata[2];
66static int8_t index[2];
67
68static int adpcm_data_size;
69static uint8_t step_mask;
70static uint8_t step_sign_mask;
71static int8_t step_shift;
72static 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 */
83void 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 */
103void 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 */
120int16_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 */
150int16_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}