M
me555555
Unregistered / Unconfirmed
GUEST, unregistred user!
Adpcm文件头组成: 1. 字符串"RIFF" 2. 4个字节(指明文件大小) 3. 字符串"WAVE" 4. 字符串"fmt" 5. IMAADPCMWAVEFORMAT结构大小 6. 结构IMAADPCMWAVEFORMAT // 20 7. 字符串"fact" 8. fact的大小 9. datafactsize 10.字符串"data" 11. 数据的大小 12. 数据内容 // 数据头到文件的偏移量为60 单声道8000采样率, 16位的pcm进行4:1压缩, apdcm文件头信息typedef struct { WORD wFormatTag;
// wave_format_dvi_adpcm / wave_format_ima_adpcm (0x0011)WORD nChannels;
// 通道数 - 1 DWORD nSamplesPerSec;
// 采样率 - 8000DWORD nAvgBytesPerSec;
// 每秒多少个字节, 4055 = 256*8000/505 WORD nBlockAlign;
// 数据块的调整数, 取决于每个采样点的位数 - 256 WORD wBitsPerSample;
// 每样本数据位数 - 4 WORD cbSize;
// 保留参数- 2 }WAVEFORMATEX;
// size:18 typedef struct ima_adpcmwaveformat_tag {WAVEFORMATEX wfx;WORD wSamplesPerBlock;
// 每个数据块包含采样点数, 505}IMAADPCMWAVEFORMAT;
// size:20 Fact块typedef struct factchunk{char[4];
// “fact”字符串DWORD chunksize;
// 4DWORD datafactsize;
// 指定该文件包含的采样点数, }FACTTRUNK;
相关结构定义:#define IMA_ADPCM_4BIT_BLOCK 256 #define IMA_ADPCM_PCM_RAW_LEN 1010 // block header: 4 bit decode, mono typedef struct dvi_adpcm_4bit_mono_blockheader_tag { short isamp0;
unsigned char bsteptableindex;
unsigned char breserved;
}dvi_adpcm_4bit_mono_blockheader;
typedef dvi_adpcm_4bit_mono_blockheader ima_adpcm_4bit_mono_blockheader;
// step table static const int steptab[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};
压缩算法:int Enconde_IMA_ADPCM_4BIT_MONO(unsigned char* pcmData, int iDataLen, unsigned char* outBuf, int iBufLen) { // index table for ima 4bit const int indextab[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 };
if (iDataLen < 2) return -1;
if (iDataLen > IMA_ADPCM_PCM_RAW_LEN) iDataLen = IMA_ADPCM_PCM_RAW_LEN;
ima_adpcm_4bit_mono_blockheader bheader = {0};
short* rawData = (short*)(pcmData);
int index = 0;
bheader.isamp0 = rawData[0];
bheader.bsteptableindex = index;
memcpy(outBuf, &bheader, sizeof(bheader));
int len = sizeof(bheader);
// save current sample short presamp = bheader.isamp0;
int n = 1;
int diff = 0;
unsigned char code = 0;
bool bodd = true;
for (n = 1;
n < iDataLen/2;
n++) { // calculate diff diff = rawData[n] - presamp;
if (diff < 0){ diff = -diff;
code = 8;
}else
{ code = 0;
} // set the rest of the code if (diff >= steptab[index]){ code = code | 4;
diff = diff - steptab[index];
} if (diff >= (steptab[index]>>1)){ code = code | 2;
diff = diff - (steptab[index]>>1);
} if (diff >= (steptab[index]>>2)){ code = code | 1;
} if (bodd) // first 4bit outBuf[len] = code;
else
outBuf[len++] = (code<<4) | outBuf[len];
bodd = !bodd;
// predict the current sample based on the sample code: diff = 0;
if (code & 4) diff = diff + steptab[index];
if (code & 2) diff = diff + (steptab[index]>>1);
if (code & 1) { diff = diff + (steptab[index]>>2);
}diff = diff + (steptab[index]>>3);
if (code & 8) diff = -diff;
presamp = presamp + diff;
if (presamp < -32768)presamp = -32768;
if (presamp > 32767) presamp = 32767;
// adjust the step table index: index = index + indextab
// wave_format_dvi_adpcm / wave_format_ima_adpcm (0x0011)WORD nChannels;
// 通道数 - 1 DWORD nSamplesPerSec;
// 采样率 - 8000DWORD nAvgBytesPerSec;
// 每秒多少个字节, 4055 = 256*8000/505 WORD nBlockAlign;
// 数据块的调整数, 取决于每个采样点的位数 - 256 WORD wBitsPerSample;
// 每样本数据位数 - 4 WORD cbSize;
// 保留参数- 2 }WAVEFORMATEX;
// size:18 typedef struct ima_adpcmwaveformat_tag {WAVEFORMATEX wfx;WORD wSamplesPerBlock;
// 每个数据块包含采样点数, 505}IMAADPCMWAVEFORMAT;
// size:20 Fact块typedef struct factchunk{char[4];
// “fact”字符串DWORD chunksize;
// 4DWORD datafactsize;
// 指定该文件包含的采样点数, }FACTTRUNK;
相关结构定义:#define IMA_ADPCM_4BIT_BLOCK 256 #define IMA_ADPCM_PCM_RAW_LEN 1010 // block header: 4 bit decode, mono typedef struct dvi_adpcm_4bit_mono_blockheader_tag { short isamp0;
unsigned char bsteptableindex;
unsigned char breserved;
}dvi_adpcm_4bit_mono_blockheader;
typedef dvi_adpcm_4bit_mono_blockheader ima_adpcm_4bit_mono_blockheader;
// step table static const int steptab[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};
压缩算法:int Enconde_IMA_ADPCM_4BIT_MONO(unsigned char* pcmData, int iDataLen, unsigned char* outBuf, int iBufLen) { // index table for ima 4bit const int indextab[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 };
if (iDataLen < 2) return -1;
if (iDataLen > IMA_ADPCM_PCM_RAW_LEN) iDataLen = IMA_ADPCM_PCM_RAW_LEN;
ima_adpcm_4bit_mono_blockheader bheader = {0};
short* rawData = (short*)(pcmData);
int index = 0;
bheader.isamp0 = rawData[0];
bheader.bsteptableindex = index;
memcpy(outBuf, &bheader, sizeof(bheader));
int len = sizeof(bheader);
// save current sample short presamp = bheader.isamp0;
int n = 1;
int diff = 0;
unsigned char code = 0;
bool bodd = true;
for (n = 1;
n < iDataLen/2;
n++) { // calculate diff diff = rawData[n] - presamp;
if (diff < 0){ diff = -diff;
code = 8;
}else
{ code = 0;
} // set the rest of the code if (diff >= steptab[index]){ code = code | 4;
diff = diff - steptab[index];
} if (diff >= (steptab[index]>>1)){ code = code | 2;
diff = diff - (steptab[index]>>1);
} if (diff >= (steptab[index]>>2)){ code = code | 1;
} if (bodd) // first 4bit outBuf[len] = code;
else
outBuf[len++] = (code<<4) | outBuf[len];
bodd = !bodd;
// predict the current sample based on the sample code: diff = 0;
if (code & 4) diff = diff + steptab[index];
if (code & 2) diff = diff + (steptab[index]>>1);
if (code & 1) { diff = diff + (steptab[index]>>2);
}diff = diff + (steptab[index]>>3);
if (code & 8) diff = -diff;
presamp = presamp + diff;
if (presamp < -32768)presamp = -32768;
if (presamp > 32767) presamp = 32767;
// adjust the step table index: index = index + indextab
代码:
;
if (index < 0) index = 0;
if (index > 88) index = 88;
} return 0;
} 解压算法:int Decode_IMA_ADPCM_4BIT_MONO(unsigned char* imaData, int iDataLen, unsigned char* outBuf, int iBufLen) { // index table for ima 4 const int indextab[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 };
if (iDataLen < 4) return -1;
else
if (iDataLen > IMA_ADPCM_4BIT_BLOCK) iDataLen = IMA_ADPCM_4BIT_BLOCK;
short* pcmData = (short*)(outBuf);
short samp0 = ((short*)(imaData))[0];
int index = imaData[2];
int iLen = 0;
pcmData[iLen++] = samp0;
short presamp = samp0;
// pre sample // get next sample from the fourth int n = 4;
int diff = 0;
unsigned char code = 0;
short sampx = 0;
bool odd = true;
while (n < iDataLen) { if (odd) code = imaData[n]&0x0F;
else
code = imaData[n]>>4;
// calculate diff = 0;
if (code & 4) diff = diff + steptab[index];
if (code & 2) diff = diff + (steptab[index] >> 1);
if (code & 1) diff = diff + (steptab[index] >> 2);
diff = diff + (steptab[index] >> 3);
if (code & 8) diff = -diff;
sampx = presamp + diff;
// check sampx if (sampx < -32768) sampx = -32768;
if (sampx > 32767) sampx = 32767;
pcmData[iLen++] = sampx;
presamp = sampx;
// adjust index index = index + indextab[code];
if (index < 0) index = 0;
if (index >88) index = 88;
odd = !odd;
if (odd) n++;
if (iLen > iBufLen/2) return -1;
} return 0;
}