fix compile errors
[wdl/wdl-ol.git] / WDL / adpcm_encode.h
blob77ff749d0dd94f671ea2936df8163c43527b9075
1 #ifndef _WDL_ADPCM_ENCODE_H_
2 #define _WDL_ADPCM_ENCODE_H_
5 #include "pcmfmtcvt.h"
7 void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps,
8 unsigned char *bufout, int *bufout_used, short **predState);
10 #define WDL_adpcm_encode_IMA_samplesneededbytes(bytes,bps) ((((bytes)-4)*8)/(bps)+1)
13 // untested. also probably slow.
14 #ifdef WDL_ADPCM_ENCODE_IMPL
17 static signed char ima_adpcm_index_table[8] = { -1, -1, -1, -1, 2, 4, 6, 8, };
18 static short ima_adpcm_step_table[89] = {
19 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
20 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
21 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
22 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
23 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
24 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
25 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
26 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
27 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
30 static char calcBestNibble(int *initial_step_index, int lastSpl, int thisSpl, short *lastsplout, int bps)
33 int step=ima_adpcm_step_table[*initial_step_index];
35 char sign=0;
36 int adiff = thisSpl - lastSpl;
37 if (adiff<0) { adiff=-adiff; sign=8; }
39 // adiff == (nib*step)/4 + step/8
40 // adiff - step/8 = nib*step/4
41 // nib = 4*(adiff-step/8)/step = 4*adiff/step - 0.5
42 int nib = step ? ((4 * adiff - step/2) / step) : 0;
43 if (nib<0) nib=0;
44 else if(nib>7) nib=7;
46 if (bps==2) nib&=4;
48 int diff = (nib*step)/4 + step/8;
49 *lastsplout = lastSpl + (sign?-diff:diff);
52 *initial_step_index += ima_adpcm_index_table[nib];
54 if (*initial_step_index<0)*initial_step_index=0;
55 else if (*initial_step_index>88)*initial_step_index=88;
57 return (char)nib|sign;
62 void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps,
63 unsigned char *bufout, int *bufout_used, short **predState)
65 int x;
66 if (!*predState) *predState=(short *)calloc(nch,sizeof(short));
68 short *pstate = *predState;
69 for(x=0;x<nch;x++)
71 int left=numsamples;
72 PCMFMTCVT_DBL_TYPE *spl = samples+x;
73 unsigned char *wrptr = bufout + x*4;
75 int step_index=pstate[x];
77 short last_out;
78 double_TO_INT16(last_out,*spl);
79 left--;
81 *wrptr++ = last_out&0xff; *wrptr++ = last_out>>8;
82 spl+=nch;
84 *wrptr++ = step_index&0xff; *wrptr++ = step_index>>8;
86 wrptr += (nch-1)*4;
89 int outpos=0;
90 const int outblocklen = bps == 2 ? 16 : 8;
91 unsigned char buildchar=0;
93 while (left-->0)
95 short this_spl;
96 double_TO_INT16(this_spl,*spl);
97 char nib = calcBestNibble(&step_index,last_out,this_spl,&last_out,bps);
99 spl+=nch;
101 // update output
102 if (bps == 2)
104 nib>>=2;
105 switch (outpos&3)
107 case 0: buildchar = nib; break;
108 case 1: buildchar |= nib<<2; break;
109 case 2: buildchar |= nib<<4; break;
110 case 3: *wrptr++ = buildchar | (nib<<6); break;
113 else
115 if (!(outpos&1)) buildchar = nib;
116 else *wrptr++ = buildchar | (nib<<4);
119 // skip other channels
120 if (++outpos == outblocklen)
122 wrptr += ((nch-1)*outblocklen*bps)/8;
123 outpos=0;
126 pstate[x] = step_index;
129 *bufout_used = (((numsamples-1)*bps)/8 + 4)*nch;
134 #endif
137 #endif//_WDL_ADPCM_ENCODE_H_