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