xref: /third_party/libsnd/tests/alaw_test.c (revision b815c7f3)
1/*
2** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
3**
4** This program is free software; you can redistribute it and/or modify
5** it under the terms of the GNU General Public License as published by
6** the Free Software Foundation; either version 2 of the License, or
7** (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12** GNU General Public License for more details.
13**
14** You should have received a copy of the GNU General Public License
15** along with this program; if not, write to the Free Software
16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#include "sfconfig.h"
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#if HAVE_UNISTD_H
26#include <unistd.h>
27#else
28#include "sf_unistd.h"
29#endif
30
31#include <sndfile.h>
32
33#include "utils.h"
34
35#define	BUFFER_SIZE		(65536)
36
37static unsigned char	alaw_encode (int sample) ;
38static int				alaw_decode (unsigned int alawbyte) ;
39
40static	short			short_buffer [BUFFER_SIZE] ;
41static	unsigned char	alaw_buffer [BUFFER_SIZE] ;
42
43int
44main (void)
45{	SNDFILE		*file ;
46	SF_INFO		sfinfo ;
47	const char	*filename ;
48	int			k ;
49
50	print_test_name ("alaw_test", "encoder") ;
51
52	filename = "alaw_test.raw" ;
53
54	sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ALAW, 44100, 1) ;
55
56	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
57	{	printf ("sf_open_write failed with error : ") ;
58		fflush (stdout) ;
59		puts (sf_strerror (NULL)) ;
60		exit (1) ;
61		} ;
62
63	/* Generate a file containing all possible 16 bit sample values
64	** and write it to disk as alaw encoded.frames.
65	*/
66
67	for (k = 0 ; k < 0x10000 ; k++)
68		short_buffer [k] = k & 0xFFFF ;
69
70	sf_write_short (file, short_buffer, BUFFER_SIZE) ;
71	sf_close (file) ;
72
73	/* Now open that file and compare the alaw encoded sample values
74	** with what they should be.
75	*/
76
77	if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
78	{	printf ("sf_open_write failed with error : ") ;
79		puts (sf_strerror (NULL)) ;
80		exit (1) ;
81		} ;
82
83	check_log_buffer_or_die (file, __LINE__) ;
84
85	if (sf_read_raw (file, alaw_buffer, BUFFER_SIZE) != BUFFER_SIZE)
86	{	printf ("sf_read_raw : ") ;
87		puts (sf_strerror (file)) ;
88		exit (1) ;
89		} ;
90
91	for (k = 0 ; k < 0x10000 ; k++)
92		if (alaw_encode (short_buffer [k]) != alaw_buffer [k])
93		{	printf ("Encoder error : sample #%d (0x%02X should be 0x%02X)\n", k, alaw_buffer [k], alaw_encode (short_buffer [k])) ;
94			exit (1) ;
95			} ;
96
97	sf_close (file) ;
98
99	puts ("ok") ;
100
101	print_test_name ("alaw_test", "decoder") ;
102	/* Now generate a file containing all possible 8 bit encoded
103	** sample values and write it to disk as alaw encoded.frames.
104	*/
105
106	if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
107	{	printf ("sf_open_write failed with error : ") ;
108		puts (sf_strerror (NULL)) ;
109		exit (1) ;
110		} ;
111
112	for (k = 0 ; k < 256 ; k++)
113		alaw_buffer [k] = k & 0xFF ;
114
115	sf_write_raw (file, alaw_buffer, 256) ;
116	sf_close (file) ;
117
118	/* Now open that file and compare the alaw decoded sample values
119	** with what they should be.
120	*/
121
122	if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
123	{	printf ("sf_open_write failed with error : ") ;
124		puts (sf_strerror (NULL)) ;
125		exit (1) ;
126		} ;
127
128	check_log_buffer_or_die (file, __LINE__) ;
129
130	if (sf_read_short (file, short_buffer, 256) != 256)
131	{	printf ("sf_read_short : ") ;
132		puts (sf_strerror (file)) ;
133		exit (1) ;
134		} ;
135
136
137	for (k = 0 ; k < 256 ; k++)
138		if (short_buffer [k] != alaw_decode (alaw_buffer [k]))
139		{	printf ("Decoder error : sample #%d (0x%02X should be 0x%02X)\n", k, short_buffer [k], alaw_decode (alaw_buffer [k])) ;
140			exit (1) ;
141			} ;
142
143	sf_close (file) ;
144
145	puts ("ok") ;
146
147	unlink (filename) ;
148
149	return 0 ;
150} /* main */
151
152
153/*=================================================================================
154**	The following routines came from the sox-12.15 (Sound eXcahcnge) distribution.
155**
156**	This code is not compiled into libsndfile. It is only used to test the
157**	libsndfile lookup tables for correctness.
158**
159**	I have included the original authors comments.
160*/
161
162/*
163** A-law routines by Graeme W. Gill.
164** Date: 93/5/7
165**
166** References:
167** 1) CCITT Recommendation G.711
168**
169*/
170
171#define ACLIP 31744
172
173static
174unsigned char alaw_encode (int sample)
175{	static int exp_lut [128] =
176	{	1, 1, 2, 2, 3, 3, 3, 3,
177		4, 4, 4, 4, 4, 4, 4, 4,
178		5, 5, 5, 5, 5, 5, 5, 5,
179		5, 5, 5, 5, 5, 5, 5, 5,
180		6, 6, 6, 6, 6, 6, 6, 6,
181		6, 6, 6, 6, 6, 6, 6, 6,
182		6, 6, 6, 6, 6, 6, 6, 6,
183		6, 6, 6, 6, 6, 6, 6, 6,
184		7, 7, 7, 7, 7, 7, 7, 7,
185		7, 7, 7, 7, 7, 7, 7, 7,
186		7, 7, 7, 7, 7, 7, 7, 7,
187		7, 7, 7, 7, 7, 7, 7, 7,
188		7, 7, 7, 7, 7, 7, 7, 7,
189		7, 7, 7, 7, 7, 7, 7, 7,
190		7, 7, 7, 7, 7, 7, 7, 7,
191		7, 7, 7, 7, 7, 7, 7, 7
192		} ;
193
194	int sign, exponent, mantissa ;
195	unsigned char Alawbyte ;
196
197	/* Get the sample into sign-magnitude. */
198	sign = ((~sample) >> 8) & 0x80 ;			/* set aside the sign */
199	if (sign == 0)
200		sample = -sample ;		/* get magnitude */
201	if (sample > ACLIP)
202		sample = ACLIP ;						/* clip the magnitude */
203
204	/* Convert from 16 bit linear to ulaw. */
205	if (sample >= 256)
206	{	exponent = exp_lut [(sample >> 8) & 0x7F] ;
207		mantissa = (sample >> (exponent + 3)) & 0x0F ;
208		Alawbyte = ((exponent << 4) | mantissa) ;
209		}
210	else
211		Alawbyte = (sample >> 4) ;
212
213	Alawbyte ^= (sign ^ 0x55) ;
214
215	return Alawbyte ;
216} /* alaw_encode */
217
218static
219int alaw_decode (unsigned int Alawbyte)
220{	static int exp_lut [8] = { 0, 264, 528, 1056, 2112, 4224, 8448, 16896 } ;
221	int sign, exponent, mantissa, sample ;
222
223	Alawbyte ^= 0x55 ;
224	sign = (Alawbyte & 0x80) ;
225	Alawbyte &= 0x7f ;			/* get magnitude */
226	if (Alawbyte >= 16)
227	{	exponent = (Alawbyte >> 4) & 0x07 ;
228		mantissa = Alawbyte & 0x0F ;
229		sample = exp_lut [exponent] + (mantissa << (exponent + 3)) ;
230		}
231	else
232		sample = (Alawbyte << 4) + 8 ;
233	if (sign == 0)
234		sample = -sample ;
235
236	return sample ;
237} /* alaw_decode */
238
239