(此文来自互联网,写得比较粗俗易懂,我补充了一些注释) 这里没有做编码转换, 只是给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打开了。
|