/ ima_adpcm.c
ima_adpcm.c
  1  /*
  2  
  3  This software is part of libcsdr, a set of simple DSP routines for 
  4  Software Defined Radio.
  5  
  6  Copyright (c) 2015, Andras Retzler <randras@sdr.hu>
  7  All rights reserved.
  8  
  9  Redistribution and use in source and binary forms, with or without
 10  modification, are permitted provided that the following conditions are met:
 11      * Redistributions of source code must retain the above copyright
 12        notice, this list of conditions and the following disclaimer.
 13      * Redistributions in binary form must reproduce the above copyright
 14        notice, this list of conditions and the following disclaimer in the
 15        documentation and/or other materials provided with the distribution.
 16      * Neither the name of the copyright holder nor the
 17        names of its contributors may be used to endorse or promote products
 18        derived from this software without specific prior written permission.
 19  
 20  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 21  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 22  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 23  DISCLAIMED. IN NO EVENT SHALL ANDRAS RETZLER BE LIABLE FOR ANY
 24  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 25  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 26  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 27  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 29  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 30  
 31     Copyright 1997 Tim Kientzle.  All rights reserved.
 32  
 33  Redistribution and use in source and binary forms, with or without
 34  modification, are permitted provided that the following conditions are
 35  met:
 36  
 37  1. Redistributions of source code must retain the above copyright
 38     notice, this list of conditions and the following disclaimer.
 39  2. Redistributions in binary form must reproduce the above copyright
 40     notice, this list of conditions and the following disclaimer in the
 41     documentation and/or other materials provided with the distribution.
 42  3. All advertising materials mentioning features or use of this software
 43     must display the following acknowledgement:
 44        This product includes software developed by Tim Kientzle
 45        and published in ``The Programmer's Guide to Sound.''
 46  4. Neither the names of Tim Kientzle nor Addison-Wesley
 47     may be used to endorse or promote products derived from this software
 48     without specific prior written permission.
 49  
 50  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 51  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 52  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 53  IN NO EVENT SHALL TIM KIENTZLE OR ADDISON-WESLEY BE LIABLE FOR
 54  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 55  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 56  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 57  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 58  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 59  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 60  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 61  */
 62  
 63  /***********************************************************
 64  Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
 65  Netherlands.
 66  
 67                          All Rights Reserved
 68  
 69  Permission to use, copy, modify, and distribute this software and its 
 70  documentation for any purpose and without fee is hereby granted, 
 71  provided that the above copyright notice appear in all copies and that
 72  both that copyright notice and this permission notice appear in 
 73  supporting documentation, and that the names of Stichting Mathematisch
 74  Centrum or CWI not be used in advertising or publicity pertaining to
 75  distribution of the software without specific, written prior permission.
 76  
 77  STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
 78  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 79  FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
 80  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 81  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 82  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 83  OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 84  
 85  ******************************************************************/
 86  
 87  #ifdef USE_IMA_ADPCM
 88  
 89  #include "ima_adpcm.h"
 90   
 91  const int indexAdjustTable[16] = {
 92     -1, -1, -1, -1,  // +0 - +3, decrease the step size
 93      2, 4, 6, 8,     // +4 - +7, increase the step size
 94     -1, -1, -1, -1,  // -0 - -3, decrease the step size
 95      2, 4, 6, 8,     // -4 - -7, increase the step size
 96  };
 97  
 98  const int _stepSizeTable[89] = {
 99     7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34,
100     37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
101     157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494,
102     544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
103     1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
104     4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
105     11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,
106     27086, 29794, 32767
107  };
108  
109  static inline short ImaAdpcmDecode(unsigned char deltaCode, ima_adpcm_state_t* state) {
110     // Get the current step size
111     int step = _stepSizeTable[state->index];
112  
113     // Construct the difference by scaling the current step size
114     // This is approximately: difference = (deltaCode+.5)*step/4
115     int difference = step>>3;
116     if ( deltaCode & 1 ) difference += step>>2;
117     if ( deltaCode & 2 ) difference += step>>1;
118     if ( deltaCode & 4 ) difference += step;
119     if ( deltaCode & 8 ) difference = -difference;
120  
121     // Build the new sample
122     state->previousValue += difference;
123     if (state->previousValue > 32767) state->previousValue = 32767;
124     else if (state->previousValue < -32768) state->previousValue = -32768;
125  
126     // Update the step for the next sample
127     state->index += indexAdjustTable[deltaCode];
128     if (state->index < 0) state->index = 0;
129     else if (state->index > 88) state->index = 88;
130  
131     return state->previousValue;
132  }
133  
134  static inline unsigned char ImaAdpcmEncode(short sample, ima_adpcm_state_t* state) {
135     int diff = sample - state->previousValue;
136     int step = _stepSizeTable[state->index];
137     int deltaCode = 0;
138  
139     // Set sign bit
140     if (diff < 0) { deltaCode = 8; diff = -diff; }
141  
142     // This is essentially deltaCode = (diff<<2)/step,
143     // except the roundoff is handled differently.
144     if ( diff >= step ) {  deltaCode |= 4;  diff -= step;  }
145     step >>= 1;
146     if ( diff >= step ) {  deltaCode |= 2;  diff -= step;  }
147     step >>= 1;
148     if ( diff >= step ) {  deltaCode |= 1;  diff -= step;  }
149  
150     ImaAdpcmDecode(deltaCode,state);  // update state
151     return deltaCode;
152  }
153  
154  ima_adpcm_state_t encode_ima_adpcm_i16_u8(short* input, unsigned char* output, int input_length, ima_adpcm_state_t state)
155  {
156  	int k=0;
157  	for(int i=0;i<input_length/2;i++) 
158  	{
159  		output[k]=ImaAdpcmEncode(input[2*i],&state);
160  		output[k++]|=ImaAdpcmEncode(input[2*i+1],&state)<<4;
161  	}
162  	return state;
163  }
164  
165  ima_adpcm_state_t decode_ima_adpcm_u8_i16(unsigned char* input, short* output, int input_length, ima_adpcm_state_t state)
166  {
167  	int k=0;
168  	for(int i=0;i<input_length;i++) 
169  	{
170  		output[k++]=ImaAdpcmDecode(input[i]&0xf,&state);
171  		output[k++]=ImaAdpcmDecode( (input[i]>>4)&0xf,&state);
172  	}
173  	return state;
174  }
175  
176  #endif