⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adpcm16.cpp

📁 8位无符号4-BIT ADPCM编码和解码程序
💻 CPP
字号:

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
	unsigned char Write_Code;
	unsigned char Read_Code;
	unsigned char SampH;
	unsigned char SampL;
	signed long Samp;
	signed long SampleA;
	signed long SampleB;
	bool flags;
	FILE *rfp,*wfp,*out,*outz;

	/* Table of index changes 
	const int IndexTable[16] = {
	0xff, 0xff, 0xff, 0xff, 2, 4, 6, 8,
	0xff, 0xff, 0xff, 0xff, 2, 4, 6, 8
	};*/
	const int IndexTable[16] = {
	-1, -1, -1, -1, 2, 4, 6, 8,
	-1, -1, -1, -1, 2, 4, 6, 8
	};
	/* Quantizer step size lookup table */
	const long 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
	};
	signed long diff; /* Difference between sample and predicted sample */
	long step; /* Quantizer step size */
	signed long predsample; /* Output of ADPCM predictor */
	signed long diffq; /* Dequantized predicted difference */
	int index; /* Index into step size table */
	int indexa,indexb;
	typedef struct premachine{
		signed long prevsample;
		int previndex;
	};
	struct premachine state;
/*****************************************************************************
* ADPCMEncoder - ADPCM encoder routine *
******************************************************************************
* Input Variables: *
* signed long sample - 16-bit signed speech sample *
* Return Variable: *
* char - 8-bit number containing the 4-bit ADPCM code *
*****************************************************************************/
char ADPCMEncoder( signed long sample )
{
int code; /* ADPCM output value */
int tempstep; /* Temporary step size */
/* Restore previous values of predicted sample and quantizer step
size index
*/
predsample = state.prevsample;
index = state.previndex;
step = StepSizeTable[index];
/* Compute the difference between the actual 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 |= 4;
diff -= tempstep;
}
tempstep >>= 1;
if( diff >= tempstep )
{
code |= 2;
diff -= tempstep;
}
tempstep >>= 1;
if( diff >= tempstep )
code |= 1;
/* Inverse quantize the ADPCM code into a predicted difference
using the quantizer step size
*/
diffq = step >> 3;
if( code & 4 )
diffq += step;
if( code & 2 )
diffq += step >> 1;
if( code & 1 )
diffq += step >> 2;
/* 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
*/
indexa=index;
index += IndexTable[code];
indexb=index;
/* 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
*/
state.prevsample = predsample;
state.previndex = index;
/* Return the new ADPCM code */
return ( code & 0x0f );
}

/*****************************************************************************
* ADPCMDecoder - ADPCM Decoder routine *
******************************************************************************
* Input Variables: *
* char - 8-bit number containing the 4-bit ADPCM code *
* Return Variable: *
* signed long sample - 16-bit signed speech sample *
*****************************************************************************/
signed long ADPCMDecoder(unsigned char inCode)
{
/* Restore previous values of predicted sample and quantizer step
size index
*/
predsample = state.prevsample;
index = state.previndex;
step = StepSizeTable[index];
/* Inverse quantize the ADPCM code into a predicted difference
using the quantizer step size
*/

diffq = step >> 3;
if( inCode & 4 )
diffq += step;
if( inCode & 2 )
diffq += step >> 1;
if( inCode & 1 )
diffq += step >> 2;
/* Fixed predictor computes new predicted sample by adding the
old predicted sample to predicted difference
*/
if( inCode & 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[inCode];
/* 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
*/
state.prevsample = predsample;
state.previndex = index;
/* Return the new ADPCM code */
return predsample;

}
void main()
{
	signed long error;
	int cou;
	Samp=5;SampleA=10;
	Samp -=SampleA;
	/*
	//test start
	if ((rfp = fopen("f:\\zsl\\adpcm\\story805.pcm","rb")) == NULL)
		{
			printf("Cannot open file story805.pcm\n");
			exit(-1);
		}
	if ((wfp = fopen("f:\\zsl\\adpcm\\story805.dat","wb")) == NULL)
		{
			printf("Cannot open file story805.dat\n");
			exit(-1); 
		}
	while(!feof(rfp))
	{
		SampL=fgetc(rfp);
		fputc(SampL,wfp);
	}
	fclose(rfp);
	fclose(wfp);
	exit(-1);
	//test end
	*/
	if ((rfp = fopen("f:\\zsl\\adpcm\\story805.pcm","rb")) == NULL)
		{
			printf("Cannot open file story805.pcm\n");
			exit(-1);
		}
	if ((wfp = fopen("f:\\zsl\\adpcm\\story805.dat","wb")) == NULL)
		{
			printf("Cannot open file story805.dat\n");
			exit(-1);
		}
	if ((out = fopen("f:\\zsl\\adpcm\\story805a.out","wb")) == NULL)
		{
			printf("Cannot open file story805a.out\n");
			exit(-1);
		}
	if ((outz = fopen("f:\\zsl\\adpcm\\story805pre.pcm","wb")) == NULL)
		{
			printf("Cannot open file story805pre.pcm\n");
			exit(-1);
		}
	state.prevsample=0;
	state.previndex=0;
	flags = true;
	SampL=fgetc(rfp);
	SampH=fgetc(rfp);
	if ((SampH &0x80)==0x80)
		Samp=-(32768-(SampH-0x80)*256-SampL);
	else
		Samp=SampH*256+SampL;
	cou=1;
		while(!feof(rfp))
		{
			if (flags)
			{
				Write_Code=ADPCMEncoder(Samp) << 4;
				flags = false;
			}
			else
			{
				flags = true;
				Write_Code += ADPCMEncoder(Samp) & 0x0f;
				fputc(Write_Code,wfp);
			}

			//test 
			error=Samp-state.prevsample;
			fprintf(out,"%10d%10d%10d%10d%10d%10d%10d\n",Samp,state.prevsample,Write_Code,state.previndex,step,indexa,indexb);
			Samp=state.prevsample;
				if (Samp >= 0)
				{
				SampH=Samp / 256;
				SampL = Samp - 256 * SampH;
				}
				else
					{
					Samp= 32768+Samp;
					SampH = Samp / 256;
					SampL = Samp - 256 * SampH;
					SampH += 0x80;
					}
				//fprintf(out,"%10d%10d\n",SampL,SampH);
				fputc(SampL,outz);
				fputc(SampH,outz);
			cou++;
			SampL=fgetc(rfp);
			SampH=fgetc(rfp);
			if ((SampH &0x80)==0x80)
				Samp=-(32768-(SampH-0x80)*256-SampL);
			else
				Samp=SampH*256+SampL;
		}
		if (!flags)
		{
			Write_Code=Write_Code & 0xf0;
			fputc(Write_Code,wfp);
		}
	fclose(rfp);
	fclose(wfp);
	fclose(out);
	fclose(outz);

	if ((rfp = fopen("f:\\zsl\\adpcm\\story805.dat","rb")) == NULL)
		{
			printf("Cannot open file story805.dat\n");
			exit(-1);
		}
	if ((wfp = fopen("f:\\zsl\\adpcm\\story805.dec","wb")) == NULL)
		{
			printf("Cannot open file story805.dec\n");
			exit(-1);
		}

	state.prevsample=0;
	state.previndex=0;
	Read_Code=fgetc(rfp);
	while(!feof(rfp))
	{
		Samp=ADPCMDecoder((Read_Code & 0xf0) >> 4);
		if (Samp >= 0)
			{
			SampH=Samp / 256;
			SampL = Samp - 256 * SampH;
			}
		else
			{
			Samp= 32768+Samp;
			SampH = Samp / 256;
			SampL = Samp - 256 * SampH;
			SampH += 0x80;
			}
		fputc(SampL,wfp);
		fputc(SampH,wfp);
		Samp=ADPCMDecoder(Read_Code & 0x0f);
			if (Samp >= 0)
			{
			SampH=Samp / 256;
			SampL = Samp - 256 * SampH;
			}
		else
			{
			Samp=32768+Samp;
			SampH = Samp / 256;
			SampL = Samp - 256 * SampH;
			SampH += 0x80;
			}
		fputc(SampL,wfp);
		fputc(SampH,wfp);
		Read_Code=fgetc(rfp);
	}
	fclose(rfp);
	fclose(wfp);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -