c2644f10ea1a0a965f6aacd6522014e5dd67b390
[platform/upstream/libsndfile.git] / tests / ulaw_test.c
1 /*
2 ** Copyright (C) 1999-2011 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 #endif
28
29 #include <sndfile.h>
30
31 #include "utils.h"
32
33 #define BUFFER_SIZE             (65536)
34
35 static unsigned char    ulaw_encode (int sample) ;
36 static int                              ulaw_decode (unsigned int ulawbyte) ;
37
38 static  short                   short_buffer [BUFFER_SIZE] ;
39 static  unsigned char   ulaw_buffer [BUFFER_SIZE] ;
40
41 int
42 main (void)
43 {       SNDFILE         *file ;
44         SF_INFO         sfinfo ;
45         const char      *filename ;
46         int                     k ;
47
48         print_test_name ("ulaw_test", "encoder") ;
49
50         filename = "test.raw" ;
51
52         sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ULAW, 44100, 1) ;
53
54         if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
55         {       printf ("sf_open_write failed with error : ") ;
56                 fflush (stdout) ;
57                 puts (sf_strerror (NULL)) ;
58                 exit (1) ;
59                 } ;
60
61         /* Generate a file containing all possible 16 bit sample values
62         ** and write it to disk as ulaw encoded.frames.
63         */
64
65         for (k = 0 ; k < 0x10000 ; k++)
66                 short_buffer [k] = k & 0xFFFF ;
67
68         sf_write_short (file, short_buffer, BUFFER_SIZE) ;
69         sf_close (file) ;
70
71         /* Now open that file and compare the ulaw encoded sample values
72         ** with what they should be.
73         */
74
75         if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
76         {       printf ("sf_open_write failed with error : ") ;
77                 puts (sf_strerror (NULL)) ;
78                 exit (1) ;
79                 } ;
80
81         check_log_buffer_or_die (file, __LINE__) ;
82
83         if (sf_read_raw (file, ulaw_buffer, BUFFER_SIZE) != BUFFER_SIZE)
84         {       printf ("sf_read_raw : ") ;
85                 puts (sf_strerror (file)) ;
86                 exit (1) ;
87                 } ;
88
89         for (k = 0 ; k < 0x10000 ; k++)
90                 if (ulaw_encode (short_buffer [k]) != ulaw_buffer [k])
91                 {       printf ("Encoder error : sample #%d (0x%02X should be 0x%02X)\n", k, ulaw_buffer [k], ulaw_encode (short_buffer [k])) ;
92                         exit (1) ;
93                         } ;
94
95         sf_close (file) ;
96
97         puts ("ok") ;
98
99         print_test_name ("ulaw_test", "decoder") ;
100
101         /* Now generate a file containing all possible 8 bit encoded
102         ** sample values and write it to disk as ulaw encoded.frames.
103         */
104
105         if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
106         {       printf ("sf_open_write failed with error : ") ;
107                 puts (sf_strerror (NULL)) ;
108                 exit (1) ;
109                 } ;
110
111         for (k = 0 ; k < 256 ; k++)
112                 ulaw_buffer [k] = k & 0xFF ;
113
114         sf_write_raw (file, ulaw_buffer, 256) ;
115         sf_close (file) ;
116
117         /* Now open that file and compare the ulaw decoded sample values
118         ** with what they should be.
119         */
120
121         if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
122         {       printf ("sf_open_write failed with error : ") ;
123                 puts (sf_strerror (NULL)) ;
124                 exit (1) ;
125                 } ;
126
127         check_log_buffer_or_die (file, __LINE__) ;
128
129         if (sf_read_short (file, short_buffer, 256) != 256)
130         {       printf ("sf_read_short : ") ;
131                 puts (sf_strerror (file)) ;
132                 exit (1) ;
133                 } ;
134
135
136         for (k = 0 ; k < 256 ; k++)
137                 if (short_buffer [k] != ulaw_decode (ulaw_buffer [k]))
138                 {       printf ("Decoder error : sample #%d (0x%04X should be 0x%04X)\n", k, short_buffer [k], ulaw_decode (ulaw_buffer [k])) ;
139                         exit (1) ;
140                         } ;
141
142         sf_close (file) ;
143
144         puts ("ok") ;
145
146         unlink (filename) ;
147
148         return 0 ;
149 } /* main */
150
151
152 /*=================================================================================
153 **      The following routines came from the sox-12.15 (Sound eXcahcnge) distribution.
154 **
155 **      This code is not compiled into libsndfile. It is only used to test the
156 **      libsndfile lookup tables for correctness.
157 **
158 **      I have included the original authors comments.
159 */
160
161 /*
162 ** This routine converts from linear to ulaw.
163 **
164 ** Craig Reese: IDA/Supercomputing Research Center
165 ** Joe Campbell: Department of Defense
166 ** 29 September 1989
167 **
168 ** References:
169 ** 1) CCITT Recommendation G.711  (very difficult to follow)
170 ** 2) "A New Digital Technique for Implementation of Any
171 **     Continuous PCM Companding Law," Villeret, Michel,
172 **     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
173 **     1973, pg. 11.12-11.17
174 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
175 **     for Analog-to_Digital Conversion Techniques,"
176 **     17 February 1987
177 **
178 ** Input: Signed 16 bit linear sample
179 ** Output: 8 bit ulaw sample
180 */
181
182 #define uBIAS 0x84              /* define the add-in bias for 16 bit.frames */
183 #define uCLIP 32635
184
185 static
186 unsigned char ulaw_encode (int sample)
187 {       static int exp_lut [256] =
188         {       0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
189                 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
190                 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
191                 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
192                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
193                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
194                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
195                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
196                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
197                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
198                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
199                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
200                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
201                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
202                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
203                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
204                 } ;
205
206     int sign, exponent, mantissa ;
207     unsigned char ulawbyte ;
208
209     /* Get the sample into sign-magnitude. */
210     sign = (sample >> 8) & 0x80 ;                                       /* set aside the sign */
211     if ( sign != 0 )
212                 sample = -sample ;                                                      /* get magnitude */
213     if ( sample > uCLIP )
214                 sample = uCLIP ;                                                        /* clip the magnitude */
215
216     /* Convert from 16 bit linear to ulaw. */
217     sample = sample + uBIAS ;
218     exponent = exp_lut [( sample >> 7 ) & 0xFF] ;
219     mantissa = (sample >> ( exponent + 3 ) ) & 0x0F ;
220     ulawbyte = ~ (sign | ( exponent << 4 ) | mantissa) ;
221
222         return ulawbyte ;
223 } /* ulaw_encode */
224
225
226 /*
227 ** This routine converts from ulaw to 16 bit linear.
228 **
229 ** Craig Reese: IDA/Supercomputing Research Center
230 ** 29 September 1989
231 **
232 ** References:
233 ** 1) CCITT Recommendation G.711  (very difficult to follow)
234 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
235 **     for Analog-to_Digital Conversion Techniques,"
236 **     17 February 1987
237 **
238 ** Input: 8 bit ulaw sample
239 ** Output: signed 16 bit linear sample
240 */
241
242 static
243 int ulaw_decode (unsigned int ulawbyte)
244 {       static int exp_lut [8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 } ;
245     int sign, exponent, mantissa, sample ;
246
247     ulawbyte = ~ ulawbyte ;
248     sign = (ulawbyte & 0x80) ;
249     exponent = (ulawbyte >> 4) & 0x07 ;
250     mantissa = ulawbyte & 0x0F ;
251     sample = exp_lut [exponent] + (mantissa << (exponent + 3)) ;
252     if (sign != 0)
253                 sample = -sample ;
254
255     return sample ;
256 } /* ulaw_decode */
257