1 /* libSoX ADPCM codecs: IMA, OKI, CL.   (c) 2007-8 robs@users.sourceforge.net
2  *
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.
7  *
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.
12  *
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
16  */
17 
18 #include "sox_i.h"
19 #include "adpcms.h"
20 
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,
28   32767};
29 
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};
35 
36 static int const step_changes[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
37 
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};
41 
42 static int const cl3_steps[5] = {0x100, 0x200, 0x400, 0x800, 0xA00};
43 static int const cl3_changes[4] = {-1, 0, 0, 1};
44 
45 static int const cl2_steps[6] = {0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000};
46 static int const cl2_changes[2] = {-1, 1};
47 
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},
54 };
55 
lsx_adpcm_init(adpcm_t * p,int type,int first_sample)56 void lsx_adpcm_init(adpcm_t * p, int type, int first_sample)
57 {
58   p->setup = setup_table[type];
59   p->last_output = first_sample;
60   p->step_index = 0;
61   p->errors = 0;
62 }
63 
64 #define min_sample -0x8000
65 #define max_sample 0x7fff
66 
lsx_adpcm_decode(int code,adpcm_t * p)67 int lsx_adpcm_decode(int code, adpcm_t * p)
68 {
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)
72     s = -s;
73   s += p->last_output;
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);
79       p->errors++;
80     }
81     s = s < min_sample? min_sample : max_sample;
82   }
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;
86 }
87 
lsx_adpcm_encode(int sample,adpcm_t * p)88 int lsx_adpcm_encode(int sample, adpcm_t * p)
89 {
90   int delta = sample - p->last_output;
91   int sign = 0;
92   int code;
93   if (delta < 0) {
94     sign = p->setup.sign;
95     delta = -delta;
96   }
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 */
100   return code;
101 }
102 
103 
104 /*
105  * Format methods
106  *
107  * Almost like the raw format functions, but cannot be used directly
108  * since they require an additional state parameter.
109  */
110 
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
116  * Returns    :
117  * Exceptions :
118  * Notes      : 1. This function is used for framed ADPCM formats to reset
119  *                 the decoder between frames.
120  ******************************************************************************/
121 
lsx_adpcm_reset(adpcm_io_t * state,sox_encoding_t type)122 void lsx_adpcm_reset(adpcm_io_t * state, sox_encoding_t type)
123 {
124   state->file.count = 0;
125   state->file.pos = 0;
126   state->store.byte = 0;
127   state->store.flag = 0;
128 
129   lsx_adpcm_init(&state->encoder, (type == SOX_ENCODING_OKI_ADPCM) ? 1 : 0, 0);
130 }
131 
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
139  *                    SOX_EOF
140  * Exceptions :
141  * Notes      : 1. This function can be used as a startread or
142  *                 startwrite method.
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  ******************************************************************************/
148 
adpcm_start(sox_format_t * ft,adpcm_io_t * state,sox_encoding_t type)149 static int adpcm_start(sox_format_t * ft, adpcm_io_t * state, sox_encoding_t type)
150 {
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;
155 
156   lsx_adpcm_reset(state, type);
157 
158   return lsx_rawstart(ft, sox_true, sox_false, sox_true, type, 4);
159 }
160 
lsx_adpcm_oki_start(sox_format_t * ft,adpcm_io_t * state)161 int lsx_adpcm_oki_start(sox_format_t * ft, adpcm_io_t * state)
162 {
163   return adpcm_start(ft, state, SOX_ENCODING_OKI_ADPCM);
164 }
165 
lsx_adpcm_ima_start(sox_format_t * ft,adpcm_io_t * state)166 int lsx_adpcm_ima_start(sox_format_t * ft, adpcm_io_t * state)
167 {
168   return adpcm_start(ft, state, SOX_ENCODING_IMA_ADPCM);
169 }
170 
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
180  * Exceptions :
181  * Notes      :
182  ******************************************************************************/
183 
lsx_adpcm_read(sox_format_t * ft,adpcm_io_t * state,sox_sample_t * buffer,size_t len)184 size_t lsx_adpcm_read(sox_format_t * ft, adpcm_io_t * state, sox_sample_t * buffer, size_t len)
185 {
186   size_t n = 0;
187   uint8_t byte;
188   int16_t word;
189 
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;
194     ++n;
195   }
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);
199 
200     if (++n < len) {
201       word = lsx_adpcm_decode(byte, &state->encoder);
202       *buffer++ = SOX_SIGNED_16BIT_TO_SAMPLE(word, ft->clips);
203       ++n;
204     } else {
205       state->store.byte = byte;
206       state->store.flag = 1;
207     }
208   }
209   return n;
210 }
211 
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
218  * Exceptions :
219  * Notes      :
220  ******************************************************************************/
221 
lsx_adpcm_stopread(sox_format_t * ft UNUSED,adpcm_io_t * state)222 int lsx_adpcm_stopread(sox_format_t * ft UNUSED, adpcm_io_t * state)
223 {
224   if (state->encoder.errors)
225     lsx_warn("%s: ADPCM state errors: %u", ft->filename, state->encoder.errors);
226   free(state->file.buf);
227 
228   return (SOX_SUCCESS);
229 }
230 
231 
232 /******************************************************************************
233  * Function   : write
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
241  *                       SOX_EOF
242  * Exceptions :
243  * Notes      :
244  ******************************************************************************/
245 
lsx_adpcm_write(sox_format_t * ft,adpcm_io_t * state,const sox_sample_t * buffer,size_t length)246 size_t lsx_adpcm_write(sox_format_t * ft, adpcm_io_t * state, const sox_sample_t * buffer, size_t length)
247 {
248   size_t count = 0;
249   uint8_t byte = state->store.byte;
250   uint8_t flag = state->store.flag;
251   short word;
252 
253   while (count < length) {
254     SOX_SAMPLE_LOCALS;
255     word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++, ft->clips);
256 
257     byte <<= 4;
258     byte |= lsx_adpcm_encode(word, &state->encoder) & 0x0F;
259 
260     flag = !flag;
261 
262     if (flag == 0) {
263       state->file.buf[state->file.count++] = byte;
264 
265       if (state->file.count >= state->file.size) {
266         lsx_writebuf(ft, state->file.buf, state->file.count);
267 
268         state->file.count = 0;
269       }
270     }
271 
272     count++;
273   }
274 
275   /* keep last byte across calls */
276   state->store.byte = byte;
277   state->store.flag = flag;
278   return (count);
279 }
280 
281 /******************************************************************************
282  * Function   : lsx_adpcm_flush
283  * Description: Flushes any leftover samples.
284  * Parameters : ft   - file info structure
285  *              state  - ADPCM state structure
286  * Returns    :
287  * Exceptions :
288  * Notes      : 1. Called directly for writing framed formats
289  ******************************************************************************/
290 
lsx_adpcm_flush(sox_format_t * ft,adpcm_io_t * state)291 void lsx_adpcm_flush(sox_format_t * ft, adpcm_io_t * state)
292 {
293   uint8_t byte = state->store.byte;
294   uint8_t flag = state->store.flag;
295 
296   /* flush remaining samples */
297 
298   if (flag != 0) {
299     byte <<= 4;
300     state->file.buf[state->file.count++] = byte;
301   }
302   if (state->file.count > 0)
303     lsx_writebuf(ft, state->file.buf, state->file.count);
304 }
305 
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
313  * Exceptions :
314  * Notes      :
315  ******************************************************************************/
316 
lsx_adpcm_stopwrite(sox_format_t * ft,adpcm_io_t * state)317 int lsx_adpcm_stopwrite(sox_format_t * ft, adpcm_io_t * state)
318 {
319   lsx_adpcm_flush(ft, state);
320   free(state->file.buf);
321   return (SOX_SUCCESS);
322 }
323