這裏沒有做編碼轉換, 只是給RAW 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-lawalgorithm,主要運用於歐洲和世界其他地區。
中國使用的是A-law algorithm。
公司的HXD09語音交換機使用的就是A-lawPCM作爲語音文件存儲格式,但是沒有加入wav文件頭, 不能直接用Media Player播放,非常不方便。
其實給這些文件加上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 lawPCM
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);
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);
if (nRead >0)
{
fwrite(readBuf,1, nRead, fp_d);
}
nFileLen += nRead;
}
fseek(fp_d, 0L, SEEK_SET);
DestionFileHeader.nRIFFLength = nFileLen - 8 +nSize;
DestionFileHeader.nDataLength = nFileLen;
nWrite =fwrite(&DestionFileHeader, 1, nSize, fp_d);
if (nWrite != nSize)
{
fclose(fp_s);
fclose(fp_d);
return -4;
}
fclose(fp_s);
fclose(fp_d);
return nFileLen;
}
加上了wave文件頭, 就可以直接用winamp打開了。
轉自http://blog.sina.com.cn/s/blog_5eb1ba9e0100c7p0.html