分享

A

 oskycar 2013-11-11

(此文来自互联网,写得比较粗俗易懂,我补充了一些注释)

这里没有做编码转换, 只是给LAW PCM数据加上了wav文件头。

A law PCM 和unsigned PCM互相转换可以参考G711手册, 或者留言找我。

PCM(脉冲编码调制),是国际电信联盟订定出来的一套语音压缩标准,主要用于电话。它主要用脉冲编码调制对音频采样,采样率为8k每秒。它利用一个 64Kbps 未压缩通道传输语音讯号。起压缩率为1:2,即把16位数据压缩成8位。G.711是主流的波形声音编解码器。

  G.711 标准下主要有两种压缩算法。一种是μ-law algorithm (又称often u-law, ulaw, mu-law),主要运用于北美和日本;另一种是A-law algorithm,主要运用于欧洲和世界其他地区。

中国使用的是A-law algorithm。

公司的HXD09语音交换机使用的就是A-law PCM作为语音文件存储格式,但是没有加入wav文件头, 不能直接用Media Player播放,非常不方便。

如果是LINUX操作系统,加上下面两句

typedef unsigned short WORD;
typedef unsigned long DWORD;

其实给这些文件加上wav文件头即可用Media Player播放, 很简单吧。

// Define WAVE File Header
struct tagHXD_WAVFLIEHEAD
{
CHAR RIFFNAME[4];
DWORD nRIFFLength;
CHAR WAVNAME[4];
CHAR FMTNAME[4];
DWORD nFMTLength;
WORD nAudioFormat;
WORD nChannleNumber;
DWORD nSampleRate;
DWORD nBytesPerSecond;
WORD nBytesPerSample;
WORD nBitsPerSample;
CHAR DATANAME[4];
DWORD nDataLength;
};

typedef tagHXD_WAVFLIEHEAD HXD_WAVFLIEHEAD;

int a_law_pcm_to_wav(const char *pcm_file, const char *wav)
{
// 开始准备WAV的文件头
HXD_WAVFLIEHEAD DestionFileHeader;
DestionFileHeader.RIFFNAME[0] = 'R';
DestionFileHeader.RIFFNAME[1] = 'I';
DestionFileHeader.RIFFNAME[2] = 'F';
DestionFileHeader.RIFFNAME[3] = 'F';

DestionFileHeader.WAVNAME[0] = 'W';
DestionFileHeader.WAVNAME[1] = 'A';
DestionFileHeader.WAVNAME[2] = 'V';
DestionFileHeader.WAVNAME[3] = 'E';

DestionFileHeader.FMTNAME[0] = 'f';
DestionFileHeader.FMTNAME[1] = 'm';
DestionFileHeader.FMTNAME[2] = 't';
DestionFileHeader.FMTNAME[3] = 0x20;
DestionFileHeader.nFMTLength = 16; // 表示 FMT 的长度
DestionFileHeader.nAudioFormat = 6; //这个表示a law PCM

DestionFileHeader.DATANAME[0] = 'd';
DestionFileHeader.DATANAME[1] = 'a';
DestionFileHeader.DATANAME[2] = 't';
DestionFileHeader.DATANAME[3] = 'a';
DestionFileHeader.nBitsPerSample = 8;
DestionFileHeader.nBytesPerSample = 1; //
DestionFileHeader.nSampleRate = 8000; //
DestionFileHeader.nBytesPerSecond = 8000;
DestionFileHeader.nChannleNumber = 1;

// 文件头的基本部分
int nFileLen = 0;
int nSize = sizeof(DestionFileHeader);

FILE *fp_s = NULL;
FILE *fp_d = NULL;

fp_s = fopen(pcm_file, "rb");
if (fp_s == NULL)
return -1;

fp_d = fopen(wav, "wb+");
if (fp_d == NULL)
return -2;


int nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);     //将文件头写入wav文件
if (nWrite != nSize)
{
fclose(fp_s);
fclose(fp_d);
return -3;
}

while( !feof(fp_s))
{
char readBuf[4096];
int nRead = fread(readBuf, 1, 4096, fp_s);    //将pcm文件读到readBuf
if (nRead > 0)
{
fwrite(readBuf, 1, nRead, fp_d);      //将readBuf文件的数据写到wav文件
}

nFileLen += nRead;
}
fseek(fp_d, 0L, SEEK_SET);   //将读写位置移动到文件开头

DestionFileHeader.nRIFFLength = nFileLen - 8 + nSize;
DestionFileHeader.nDataLength = nFileLen;
nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);   //重新将文件头写入到wav文件
if (nWrite != nSize)
{
fclose(fp_s);
fclose(fp_d);
return -4;
}

fclose(fp_s);
fclose(fp_d);

return nFileLen;
}

加上了wave文件头, 就可以直接用winamp打开了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多