PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
audio_adpcm.c
Go to the documentation of this file.
1 /** \file
2  Original code based on Microchip application note AN643, it used
3 16-bit signed ADC samples and the standard IMA ADPCM compression.
4 This version has been modified to use Dialogic ADPCM, which
5 uses 12-bit samples and a smaller table.
6 Specification is at:
7 http://multimedia.cx/mirror/dialogic-adpcm.pdf
8 
9 */
10 
11 #include "pic24_all.h"
12 
13 struct ADPCMstate {
14  int16_t i16_prevsample;/* Predicted sample */
15  int16_t i16_previndex;/* Index into step size table */
16 };
17 
18 static struct ADPCMstate state;
19 
20 /* Table of index changes */
21 static const int8_t ai8_IndexTable[16] = {
22  -1, -1, -1, -1, 2, 4, 6, 8,
23  -1, -1, -1, -1, 2, 4, 6, 8
24 };
25 
26 
27 #define MAX_POS 2047
28 #define MAX_NEG -2048
29 #define MAX_INDEX 48
30 
31 static const uint16_t au16_StepSizeTable[49] = {
32  16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
33  50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
34  157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
35  494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
36 };
37 
38 void ADPCMEncoderInit(void) {
39  state.i16_prevsample=0;
40  state.i16_previndex=0;
41 }
42 
43 static int16_t i16_diff; /* Difference between sample and predicted sample */
44 static int16_t i16_step; /* Quantizer step size */
45 static int16_t i16_predsample; /* Output of ADPCM predictor */
46 static int16_t i16_diffq; /* Dequantized predicted difference */
47 static int16_t i16_index; /* Index into step size table */
48 /*****************************************************************************
49 * ADPCMEncoder - ADPCM encoder routine *
50 ******************************************************************************
51 * Input Variables: *
52 * int16_t sample - 16-bit signed speech sample *
53 * Return Variable: *
54 * char - 8-bit number containing the 4-bit ADPCM code *
55 *****************************************************************************/
56 uint8_t ADPCMEncoder( int16_t i16_sample) {
57  uint8_t code; /* ADPCM output value */
58  int16_t tempstep; /* Temporary step size */
59  /* Restore previous values of predicted sample and quantizer step
60  size index
61  */
62  i16_predsample = state.i16_prevsample;
63  i16_index = state.i16_previndex;
64  i16_step = au16_StepSizeTable[i16_index];
65  /* Compute the difference between the actual sample (sample) and the
66  the predicted sample (predsample)
67  */
68  i16_diff = i16_sample - i16_predsample;
69  if (i16_diff >= 0)
70  code = 0;
71  else {
72  code = 8;
73  i16_diff = -i16_diff;
74  }
75  /* Quantize the difference into the 4-bit ADPCM code using the
76  the quantizer step size
77  */
78  tempstep = i16_step;
79  if ( i16_diff >= tempstep ) {
80  code |= 4;
81  i16_diff -= tempstep;
82  }
83  tempstep >>= 1;
84  if ( i16_diff >= tempstep ) {
85  code |= 2;
86  i16_diff -= tempstep;
87  }
88  tempstep >>= 1;
89  if ( i16_diff >= tempstep )
90  code |= 1;
91  /* Inverse quantize the ADPCM code into a predicted difference
92  using the quantizer step size
93  */
94  i16_diffq = i16_step >> 3;
95  if ( code & 4 )
96  i16_diffq += i16_step;
97  if ( code & 2 )
98  i16_diffq += i16_step >> 1;
99  if ( code & 1 )
100  i16_diffq += i16_step >> 2;
101  /* Fixed predictor computes new predicted sample by adding the
102  old predicted sample to predicted difference
103  */
104  if ( code & 8 )
105  i16_predsample -= i16_diffq;
106  else
107  i16_predsample += i16_diffq;
108  /* Check for overflow of the new predicted sample
109  */
110  if ( i16_predsample > MAX_POS )
111  i16_predsample = MAX_POS;
112  else if ( i16_predsample < MAX_NEG )
113  i16_predsample = MAX_NEG;
114  /* Find new quantizer stepsize index by adding the old index
115  to a table lookup using the ADPCM code
116  */
117  i16_index += ai8_IndexTable[code];
118  /* Check for overflow of the new quantizer step size index
119  */
120  if ( i16_index < 0 )
121  i16_index = 0;
122  if ( i16_index > MAX_INDEX )
123  i16_index = MAX_INDEX;
124  /* Save the predicted sample and quantizer step size index for
125  next iteration
126  */
127  state.i16_prevsample = i16_predsample;
128  state.i16_previndex = i16_index;
129  /* Return the new ADPCM code */
130  return ( code & 0x0f );
131 }
132 
133 void ADPCMDecoderInit(void) {
134  state.i16_prevsample= 0;
135  state.i16_previndex=0;
136 }
137 
138 /*****************************************************************************
139 * ADPCMDecoder - ADPCM decoder routine *
140 ******************************************************************************
141 * Input Variables: *
142 * char code - 8-bit number containing the 4-bit ADPCM code *
143 * Return Variable: *
144 * int16_t - 16-bit signed speech sample *
145 *****************************************************************************/
146 int16_t ADPCMDecoder(uint8_t u8_code) {
147  /* Restore previous values of predicted sample and quantizer step
148  size index
149  */
150  i16_predsample = state.i16_prevsample;
151  i16_index = state.i16_previndex;
152  /* Find quantizer step size from lookup table using index
153  */
154  i16_step = au16_StepSizeTable[i16_index];
155  /* Inverse quantize the ADPCM code into a difference using the
156  quantizer step size
157  */
158  i16_diffq = i16_step >> 3;
159  if ( u8_code & 4 )
160  i16_diffq += i16_step;
161  if ( u8_code & 2 )
162  i16_diffq += i16_step >> 1;
163  if ( u8_code & 1 )
164  i16_diffq += i16_step >> 2;
165  /* Add the difference to the predicted sample
166  */
167  if ( u8_code & 8 )
168  i16_predsample -= i16_diffq;
169  else
170  i16_predsample += i16_diffq;
171  /* Check for overflow of the new predicted sample
172  */
173  if ( i16_predsample > MAX_POS )
174  i16_predsample = MAX_POS;
175  else if ( i16_predsample < MAX_NEG )
176  i16_predsample = MAX_NEG;
177  /* Find new quantizer step size by adding the old index and a
178  table lookup using the ADPCM code
179  */
180  i16_index += ai8_IndexTable[u8_code];
181  /* Check for overflow of the new quantizer step size index
182  */
183  if ( i16_index < 0 )
184  i16_index = 0;
185  if ( i16_index > MAX_INDEX )
186  i16_index = MAX_INDEX;
187  /* Save predicted sample and quantizer step size index for next
188  iteration
189  */
190  state.i16_prevsample = i16_predsample;
191  state.i16_previndex = i16_index;
192  /* Return the new speech sample */
193  return( i16_predsample );
194 }