Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/audioconvert/ac_adpcm.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 16.4 KB
Line 
1/***********************************************************
2 -*- mode: C; tab-width:8; c-basic-offset:8 -*-
3 * vi:set ts=8:
4
5Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
6Netherlands.
7
8                        All Rights Reserved
9
10Permission to use, copy, modify, and distribute this software and its
11documentation for any purpose and without fee is hereby granted,
12provided that the above copyright notice appear in all copies and that
13both that copyright notice and this permission notice appear in
14supporting documentation, and that the names of Stichting Mathematisch
15Centrum or CWI not be used in advertising or publicity pertaining to
16distribution of the software without specific, written prior permission.
17
18STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
19THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
20FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
21FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
24OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26******************************************************************/
27
28/*
29** Intel/DVI ADPCM coder/decoder.
30**
31** The algorithm for this coder was taken from the IMA Compatability Project
32** proceedings, Vol 2, Number 2; May 1992.
33**
34** Version 1.2, 18-Dec-92.
35**
36** Change log:
37** - Fixed a stupid bug, where the delta was computed as
38**   stepsize*code/4 in stead of stepsize*(code+0.5)/4.
39** - There was an off-by-one error causing it to pick
40**   an incorrect delta once in a blue moon.
41** - The NODIVMUL define has been removed. Computations are now always done
42**   using shifts, adds and subtracts. It turned out that, because the standard
43**   is defined using shift/add/subtract, you needed bits of fixup code
44**   (because the div/mul simulation using shift/add/sub made some rounding
45**   errors that real div/mul don't make) and all together the resultant code
46**   ran slower than just using the shifts all the time.
47** - Changed some of the variable names to be more meaningful.
48*/
49
50#include "al_siteconfig.h"
51
52#include <AL/al.h>
53#include <stdio.h>
54#include <stdlib.h>
55
56#include "audioconvert/ac_adpcm.h"
57#include "audioconvert/ac_endian.h"
58#include "audioconvert/ac_wave.h"
59
60#define MS_ADPCM_max ((1<<(16-1))-1)
61#define MS_ADPCM_min -(1<<(16-1))
62
63#define NELEMS(x) ((sizeof x) / (sizeof *x))
64
65/* IMA in-wave-file */
66static ALint IMA_ADPCM_nibble(alIMAADPCM_decodestate_LOKI *state, ALubyte nybble);
67static void Fill_IMA_ADPCM_block(ALubyte *decoded, ALubyte *encoded,
68        int channel, int numchannels, alIMAADPCM_decodestate_LOKI *state);
69
70/* Intel ADPCM step variation table */
71static int indexTable[16] = {
72    -1, -1, -1, -1, 2, 4, 6, 8,
73    -1, -1, -1, -1, 2, 4, 6, 8,
74};
75
76static int stepsizeTable[89] = {
77    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
78    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
79    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
80    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
81    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
82    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
83    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
84    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
85    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
86};
87
88void
89ac_adpcm_coder(short indata[], char outdata[], int len,adpcm_state_t *state) {
90
91    short *inp;                 /* Input buffer pointer */
92    signed char *outp;          /* output buffer pointer */
93    int val;                    /* Current input sample value */
94    int sign;                   /* Current adpcm sign bit */
95    int delta;                  /* Current adpcm output value */
96    int diff;                   /* Difference between val and valprev */
97    int step;                   /* Stepsize */
98    int valpred;                /* Predicted output value */
99    int vpdiff;                 /* Current change to valpred */
100    int ind;                    /* Current step change index */
101    int outputbuffer = 0;       /* place to keep previous 4-bit value */
102    int bufferstep;             /* toggle between outputbuffer/output */
103
104    outp = (signed char *)outdata;
105    inp = indata;
106
107    valpred = state->valprev;
108    ind = state->index;
109    step = stepsizeTable[ind];
110
111    bufferstep = 1;
112
113    for ( ; len > 0 ; len-- ) {
114        val = *inp++;
115
116        /* Step 1 - compute difference with previous value */
117        diff = val - valpred;
118        sign = (diff < 0) ? 8 : 0;
119        if ( sign ) diff = (-diff);
120
121        /* Step 2 - Divide and clamp */
122        /* Note:
123        ** This code *approximately* computes:
124        **    delta = diff*4/step;
125        **    vpdiff = (delta+0.5)*step/4;
126        ** but in shift step bits are dropped. The net result of this is
127        ** that even if you have fast mul/div hardware you cannot put it to
128        ** good use since the fixup would be too expensive.
129        */
130        delta = 0;
131        vpdiff = (step >> 3);
132
133        if ( diff >= step ) {
134            delta = 4;
135            diff -= step;
136            vpdiff += step;
137        }
138        step >>= 1;
139        if ( diff >= step  ) {
140            delta |= 2;
141            diff -= step;
142            vpdiff += step;
143        }
144        step >>= 1;
145        if ( diff >= step ) {
146            delta |= 1;
147            vpdiff += step;
148        }
149
150        /* Step 3 - Update previous value */
151        if ( sign )
152          valpred -= vpdiff;
153        else
154          valpred += vpdiff;
155
156        /* Step 4 - Clamp previous value to 16 bits */
157        if ( valpred > 32767 )
158          valpred = 32767;
159        else if ( valpred < -32768 )
160          valpred = -32768;
161
162        /* Step 5 - Assemble value, update index and step values */
163        delta |= sign;
164
165        ind += indexTable[delta];
166        if ( ind < 0 ) ind = 0;
167        if ( ind > 88 ) ind = 88;
168        step = stepsizeTable[ind];
169
170        /* Step 6 - Output value */
171        if ( bufferstep ) {
172            outputbuffer = (delta << 4) & 0xf0;
173        } else {
174            *outp++ = (delta & 0x0f) | outputbuffer;
175        }
176        bufferstep = !bufferstep;
177    }
178
179    /* Output last step, if needed */
180    if ( !bufferstep )
181      *outp++ = outputbuffer;
182
183    state->valprev = valpred;
184    state->index = ind;
185}
186
187void
188ac_adpcm_decoder(char indata[], short outdata[], int len, adpcm_state_t *state,
189int position)
190{
191    signed char *inp;           /* Input buffer pointer */
192    short *outp;                /* output buffer pointer */
193    int sign;                   /* Current adpcm sign bit */
194    int delta;                  /* Current adpcm output value */
195    int step;                   /* Stepsize */
196    int valpred;                /* Predicted value */
197    int vpdiff;                 /* Current change to valpred */
198    int ind;                    /* Current step change index */
199    int inputbuffer = 0;        /* place to keep next 4-bit value */
200    int bufferstep;             /* toggle between inputbuffer/input */
201
202    outp = outdata;
203    inp = (signed char *)indata;
204
205    valpred = state->valprev;
206    ind = state->index;
207    step = stepsizeTable[ind];
208
209    inp += position>>1;
210    bufferstep = position&1;
211    if(bufferstep) {
212            inputbuffer = *inp++;
213    }
214
215    for ( ; len > 0 ; len-- ) {
216
217        /* Step 1 - get the delta value */
218        if ( bufferstep ) {
219            delta = inputbuffer & 0xf;
220        } else {
221            inputbuffer = *inp++;
222            delta = (inputbuffer >> 4) & 0xf;
223        }
224        bufferstep = !bufferstep;
225
226        /* Step 2 - Find new index value (for later) */
227        ind += indexTable[delta];
228        if ( ind < 0 ) ind = 0;
229        if ( ind > 88 ) ind = 88;
230
231        /* Step 3 - Separate sign and magnitude */
232        sign = delta & 8;
233        delta = delta & 7;
234
235        /* Step 4 - Compute difference and new predicted value */
236        /*
237        ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
238        ** in adpcm_coder.
239        */
240        vpdiff = step >> 3;
241        if ( delta & 4 ) vpdiff += step;
242        if ( delta & 2 ) vpdiff += step>>1;
243        if ( delta & 1 ) vpdiff += step>>2;
244
245        if ( sign )
246          valpred -= vpdiff;
247        else
248          valpred += vpdiff;
249
250        /* Step 5 - clamp output value */
251        if ( valpred > 32767 )
252          valpred = 32767;
253        else if ( valpred < -32768 )
254          valpred = -32768;
255
256        /* Step 6 - Update step value */
257        step = stepsizeTable[ind];
258
259        /* Step 7 - Output value */
260        *outp++ = valpred;
261    }
262
263    state->valprev = valpred;
264    state->index = ind;
265}
266
267int msadpcm_decode(ALubyte *encoded, ALubyte *decoded, ALuint audio_len,
268                           alMSADPCM_state_LOKI *dstate, int offset) {
269        alMSADPCM_decodestate_LOKI *state[2];
270        ALint encoded_len, samplesleft;
271        ALbyte nybble, stereo;
272        ALshort *coeff[2];
273        ALint new_sample;
274
275        /* scale encoded */
276        encoded += (offset/4);
277
278        /* Allocate the proper sized output buffer */
279        encoded_len = audio_len /* 4:1 with 16bit samples */;
280
281        /* Get ready... Go! */
282        stereo = (dstate->wavefmt.channels == 2);
283        state[0] = &dstate->state[0];
284        state[1] = &dstate->state[(int) stereo];
285
286        if(encoded_len < dstate->wavefmt.blockalign ) {
287                fprintf(stderr, "too short\n");
288        }
289
290        while ( encoded_len >= dstate->wavefmt.blockalign ) {
291                /* Grab the initial information for this block */
292                state[0]->hPredictor = *encoded++;
293                if ( stereo ) {
294                        state[1]->hPredictor = *encoded++;
295                }
296                state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
297                encoded += sizeof(ALshort);
298                if ( stereo ) {
299                        state[1]->iDelta = ((encoded[1]<<8)|encoded[0]);
300                        encoded += sizeof(ALshort);
301                }
302                state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
303                encoded += sizeof(ALshort);
304                if ( stereo ) {
305                        state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
306                        encoded += sizeof(ALshort);
307                }
308                state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
309                encoded += sizeof(ALshort);
310                if ( stereo ) {
311                        state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
312                        encoded += sizeof(ALshort);
313                }
314                coeff[0] = dstate->aCoeff[(int) state[0]->hPredictor];
315                coeff[1] = dstate->aCoeff[(int) state[1]->hPredictor];
316
317                /* Store the two initial samples we start with */
318                decoded[0] = state[0]->iSamp2&0xFF;
319                decoded[1] = state[0]->iSamp2>>8;
320                decoded += 2;
321                if ( stereo ) {
322                        decoded[0] = state[1]->iSamp2&0xFF;
323                        decoded[1] = state[1]->iSamp2>>8;
324                        decoded += 2;
325                }
326                decoded[0] = state[0]->iSamp1&0xFF;
327                decoded[1] = state[0]->iSamp1>>8;
328                decoded += 2;
329                if ( stereo ) {
330                        decoded[0] = state[1]->iSamp1&0xFF;
331                        decoded[1] = state[1]->iSamp1>>8;
332                        decoded += 2;
333                }
334
335                /* Decode and store the other samples in this block */
336                samplesleft = (dstate->wSamplesPerBlock-2)*
337                                        dstate->wavefmt.channels;
338
339                while ( samplesleft > 0 ) {
340                        nybble = (*encoded)>>4;
341                        new_sample = MS_ADPCM_nibble(state[0], nybble, coeff[0]);
342                        decoded[0] = new_sample & 0xFF;
343                        new_sample >>= 8;
344                        decoded[1] = new_sample & 0xFF;
345                        decoded   += 2;
346
347                        nybble = (*encoded) & 0x0F;
348                        new_sample = MS_ADPCM_nibble(state[1],nybble,coeff[1]);
349                        decoded[0] = new_sample & 0xFF;
350                        new_sample >>= 8;
351                        decoded[1] = new_sample & 0xFF;
352                        decoded   += 2;
353
354                        ++encoded;
355                        samplesleft -= 2;
356                }
357                encoded_len -= dstate->wavefmt.blockalign;
358        }
359
360        /* free(freeable); */
361        return 0;
362}
363
364ALint MS_ADPCM_nibble(alMSADPCM_decodestate_LOKI *state,
365                                        ALubyte nybble, ALshort *coeff) {
366        const ALint adaptive[] = {
367                230, 230, 230, 230, 307, 409, 512, 614,
368                768, 614, 512, 409, 307, 230, 230, 230
369        };
370        ALint new_sample, delta;
371
372        new_sample = ((state->iSamp1 * coeff[0]) +
373                      (state->iSamp2 * coeff[1]))/256;
374
375        if(nybble & 0x08) {
376                new_sample += state->iDelta * (nybble-0x10);
377        } else {
378                new_sample += state->iDelta * nybble;
379        }
380
381        if(new_sample < MS_ADPCM_min) {
382                new_sample = MS_ADPCM_min;
383        } else if(new_sample > MS_ADPCM_max) {
384                new_sample = MS_ADPCM_max;
385        }
386
387        delta = ((ALint) state->iDelta * adaptive[nybble]);
388        if(delta < 4096) {
389                delta = 16;
390        } else {
391                delta /= 256;
392        }
393
394        state->iDelta = delta;
395        state->iSamp2 = state->iSamp1;
396        state->iSamp1 = new_sample;
397
398        return new_sample;
399}
400
401int InitIMA_ADPCM(alIMAADPCM_state_LOKI *state, alWaveFMT_LOKI *format)
402{
403        ALubyte  *rogue_feel;
404        ALushort extra_info;
405
406        /* Set the rogue pointer to the IMA_ADPCM specific data */
407        state->wavefmt.encoding     = swap16le(format->encoding);
408        state->wavefmt.channels     = swap16le(format->channels);
409        state->wavefmt.frequency    = swap32le(format->frequency);
410        state->wavefmt.byterate     = swap32le(format->byterate);
411        state->wavefmt.blockalign   = swap16le(format->blockalign);
412        state->wavefmt.bitspersample =
413                                         swap16le(format->bitspersample);
414        rogue_feel = (ALubyte *)format + sizeof(*format);
415        if ( sizeof(*format) == 16 ) {
416                extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
417                rogue_feel += sizeof(ALushort);
418        }
419        state->wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
420
421        state->state[0].valprev = 0;
422        state->state[0].index   = 0;
423
424        state->state[1].valprev = 0;
425        state->state[1].index   = 0;
426
427        return(0);
428}
429
430static ALint IMA_ADPCM_nibble(alIMAADPCM_decodestate_LOKI *state, ALubyte nybble)
431{
432        const ALint max_audioval = ((1<<(16-1))-1);
433        const ALint min_audioval = -(1<<(16-1));
434        const int index_table[16] = {
435                -1, -1, -1, -1,
436                 2,  4,  6,  8,
437                -1, -1, -1, -1,
438                 2,  4,  6,  8
439        };
440        const ALint step_table[89] = {
441                7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
442                34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
443                143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
444                449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
445                1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
446                3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
447                9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
448                22385, 24623, 27086, 29794, 32767
449        };
450        ALint delta, step;
451
452        /* Compute difference and new sample value */
453        step = step_table[(int) state->index];
454        delta = step >> 3;
455        if ( nybble & 0x04 ) delta += step;
456        if ( nybble & 0x02 ) delta += (step >> 1);
457        if ( nybble & 0x01 ) delta += (step >> 2);
458        if ( nybble & 0x08 ) delta = -delta;
459        state->valprev += delta;
460
461        /* Update index value */
462        state->index += index_table[nybble];
463        if ( state->index > 88 ) {
464                state->index = 88;
465        } else
466        if ( state->index < 0 ) {
467                state->index = 0;
468        }
469
470        /* Clamp output sample */
471        if ( state->valprev > max_audioval ) {
472                state->valprev = max_audioval;
473        } else
474        if ( state->valprev < min_audioval ) {
475                state->valprev = min_audioval;
476        }
477        return(state->valprev);
478}
479
480/* Fill the decode buffer with a channel block of data (8 samples) */
481static void Fill_IMA_ADPCM_block(ALubyte *decoded, ALubyte *encoded,
482        int channel, int numchannels, alIMAADPCM_decodestate_LOKI *state)
483{
484        int i;
485        ALbyte  nybble;
486        ALint new_sample;
487
488        decoded += (channel * 2);
489        for ( i=0; i<4; ++i ) {
490                nybble = (*encoded)&0x0F;
491                new_sample = IMA_ADPCM_nibble(state, nybble);
492                decoded[0] = new_sample&0xFF;
493                new_sample >>= 8;
494                decoded[1] = new_sample&0xFF;
495                decoded += 2 * numchannels;
496
497                nybble = (*encoded)>>4;
498                new_sample = IMA_ADPCM_nibble(state, nybble);
499                decoded[0] = new_sample&0xFF;
500                new_sample >>= 8;
501                decoded[1] = new_sample&0xFF;
502                decoded += 2 * numchannels;
503
504                ++encoded;
505        }
506}
507
508int IMA_ADPCM_decode(ALubyte *indata, ALubyte *outdata,
509                ALuint len, alIMAADPCM_state_LOKI *istate, int offset) {
510        alIMAADPCM_decodestate_LOKI *state;
511        int indata_len;
512        int c, channels = istate->wavefmt.channels;
513        int samplesleft;
514
515        indata += offset;
516        state = istate->state;
517
518        if(len < istate->wavefmt.blockalign) {
519#ifdef DEBUG_CONVERT
520                fprintf(stderr, "IMA_ADPCM_decode len too small!\n");
521#endif
522                return -1;
523        }
524
525        indata_len = len;
526        /* Get ready... Go! */
527        while ( indata_len >= istate->wavefmt.blockalign ) {
528                /* Grab the initial information for this block */
529                for ( c=0; c<channels; ++c ) {
530                        /* Fill the state information for this block */
531                        state[c].valprev = ((indata[1]<<8)|indata[0]);
532                        indata += 2;
533                        if ( state[c].valprev & 0x8000 ) {
534                                state[c].valprev -= 0x10000;
535                        }
536                        state[c].index = *indata++;
537                        /* Reserved byte in buffer header, should be 0 */
538                        if ( *indata++ != 0 ) {
539                                /* Uh oh, corrupt data?  Buggy code? */;
540                        }
541
542                        /* Store the initial valprev we start with */
543                        outdata[0] = state[c].valprev&0xFF;
544                        outdata[1] = state[c].valprev>>8;
545                        outdata += 2;
546                }
547
548                /* Decode and store the other samples in this block */
549                samplesleft = (istate->wSamplesPerBlock-1)*channels;
550                while ( samplesleft > 0 ) {
551                        for ( c=0; c<channels; ++c ) {
552                                Fill_IMA_ADPCM_block(outdata, indata,
553                                                c, channels, &state[c]);
554                                indata += 4;
555                                samplesleft -= 8;
556                        }
557                        outdata += (channels * 8 * 2);
558                }
559                indata_len -= istate->wavefmt.blockalign;
560        }
561
562        return 0;
563}
564
565int IMA_ADPCM_decode_FULL(alIMAADPCM_state_LOKI *istate,
566                        ALubyte **audio_buf, ALuint *audio_len) {
567        ALubyte *freeable, *encoded;
568        ALint encoded_len;
569        unsigned int channels;
570
571
572
573        /* Check to make sure we have enough variables in the state array */
574        channels = istate->wavefmt.channels;
575        if ( channels > NELEMS(istate->state) ) {
576#ifdef DEBUG_CONVERT
577                fprintf(stderr, "IMA ADPCM decoder can only handle %d channels",
578                                                NELEMS(istate->state));
579#endif
580
581                return(-1);
582        }
583
584        /* Allocate the proper sized output buffer */
585        encoded_len = *audio_len;
586        encoded = *audio_buf;
587        freeable = *audio_buf;
588        *audio_len = (encoded_len/istate->wavefmt.blockalign) *
589                                istate->wSamplesPerBlock*
590                                istate->wavefmt.channels*sizeof(ALshort);
591
592        *audio_buf = malloc(*audio_len);
593        if ( *audio_buf == NULL ) {
594#ifdef DEBUG_CONVERT
595                fprintf(stderr, "No mem\n");
596#endif
597                return(-1);
598        }
599
600        return IMA_ADPCM_decode(encoded, *audio_buf,
601                        encoded_len, istate, 0);
602}
Note: See TracBrowser for help on using the repository browser.