1、wav音频文件的格式
wav文件由文件头和采样数据2部分组成。
文件头又分为RIFF(Resource Interchange File Format)、WAVE文件标识段 和 声音数据格式说明段组成。
各段的起始地址分别由RIFF标识符、WAVE标识符、以及波形格式标识符(FMT)标定。
(1)文件头格式
注意:下面的地址是连续的
虽然上图给出的数据标识符起始地址刚好是文件头的末地址+1,但并不代表总是这样。
因此,我们在读取数据时最好是找到数据标识符,该标识符的4个字节刚好是'd'、‘a’、‘t’、‘a’。
(2)数据格式
wav结构体定义:
typedef struct _wave_pcm_hdr {char riff[4]; //资源交换文件标志int size_8; //从下个地址开始到文件结尾的字节数 char wave[4]; //wave文件标识 char fmt[4]; //波形格式标识 int fmt_size;//过滤字节(一般为00000010H) short int formate_tag; //格式种类,值为1时,表示PCM线性编码 short int channels; //通道数,单声道为1,双声道为2 int samples_per_sec; //采样频率 int avg_bytes_per_sec;//数据传输率 (每秒字节=采样频率×每个样本字节数) short int block_align; //块对齐字节数 = channles * bit_samp / 8 short int bits_per_sample; //bits per sample (又称量化位数) char data[4];int data_size; }_wave_pcm_hdr; _wave_pcm_hdr default_wave_hdr= {{ 'R', 'I', 'F', 'F' },0,{ 'W', 'A', 'V', 'E' },{ 'f', 'm', 't', ' ' },16,1,1,16000,32000,2,16,{ 'd', 'a', 't', 'a' },0};
代码:
#include "stdafx.h" #include "msp_cmn.h" #include "msp_errors.h" #include "qtts.h" #include <string> #include <Windows.h> #ifdef _WIN64 #pragma comment (lib,"msc_x64.lib") #else #pragma comment (lib,"msc.lib") #endif // _WIN64#pragma comment(lib,"WinMM.lib") typedef struct _wave_pcm_hdr {char riff[4]; //资源交换文件标志int size_8; //从下个地址开始到文件结尾的字节数 char wave[4]; //wave文件标识 char fmt[4]; //波形格式标识 int fmt_size;//过滤字节(一般为00000010H) short int formate_tag; //格式种类,值为1时,表示PCM线性编码 short int channels; //通道数,单声道为1,双声道为2 int samples_per_sec; //采样频率 int avg_bytes_per_sec;//数据传输率 (每秒字节=采样频率×每个样本字节数) short int block_align; //块对齐字节数 = channles * bit_samp / 8 short int bits_per_sample; //bits per sample (又称量化位数) char data[4];int data_size; }_wave_pcm_hdr; _wave_pcm_hdr default_wave_hdr= {{ 'R', 'I', 'F', 'F' },0,{ 'W', 'A', 'V', 'E' },{ 'f', 'm', 't', ' ' },16,1,1,16000,32000,2,16,{ 'd', 'a', 't', 'a' },0};int _tmain(int argc, _TCHAR* argv[]) {const char* usr = NULL;const char* pwd = NULL;const char* lgi_param = "appid = 58610d7f";int ret = MSPLogin(usr, pwd, lgi_param);if (MSP_SUCCESS != ret){printf("MSPLogin failed, error code is: %d", ret);}const char * ssb_param = "voice_name = xiaoyan, aue = speex-wb;7, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";ret = -1;const char * sessionID = QTTSSessionBegin(ssb_param, &ret);if (MSP_SUCCESS != ret){printf("QTTSSessionBegin failed, error code is : %d", ret);}const char* src_text;char ch[1000];src_text=gets(ch);unsigned int text_len = strlen(src_text); //textLen参数为合成文本所占字节数ret = QTTSTextPut(sessionID, src_text, text_len, NULL);if (MSP_SUCCESS != ret){printf("QTTSTextPut failed, error code is : %d", ret);}FILE* fp = fopen("112.wav", "wb");fwrite(&default_wave_hdr, sizeof(default_wave_hdr),1,fp);unsigned int audio_len = 0;int synth_status = 0;while (1){const void * data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);if (NULL != data){fwrite(data, audio_len, 1, fp);default_wave_hdr.data_size += audio_len;}if (MSP_TTS_FLAG_DATA_END == synth_status || MSP_SUCCESS != ret){break;}}fclose(fp);default_wave_hdr.size_8 += default_wave_hdr.data_size + (sizeof(default_wave_hdr) - 8);fseek(fp, 4, 0);fwrite(&default_wave_hdr.size_8, sizeof(default_wave_hdr.size_8), 1, fp);fseek(fp, 40, 0);fwrite(&default_wave_hdr.data_size, sizeof(default_wave_hdr.data_size), 1, fp);fclose(fp);ret = QTTSSessionEnd(sessionID, "normal end");if (MSP_SUCCESS != ret){printf("QTTSSessionEnd failed, error code is : %d", ret);}PlaySoundA("qweqwr.wav", NULL, SND_ALIAS);ret = MSPLogout();if (MSP_SUCCESS != ret){printf("MSPLogout failed, error code is: %d", ret);}system("pause");return 0; }
代码
转载于:https://www.cnblogs.com/ye-ming/p/7851851.html