00001
00011 #include "pic24_all.h"
00012
00013 struct ADPCMstate {
00014 int16 i16_prevsample;
00015 int16 i16_previndex;
00016 };
00017
00018 static struct ADPCMstate state;
00019
00020
00021 static const int8 ai8_IndexTable[16] = {
00022 -1, -1, -1, -1, 2, 4, 6, 8,
00023 -1, -1, -1, -1, 2, 4, 6, 8
00024 };
00025
00026
00027 #define MAX_POS 2047
00028 #define MAX_NEG -2048
00029 #define MAX_INDEX 48
00030
00031 static const uint16 au16_StepSizeTable[49] = {
00032 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
00033 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
00034 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
00035 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
00036 };
00037
00038 void ADPCMEncoderInit(void) {
00039 state.i16_prevsample=0;
00040 state.i16_previndex=0;
00041 }
00042
00043 static int16 i16_diff;
00044 static int16 i16_step;
00045 static int16 i16_predsample;
00046 static int16 i16_diffq;
00047 static int16 i16_index;
00048
00049
00050
00051
00052
00053
00054
00055
00056 uint8 ADPCMEncoder( int16 i16_sample) {
00057 uint8 code;
00058 int16 tempstep;
00059
00060
00061
00062 i16_predsample = state.i16_prevsample;
00063 i16_index = state.i16_previndex;
00064 i16_step = au16_StepSizeTable[i16_index];
00065
00066
00067
00068 i16_diff = i16_sample - i16_predsample;
00069 if (i16_diff >= 0)
00070 code = 0;
00071 else {
00072 code = 8;
00073 i16_diff = -i16_diff;
00074 }
00075
00076
00077
00078 tempstep = i16_step;
00079 if ( i16_diff >= tempstep ) {
00080 code |= 4;
00081 i16_diff -= tempstep;
00082 }
00083 tempstep >>= 1;
00084 if ( i16_diff >= tempstep ) {
00085 code |= 2;
00086 i16_diff -= tempstep;
00087 }
00088 tempstep >>= 1;
00089 if ( i16_diff >= tempstep )
00090 code |= 1;
00091
00092
00093
00094 i16_diffq = i16_step >> 3;
00095 if ( code & 4 )
00096 i16_diffq += i16_step;
00097 if ( code & 2 )
00098 i16_diffq += i16_step >> 1;
00099 if ( code & 1 )
00100 i16_diffq += i16_step >> 2;
00101
00102
00103
00104 if ( code & 8 )
00105 i16_predsample -= i16_diffq;
00106 else
00107 i16_predsample += i16_diffq;
00108
00109
00110 if ( i16_predsample > MAX_POS )
00111 i16_predsample = MAX_POS;
00112 else if ( i16_predsample < MAX_NEG )
00113 i16_predsample = MAX_NEG;
00114
00115
00116
00117 i16_index += ai8_IndexTable[code];
00118
00119
00120 if ( i16_index < 0 )
00121 i16_index = 0;
00122 if ( i16_index > MAX_INDEX )
00123 i16_index = MAX_INDEX;
00124
00125
00126
00127 state.i16_prevsample = i16_predsample;
00128 state.i16_previndex = i16_index;
00129
00130 return ( code & 0x0f );
00131 }
00132
00133 void ADPCMDecoderInit(void) {
00134 state.i16_prevsample= 0;
00135 state.i16_previndex=0;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 int16 ADPCMDecoder(uint8 u8_code) {
00147
00148
00149
00150 i16_predsample = state.i16_prevsample;
00151 i16_index = state.i16_previndex;
00152
00153
00154 i16_step = au16_StepSizeTable[i16_index];
00155
00156
00157
00158 i16_diffq = i16_step >> 3;
00159 if ( u8_code & 4 )
00160 i16_diffq += i16_step;
00161 if ( u8_code & 2 )
00162 i16_diffq += i16_step >> 1;
00163 if ( u8_code & 1 )
00164 i16_diffq += i16_step >> 2;
00165
00166
00167 if ( u8_code & 8 )
00168 i16_predsample -= i16_diffq;
00169 else
00170 i16_predsample += i16_diffq;
00171
00172
00173 if ( i16_predsample > MAX_POS )
00174 i16_predsample = MAX_POS;
00175 else if ( i16_predsample < MAX_NEG )
00176 i16_predsample = MAX_NEG;
00177
00178
00179
00180 i16_index += ai8_IndexTable[u8_code];
00181
00182
00183 if ( i16_index < 0 )
00184 i16_index = 0;
00185 if ( i16_index > MAX_INDEX )
00186 i16_index = MAX_INDEX;
00187
00188
00189
00190 state.i16_prevsample = i16_predsample;
00191 state.i16_previndex = i16_index;
00192
00193 return( i16_predsample );
00194 }