1 /* libSoX ADPCM codecs: IMA, OKI, CL. (c) 2007-8 robs@users.sourceforge.net
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 static int const ima_steps
[89] = { /* ~16-bit precision; 4 bit code */
22 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
23 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
24 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
25 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
26 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
27 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
30 static int const oki_steps
[49] = { /* ~12-bit precision; 4 bit code */
31 256, 272, 304, 336, 368, 400, 448, 496, 544, 592, 656, 720, 800, 880, 960,
32 1056, 1168, 1280, 1408, 1552, 1712, 1888, 2080, 2288, 2512, 2768, 3040, 3344,
33 3680, 4048, 4464, 4912, 5392, 5936, 6528, 7184, 7904, 8704, 9568, 10528,
34 11584, 12736, 14016, 15408, 16960, 18656, 20512, 22576, 24832};
36 static int const step_changes
[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
38 /* Creative Labs ~8 bit precision; 4, 3, & 2 bit codes: */
39 static int const cl4_steps
[4] = {0x100, 0x200, 0x400, 0x800};
40 static int const cl4_changes
[8] = {-1, 0, 0, 0, 0, 1, 1, 1};
42 static int const cl3_steps
[5] = {0x100, 0x200, 0x400, 0x800, 0xA00};
43 static int const cl3_changes
[4] = {-1, 0, 0, 1};
45 static int const cl2_steps
[6] = {0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000};
46 static int const cl2_changes
[2] = {-1, 1};
48 static adpcm_setup_t
const setup_table
[] = {
49 {88, 8, 2, ima_steps
, step_changes
, ~0},
50 {48, 8, 2, oki_steps
, step_changes
, ~15},
51 { 3, 8, 0, cl4_steps
, cl4_changes
, ~255},
52 { 4, 4, 0, cl3_steps
, cl3_changes
, ~255},
53 { 5, 2, 0, cl2_steps
, cl2_changes
, ~255},
56 void lsx_adpcm_init(adpcm_t
* p
, int type
, int first_sample
)
58 p
->setup
= setup_table
[type
];
59 p
->last_output
= first_sample
;
64 #define min_sample -0x8000
65 #define max_sample 0x7fff
67 int lsx_adpcm_decode(int code
, adpcm_t
* p
)
69 int s
= ((code
& (p
->setup
.sign
- 1)) << 1) | 1;
70 s
= ((p
->setup
.steps
[p
->step_index
] * s
) >> (p
->setup
.shift
+ 1)) & p
->setup
.mask
;
71 if (code
& p
->setup
.sign
)
74 if (s
< min_sample
|| s
> max_sample
) {
75 int grace
= (p
->setup
.steps
[p
->step_index
] >> (p
->setup
.shift
+ 1)) & p
->setup
.mask
;
76 if (s
< min_sample
- grace
|| s
> max_sample
+ grace
) {
77 lsx_debug_most("code=%i step=%i grace=%i s=%i",
78 code
& (2 * p
->setup
.sign
- 1), p
->setup
.steps
[p
->step_index
], grace
, s
);
81 s
= s
< min_sample
? min_sample
: max_sample
;
83 p
->step_index
+= p
->setup
.changes
[code
& (p
->setup
.sign
- 1)];
84 p
->step_index
= range_limit(p
->step_index
, 0, p
->setup
.max_step_index
);
85 return p
->last_output
= s
;
88 int lsx_adpcm_encode(int sample
, adpcm_t
* p
)
90 int delta
= sample
- p
->last_output
;
97 code
= (delta
<< p
->setup
.shift
) / p
->setup
.steps
[p
->step_index
];
98 code
= sign
| min(code
, p
->setup
.sign
- 1);
99 lsx_adpcm_decode(code
, p
); /* Update encoder state */
107 * Almost like the raw format functions, but cannot be used directly
108 * since they require an additional state parameter.
111 /******************************************************************************
112 * Function : lsx_adpcm_reset
113 * Description: Resets the ADPCM codec state.
114 * Parameters : state - ADPCM state structure
115 * type - SOX_ENCODING_OKI_ADPCM or SOX_ENCODING_IMA_ADPCM
118 * Notes : 1. This function is used for framed ADPCM formats to reset
119 * the decoder between frames.
120 ******************************************************************************/
122 void lsx_adpcm_reset(adpcm_io_t
* state
, sox_encoding_t type
)
124 state
->file
.count
= 0;
126 state
->store
.byte
= 0;
127 state
->store
.flag
= 0;
129 lsx_adpcm_init(&state
->encoder
, (type
== SOX_ENCODING_OKI_ADPCM
) ? 1 : 0, 0);
132 /******************************************************************************
133 * Function : lsx_adpcm_start
134 * Description: Initialises the file parameters and ADPCM codec state.
135 * Parameters : ft - file info structure
136 * state - ADPCM state structure
137 * type - SOX_ENCODING_OKI_ADPCM or SOX_ENCODING_IMA_ADPCM
138 * Returns : int - SOX_SUCCESS
141 * Notes : 1. This function can be used as a startread or
143 * 2. VOX file format is 4-bit OKI ADPCM that decodes to
144 * to 12 bit signed linear PCM.
145 * 3. Dialogic only supports 6kHz, 8kHz and 11 kHz sampling
146 * rates but the codecs allows any user specified rate.
147 ******************************************************************************/
149 static int adpcm_start(sox_format_t
* ft
, adpcm_io_t
* state
, sox_encoding_t type
)
151 /* setup file info */
152 state
->file
.buf
= lsx_malloc(sox_globals
.bufsiz
);
153 state
->file
.size
= sox_globals
.bufsiz
;
154 ft
->signal
.channels
= 1;
156 lsx_adpcm_reset(state
, type
);
158 return lsx_rawstart(ft
, sox_true
, sox_false
, sox_true
, type
, 4);
161 int lsx_adpcm_oki_start(sox_format_t
* ft
, adpcm_io_t
* state
)
163 return adpcm_start(ft
, state
, SOX_ENCODING_OKI_ADPCM
);
166 int lsx_adpcm_ima_start(sox_format_t
* ft
, adpcm_io_t
* state
)
168 return adpcm_start(ft
, state
, SOX_ENCODING_IMA_ADPCM
);
171 /******************************************************************************
172 * Function : lsx_adpcm_read
173 * Description: Converts the OKI ADPCM 4-bit samples to 16-bit signed PCM and
174 * then scales the samples to full sox_sample_t range.
175 * Parameters : ft - file info structure
176 * state - ADPCM state structure
177 * buffer - output buffer
178 * len - size of output buffer
179 * Returns : - number of samples returned in buffer
182 ******************************************************************************/
184 size_t lsx_adpcm_read(sox_format_t
* ft
, adpcm_io_t
* state
, sox_sample_t
* buffer
, size_t len
)
190 if (len
&& state
->store
.flag
) {
191 word
= lsx_adpcm_decode(state
->store
.byte
, &state
->encoder
);
192 *buffer
++ = SOX_SIGNED_16BIT_TO_SAMPLE(word
, ft
->clips
);
193 state
->store
.flag
= 0;
196 while (n
< len
&& lsx_read_b_buf(ft
, &byte
, (size_t) 1) == 1) {
197 word
= lsx_adpcm_decode(byte
>> 4, &state
->encoder
);
198 *buffer
++ = SOX_SIGNED_16BIT_TO_SAMPLE(word
, ft
->clips
);
201 word
= lsx_adpcm_decode(byte
, &state
->encoder
);
202 *buffer
++ = SOX_SIGNED_16BIT_TO_SAMPLE(word
, ft
->clips
);
205 state
->store
.byte
= byte
;
206 state
->store
.flag
= 1;
212 /******************************************************************************
213 * Function : stopread
214 * Description: Frees the internal buffer allocated in voxstart/imastart.
215 * Parameters : ft - file info structure
216 * state - ADPCM state structure
217 * Returns : int - SOX_SUCCESS
220 ******************************************************************************/
222 int lsx_adpcm_stopread(sox_format_t
* ft UNUSED
, adpcm_io_t
* state
)
224 if (state
->encoder
.errors
)
225 lsx_warn("%s: ADPCM state errors: %u", ft
->filename
, state
->encoder
.errors
);
226 free(state
->file
.buf
);
228 return (SOX_SUCCESS
);
232 /******************************************************************************
234 * Description: Converts the supplied buffer to 12 bit linear PCM and encodes
235 * to OKI ADPCM 4-bit samples (packed a two nibbles per byte).
236 * Parameters : ft - file info structure
237 * state - ADPCM state structure
238 * buffer - output buffer
239 * length - size of output buffer
240 * Returns : int - SOX_SUCCESS
244 ******************************************************************************/
246 size_t lsx_adpcm_write(sox_format_t
* ft
, adpcm_io_t
* state
, const sox_sample_t
* buffer
, size_t length
)
249 uint8_t byte
= state
->store
.byte
;
250 uint8_t flag
= state
->store
.flag
;
253 while (count
< length
) {
255 word
= SOX_SAMPLE_TO_SIGNED_16BIT(*buffer
++, ft
->clips
);
258 byte
|= lsx_adpcm_encode(word
, &state
->encoder
) & 0x0F;
263 state
->file
.buf
[state
->file
.count
++] = byte
;
265 if (state
->file
.count
>= state
->file
.size
) {
266 lsx_writebuf(ft
, state
->file
.buf
, state
->file
.count
);
268 state
->file
.count
= 0;
275 /* keep last byte across calls */
276 state
->store
.byte
= byte
;
277 state
->store
.flag
= flag
;
281 /******************************************************************************
282 * Function : lsx_adpcm_flush
283 * Description: Flushes any leftover samples.
284 * Parameters : ft - file info structure
285 * state - ADPCM state structure
288 * Notes : 1. Called directly for writing framed formats
289 ******************************************************************************/
291 void lsx_adpcm_flush(sox_format_t
* ft
, adpcm_io_t
* state
)
293 uint8_t byte
= state
->store
.byte
;
294 uint8_t flag
= state
->store
.flag
;
296 /* flush remaining samples */
300 state
->file
.buf
[state
->file
.count
++] = byte
;
302 if (state
->file
.count
> 0)
303 lsx_writebuf(ft
, state
->file
.buf
, state
->file
.count
);
306 /******************************************************************************
307 * Function : lsx_adpcm_stopwrite
308 * Description: Flushes any leftover samples and frees the internal buffer
309 * allocated in voxstart/imastart.
310 * Parameters : ft - file info structure
311 * state - ADPCM state structure
312 * Returns : int - SOX_SUCCESS
315 ******************************************************************************/
317 int lsx_adpcm_stopwrite(sox_format_t
* ft
, adpcm_io_t
* state
)
319 lsx_adpcm_flush(ft
, state
);
320 free(state
->file
.buf
);
321 return (SOX_SUCCESS
);