> 文档中心 > VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例

VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例

VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例

  • 前言
  • 一. 工程实现
  • 二. 生成编译
  • 三. 小结

前言

语音识别相关算法一般在MATLAB上进行仿真验证与实验,在工程上一般还是在VS中进行实现落地,本系列将介绍语音信号处理在C语言中的一系列应用,后期将以此为基础,再落地移植到嵌入式平台。

今天介绍PCM格式语音存为WAV格式语音的工程应用。两种格式语音的唯一区别在于WAV语音包含文件头信息,而PCM格式语音仅包含语音数据流。语音格式转换也算是一种比较常见的应用,可以让我们更好的理解语音文件的格式信息。

一. 工程实现

打开VS2015
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
点击新建一个项目(工程),输入项目名:Pcm2wav
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
点击“确定”,创建项目
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
左侧解决方案资源管理器视图中,源文件栏右键添加新建项,
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
点击C++文件,新建一个源文件Pcm2wav.cpp,点击“添加”
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
输入代码如下:

// // Pcm2wav.cpp// pcm格式语音转存为wav格式语音文件// date:2022-5-9 22:32:21// author : C.S#include   #include   #include #pragma warning (disable :4996)#define  uint32_tunsigned int  #define  uint16_tunsigned short   typedef struct _riff_t {char riff[4];/* "RIFF" (ASCII characters) */uint32_t len;/* Length of package (binary, little endian) */char wave[4];/* "WAVE" (ASCII characters) */} riff_t;/* The FORMAT chunk */typedef struct _format_t {char  fmt[4];/* "fmt_" (ASCII characters) */uint32_t   len;/* length of FORMAT chunk (always 0x10) */uint16_t  type;/* codec type*/uint16_t channel;/* Channel numbers (0x01 = mono, 0x02 = stereo) */uint32_t   rate;/* Sample rate (binary, in Hz) */uint32_t   bps;/* Average Bytes Per Second */uint16_t blockalign;/*number of bytes per sample */uint16_t bitpspl;/* bits per sample */} format_t;typedef struct _data_t {char data[4];   /* "data" (ASCII characters) */uint32_t len;  /* length of data */}data_t;typedef struct _wav_head{riff_t riff;format_t format;data_t   data;}wav_head;int main(int argc, char **argv){/*char src_file[128] = { 0 };char dst_file[128] = { 0 };*/char *src_file = "test.pcm";char *dst_file = "test.wav";int channels = 2;int bits = 16;int sample_rate = 48000;//以下是为了建立.wav头而准备的变量    wav_head header;FILE   *fp, *fpCpy;printf("parameter analyse succeess\n");if ((fp = fopen(src_file, "rb")) == NULL) //读取文件    {printf("open pcm file %s error\n", argv[1]);return -1;}if ((fpCpy = fopen(dst_file, "wb")) == NULL) //为转换建立一个新文件    {printf("create wav file error\n");return -1;}//以下是创建wav头的HEADER;但.dwsize未定,因为不知道Data的长度。    memcpy(header.riff.riff, "RIFF", 4);memcpy(header.riff.wave, "WAVE", 4);//以上是创建wav头的HEADER;    if (ferror(fpCpy)){printf("error\n");}memcpy(&header.format.fmt, "fmt ", 4);header.format.len = 0x10;header.format.type = 0x1;header.format.channel = channels;header.format.rate = sample_rate;header.format.bps = sample_rate * bits / 8 * channels;header.format.blockalign = bits / 8 * channels;header.format.bitpspl = bits;memcpy(&header.data.data, "data", 4);fseek(fp, 0, SEEK_END);long count = ftell(fp);fseek(fp, 0, SEEK_SET);printf("length:%ud", count);header.data.len = (uint32_t)count;header.riff.len = header.data.len + 36;int size = sizeof(header);fwrite(&header, sizeof(header), 1, fpCpy);char *buffer = (char *)malloc((count) * sizeof(char));fread(buffer, 1, count, fp);fwrite(buffer, 1, count, fpCpy);free(buffer);fclose(fp);      //关闭文件    fclose(fpCpy);   //关闭文件    return 0;}

二. 生成编译

点击目录栏“生成”中“生成解决方案”
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
生成成功!找一个PCM格式语音,命名为test.pcm,放在Pcm2wav.cpp同目录下,点击调试运行,生成一个test.wav文件,调用成功。
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
VS语音信号处理(5) C语言PCM格式语音存为WAV格式语音工程实例
可以看到生成的test.wav大小与test.pcm基本相同,即WAV语音数据生成成功。

三. 小结

最近项目上需要对语音信号进行处理,这个是对语音格式进行转换的工程,相对也比较简单,值得注意的是,如果没有将test.pcm导入的话,工程不会报警提示,所以有需要的同学在应用的时候需要注意一下,没有源语音是得不到wav语音的。另外,进行变换前需确认PCM格式语音的采样率,通道数,位数等信息,否则生成的WAV语音听起来将会变调失真。