Values changing without reason?
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:
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);
}
Main:
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");
}