技术标签: java pcm转adpcm
二、给个英文参考网址吧
这两个讲的很详细,请仔细阅读!通过阅读我发现细节在与adpcm格式的wav文件的block的特点,每一个block包含header和data两部分,
Typedef struct{
short sample0; //block中第一个采样值(未压缩)
BYTE index; //上一个block最后一个index,第一个block的index=0;
BYTE reserved; //尚未使用
}MonoBlockHeader
关键是我们要抓住每一个block的header里面的信息,即sample0,运算的时候注意运用!
三、还是给个代码吧,多的也不说了!
1、adpcm.c文件代码
#include"adpcm.h"
/* Intel ADPCM step variation table */
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 )
{
int i=0,j=0;
chartmp_data;
structadpcm_state *tmp_state =state;
longstep;/* Quantizer step size */
signedlongpredsample;/* Output of ADPCM predictor */
signedlongdiffq;/* Dequantized predicted difference */
intindex;/* Index into step size table */
intSamp;
unsignedcharSampH,SampL;
unsignedcharinCode;
/* Restore previous values of predicted sample and quantizer step
size index
*/
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];
/* 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;
elseif(predsample
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;
/* Return the new ADPCM code */
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;
}
/* Save the predicted sample and quantizer step size index for
next iteration
*/
state->valprev =(short)predsample;
state->index =(char)index;
}
2、adpcm.h文件代码
#ifndefADPCM_H
#defineADPCM_H
#ifdef__cplusplus
extern"C"{
#endif
struct adpcm_state {
short valprev; /* Previous output value */
char index; /* Index into stepsize table */
};
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_BlkSize 256
charch[CFG_BlkSize]; //用来存储wav文件的头信息
charsavedata[CFG_BlkSize*4];
unsignedcharRiffHeader[]={
'R','I','F','F',// Chunk ID (RIFF)
0x70,0x70,0x70,0x70,// Chunk payload size (calculate after rec!)
'W','A','V','E',// RIFF resource format type
'f','m','t',' ',// Chunk ID (fmt )
0x10,0x00,0x00,0x00,// Chunk payload size (0x14 = 20 bytes)
0x01,0x00, // Format Tag ()
0x01,0x00, // Channels (1)
0x40,0x1f,0x00,0x00,// Sample Rate, = 16.0kHz
0x80,0x3e,0x00,0x00,// Byte rate 32.0K
0x02,0x00, // BlockAlign == NumChannels * BitsPerSample/8
0x10,0x00 // BitsPerSample
};
unsignedcharRIFFHeader504[]={
'd','a','t','a',// Chunk ID (data)
0x70,0x70,0x70,0x70 // Chunk payload size (calculate after rec!)
};
/****************************************************************
函数名称: main
功能描述:
输入参数: none
输出参数: none
****************************************************************/
voidmain(void)
{
FILE *fpi,*fpo;
unsignedlongiLen,temp;
structadpcm_state ADPCMstate;
unsignedlongi =0;
unsignedlongj;
fpi=fopen("f:\\lk\\test.adpcm","rb"); //为读,打开一个wav文件
if((fpi=fopen("f:\\lk\\test.adpcm","rb"))==NULL) //若打开文件失败,退出
{
printf("can't open this file\n");
printf("\nread error!\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't open this file\n");
printf("\nwrite error!\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格式的,试验者可以随意命名格式,我为了区分才这样命名后缀的,希望我总结的能够读者带来帮助,谢谢您的阅读!
柏韵Pureaudio AirDSD Pro audio streaming Pre-amp串流播放解码前级类“牛入牛出” 模拟输入 前级 DSD24.5M PCM768KHz DXD 352.8kHz SACD iso DSDDop 数播 DAC解码 无线WiFi音频 流媒体 DLNA 蓝牙BT5.0Air..._蓝牙解码格式哪个最好
有四种方法制作模板,下边先将前三种制作模板。注意:模板组件里面第一行只能有一个标签,并且结束标签必须在最后一行,否则结束标签之后的html是无法显示的;一:直接在构造器中制作模板,构造器模板 <script> new Vue({ el:'#ele', data:{ mes...
python实验,置换加密解密算法原理实现,文件读取修改,课程实验置换密码加密解密过程,设明文为:4D 61 65 53 2D 4F 69 20 4E。密钥为8,1,6,3,5,7,4,9,2。求加密后的16进制密文。先思考和描述算法,也就是对明文4D 61 65 53 2D 4F 69 20 4E实现置换8,1,6,3,5,7,4,9,2。_换位加密 解密 算法 python
知识点1【链表的概述】(了解)1、数组特点:1、空间连续、元素类型相同、通过下标快速访问2、静态数组:空间一旦确定不能更改(动态数组除外)3、静态、动态数组 插入删除元素 需要移动大量数据2、链表的概述链表是一种物理存储上非连续,数据元素的逻辑连续通过链表节点中的指针变量保存下个节点的地址,实现的一种线性存储结构。3、链表的特点链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成(malloc,calloc),每个节点包 括两个部分:数据域:存放节点数据_如何判断一个链表是否释放成功
为什么选择backtrader我们在投资的过程中,经常会有各种各样的idea。这些idea实际如何?如何评估。这时候我们需要使用历史数据对我们的idea进行回测。但是从零构筑一个回测框架,工作量和对技能的要求比较高。我们也没有必要为了吃个馒头而去种麦子。backtrader是这样一个基于python的回测框架。通过它我们可以快速的对策略进行回测验证我们的Idea。backtrader可以..._back trader
Huffman的特点是每次取出优先队列,也即是堆中最小的两个节点链接成一个新的节点,将新的节点放回到堆中。Huffman树每一个叶子都是一个字符。非叶子节点只是我们生成的节点,不是我们需要编码的字符。#include<iostream>#include<stdlib.h>#include<string.h>#include<queue>..._根据字符的权值进行哈夫曼编码
实战需求SwiftUI ScrollView 自适应屏幕卡片组件本文价值与收获看完本文后,您将能够作出下面的界面看完本文您将掌握的技能掌握 ScrollView掌握 GeometryReader掌握 cornerRadius基础知识ScrollView一个可以滚动的视图struct ScrollView<Content> where Content : View滚动视图在可滚动内容区域内显示其内容。主题创建滚动视图1、init(Axis.Set, sh_swiftui scrollview onappear
打开apache-jmeter-5.0\bin\jmeter.properties 文件修改第三十七行,去掉前面的#,改为language=zh_CN重新打开就是中文界面了_jmeter-captcha语音包
坐标轴最小和最大值¶为了在图表上显示特定区域,可以手动设置坐标轴的最小值和最大值。 from openpyxl import Workbook from openpyxl.chart import ( ScatterChart, Reference, Series, ) wb = Workbook() ws = wb.active ws.append(['X', '1/X']) fo_openpyxl 图表 坐标轴设置
import com.owinfo.utils.basetools.OwinfoStringUtil;import org.springframework.data.redis.core.RedisTemplate;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.awt.image.RenderedImage;import java.io.ByteAr._java redis存入图片验证码时效性验证
原标题:初入审计行业,应该掌握哪些技能?现如今很多审计人员对未来感到很迷茫,这不单单是因为行业发展前景的问题,更多的是不知道怎么才能充实自己,更不知道如何才能让自己在行业中不断进步。其实单凭审计知识是远远不能在这个行业立足的,只有掌握多项技能才能有备无患。增强专业能力专业能力是审计行业发展的基础,目前来看最火热的莫过于注册会计师考试。其实说实话CPA这个东西不知道让多少人愁白了头,它是一个繁杂且漫...
标题 箭头函数指向来看看this的一个使用案例:1.在函数中,settimeout没有被调用,指向window:2.箭头函数中,this指向定义时的this,而不是执行是的this:3.多层嵌套箭头函数:4.外层this指向window,内层this也会指向window:5.箭头函数,非箭头函数混合情况:...