ADPCM-PCM 的压缩
来源:互联网 发布:下载天猫淘宝网 编辑:程序博客网 时间:2024/05/22 02:26
转化后输出的数据分配的空间要算好,上面的byte2的空间在下面转换成NSdata的时候分配的空间多了一倍要进行修改
import “ADPCM.h”
define RATE 8000
define SIZE AFMT_S16_LE
define CHANNELS 2
define FRAME_SIZE 1000
static int indexTable[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8,
};
static int 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
};
@implementation ADPCM
pragma mark 编码
int adpcm_coder(short *indata, unsigned char *outdata, int len)
{
int val; /* Current input sample value */
unsigned int delta; /* Current adpcm output value */
int diff; /* Difference between val and valprev */
int step; /* Stepsize */
int valpred; /* Predicted output value */
// Current change to valpred
int index ; /* Current step change index */
unsigned int outputbuffer = 0;/* place to keep previous 4-bit value */
int count = 0; /* the number of bytes encoded */
//
// valpred = state->valprev;
// index = (int)state->index;
step = stepsizeTable[index];
valpred = *indata;index = 0;*outdata = (unsigned char)(len/2+4);*(++outdata) = (unsigned char)((len/2+4)>>8);*(++outdata) = (unsigned char)((len/2+4)>>16);*(++outdata) = (unsigned char)((len/2+4)>>24);*(++outdata) = 0x11;*(++outdata) = 0x00;
// *indata = 0xf00f;
*(++outdata)=(unsigned char)(*indata);
// outdata++;
// outdata++;
*(++outdata)=(*indata)>>8;
*(++outdata)=0;
*(++outdata)=0;
// *(++outdata)=3;
// *(++outdata)=4;
while (len > 0 ) { /* Step 1 - compute difference with previous value */ val = *(++indata); diff = val - valpred; if(diff < 0) { delta = 8; diff = (-diff); } else { delta = 0; } /* Step 2 - Divide and clamp */ /* Note: ** This code *approximately* computes: ** delta = diff*4/step; ** vpdiff = (delta+0.5)*step/4; ** but in shift step bits are dropped. The net result of this is ** that even if you have fast mul/div hardware you cannot put it to ** good use since the fixup would be too expensive. */
// vpdiff = (step >> 3);
if ( diff >= stepsizeTable[index] ) { delta = delta|4; diff -= stepsizeTable[index] - step;
// vpdiff += step;
}
// stepsizeTable[index] >>= 1;
if ( diff >= (stepsizeTable[index] >> 1) ) {
delta = delta|2;
diff -= stepsizeTable[index] - (stepsizeTable[index] >> 1);
// vpdiff += step;
}
// step >>= 2;
if ( diff >= (stepsizeTable[index] >> 2) ) {
delta = delta| 1;
// vpdiff += step;
}
/* Phil Frisbie combined steps 3 and 4 */ /* Step 3 - Update previous value */ /* Step 4 - Clamp previous value to 16 bits */ diff = 0; if (delta&4)diff = diff +stepsizeTable[index]; if (delta&2)diff = diff + (stepsizeTable[index] >> 1); if (delta&1)diff = diff + (stepsizeTable[index] >> 2); diff = diff + (stepsizeTable[index] >> 3); if ( (delta&8) !=0 ) { diff = -diff;
// valpred -= vpdiff;
// if ( valpred < -32768 )
// valpred = -32768;
}
valpred = diff + valpred ;
if ( valpred < -32768 ){
valpred = -32768;
}else{
if ( valpred > 32767 ) valpred = 32767; } /* Step 5 - Assemble value, update index and step values */ index += indexTable[delta]; if ( index < 0 ) index = 0; else if ( index > 88 ) index = 88;
// step = stepsizeTable[index];
/* Step 6 - Output value */ outputbuffer = (delta ); /* Step 1 - compute difference with previous value */ /* Step 1 - compute difference with previous value */ val = *(++indata); diff = val - valpred; if(diff < 0) { delta = 8; diff = (-diff); } else { delta = 0; } /* Step 2 - Divide and clamp */ /* Note: ** This code *approximately* computes: ** delta = diff*4/step; ** vpdiff = (delta+0.5)*step/4; ** but in shift step bits are dropped. The net result of this is ** that even if you have fast mul/div hardware you cannot put it to ** good use since the fixup would be too expensive. */ // vpdiff = (step >> 3); if ( diff >= stepsizeTable[index] ) { delta = delta|4; diff -= stepsizeTable[index] - step; // vpdiff += step; } // stepsizeTable[index] >>= 1; if ( diff >= (stepsizeTable[index] >> 1) ) { delta = delta|2; diff -= stepsizeTable[index] - (stepsizeTable[index] >> 1); // vpdiff += step; } // step >>= 2; if ( diff >= (stepsizeTable[index] >> 2) ) { delta = delta| 1; // vpdiff += step; } /* Phil Frisbie combined steps 3 and 4 */ /* Step 3 - Update previous value */ /* Step 4 - Clamp previous value to 16 bits */ diff = 0; if (delta&4)diff = diff +stepsizeTable[index]; if (delta&2)diff = diff + (stepsizeTable[index] >> 1); if (delta&1)diff = diff + (stepsizeTable[index] >> 2); diff = diff + (stepsizeTable[index] >> 3); if ( (delta&8) !=0 ) { diff = -diff; // valpred -= vpdiff; // if ( valpred < -32768 ) // valpred = -32768; } valpred = diff + valpred ; if ( valpred < -32768 ){ valpred = -32768; }else{ if ( valpred > 32767 ) valpred = 32767; } /* Step 5 - Assemble value, update index and step values */ index += indexTable[delta]; if ( index < 0 ) index = 0; else if ( index > 88 ) index = 88; /* Step 6 - Output value */ *(++outdata) = (unsigned char)((delta<<4 )| outputbuffer); count++; len -= 2;}
// valpred = (short)valpred;
// index = (char)index;
return count;
}
pragma mark adpcm解码
int adpcm_decoder(unsigned char *indata, short *outdata, int len)
{
unsigned int delta; /* Current adpcm output value */
// int step; /* Stepsize */
int valpred; /* Predicted value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
unsigned char inputbuffer = 0;/* place to keep next 4-bit value */
int count = 0;
//file head*outdata = (*indata)|(*(++indata)<<8);*(++outdata) = (*(++indata))|(*(++indata)<<8);*(++outdata) =(*(++indata))|(*(++indata)<<8);//first sample*(++outdata) = (*(++indata))|(*(++indata)<<8);index=*(++indata);index=*(++indata);valpred = *outdata;index = 0;
// step = stepsizeTable[index];
/* Loop unrolling by Phil Frisbie *//* This assumes there are ALWAYS an even number of samples */while ( len-- > 0 ) { /* Step 1 - get the delta value */ inputbuffer = *(++indata); delta = (inputbuffer & 0x0f); /* Step 2 - Find new index value (for later) */
// index += indexTable[delta];
// if ( index < 0 ) index = 0;
// else if ( index > 88 ) index = 88;
/* Phil Frisbie combined steps 3, 4, and 5 */ /* Step 3 - Separate sign and magnitude */ /* Step 4 - Compute difference and new predicted value */ /* Step 5 - clamp output value */ /* ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment ** in adpcm_coder. */ vpdiff = 0; if ( (delta & 4) != 0 ) vpdiff += stepsizeTable[index]; if ( (delta & 2) != 0 ) vpdiff += stepsizeTable[index]>>1; if ( (delta & 1) != 0 ) vpdiff += stepsizeTable[index]>>2; vpdiff = vpdiff + (stepsizeTable[index]>>3); if ( (delta & 8) != 0 ) { valpred -= vpdiff; } if ( valpred < -32768 ){ valpred = -32768; }else {
// valpred += vpdiff;
if ( valpred > 32767 )
valpred = 32767;
}
/* Step 6 - Update step value */
// step = stepsizeTable[index];
/* Step 7 - Output value */ *(++outdata) = (short)valpred; index += indexTable[delta]; if ( index < 0 ) index = 0; else if ( index > 88 ) index = 88; /* Step 1 - get the delta value */ delta = inputbuffer & 0xf0; /* Step 2 - Find new index value (for later) */ vpdiff = 0; if ( (delta & 4) != 0 ) vpdiff += stepsizeTable[index]; if ( (delta & 2) != 0 ) vpdiff += stepsizeTable[index]>>1; if ( (delta & 1) != 0 ) vpdiff += stepsizeTable[index]>>2; vpdiff = vpdiff + (stepsizeTable[index]>>3); if ( (delta & 8) != 0 ) { valpred -= vpdiff; } if ( valpred < -32768 ){ valpred = -32768; }else { // valpred += vpdiff; if ( valpred > 32767 ) valpred = 32767; } /* Step 6 - Update step value */ // step = stepsizeTable[index]; /* Step 7 - Output value */
// *(++outdata) = (short)valpred;
index += indexTable[delta]; if ( index < 0 ) index = 0; else if ( index > 88 ) index = 88; /* Step 7 - Output value */ *(++outdata) = (short)valpred; count += 2;}
// state->valprev = (short)valpred;
// state->index = (char)index;
return count;
}
pragma mark 编码调用方法
(void)adpcmCodeWithFilePath:(NSString )inPathString saveFilePath:(NSString )outPathString{
int fd,mid;
// int arg;
// int status;// for encode use
unsigned char inbuf[FRAME_SIZE*4]; // 2 channels , 16bit data , so *4
short inenc[FRAME_SIZE]; // 1 channel, 16bit data, but short type, so *1
unsigned char encbuf[FRAME_SIZE/2];// for decode use
// short decbuf[FRAME_SIZE]; // decode restore inenc
// unsigned char outbuf[FRAME_SIZE*4]; // restore inbuf// adpcm
struct adpcm_state enc_state;//获得char路径
char *inPath = [self getCharPath:inPathString];
char *outPath = [self getCharPath:outPathString];//打开文件
fd = open(inPath, O_RDWR);
if (fd < 0)
{
perror(“Open /dev/dsp fail”);
exit(1);
}mid = open(outPath, O_RDWR);
// encode
enc_state.valprev = 0;
enc_state.index = 0;while(1)
{
// encode
printf(“encode\n”);
read(fd, inbuf, sizeof(inbuf));for(int i = 0;i < FRAME_SIZE * 4;i += 4){ inenc[i/4] = inbuf[i] + inbuf[i+1]*256;}
// adpcm_coder(inenc, encbuf, FRAME_SIZE, &enc_state);
// decode
// printf(“decode\n”);
// adpcm_decoder(encbuf, decbuf, FRAME_SIZE/2, &dec_state);
//
// for(int i=0;i < FRAME_SIZE;i++){
// outbuf[i*4] = decbuf[i] & 0xff;
// outbuf[i*4+1] = decbuf[i] >> 8;
// outbuf[i*4+2] = decbuf[i] & 0xff;
// outbuf[i*4+3] = decbuf[i] >> 8;
// }
write(mid, inenc, sizeof(inenc));}
}
pragma mark 把NSString转变成char
(char )getCharPath:(NSString )path {
NSUInteger pathLenth = [path length];
char newPath = (char )malloc(sizeof(char)*pathLenth + 1);
[path getCString:newPath maxLength:pathLenth + 1 encoding:NSUTF8StringEncoding];
return newPath;
}
- ADPCM-PCM 的压缩
- PCM音频文件(.wav)压缩成ADPCM(.wav)
- ADPCM与PCM的区别 以及wave文件的压缩与解压缩
- ADPCM与PCM的区别 以及wave文件的压缩与解压缩
- ADPCM与PCM的区别 以及wave文件的压缩与解压缩
- 简述PCM,DPCM,ADPCM的区别。
- PCM跟ADPCM的一些笔记
- adpcm的压缩和解压缩实现
- adpcm的压缩和解压缩实现
- pcm,dpcm,adpcm
- ADPCM WAVE文件的压缩与解压缩
- PCM音频文件(.wav)压缩成ADPCM(.wav) ,wav文件分析,wav 文件格式
- wav数据分析-pcm-adpcm
- ADPCM压缩算法
- ADPCM压缩算法
- ADPCM压缩算法
- ADPCM压缩算法
- ADPCM压缩算法
- Wi-Fi Direct
- Android - How to turn off Wifi-direct
- Android Tutorial Android Wifi-Direct Tutorial
- Nginx、LVS、HAProxy负载均衡软件的优缺点
- wifi direct—深入理解Wi-Fi P2P
- ADPCM-PCM 的压缩
- 《深入理解Android:Wi-Fi,NFC和GPS》—android源码下载
- 国产CPU迷局 龙芯该如何参与市场竞争
- Wi-Fi Direct技术
- UUID生成方法总结
- iptables基础(2)
- CentOS7—Firefox—截图工具—fireshot插件
- Serval Project——Android
- Dev-Cpp/Mingw32 环境介绍(1)