【音视频数据数据处理 10】【PCM篇】将PCM转为WAV格式音频

  • 一、WAV头信息
    • 1.1 RIFF区块
    • 1.2 FORMAT区块
    • 1.3 DATA区块
  • 二、PCM 转 WAV 代码实现

PCM转为WAV格式是相对比较简单的,因为WAV格式的内容其实就是PCM数据,
所以在PCM 的基础上加上一个WAV头信息,就成了播放器认识的wav文件了。

好,写代码前,我们来认识一下WAV头信息。

一、WAV头信息

WAV文件遵循RIFF规则,其内容以区块(chunk)为最小单位进行存储。
WAV文件一般由3个区块组成:RIFF chunk、Format chunk 和 Data chunk。
另外,文件中还可能包含一些可选的区块,如:Fact chunk、Cue points chunk、Playlist chunk、Associated data list chunk等。

常见的wave文件的格式图示:

1.1 RIFF区块

大端存储的机器环境上(高位存在低位,低位存在高位)
小端存储的机器环境上(高位存在高位,低位存在低位)

名称 偏移地址 字节数 端序 内容
ID 0x00 4Byte 大端 ‘RIFF’ (0x52494646)
Size 0x04 4Byte 小端 fileSize - 8
Type 0x08 4Byte 大端 ‘WAVE’(0x57415645)
  • 以’RIFF’为标识
  • Size是整个文件的长度减去ID和Size的长度
  • Type是WAVE表示后面需要两个子块:Format区块和Data区块

1.2 FORMAT区块

名称 偏移地址 字节数 端序 内容
ID 0x00 4Byte 大端 'fmt ’ (0x666D7420)
Size 0x04 4Byte 小端 16
AudioFormat 0x08 2Byte 小端 音频格式
NumChannels 0x0A 2Byte 小端 声道数
SampleRate 0x0C 4Byte 小端 采样率
ByteRate 0x10 4Byte 小端 每秒数据字节数
BlockAlign 0x14 2Byte 小端 数据块对齐
BitsPerSample 0x16 2Byte 小端 采样位数
  • 以’fmt '为标识
  • Size表示该区块数据的长度(不包含ID和Size的长度)
  • AudioFormat表示Data区块存储的音频数据的格式,PCM音频数据的值为1
  • NumChannels表示音频数据的声道数,1:单声道,2:双声道
  • SampleRate表示音频数据的采样率
  • ByteRate每秒数据字节数 = SampleRate * NumChannels * BitsPerSample / 8
  • BlockAlign每个采样所需的字节数 = NumChannels * BitsPerSample / 8
  • BitsPerSample每个采样存储的bit数,8:8bit,16:16bit,32:32bit

1.3 DATA区块

名称 偏移地址 字节数 端序 内容
ID 0x00 4Byte 大端 ‘data’ (0x64617461)
Size 0x04 4Byte 小端 N
Data 0x08 NByte 小端 音频数据

好,至此清楚格式了,我们来写代码吧。

二、PCM 转 WAV 代码实现

#include <stdio.h>
#include <stdlib.h>char name[]="tiankongzhicheng_44100_2ch_16bit.pcm"; typedef struct wav_riff{__int8  id[4];__int32 size;__int8   type[4];
}wav_riff;typedef struct wav_format{__int8  id[4];__int32 size;__int16 audioformat;__int16 numchannels;__int32 samplerate;__int32 byterate;__int16 blockalign;__int16 bitspersample;
}wav_format;typedef struct wav_data{__int8 id[4];__int32 size;
}wav_data;void split_PCM(int ch, int bit, int bps)
{unsigned char data[2];int size = ch * bit * bps / 8, num;wav_riff riff;wav_format format;wav_data data_;FILE *pcm = fopen(name, "rb+");FILE *wav = fopen("16000_2ch_16bit.wav","wb+");   // 申请两个声道的数据unsigned char *buff = (unsigned char*)malloc(4);// 填充 wav_riff 头信息( ‘RIFF’ (0x52494646) 大端存储,先高位 )riff.id[0] = 'R'; riff.id[1] = 'I';riff.id[2] = 'F';riff.id[3] = 'F';riff.size = sizeof(wav_riff) + sizeof(wav_format) ;       // riff.type[0] = 'W';   // (WAVE  0x57415645)riff.type[1] = 'A'; riff.type[2] = 'V';  riff.type[3] = 'E';num = fwrite(&riff,  sizeof(wav_riff),1, wav);printf("写入wav_riff %d 个字节\n", sizeof(wav_riff)); // 填充 wav_format 头信息  'fmt ’ (0x666D7420)format.id[0] = 'f';format.id[1] = 'm';format.id[2] = 't';format.id[3] = ' ';format.size = 16;format.audioformat = 1;    //pcmformat.numchannels = 2;format.samplerate = 44100;format.byterate = 4 * 44100;  //2 * 44100 * 16 / 8;format.blockalign = 4;          //ch * bit / 8;format.bitspersample = 16;num = fwrite(&format, sizeof(wav_format),1,  wav);printf("写入wav_format %d 个字节\n", sizeof(wav_format)); //写入Data 区块  ‘data’ (0x64617461)data_.id[0] = 'd'; data_.id[1] = 'a';data_.id[2] = 't';data_.id[3] = 'a';data_.size = 0;num = fwrite(&data_,  sizeof(wav_data),1, wav);printf("写入wav_data %d 个字节\n", sizeof(wav_data)); fread(buff, 1, 4, pcm);while(!feof(pcm)){// 写入pcm 数据data_.size += fwrite(buff, 1, 4, wav);   fread(buff, 1, 4, pcm);}printf("写入pcm  %d个字节\n",data_.size);// 配置文件大小 riff.size = data_.size + sizeof(wav_riff) + sizeof(wav_format) + sizeof(wav_data);rewind(wav);      // 设置文件位置为给定流 stream 的文件的开头// 重写 wav 头信息 num = fwrite(&riff,  sizeof(wav_riff),1, wav);printf("写入wav_riff %d 个字节\n", sizeof(wav_riff)); num = fwrite(&format, sizeof(wav_format),1, wav);printf("写入wav_format %d 个字节\n", sizeof(wav_format)); num = fwrite(&data_,  sizeof(wav_data), 1, wav);   // 注意,该重写很重要,如果播放时数据大小 data_.size=0,播放失败 printf("写入wav_data %d 个字节\n", sizeof(wav_data)); free(buff);fclose(wav);fclose(pcm);
}int main(void)
{split_PCM(2, 16, 44100);printf("程序结束\n");return 0;
}

转换完毕,播放 wav 音乐:

《WAV文件格式详解》
《视音频数据处理入门:PCM音频采样数据处理》

【音视频数据数据处理 10】【PCM篇】将PCM转为WAV格式音频相关推荐

  1. 【音视频数据数据处理 14】【FLV篇】解析FLV视频码流,并分离FLV中的视频及MP3音频文件

    [音视频数据数据处理 14][FLV篇]解析FLV视频码流,并分离FLV中的视频及MP3音频文件 一.FLV封装原理 1.1 Tag Data 1.1.1 Audio Tag Data结构(音频Tag ...

  2. 【音视频数据数据处理 12】【H.264篇】解析H.264原始码流中的I帧 / P帧 / B帧数据(暂未解决,本文先放着,来日更新)

    [音视频数据数据处理 12][H.264篇]解析H.264原始码流中的I帧 / P帧 / B帧数据 一.如何判断是 I帧 / P帧 / B帧 1.1 slice_type 1.2 slice_head ...

  3. 【音视频数据数据处理 7】【RGB/BMP篇】生成24色 RGB24图 和 BMP图

    [音视频数据数据处理 7][RGB篇]生成一张24色 RGB24图 和 BMP图 一.生成24色 RGB24图代码实现 二.生成24色 BMP图代码实现 先上24色图,及其对应的RGB值. 本文地址: ...

  4. 【音视频数据数据处理 1】【YUV篇】分离YUV420P像素数据中的Y、U、V分量

    [音视频数据数据处理 1][YUV篇]分离YUV420P像素数据中的Y.U.V分量 一.YUV420P 数据格式介绍 二.分离YUV420P像素数据中的Y.U.V分量 - 代码实现 三.查看生成的YU ...

  5. [Android] [音视频系列]在 Android 平台使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现读写音频 wav 文件

    参考 官方文档地址:https://developer.android.google.cn/reference/android/media/AudioRecord GitHub 地址:https:// ...

  6. 1小时学会:最简单的iOS直播推流(三)使用系统接口捕获音视频数据

    最简单的iOS 推流代码,视频捕获,软编码(faac,x264),硬编码(aac,h264),美颜,flv编码,rtmp协议,陆续更新代码解析,你想学的知识这里都有,愿意懂直播技术的同学快来看!! 源 ...

  7. 音视频方案,音视频扩展内容- 音视频数据解析,码流分析及质量评价(笔记)3

    -- 音视频编解码流程如下图: -- 关于音频各种参数: freq:音频数据的采样率.常用的有48000,44100等. format:音频数据的格式.举例几种格式: AUDIO_U16SYS:Uns ...

  8. vlc-android对于通过Live555接收到音视频数据包后的处理分析

    转载地址:https://blog.csdn.net/c_m_deng/article/details/8487456 通过ndk-gdb跟踪调试vlc-android来分析从连接到RTSP服务器并接 ...

  9. 音视频开发(23)---音视频直播技术--10分钟搭建好直播平台

    音视频直播技术--10分钟搭建好直播平台 前言 今天给大家讲一下如何搭建最简单的音视频直播平台.在之前的文章中我已经给大家介绍过音视频直播技术架构,没看过的同学可以看一下.了解了直播的技术架构,我们就 ...

最新文章

  1. upstream--负载
  2. 相信自己,我能2 — ORM 工具的插入性能比较
  3. Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法
  4. google Chrome 浏览器源码地址地址!
  5. 基于SpringBoot+Vue开发的前后端分离博客项目-Java后端接口开发
  6. mysql 命令行怎么格式化_dbForge Data Compare for MySQL入门教程:通过命令行格式化代码...
  7. 计算机网络大连理工大学,大连理工大学计算机网络.doc
  8. R语言数据清理:视频游戏数据案例研究
  9. 如何做好项目的需求与业务调研?
  10. sodp软件如何导入多个工作面信息_如何批量导入数据到手机通讯录
  11. iphone手机屏幕投射电脑 简单几步教你完成
  12. 阿里云抢月饼代码实验,自己写着玩的
  13. the JDBC Driver has been forcibly unregistered问题解决
  14. 【大数据】城市公交网络分析与可视化(四):绘制城市公交(地铁)线路图
  15. Code Review应该关注哪些点?
  16. DW_axi_dmac控制器(术语)
  17. linux install jkd
  18. 奇数页 偶数页 页脚不一致怎么处理
  19. 电力系统微网故障检测数据集及代码python
  20. 数据结构:递归(迷宫回溯、八皇后)

热门文章

  1. hadoop详细安装及配置
  2. CALL和RET指令
  3. 蔡依林(Jolin) 2008 北京演唱会
  4. 2022年A特种设备相关管理(电梯)考试试题及在线模拟考试
  5. 第二届“金陀螺”奖揭晓,完整获奖名单公布!
  6. android 仿全民k歌 线谱乐谱音高图
  7. keyshot导入失败错误代码7_keyshot7的一些问题
  8. 用薛定谔软件(schrodinger)做交叉对接(CROSSING DOCKING)
  9. DeepDive 简介
  10. 论文见解之RCF:Richer Convolutional Features for Edge Detection