失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > java pcm转adpcm_音频编码(PCM ADPCM WAVE文件)

java pcm转adpcm_音频编码(PCM ADPCM WAVE文件)

时间:2023-08-08 22:21:53

相关推荐

java pcm转adpcm_音频编码(PCM ADPCM WAVE文件)

二、给个英文参考网址吧

这两个讲的很详细,请仔细阅读!通过阅读我发现细节在与adpcm格式的wav文件的block的特点,每一个block包含header和data两部分,

Typedefstruct{

shortsample0;//block中第一个采样值(未压缩)

BYTEindex;//上一个block最后一个index,第一个block的index=0;

BYTEreserved;//尚未使用

}MonoBlockHeader

关键是我们要抓住每一个block的header里面的信息,即sample0,运算的时候注意运用!

三、还是给个代码吧,多的也不说了!

1、adpcm.c文件代码

#include"adpcm.h"

/*IntelADPCMstepvariationtable*/

staticintindexTable[16]={

-1,-1,-1,-1,2,4,6,8,

-1,-1,-1,-1,2,4,6,8,

};

staticintstepsizeTable[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

};

voidadpcm_decoder(char*inbuff,char*outbuff,intlen_of_in,structadpcm_state*state)

{

inti=0,j=0;

chartmp_data;

structadpcm_state*tmp_state=state;

longstep;/*Quantizerstepsize*/

signedlongpredsample;/*OutputofADPCMpredictor*/

signedlongdiffq;/*Dequantizedpredicteddifference*/

intindex;/*Indexintostepsizetable*/

intSamp;

unsignedcharSampH,SampL;

unsignedcharinCode;

/*Restorepreviousvaluesofpredictedsampleandquantizerstep

sizeindex

*/

predsample=state->valprev;

index=state->index;

for(i=0;i

{

tmp_data=inbuff[i/2];

if(i%2)

inCode=(tmp_data&0xf0)>>4;

else

inCode=tmp_data&0x0f;

step=stepsizeTable[index];

/*InversequantizetheADPCMcodeintoapredicteddifference

usingthequantizerstepsize

*/

diffq=step>>3;

if(inCode&4)

diffq+=step;

if(inCode&2)

diffq+=step>>1;

if(inCode&1)

diffq+=step>>2;

/*Fixedpredictorcomputesnewpredictedsamplebyaddingthe

oldpredictedsampletopredicteddifference

*/

if(inCode&8)

predsample-=diffq;

else

predsample+=diffq;

/*Checkforoverflowofthenewpredictedsample

*/

if(predsample>32767)

predsample=32767;

elseif(predsample

predsample=-32768;

/*Findnewquantizerstepsizeindexbyaddingtheoldindex

toatablelookupusingtheADPCMcode

*/

index+=indexTable[inCode];

/*Checkforoverflowofthenewquantizerstepsizeindex

*/

if(index<0)

index=0;

if(index>88)

index=88;

/*ReturnthenewADPCMcode*/

Samp=predsample;

if(Samp>=0)

{

SampH=Samp/256;

SampL=Samp-256*SampH;

}

else

{

Samp=32768+Samp;

SampH=Samp/256;

SampL=Samp-256*SampH;

SampH+=0x80;

}

outbuff[j++]=SampL;

outbuff[j++]=SampH;

}

/*Savethepredictedsampleandquantizerstepsizeindexfor

nextiteration

*/

state->valprev=(short)predsample;

state->index=(char)index;

}

2、adpcm.h文件代码

#ifndefADPCM_H

#defineADPCM_H

#ifdef__cplusplus

extern"C"{

#endif

structadpcm_state{

shortvalprev;/*Previousoutputvalue*/

charindex;/*Indexintostepsizetable*/

};

voidadpcm_decoder(char*inbuff,char*outbuff,intlen_of_in,structadpcm_state*state);

#ifdef__cplusplus

}/*extern"C"*/

#endif

#endif/*ADPCM_H*/

3、main.c文件代码

#include"stdio.h"

#include"stdlib.h"

#include"adpcm.h"

#defineCFG_BlkSize256

charch[CFG_BlkSize];//用来存储wav文件的头信息

charsavedata[CFG_BlkSize*4];

unsignedcharRiffHeader[]={

'R','I','F','F',//ChunkID(RIFF)

0x70,0x70,0x70,0x70,//Chunkpayloadsize(calculateafterrec!)

'W','A','V','E',//RIFFresourceformattype

'f','m','t','',//ChunkID(fmt)

0x10,0x00,0x00,0x00,//Chunkpayloadsize(0x14=20bytes)

0x01,0x00,//FormatTag()

0x01,0x00,//Channels(1)

0x40,0x1f,0x00,0x00,//SampleRate,=16.0kHz

0x80,0x3e,0x00,0x00,//Byterate32.0K

0x02,0x00,//BlockAlign==NumChannels*BitsPerSample/8

0x10,0x00//BitsPerSample

};

unsignedcharRIFFHeader504[]={

'd','a','t','a',//ChunkID(data)

0x70,0x70,0x70,0x70//Chunkpayloadsize(calculateafterrec!)

};

/****************************************************************

函数名称:main

功能描述:

输入参数:none

输出参数:none

****************************************************************/

voidmain(void)

{

FILE*fpi,*fpo;

unsignedlongiLen,temp;

structadpcm_stateADPCMstate;

unsignedlongi=0;

unsignedlongj;

fpi=fopen("f:\\lk\\test.adpcm","rb");//为读,打开一个wav文件

if((fpi=fopen("f:\\lk\\test.adpcm","rb"))==NULL)//若打开文件失败,退出

{

printf("can'topenthisfile\n");

printf("\nreaderror!\n");

printf("\n%d\n",i);

exit(0);

}

fseek(fpi,0,SEEK_END);

iLen=ftell(fpi);

printf("\n======================================================\n");

printf("\n========================%d========================\n",iLen);

printf("\n======================================================\n");

if((iLen-44)%CFG_BlkSize)

iLen=(iLen-44)/CFG_BlkSize+1;

else

iLen=(iLen-44)/CFG_BlkSize;

fpo=fopen("f:\\lk\\new.pcm","rb+");//为写,打开一个wav文件

if((fpo=fopen("f:\\lk\\new.pcm","rb+"))==NULL)//若打开文件失败,退出

{

printf("can'topenthisfile\n");

printf("\nwriteerror!\n");

exit(0);

}

fseek(fpo,0,SEEK_SET);

fwrite(RiffHeader,sizeof(RiffHeader),1,fpo);//写文件riff

fwrite(RIFFHeader504,sizeof(RIFFHeader504),1,fpo);//写data块头

while(i

{

fseek(fpi,48+i*CFG_BlkSize,SEEK_SET);

fread(ch,1,CFG_BlkSize,fpi);

printf("\n======================================================\n");

for(j=0;j<100;j++)

printf("|%d|",ch[j]);

printf("\n======================================================\n");

添加读取BlockHeader部分开始

if(i==0)

{

ADPCMstate.index=0;//第一个block的index为0当前的BlockSize为256即采样点数为(256-4)*2+1=505

}

else

{

ADPCMstate.index=ch[2];

}

ADPCMstate.valprev=(short)ch[0]+((short)(ch[1]))*256;//每一个block里面帧头有一个未压缩的数据存储时先低后高

savedata[0]=ch[0];//存储第一个没有被压缩的数据

savedata[1]=ch[1];//存储第一个没有被压缩的数据

添加读取BlockHeader部分结束

adpcm_decoder(&ch[4],&savedata[2],CFG_BlkSize-4,&ADPCMstate);//解码出来了(256-4)*4个字节

temp=(CFG_BlkSize-4)*4+2;

fseek(fpo,44+i*temp,SEEK_SET);//开始写声音数据

fwrite(savedata,temp,1,fpo);

i++;

}

temp*=i;

RiffHeader[4]=(unsignedchar)((40+temp)&0x000000ff);

RiffHeader[5]=(unsignedchar)(((40+temp)&0x0000ff00)>>8);

RiffHeader[6]=(unsignedchar)(((40+temp)&0x00ff0000)>>16);

RiffHeader[7]=(unsignedchar)(((40+temp)&0xff000000)>>24);

fseek(fpo,4,SEEK_SET);

fwrite(&RiffHeader[4],4,1,fpo);

RiffHeader[40]=(unsignedchar)(temp&0x000000ff);

RiffHeader[41]=(unsignedchar)((temp&0x0000ff00)>>8);

RiffHeader[42]=(unsignedchar)((temp&0x00ff0000)>>16);

RiffHeader[43]=(unsignedchar)((temp&0xff000000)>>24);

fseek(fpo,40,SEEK_SET);

fwrite(&RiffHeader[40],4,1,fpo);

fclose(fpi);

fclose(fpo);

printf("\n==========================OK!=========================\n");

}

四、以上是给出的代码,绝对管用,读者在实验时候请在vc++6.0环境下建立工程,实验时候请在f:\\lk\\下放置一个adpcm格式的文件和一个空的pcm格式文件,当然了这个pcm和adpcm其实都是wav格式的,试验者可以随意命名格式,我为了区分才这样命名后缀的,希望我总结的能够读者带来帮助,谢谢您的阅读!

如果觉得《java pcm转adpcm_音频编码(PCM ADPCM WAVE文件)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。