怎么得到pcm编码的wav音频 PCM音频数据封装为WAV文件

PCM(Pulse Code Modulation,脉冲编码调制),PCM音频数据是指经过采样、量化、编码转换成的未压缩数字音频数据。

WAV最常见的声音文件格式之一,是微软公司专门为Windows开发的一种标准数字音频文件,该文件能记录各种单声道或立体声的声音信息,并能保证声音不失真。

WAV格式组成

怎么得到pcm编码的wav音频 PCM音频数据封装为WAV文件(1)

RIFF(Resource Interchange File Format,资源交换档案标准),是一种把资料储存在被标记的区块(tagged chunks)中的档案格式(meta-format),不同编码的音频/视频流按照RIFF所定义的存储规则保存,在读取播放时,就可以按照RIFF规则分析文件,正常解析出音频/视频流。

示例代码

按照上述定义,声明如下数据结构

C 音视频开发学习资料:点击领取→音视频开发(资料文档 视频教程 面试题)(FFmpeg WebRTC RTMP RTSP HLS RTP)

struct RIFF_t { char ID[4]; uint32_t size; char format[4]; }; struct FMT_t { char ID[4]; uint32_t size; uint16_t audio_format; uint16_t channels; uint32_t sample_rate; uint32_t byte_rate; uint16_t block_align; uint16_t bits_per_sample; }; struct DATA_t { char ID[4]; uint32_t size; //void *data; //此处因为数据需要从文件中边读取边存储,因此为了方便操作,不声明data }; struct PCM_to_WAV_t { char *in_file_name; char *out_file_name; FILE *in_file; FILE *out_file; uint16_t pcm_data; //保存从PCM文件中读取的数据,因为PCM数据大小必然是16的倍数,所以声明为uint16_t struct RIFF_t riff; struct FMT_t fmt; struct DATA_t data; };

  • 初始化操作

int PCM_to_WAV_Init(PCM_to_WAV_t *p2w, int argc, char** argv) { if (argc == 3) { p2w->in_file_name = argv[1]; p2w->fmt.sample_rate = 44100; p2w->fmt.channels = 2; p2w->fmt.bits_per_sample = 16; p2w->out_file_name = argv[2]; } else if (argc == 6) { p2w->in_file_name = argv[1]; p2w->fmt.sample_rate = atoi(argv[2]); p2w->fmt.channels = atoi(argv[3]); p2w->fmt.bits_per_sample = atoi(argv[4]); p2w->out_file_name = argv[5]; } else { printf("$.exe $.pcm $sample_rate $channels $bits_per_sample $.wav\n"); printf("Example: $.exe in.pcm 44100 2 16 out.wav\n"); printf("$.exe $.pcm $.wav\n"); printf("Example: $.exe in.pcm out.wav\n"); return -1; } p2w->pcm_data = 0; p2w->in_file = NULL; p2w->out_file = NULL; memcpy(p2w->riff.ID, "RIFF", 4); memcpy(p2w->riff.format, "WAVE", 4); p2w->riff.size = 36; memcpy(p2w->fmt.ID, "fmt ", 4); p2w->fmt.size = 16; p2w->fmt.audio_format = 1; p2w->fmt.byte_rate = p2w->fmt.sample_rate * p2w->fmt.channels * p2w->fmt.bits_per_sample / 8; p2w->fmt.block_align = p2w->fmt.channels * p2w->fmt.bits_per_sample / 8; memcpy(p2w->data.ID, "data", 4); p2w->data.size = 0; return 0; }

  • 转换过程

int PCM_to_WAV(PCM_to_WAV_t *p2w) { p2w->in_file = fopen(p2w->in_file_name, "rb "); p2w->out_file = fopen(p2w->out_file_name, "wb "); if (p2w->in_file == NULL || p2w->out_file == NULL) { printf("open file error\n"); return -1; } fseek(p2w->out_file, sizeof(struct RIFF_t), 1); fwrite(&p2w->fmt, sizeof(struct FMT_t), 1, p2w->out_file); fseek(p2w->out_file, sizeof(struct DATA_t), 1); fread(&p2w->pcm_data, sizeof(uint16_t), 1, p2w->in_file); while (! feof(p2w->in_file) ) { p2w->data.size = 2; fwrite(&p2w->pcm_data, sizeof(uint16_t), 1, p2w->out_file); fread(&p2w->pcm_data, sizeof(uint16_t), 1, p2w->in_file); } p2w->riff.size = p2w->data.size; rewind(p2w->out_file); fwrite(&p2w->riff, sizeof(struct RIFF_t), 1, p2w->out_file); fseek(p2w->out_file, sizeof(struct FMT_t), 1); fwrite(&p2w->data, sizeof(struct DATA_t), 1, p2w->out_file); fclose(p2w->in_file); fclose(p2w->out_file); return 0; }

  • 打印块信息

C 音视频开发学习资料:点击领取→音视频开发(资料文档 视频教程 面试题)(FFmpeg WebRTC RTMP RTSP HLS RTP)

void PCM_to_WAV_Info(PCM_to_WAV_t *p2w) { printf("in file: %s\nout file: %s\n", p2w->in_file_name, p2w->out_file_name); printf("RIFF: \n\tID: %4.4s\n\tsize: %d\n\tformat: %4.4s\n", p2w->riff.ID, p2w->riff.size, p2w->riff.format); printf("FMT: \n\tID: %4.4s\n\tSize: %d\n\tAudio fmt: %d\n\tChannels: %d\n", p2w->fmt.ID, p2w->fmt.size, p2w->fmt.audio_format, p2w->fmt.channels); printf("\tsample rate: %d\n\tByte Rate: %d\n\tBlock Align: %d\n\tBits Per Sample: %d\n", p2w->fmt.sample_rate, p2w->fmt.byte_rate, p2w->fmt.block_align, p2w->fmt.bits_per_sample); printf("DATA: \n\tID: %4.4s\n\tSize: %d\n", p2w->data.ID, p2w->data.size); }

  • 调用

int main(int argc, char **argv) { struct PCM_to_WAV_t pcm2wav; if (PCM_to_WAV_Init(&pcm2wav, argc, argv) != 0) return -1; if (PCM_to_WAV(&pcm2wav) != 0) return -1; PCM_to_WAV_Info(&pcm2wav); return 0; }

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页