标签:64位 tput tps col kali 代码 http its close
#include <stdio.h> #include <string.h> /** * Convert PCM raw data to WAVE format * @param pcmpath Input PCM file. * @param channels Channel number of PCM file. * @param sample_rate Sample rate of PCM file. * @param wavepath Output WAVE file. */ int transform_pcm_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath) { typedef struct WAVE_HEADER{ char fccID[4]; //内容为"RIFF" unsigned int dwSize; //最后填写,WAVE格式音频的大小 char fccType[4]; //内容为"WAVE" }WAVE_HEADER; typedef struct WAVE_FMT{ char fccID[4]; //内容为"fmt " unsigned int dwSize; //内容为WAVE_FMT占的字节数,为16 short int wFormatTag; //如果为PCM,改值为 1 short int wChannels; //通道数,单通道=1,双通道=2 unsigned int dwSamplesPerSec;//采样频率 unsigned int dwAvgBytesPerSec;/* ==dwSamplesPerSec*wChannels*uiBitsPerSample/8 */ short int wBlockAlign;//==wChannels*uiBitsPerSample/8 short int uiBitsPerSample;//每个采样点的bit数,8bits=8, 16bits=16 }WAVE_FMT; typedef struct WAVE_DATA{ char fccID[4]; //内容为"data" unsigned int dwSize; //==NumSamples*wChannels*uiBitsPerSample/8 }WAVE_DATA; if(channels==2 || sample_rate==0) { channels = 2; sample_rate = 44100; } WAVE_HEADER pcmHEADER; WAVE_FMT pcmFMT; WAVE_DATA pcmDATA; short int m_pcmData; FILE *fp, *fpout; fp = fopen(pcmpath, "rb+"); if(fp==NULL) { printf("Open pcm file error.\n"); return -1; } fpout = fopen(wavepath, "wb+"); if(fpout==NULL) { printf("Create wav file error.\n"); return -1; } /* WAVE_HEADER */ memcpy(pcmHEADER.fccID, "RIFF", 4); memcpy(pcmHEADER.fccType, "WAVE", 4); fseek(fpout, sizeof(WAVE_HEADER), 1); //1=SEEK_CUR /* WAVE_FMT */ memcpy(pcmFMT.fccID, "fmt ", 4); pcmFMT.dwSize = 16; pcmFMT.wFormatTag = 0x0001; pcmFMT.wChannels = 1; pcmFMT.dwSamplesPerSec = 16000; pcmFMT.uiBitsPerSample = 16; /* ==dwSamplesPerSec*wChannels*uiBitsPerSample/8 */ pcmFMT.dwAvgBytesPerSec = pcmFMT.dwSamplesPerSec*pcmFMT.wChannels*pcmFMT.uiBitsPerSample/8; /* ==wChannels*uiBitsPerSample/8 */ pcmFMT.wBlockAlign = pcmFMT.wChannels*pcmFMT.uiBitsPerSample/8; fwrite(&pcmFMT, sizeof(WAVE_FMT), 1, fpout); /* WAVE_DATA */ memcpy(pcmDATA.fccID, "data", 4); pcmDATA.dwSize = 0; fseek(fpout, sizeof(WAVE_DATA), 1); fread(&m_pcmData, sizeof(short int), 1, fp); while(!feof(fp)) { pcmDATA.dwSize += sizeof(short int); fwrite(&m_pcmData, sizeof(short int), 1, fpout); fread(&m_pcmData, sizeof(short int), 1, fp); } //
// pcmDATA.dwSize 表示pcm文件的大小,单位是字节,http://soundfile.sapp.org/doc/WaveFormat/ 中给出的计算方法是NumSamples * NumChannels * BitsPerSample/8
// 试了一下不行,只能播出大概一秒的时间,我觉得上面那个公式 * 秒数就能表示pcm中数据的字节数了。 // pcmDATA.dwSize = (unsigned int)(pcmFMT.dwSamplesPerSec * (unsigned int)pcmFMT.wChannels * (unsigned int)pcmFMT.uiBitsPerSample / 8); pcmHEADER.dwSize = 36 + pcmDATA.dwSize; rewind(fpout); fwrite(&pcmHEADER, sizeof(WAVE_HEADER), 1, fpout); fseek(fpout, sizeof(WAVE_FMT), SEEK_CUR); fwrite(&pcmDATA, sizeof(WAVE_DATA), 1, fpout); fclose(fp); fclose(fpout); return 0; } int main() { transform_pcm_to_wave("/freeswitch/scripts/file/tts_resp_audio.pcm", 1, 16000, "/freeswitch/scripts/file/tts_resp_pcm_to_wav.wav"); return 0; }
本文的代码适用于64位的编译器。对于位数不同的编译器,就需要更改下这段代码结构体中字段的数据类型,以满足wav头文件的规范(对每个字段的字节数都有详细的描述),可参考文献【1】【3】。
【1】https://blog.csdn.net/lyl0625/article/details/7350045
【2】https://blog.csdn.net/zhangxinbin5/article/details/7929591
【3】http://soundfile.sapp.org/doc/WaveFormat/
【4】https://blog.csdn.net/xiunai78/article/details/6867331
【5】https://blog.csdn.net/u010011236/article/details/53026127#commentBox
标签:64位 tput tps col kali 代码 http its close
原文地址:https://www.cnblogs.com/Allen-win/p/9940242.html