1 #ifndef _WDL_ADPCM_ENCODE_H_
2 #define _WDL_ADPCM_ENCODE_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
];
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;
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
)
66 if (!*predState
) *predState
=(short *)calloc(nch
,sizeof(short));
68 short *pstate
= *predState
;
72 PCMFMTCVT_DBL_TYPE
*spl
= samples
+x
;
73 unsigned char *wrptr
= bufout
+ x
*4;
75 int step_index
=pstate
[x
];
78 double_TO_INT16(last_out
,*spl
);
81 *wrptr
++ = last_out
&0xff; *wrptr
++ = last_out
>>8;
84 *wrptr
++ = step_index
&0xff; *wrptr
++ = step_index
>>8;
90 const int outblocklen
= bps
== 2 ? 16 : 8;
91 unsigned char buildchar
=0;
96 double_TO_INT16(this_spl
,*spl
);
97 char nib
= calcBestNibble(&step_index
,last_out
,this_spl
,&last_out
,bps
);
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;
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;
126 pstate
[x
] = step_index
;
129 *bufout_used
= (((numsamples
-1)*bps
)/8 + 4)*nch
;
137 #endif//_WDL_ADPCM_ENCODE_H_