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