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 alaw_encode (int sample) ; 38b815c7f3Sopenharmony_cistatic int alaw_decode (unsigned int alawbyte) ; 39b815c7f3Sopenharmony_ci 40b815c7f3Sopenharmony_cistatic short short_buffer [BUFFER_SIZE] ; 41b815c7f3Sopenharmony_cistatic unsigned char alaw_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 ("alaw_test", "encoder") ; 51b815c7f3Sopenharmony_ci 52b815c7f3Sopenharmony_ci filename = "alaw_test.raw" ; 53b815c7f3Sopenharmony_ci 54b815c7f3Sopenharmony_ci sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ALAW, 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 alaw 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 alaw 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, alaw_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 (alaw_encode (short_buffer [k]) != alaw_buffer [k]) 93b815c7f3Sopenharmony_ci { printf ("Encoder error : sample #%d (0x%02X should be 0x%02X)\n", k, alaw_buffer [k], alaw_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 ("alaw_test", "decoder") ; 102b815c7f3Sopenharmony_ci /* Now generate a file containing all possible 8 bit encoded 103b815c7f3Sopenharmony_ci ** sample values and write it to disk as alaw encoded.frames. 104b815c7f3Sopenharmony_ci */ 105b815c7f3Sopenharmony_ci 106b815c7f3Sopenharmony_ci if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) 107b815c7f3Sopenharmony_ci { printf ("sf_open_write failed with error : ") ; 108b815c7f3Sopenharmony_ci puts (sf_strerror (NULL)) ; 109b815c7f3Sopenharmony_ci exit (1) ; 110b815c7f3Sopenharmony_ci } ; 111b815c7f3Sopenharmony_ci 112b815c7f3Sopenharmony_ci for (k = 0 ; k < 256 ; k++) 113b815c7f3Sopenharmony_ci alaw_buffer [k] = k & 0xFF ; 114b815c7f3Sopenharmony_ci 115b815c7f3Sopenharmony_ci sf_write_raw (file, alaw_buffer, 256) ; 116b815c7f3Sopenharmony_ci sf_close (file) ; 117b815c7f3Sopenharmony_ci 118b815c7f3Sopenharmony_ci /* Now open that file and compare the alaw decoded sample values 119b815c7f3Sopenharmony_ci ** with what they should be. 120b815c7f3Sopenharmony_ci */ 121b815c7f3Sopenharmony_ci 122b815c7f3Sopenharmony_ci if (! (file = sf_open (filename, SFM_READ, &sfinfo))) 123b815c7f3Sopenharmony_ci { printf ("sf_open_write failed with error : ") ; 124b815c7f3Sopenharmony_ci puts (sf_strerror (NULL)) ; 125b815c7f3Sopenharmony_ci exit (1) ; 126b815c7f3Sopenharmony_ci } ; 127b815c7f3Sopenharmony_ci 128b815c7f3Sopenharmony_ci check_log_buffer_or_die (file, __LINE__) ; 129b815c7f3Sopenharmony_ci 130b815c7f3Sopenharmony_ci if (sf_read_short (file, short_buffer, 256) != 256) 131b815c7f3Sopenharmony_ci { printf ("sf_read_short : ") ; 132b815c7f3Sopenharmony_ci puts (sf_strerror (file)) ; 133b815c7f3Sopenharmony_ci exit (1) ; 134b815c7f3Sopenharmony_ci } ; 135b815c7f3Sopenharmony_ci 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_ci for (k = 0 ; k < 256 ; k++) 138b815c7f3Sopenharmony_ci if (short_buffer [k] != alaw_decode (alaw_buffer [k])) 139b815c7f3Sopenharmony_ci { printf ("Decoder error : sample #%d (0x%02X should be 0x%02X)\n", k, short_buffer [k], alaw_decode (alaw_buffer [k])) ; 140b815c7f3Sopenharmony_ci exit (1) ; 141b815c7f3Sopenharmony_ci } ; 142b815c7f3Sopenharmony_ci 143b815c7f3Sopenharmony_ci sf_close (file) ; 144b815c7f3Sopenharmony_ci 145b815c7f3Sopenharmony_ci puts ("ok") ; 146b815c7f3Sopenharmony_ci 147b815c7f3Sopenharmony_ci unlink (filename) ; 148b815c7f3Sopenharmony_ci 149b815c7f3Sopenharmony_ci return 0 ; 150b815c7f3Sopenharmony_ci} /* main */ 151b815c7f3Sopenharmony_ci 152b815c7f3Sopenharmony_ci 153b815c7f3Sopenharmony_ci/*================================================================================= 154b815c7f3Sopenharmony_ci** The following routines came from the sox-12.15 (Sound eXcahcnge) distribution. 155b815c7f3Sopenharmony_ci** 156b815c7f3Sopenharmony_ci** This code is not compiled into libsndfile. It is only used to test the 157b815c7f3Sopenharmony_ci** libsndfile lookup tables for correctness. 158b815c7f3Sopenharmony_ci** 159b815c7f3Sopenharmony_ci** I have included the original authors comments. 160b815c7f3Sopenharmony_ci*/ 161b815c7f3Sopenharmony_ci 162b815c7f3Sopenharmony_ci/* 163b815c7f3Sopenharmony_ci** A-law routines by Graeme W. Gill. 164b815c7f3Sopenharmony_ci** Date: 93/5/7 165b815c7f3Sopenharmony_ci** 166b815c7f3Sopenharmony_ci** References: 167b815c7f3Sopenharmony_ci** 1) CCITT Recommendation G.711 168b815c7f3Sopenharmony_ci** 169b815c7f3Sopenharmony_ci*/ 170b815c7f3Sopenharmony_ci 171b815c7f3Sopenharmony_ci#define ACLIP 31744 172b815c7f3Sopenharmony_ci 173b815c7f3Sopenharmony_cistatic 174b815c7f3Sopenharmony_ciunsigned char alaw_encode (int sample) 175b815c7f3Sopenharmony_ci{ static int exp_lut [128] = 176b815c7f3Sopenharmony_ci { 1, 1, 2, 2, 3, 3, 3, 3, 177b815c7f3Sopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 178b815c7f3Sopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 179b815c7f3Sopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 180b815c7f3Sopenharmony_ci 6, 6, 6, 6, 6, 6, 6, 6, 181b815c7f3Sopenharmony_ci 6, 6, 6, 6, 6, 6, 6, 6, 182b815c7f3Sopenharmony_ci 6, 6, 6, 6, 6, 6, 6, 6, 183b815c7f3Sopenharmony_ci 6, 6, 6, 6, 6, 6, 6, 6, 184b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 185b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 186b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 187b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 188b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 189b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 190b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7, 191b815c7f3Sopenharmony_ci 7, 7, 7, 7, 7, 7, 7, 7 192b815c7f3Sopenharmony_ci } ; 193b815c7f3Sopenharmony_ci 194b815c7f3Sopenharmony_ci int sign, exponent, mantissa ; 195b815c7f3Sopenharmony_ci unsigned char Alawbyte ; 196b815c7f3Sopenharmony_ci 197b815c7f3Sopenharmony_ci /* Get the sample into sign-magnitude. */ 198b815c7f3Sopenharmony_ci sign = ((~sample) >> 8) & 0x80 ; /* set aside the sign */ 199b815c7f3Sopenharmony_ci if (sign == 0) 200b815c7f3Sopenharmony_ci sample = -sample ; /* get magnitude */ 201b815c7f3Sopenharmony_ci if (sample > ACLIP) 202b815c7f3Sopenharmony_ci sample = ACLIP ; /* clip the magnitude */ 203b815c7f3Sopenharmony_ci 204b815c7f3Sopenharmony_ci /* Convert from 16 bit linear to ulaw. */ 205b815c7f3Sopenharmony_ci if (sample >= 256) 206b815c7f3Sopenharmony_ci { exponent = exp_lut [(sample >> 8) & 0x7F] ; 207b815c7f3Sopenharmony_ci mantissa = (sample >> (exponent + 3)) & 0x0F ; 208b815c7f3Sopenharmony_ci Alawbyte = ((exponent << 4) | mantissa) ; 209b815c7f3Sopenharmony_ci } 210b815c7f3Sopenharmony_ci else 211b815c7f3Sopenharmony_ci Alawbyte = (sample >> 4) ; 212b815c7f3Sopenharmony_ci 213b815c7f3Sopenharmony_ci Alawbyte ^= (sign ^ 0x55) ; 214b815c7f3Sopenharmony_ci 215b815c7f3Sopenharmony_ci return Alawbyte ; 216b815c7f3Sopenharmony_ci} /* alaw_encode */ 217b815c7f3Sopenharmony_ci 218b815c7f3Sopenharmony_cistatic 219b815c7f3Sopenharmony_ciint alaw_decode (unsigned int Alawbyte) 220b815c7f3Sopenharmony_ci{ static int exp_lut [8] = { 0, 264, 528, 1056, 2112, 4224, 8448, 16896 } ; 221b815c7f3Sopenharmony_ci int sign, exponent, mantissa, sample ; 222b815c7f3Sopenharmony_ci 223b815c7f3Sopenharmony_ci Alawbyte ^= 0x55 ; 224b815c7f3Sopenharmony_ci sign = (Alawbyte & 0x80) ; 225b815c7f3Sopenharmony_ci Alawbyte &= 0x7f ; /* get magnitude */ 226b815c7f3Sopenharmony_ci if (Alawbyte >= 16) 227b815c7f3Sopenharmony_ci { exponent = (Alawbyte >> 4) & 0x07 ; 228b815c7f3Sopenharmony_ci mantissa = Alawbyte & 0x0F ; 229b815c7f3Sopenharmony_ci sample = exp_lut [exponent] + (mantissa << (exponent + 3)) ; 230b815c7f3Sopenharmony_ci } 231b815c7f3Sopenharmony_ci else 232b815c7f3Sopenharmony_ci sample = (Alawbyte << 4) + 8 ; 233b815c7f3Sopenharmony_ci if (sign == 0) 234b815c7f3Sopenharmony_ci sample = -sample ; 235b815c7f3Sopenharmony_ci 236b815c7f3Sopenharmony_ci return sample ; 237b815c7f3Sopenharmony_ci} /* alaw_decode */ 238b815c7f3Sopenharmony_ci 239