I'm having problems with the below code. Basically, every time the function ADPCMEncoder is called, prevsample and previndex get reset to 0, for no reason that I can see... I've set a breakpoint on the last line of ADPCMEncoder after they're assigned values and they're fine, then when I set a breakpoint in main on the line after the function call, they've become 0, but I can't see what's making them do it?!
Includes/global variables etc:
Code:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> signed char IndexTable[16] = { -1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8 }; short 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 }; short sample; long prevsample; long previndex;
ADPCMEncoder:
Main:Code:unsigned char ADPCMEncoder(short sample , long prevsample, long previndex) { unsigned char code; long diff; long step; long predsample; long diffq; long index; long tempstep; /* Restore previous values of predicted sample and quantizer step size index */ predsample = prevsample; index = previndex; step = StepSizeTable[index]; /* Compute the difference between the acutal sample (sample) and the the predicted sample (predsample) */ diff = sample - predsample; if(diff >= 0) code = 0; else { code = 8; diff = -diff; } /* Quantize the difference into the 4-bit ADPCM code using the the quantizer step size */ tempstep = step; if(diff >= tempstep) { code = (code | 4); diff = diff - tempstep; } tempstep = tempstep/2; if(diff >= tempstep) { code = (code | 2); diff = diff-tempstep; } tempstep = tempstep/2; if(diff >= tempstep) { code = (code | 1); } /* Inverse quantize the ADPCM code into a predicted difference using the quantizer step size */ diffq = step >> 3; if (code & 4) diffq = diffq + step; if (code & 2) diffq = diffq + step/2; if (code & 1) diffq = diffq + step/4; if (code & 8) predsample = predsample - diffq; else predsample = predsample + diffq; /* Fixed predictor computes new predicted sample by adding the old predicted sample to predicted difference */ if(code & 8) predsample -= diffq; else predsample += diffq; /* Check for overflow of the new predicted sample */ if(predsample > 32767) predsample = 32767; else if(predsample < -32768) predsample = -32768; /* Find new quantizer stepsize index by adding the old index to a table lookup using the ADPCM code */ index += IndexTable[ code]; /* Check for overflow of the new quantizer step size index */ if(index < 0) index = 0; if(index > 88) index = 88; /* Save the predicted sample and quantizer step size index for next iteration */ prevsample = (short)(predsample); previndex = index; /* Return the new ADPCM code */ return (code & 0x0f); }
Code:void main(int argc, char **argv) { FILE *infile, *tempout, *outfile; int i, j; int inhandle; int fileindex = 0; int filesize; char newname[11] = "file"; char number[3]; unsigned char code; // Check for at least one input file if (argc < 2) { printf("Command line parameters incorrect. Please specify at least one audio file to encode.\n"); return; } // Compress audio files for (i = 1; i <= (argc - 1); i++) { // Open input file if ((infile = fopen(argv[i],"r")) == NULL) { printf("Cannot open %s.\n", argv[i]); return; } // Open temp output file if ((tempout = fopen("tempout.adp","w")) == NULL) { printf("Cannot open temporary output file.\n"); return; } inhandle = fileno(infile); filesize = filelength(inhandle); for (j = 0; j <= (filesize/4); j++) { fread(&sample, sizeof(short), 1, infile); // Read first sample code = ADPCMEncoder(sample, prevsample, previndex); // Encode sample into lower nibble of code code = (code << 4) & 0xf0; // Move ADPCM code to upper nibble // If odd number of samples, do not wait for second nibble of last byte if((j == (filesize/4)) && ((filesize/2)%2 != 0)) { fwrite(&code, sizeof(unsigned char), 1, tempout); break; } fread(&sample, sizeof(short), 1, infile); // Read second sample code |= ADPCMEncoder(sample, prevsample, previndex); // Encode sample and save in lower nibble of code fwrite(&code, sizeof(unsigned char), 1, tempout); // Write code to file } fclose(infile); fclose(tempout); itoa(i, number, 10); strcat(newname, number); strcat(newname, ".adp"); rename("tempout.adp", newname); remove("tempout.adp"); }