Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ** Intel/DVI ADPCM coder/decoder.
- **
- ** The algorithm for this coder was taken from the IMA Compatability Project
- ** proceedings, Vol 2, Number 2; May 1992.
- **
- ** Version 1.1, 16-Dec-92.
- **
- ** Change log:
- ** - Fixed a stupid bug, where the delta was computed as
- ** stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
- ** still be gotten by defining STUPID_V1_BUG.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <alloc.h>
- #include "adpcm.h"
- #define INMAX 16384
- #define OUTMAX INMAX
- #define MINVAL -32768
- #define MAXVAL 32767
- /* Intel ADPCM step variation table */
- const int indexTable[16] = {
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8,
- };
- const int stepsizeTable[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14,
- 16, 17, 19, 21, 23, 25, 28, 31,
- 34, 37, 41, 45, 50, 55, 60, 66,
- 73, 80, 88, 97, 107, 118, 130, 143,
- 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658,
- 724, 796, 876, 963, 1060, 1166, 1282, 1411,
- 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
- 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
- 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
- 32767
- };
- void adpcm_coder( int *inp, unsigned char *outp,
- int len, struct adpcm_state *state)
- {
- int val; /* Current input sample value */
- int sign; /* Current adpcm sign bit */
- int delta; /* Current adpcm output value */
- int step; /* Stepsize */
- int valprev; /* virtual previous output value */
- int vpdiff; /* Current change to valprev */
- int index; /* Current step change index */
- int outputbuffer = 0; /* place to keep previous 4-bit value */
- // this variable is now part of the structure definition!!! in the h file
- // static int bufferstep; /* toggle between outputbuffer/output */
- valprev = state->valprev;
- index = state->index;
- step = stepsizeTable[index];
- state->bufferstep = 1;
- while (--len >= 0) {
- val = ((*inp++) / 4);
- /* Step 1 - compute difference with previous value */
- delta = val - valprev;
- sign = (delta < 0) ? 8 : 0;
- if ( sign ) delta = (-delta);
- /* Step 2 - Divide and clamp */
- delta = (delta<<2) / step;
- if ( delta > 7 ) delta = 7;
- vpdiff = ((delta*step) >> 2) + (step >> 3);
- /* Step 3 - Update previous value */
- if ( sign )
- valprev = ((long)(valprev-vpdiff)<MINVAL) ? MINVAL : (valprev-vpdiff);
- else
- valprev = ((long)(valprev+vpdiff)>MAXVAL) ? MAXVAL : (valprev+vpdiff);
- /* Step 4 - Clamp previous value to 16 bits */
- // if ( valprev > 32767 )
- // valprev = 32767;
- // else if ( valprev < -32768 )
- // valprev = -32768;
- /* Step 5 - Assemble value, update index and step values */
- delta |= sign;
- index += indexTable[delta];
- if ( index < 0 ) index = 0;
- if ( index > 88 ) index = 88;
- step = stepsizeTable[index];
- /* Step 6 - Output value */
- if ( state->bufferstep ) {
- outputbuffer = (delta << 4) & 0xf0;
- } else {
- *outp++ = (delta & 0x0f) | outputbuffer;
- }
- state->bufferstep = !state->bufferstep;
- }
- /* Output last step, if needed */
- if ( !state->bufferstep )
- *outp++ = outputbuffer;
- state->valprev = valprev;
- state->index = index;
- }
- void main (void)
- {
- FILE *fIn, *fOut;
- int iLoop, iLength;
- char sFileIn[80], sFileOut[80];
- int iSample, *iptrSample;
- unsigned char cSample, *cptrSample;
- struct adpcm_state state;
- int *iRawInBuffer, *iptrRaw;
- unsigned char *cAdpcmOutBuffer, *cptrADPCM;
- state.index = 0;
- state.valprev = 0;
- state.bufferstep = 0;
- // memory allocation for input and output buffers
- printf("Allocating memory for the input data\n");
- if((iRawInBuffer =(int *) calloc (INMAX, sizeof(int))) == NULL)
- {printf("Allocation of memory failed for input buffer\n");exit(1);}
- printf("Allocating memory for the output data\n");
- if((cAdpcmOutBuffer =(char *) calloc (OUTMAX, sizeof(char))) == NULL)
- {printf("Allocation of memory failed for output buffer\n");exit(1);}
- // initilaise the memory to a known value (CHECKING ITS USED!!!!)
- printf("initialising the memory to zero\n");
- iptrRaw = iRawInBuffer;
- cptrADPCM = cAdpcmOutBuffer;
- for(iLoop=0; iLoop<INMAX; iLoop++) *iptrRaw++ = 0;
- for(iLoop=0; iLoop<OUTMAX; iLoop++) *cptrADPCM++ = '\0';
- // filename to be loaded + output filename
- for(iLoop=0;iLoop<80;iLoop++)
- {sFileIn[iLoop] = '\0'; sFileOut[iLoop] = '\0'; }
- printf("Enter the raw audio data filename : ");
- scanf("%s", &sFileIn);
- printf("\n\tFilename entered was [%s]\n", sFileIn);
- if ((fIn = fopen(sFileIn, "rb")) == NULL)
- {printf("Input file not opened\n"); exit(1);}
- printf("Enter the output filename :");
- scanf("%s", &sFileOut);
- printf("Encoded output filename is [%s]\n", sFileOut);
- if ((fOut = fopen(sFileOut, "wb")) == NULL)
- {printf("output file not opened\n");exit(1);}
- // main encoding calls in here
- printf("Starting coding routine\n");
- iptrRaw = iRawInBuffer;
- cptrADPCM = cAdpcmOutBuffer;
- fread( iptrRaw, sizeof(int), INMAX, fIn);
- printf("Read in the data file (%d elements) and stored\n", INMAX);
- // perform conversion to ADPCM
- adpcm_coder( iRawInBuffer, cAdpcmOutBuffer, INMAX, &state);
- printf("Performed conversion\n");
- //write out the data block from memory
- fwrite( cptrADPCM, sizeof(char), INMAX, fOut);
- printf("written the encoded file out\n");
- fclose(fIn);
- fclose(fOut);
- free( iRawInBuffer );
- free( cAdpcmOutBuffer );
- printf("Deallocated dynamic memory\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment