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