📄 adpcm16.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 + -