• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 static unsigned char	alaw_encode (int sample) ;
38 static int				alaw_decode (unsigned int alawbyte) ;
39 
40 static	short			short_buffer [BUFFER_SIZE] ;
41 static	unsigned char	alaw_buffer [BUFFER_SIZE] ;
42 
43 int
main(void)44 main (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 
173 static
alaw_encode(int sample)174 unsigned 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 
218 static
alaw_decode(unsigned int Alawbyte)219 int 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