最近一周做一个ADPCM算法的调研工作,以前是做电视智能浏览器,所以对这个东西不了解,虽然给我了算法的接口,
使用intel的adpcm_coder/adpcm_decoder进行压缩和解压,参数也能看懂,但是还是不知道参数该如何传进去。
在网上查阅资料,大部分都是讲ADPCM算法的,还有讲把文件分离,以及给文件添加WAVE头的,跟我的需求还是很有出入。
我这边是一个PCM文件的裸流,里面没有文件头, 压缩、 解压,然后使用cooledit播放看看解压后的音频与原始音频是否有
差异。
ADPCM的原理,网上很多,我这里也不赘述, 代码里面要区分8位、16位单声道、16位双声道。
今天我写的代码是16位双声道。 在这里需要注意的是传进去和输出来的char的比例, 因为压缩的比例是1:4,所以我这里定义了一个FRAME_SIZE, 那些乘以4,除以2,千万不能少,不然就会出现问题。
使用cooledit播放音频流的时候,会有选择单声道还是双声道,以及选择多少bit,本程序要选择44100hz,双声道,16bit。
(关于cooledit的使用自己研究下,我也是刚研究一两天)
下面就上程序了(头文件路径自己修改吧,只需要把下面的代码复制粘贴,编译的时候带上adpcm.c文件即可):
1. 压缩PCM裸流,并且解压后把流再保存起来。(PCM裸流使用cooledit是可以播放的, 解压后的也是可以播放的,不然就是有问题)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "adpcm/adpcm.h"
static struct adpcm_state en_state_L,en_state_R,de_state_L,de_state_R;
#define FRAME_SIZE (1600)
// for encode, which includes left channel and right channel.
unsigned char inbuf[FRAME_SIZE*4];
short inencL[FRAME_SIZE];
short inencR[FRAME_SIZE];
unsigned char encbufL[FRAME_SIZE/2];
unsigned char encbufR[FRAME_SIZE/2];
// for decode
short decbufL[FRAME_SIZE];
short decbufR[FRAME_SIZE];
unsigned char outbufL[FRAME_SIZE*4];
unsigned char outbufR[FRAME_SIZE*4];
int main(int argc, char *argv[])
{
FILE *f, *f2;
char fname[64],fname2[64];
if (argc < 3 )
{
exit(-1);
}
strcpy(fname, argv[1]);
strcpy(fname2, argv[2]);
if (NULL == (f2=fopen(fname2,"wb")) )
{
exit(-1);
}
if (NU