xref: /third_party/libsnd/src/ima_oki_adpcm.c (revision b815c7f3)
1/*
2** Copyright (C) 2007-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
3** Copyright (c) 2007 <robs@users.sourceforge.net>
4**
5** This library is free software; you can redistribute it and/or modify it
6** under the terms of the GNU Lesser General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or (at
8** your option) any later version.
9**
10** This library is distributed in the hope that it will be useful, but
11** WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
13** General Public License for more details.
14**
15** You should have received a copy of the GNU Lesser General Public License
16** along with this library.  If not, write to the Free Software Foundation,
17** Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
18*/
19
20/* ADPCM: IMA, OKI <==> 16-bit PCM. */
21
22#include "sfconfig.h"
23
24#include <string.h>
25
26/* Set up for libsndfile environment: */
27#include "common.h"
28
29#include "ima_oki_adpcm.h"
30
31#define MIN_SAMPLE	-0x8000
32#define MAX_SAMPLE	0x7fff
33
34static int const ima_steps [] =	/* ~16-bit precision */
35{	7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
36	50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
37	253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
38	1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
39	3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
40	11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
41	32767
42} ;
43
44static int const oki_steps [] =	/* ~12-bit precision */
45{	256, 272, 304, 336, 368, 400, 448, 496, 544, 592, 656, 720, 800, 880, 960,
46	1056, 1168, 1280, 1408, 1552, 1712, 1888, 2080, 2288, 2512, 2768, 3040, 3344,
47	3680, 4048, 4464, 4912, 5392, 5936, 6528, 7184, 7904, 8704, 9568, 10528,
48	11584, 12736, 14016, 15408, 16960, 18656, 20512, 22576, 24832
49} ;
50
51static int const step_changes [] = { -1, -1, -1, -1, 2, 4, 6, 8 } ;
52
53void
54ima_oki_adpcm_init (IMA_OKI_ADPCM * state, IMA_OKI_ADPCM_TYPE type)
55{
56	memset (state, 0, sizeof (*state)) ;
57
58	if (type == IMA_OKI_ADPCM_TYPE_IMA)
59	{	state->max_step_index = ARRAY_LEN (ima_steps) - 1 ;
60		state->steps = ima_steps ;
61		state->mask = (~0) ;
62		}
63	else
64	{	state->max_step_index = ARRAY_LEN (oki_steps) - 1 ;
65		state->steps = oki_steps ;
66		state->mask = arith_shift_left (~0, 4) ;
67		} ;
68
69} /* ima_oki_adpcm_init */
70
71
72int
73adpcm_decode (IMA_OKI_ADPCM * state, int code)
74{	int s ;
75
76	s = ((code & 7) << 1) | 1 ;
77	s = ((state->steps [state->step_index] * s) >> 3) & state->mask ;
78
79	if (code & 8)
80		s = -s ;
81	s += state->last_output ;
82
83	if (s < MIN_SAMPLE || s > MAX_SAMPLE)
84	{	int grace ;
85
86		grace = (state->steps [state->step_index] >> 3) & state->mask ;
87
88		if (s < MIN_SAMPLE - grace || s > MAX_SAMPLE + grace)
89			state->errors ++ ;
90
91		s = s < MIN_SAMPLE ? MIN_SAMPLE : MAX_SAMPLE ;
92		} ;
93
94	state->step_index += step_changes [code & 7] ;
95	state->step_index = SF_MIN (SF_MAX (state->step_index, 0), state->max_step_index) ;
96	state->last_output = s ;
97
98	return s ;
99} /* adpcm_decode */
100
101int
102adpcm_encode (IMA_OKI_ADPCM * state, int sample)
103{	int delta, sign = 0, code ;
104
105	delta = sample - state->last_output ;
106
107	if (delta < 0)
108	{	sign = 8 ;
109		delta = -delta ;
110		} ;
111
112	code = 4 * delta / state->steps [state->step_index] ;
113	code = sign | SF_MIN (code, 7) ;
114	adpcm_decode (state, code) ; /* Update encoder state */
115
116	return code ;
117} /* adpcm_encode */
118
119
120void
121ima_oki_adpcm_decode_block	(IMA_OKI_ADPCM * state)
122{	unsigned char code ;
123	int k ;
124
125	for (k = 0 ; k < state->code_count ; k++)
126	{	code = state->codes [k] ;
127		state->pcm [2 * k] = adpcm_decode (state, code >> 4) ;
128		state->pcm [2 * k + 1] = adpcm_decode (state, code) ;
129		} ;
130
131	state->pcm_count = 2 * k ;
132} /* ima_oki_adpcm_decode_block */
133
134
135void
136ima_oki_adpcm_encode_block (IMA_OKI_ADPCM * state)
137{	unsigned char code ;
138	int k ;
139
140	/*
141	**	The codec expects an even number of input samples.
142	**
143	**	Samples should always be passed in even length blocks. If the last block to
144	**	be encoded is odd length, extend that block by one zero valued sample.
145	*/
146	if (state->pcm_count % 2 == 1)
147		state->pcm [state->pcm_count ++] = 0 ;
148
149	for (k = 0 ; k < state->pcm_count / 2 ; k++)
150	{	code = adpcm_encode (state, state->pcm [2 * k]) << 4 ;
151		code |= adpcm_encode (state, state->pcm [2 * k + 1]) ;
152		state->codes [k] = code ;
153		} ;
154
155	state->code_count = k ;
156} /* ima_oki_adpcm_encode_block */
157
158
159#ifdef TEST
160
161static const unsigned char test_codes [] =
162{	0x08, 0x08, 0x04, 0x7f, 0x72, 0xf7, 0x9f, 0x7c, 0xd7, 0xbc, 0x7a, 0xa7, 0xb8,
163	0x4b, 0x0b, 0x38, 0xf6, 0x9d, 0x7a, 0xd7, 0xbc, 0x7a, 0xd7, 0xa8, 0x6c, 0x81,
164	0x98, 0xe4, 0x0e, 0x7a, 0xd7, 0x9e, 0x7b, 0xc7, 0xab, 0x7a, 0x85, 0xc0, 0xb3,
165	0x8f, 0x58, 0xd7, 0xad, 0x7a, 0xd7, 0xad, 0x7a, 0x87, 0xd0, 0x2b, 0x0e, 0x48,
166	0xd7, 0xad, 0x78, 0xf7, 0xbc, 0x7a, 0xb7, 0xa8, 0x4b, 0x88, 0x18, 0xd5, 0x8d,
167	0x6a, 0xa4, 0x98, 0x08, 0x00, 0x80, 0x88,
168} ;
169
170static const short test_pcm [] =
171{	32, 0, 32, 0, 32, 320, 880, -336, 2304, 4192, -992, 10128, 5360, -16352,
172	30208, 2272, -31872, 14688, -7040, -32432, 14128, -1392, -15488, 22960,
173	1232, -1584, 21488, -240, 2576, -15360, 960, -1152, -30032, 10320, 1008,
174	-30032, 16528, 1008, -30032, 16528, -5200, -30592, 15968, 448, -30592,
175	15968, 448, -2368, 30960, 3024, -80, 8384, 704, -1616, -29168, -1232, 1872,
176	-32768, 13792, -1728, -32768, 13792, 4480, -32192, 14368, -7360, -32752,
177	13808, -1712, -21456, 16992, 1472, -1344, 26848, -1088, 2016, -17728, 208,
178	-2112, -32768, 1376, -1728, -32768, 13792, -1728, -32768, 13792, -1728,
179	-32768, 13792, -1728, -32768, 13792, -1728, -4544, 32767, -1377, 1727,
180	15823, -2113, 207, -27345, 591, -2513, -32768, 13792, -1728, -32768, 13792,
181	10688, -31632, 14928, -6800, -32192, 14368, -1152, -20896, 17552, 2032,
182	-784, 22288, 560, -2256, -4816, 2176, 64, -21120, 9920, 6816, -24224, 16128,
183	608, -13488, 9584, 272, -2544, 16, -2304, -192, 1728, -16, 1568, 128, -1184,
184} ;
185
186
187static void
188test_oki_adpcm (void)
189{
190	IMA_OKI_ADPCM adpcm ;
191	unsigned char code ;
192	int i, j ;
193
194	printf ("    Testing encoder          : ") ;
195	fflush (stdout) ;
196
197	ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
198	for (i = 0 ; i < ARRAY_LEN (test_codes) ; i++)
199		for (j = 0, code = test_codes [i] ; j < 2 ; j++, code <<= 4)
200			if (adpcm_decode (&adpcm, code >> 4) != test_pcm [2 * i + j])
201			{	printf ("\n\nFail at i = %d, j = %d.\n\n", i, j) ;
202				exit (1) ;
203				} ;
204
205	puts ("ok") ;
206
207	printf ("    Testing decoder          : ") ;
208	fflush (stdout) ;
209
210	ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
211	for (i = 0 ; i < ARRAY_LEN (test_pcm) ; i += j)
212	{	code = adpcm_encode (&adpcm, test_pcm [i]) ;
213		code = (code << 4) | adpcm_encode (&adpcm, test_pcm [i + 1]) ;
214		if (code != test_codes [i / 2])
215			{	printf ("\n\nFail at i = %d, %d should be %d\n\n", i, code, test_codes [i / 2]) ;
216				exit (1) ;
217				} ;
218		} ;
219
220	puts ("ok") ;
221} /* test_oki_adpcm */
222
223static void
224test_oki_adpcm_block (void)
225{
226	IMA_OKI_ADPCM adpcm ;
227	int k ;
228
229	if (ARRAY_LEN (adpcm.pcm) < ARRAY_LEN (test_pcm))
230	{	printf ("\n\nLine %d : ARRAY_LEN (adpcm->pcm) > ARRAY_LEN (test_pcm) (%d > %d).\n\n", __LINE__, ARRAY_LEN (adpcm.pcm), ARRAY_LEN (test_pcm)) ;
231		exit (1) ;
232		} ;
233
234	if (ARRAY_LEN (adpcm.codes) < ARRAY_LEN (test_codes))
235	{	printf ("\n\nLine %d : ARRAY_LEN (adcodes->codes) > ARRAY_LEN (test_codes).n", __LINE__) ;
236		exit (1) ;
237		} ;
238
239	printf ("    Testing block encoder    : ") ;
240	fflush (stdout) ;
241
242	ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
243
244	memcpy (adpcm.pcm, test_pcm, sizeof (adpcm.pcm [0]) * ARRAY_LEN (test_pcm)) ;
245	adpcm.pcm_count = ARRAY_LEN (test_pcm) ;
246	adpcm.code_count = 13 ;
247
248	ima_oki_adpcm_encode_block (&adpcm) ;
249
250	if (adpcm.code_count * 2 != ARRAY_LEN (test_pcm))
251	{	printf ("\n\nLine %d : %d * 2 != %d\n\n", __LINE__, adpcm.code_count * 2, ARRAY_LEN (test_pcm)) ;
252		exit (1) ;
253		} ;
254
255	for (k = 0 ; k < ARRAY_LEN (test_codes) ; k++)
256		if (adpcm.codes [k] != test_codes [k])
257		{	printf ("\n\nLine %d : Fail at k = %d, %d should be %d\n\n", __LINE__, k, adpcm.codes [k], test_codes [k]) ;
258			exit (1) ;
259			} ;
260
261	puts ("ok") ;
262
263	printf ("    Testing block decoder    : ") ;
264	fflush (stdout) ;
265
266	ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
267
268	memcpy (adpcm.codes, test_codes, sizeof (adpcm.codes [0]) * ARRAY_LEN (test_codes)) ;
269	adpcm.code_count = ARRAY_LEN (test_codes) ;
270	adpcm.pcm_count = 13 ;
271
272	ima_oki_adpcm_decode_block (&adpcm) ;
273
274	if (adpcm.pcm_count != 2 * ARRAY_LEN (test_codes))
275	{	printf ("\n\nLine %d : %d * 2 != %d\n\n", __LINE__, adpcm.pcm_count, 2 * ARRAY_LEN (test_codes)) ;
276		exit (1) ;
277		} ;
278
279	for (k = 0 ; k < ARRAY_LEN (test_pcm) ; k++)
280		if (adpcm.pcm [k] != test_pcm [k])
281		{	printf ("\n\nLine %d : Fail at i = %d, %d should be %d.\n\n", __LINE__, k, adpcm.pcm [k], test_pcm [k]) ;
282			exit (1) ;
283			} ;
284
285	puts ("ok") ;
286} /* test_oki_adpcm_block */
287
288int
289main (void)
290{
291	test_oki_adpcm () ;
292	test_oki_adpcm_block () ;
293
294	return 0 ;
295} /* main */
296
297#endif
298