C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-19-2007, 09:37 AM   #1
Registered User
 
Join Date: Apr 2007
Posts: 5
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");
	}
subtled is offline   Reply With Quote
Old 04-19-2007, 10:06 AM   #2
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,710
> if ((infile = fopen(argv[i],"r")) == NULL)
If this is a binary file, then you should use "rb" (and "wb" for writing), otherwise end of line character translations can make a real mess of your data.

Likewise, such translations can make your simple attempt to work out the length of the file meaningless. Always use the result of fread() to decide on success/fail, not some 'guess' as to how many times around the loop you should go.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 04-19-2007, 10:20 AM   #3
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,768
Quote:
Originally Posted by subtled View Post
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?!
Throw it in a debugger and put a watch point on one of those variables. It'll break at the moment it changes, and you can see what's doing it. None of the code you posted appears to be capable of causing this.

There are usually two possibilities why a global variable is improperly overwritten. One, you may be overrunning some global buffer somewhere, and stepping on the other variables. Two, you may have made a change to a header file which changed the size of some structure (and therefore the arrangement of global variables in memory), but failed to correctly recompile a module which uses that structure.
brewbuck is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Storing values from Edit Box into an array E_I_S C++ Programming 10 06-05-2008 06:24 AM
Struct Values Muphin C++ Programming 5 08-13-2005 09:24 PM
need some advice on displaying values rEtard Windows Programming 7 06-16-2005 09:55 AM
Computing Large Values swbluto C++ Programming 8 04-07-2005 03:04 AM
can't assign proper values to an array of string Duo C Programming 1 04-04-2005 06:30 AM


All times are GMT -6. The time now is 02:51 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22