1 ////////////////////////////////////////////////////////////////////////
3 // (c) 1996 Looking Glass Technologies Inc.
6 // Module name: IMA ADPCM definitions
7 // File name: imaadpcm.h
9 // Description: IMA ADPCM (aka DVI) compress/decompress definitions
11 ////////////////////////////////////////////////////////////////////////
13 /**************************************************************************
15 Program to read in and code digitized stereo audio
16 using Intel/DVI's implementation of the classic ADPCM algorithm
17 described in the following references:
19 N. S. Jayant, "Adaptive Quantization With a One Word Memory,"
20 Bell System Tech. J., pp. 119-1144, Sep. 1973
22 L. R. Rabiner / R. W. Schafer, Digital Processing of Speech
23 Signals, Prentice Hall, 1978
25 Mark Stout, Compaq Computer, 1/92
27 4-feb-92 patmc Broken into routines
28 11-jul-96 patmc converted to C++
30 ****************************************************************************/
34 static int indextab
[16] = {-1,-1,-1,-1, 2, 4, 6, 8,
35 -1,-1,-1,-1, 2, 4, 6, 8};
37 static int steptab
[89]={
38 7, 8, 9, 10, 11, 12, 13, 14, /* DVI exten. */
39 16, 17, 19, 21, 23, 25, 28, /* OKI lookup table */
40 31, 34, 37, 41, 45, 50, 55,
41 60, 66, 73, 80, 88, 97, 107,
42 118, 130, 143, 157, 173, 190, 209,
43 230, 253, 279, 307, 337, 371, 408,
44 449, 494, 544, 598, 658, 724, 796,
45 876, 963,1060,1166,1282,1411,1552,
47 1707,1878, /* DVI exten. */
49 2066,2272,2499,2749,3024,3327,3660,4026,
50 4428,4871,5358,5894,6484,7132,7845,8630,
51 9493,10442,11487,12635,13899,15289,16818,
52 18500,20350,22385,24623,27086,29794,32767
56 IMAADPCM::IMAADPCM( void )
65 IMAADPCM::~IMAADPCM( void )
71 * initialize compressor state
79 mPredictedSample
= predSample
;
87 * get compressor state packed into a longword
90 IMAADPCM::GetState( void )
92 unsigned short hiWord
;
95 val
= mPredictedSample
& 0xFFFF;
96 hiWord
= (unsigned short) ((mIndex
& 0xFF) | ((mSpareNybble
& 0xF0) << 4)
97 | ((mNybbleToggle
& 1) << 12));
98 return val
| (hiWord
<< 16);
103 * set compressor state from packed longword
106 IMAADPCM::SetState( unsigned long state
)
108 short val
= (short) (state
& 0xFFFF);
110 mPredictedSample
= val
;
112 mIndex
= state
& 0xFF;
113 mSpareNybble
= (state
>> 4) & 0xF0;
114 mNybbleToggle
= (state
>> 12) & 1;
119 * compress a short block of size numSamples
120 * returns # of bytes written to outBlock
129 int inSampleIndex
, outSampleIndex
;
132 int code
; /* 4-bit quantized difference */
133 long diff
; /* difference between 2 consecutive samples */
134 long pdiff
; /* difference between 2 consecutive samples */
135 int step
; /* step sizes at encoding and decoding portion */
140 for (inSampleIndex
= 0; inSampleIndex
< numSamples
; inSampleIndex
++) {
142 step
= steptab
[mIndex
];
143 /* difference between actual sample & predicted value */
144 diff
= (long)inBlock
[ inSampleIndex
] - mPredictedSample
;
147 code
=0; /* set sign bit */
156 if( diff
>= tempstep
){
162 if( diff
>= tempstep
){
165 pdiff
+= (step
>> 1);
168 if( diff
>= tempstep
){
171 pdiff
+= (step
>> 2);
173 pdiff
+= (step
>> 3);
178 /* lower 4-bit of code can be sent out or stored at this point */
180 if ( mNybbleToggle
) {
181 outBlock
[ outSampleIndex
] = (char) (mSpareNybble
+ (code
& 0xF));
184 /* hiNybble is even sample */
185 mSpareNybble
= code
<< 4;
189 /* compute new sample estimate mPredictedSample */
190 mPredictedSample
+= pdiff
;
192 if (mPredictedSample
> 32767) /* check for overflow */
193 mPredictedSample
= 32767;
194 else if (mPredictedSample
< -32768)
195 mPredictedSample
= -32768;
197 /* compute new stepsize step */
198 mIndex
+= indextab
[code
];
199 if(mIndex
< 0)mIndex
= 0;
200 else if(mIndex
> 88)mIndex
= 88;
203 return outSampleIndex
;
207 * end compression - flush last nybble, if any to buffer
208 * return # of bytes written to buffer (0 or 1)
211 IMAADPCM::EndCompress(
215 if ( mNybbleToggle
) {
216 *outBlock
= (char) mSpareNybble
;
225 * decompress a short block of size numSamples
226 * returns # of bytes consumed from inBlock
229 IMAADPCM::Decompress(
235 int inByteIndex
, outSampleIndex
;
236 int code
; /* 4-bit quantized difference */
237 long diff
; /* difference between 2 consecutive samples */
238 int step
; /* step sizes at encoding and decoding portion */
243 for (outSampleIndex
= 0; outSampleIndex
< numSamples
; outSampleIndex
++) {
245 // NOTE: The nybble order for PCs is opposite from Unix
246 // Unix has high nybble first, PCs have low nybble first
247 /* fetch a nybble code to decompress */
248 if ( mNybbleToggle
) {
249 // code = mSpareNybble & 0xF;
250 code
= (mSpareNybble
& 0xF0) >> 4;
253 mSpareNybble
= inBlock
[ inByteIndex
];
254 code
= mSpareNybble
& 0xF;
255 // code = (mSpareNybble & 0xF0) >> 4;
259 /* compute new sample estimate mPredictedSample */
261 step
= steptab
[mIndex
];
262 if (code
& 4) diff
+= step
;
263 if (code
& 2) diff
+= (step
>> 1);
264 if (code
& 1) diff
+= (step
>> 2);
266 if (code
& 8) diff
= -diff
;
267 mPredictedSample
+= diff
;
269 if (mPredictedSample
> 32767) /* check for overflow */
270 mPredictedSample
= 32767;
271 else if (mPredictedSample
< -32768)
272 mPredictedSample
= -32768;
274 /* compute new stepsize step */
275 mIndex
+= indextab
[code
];
276 if (mIndex
< 0) mIndex
= 0;
277 else if (mIndex
> 88) mIndex
= 88;
279 /* output predicted sample */
280 outBlock
[outSampleIndex
] = (short) mPredictedSample
;
283 // return # of bytes consumed (not including partially consumed)
289 // decompress a block of IMA ADPCM data (RIFF WAVE block format)
299 IMAADPCM leftDecomp
, rightDecomp
;
300 IMAHeaderWord
*pIMAHdr
;
302 // Each block starts with a IMAHeaderWord, which contains
303 // the predicted first sample of the block and the stepsize
305 if ( nSamples
> 1 ) {
306 switch( nChannels
) {
308 // decompress a block
309 pIMAHdr
= (IMAHeaderWord
*) pInBuff
;
310 pOutBuff
[0] = pIMAHdr
->curValue
;
311 leftDecomp
.Init( pIMAHdr
->curValue
, pIMAHdr
->stepIndex
);
312 leftDecomp
.Decompress( pInBuff
+ sizeof(IMAHeaderWord
),
313 pOutBuff
+ 1, nSamples
- 1 );
316 // stereo - channels are interleaved every 8 samples
318 leftDecomp
.Init( pIMAHdr
->curValue
, pIMAHdr
->stepIndex
);
319 rightDecomp
.Init( pIMAHdr
->curValue
, pIMAHdr
->stepIndex
);
330 // decompress a block of IMA ADPCM data (RIFF WAVE block format)
331 // returns ptr to next byte in input buffer
334 DecompressIMABlockPartial( char *pInBuff
,
338 unsigned long *pState
)
341 IMAHeaderWord
*pIMAHdr
;
344 // decompress a block
346 // This is first fetch in this block, so we must set
347 // the decompressor state from the header word at the
348 // start of the block
349 pIMAHdr
= (IMAHeaderWord
*) pInBuff
;
350 pOutBuff
[0] = pIMAHdr
->curValue
;
351 if ( nSamples
> 1 ) {
352 decomp
.Init( pIMAHdr
->curValue
, pIMAHdr
->stepIndex
);
353 bytesEaten
= decomp
.Decompress( pInBuff
+ sizeof(IMAHeaderWord
),
354 pOutBuff
+ 1, nSamples
- 1 );
356 // save the decompressor state for future calls
357 *pState
= decomp
.GetState();
358 pInBuff
+= ( sizeof(IMAHeaderWord
) + bytesEaten
);
360 // this is not the first fetch in the block, so we must
361 // set the state from our saved packed state
362 decomp
.SetState( *pState
);
363 bytesEaten
= decomp
.Decompress( pInBuff
, pOutBuff
, nSamples
);
364 // save the decompressor state for future calls
365 *pState
= decomp
.GetState();
366 pInBuff
+= bytesEaten
;