PCM音频数据格式介绍
http://blog.csdn.net/ljxt523/article/details/52068241
1. What is PCM?
PCM(Pulse-code-modulation)是模拟信号以固定的采样频率转换成数字信号后的表现形式。
Sample Rate :
采样频率单位为:Hz。采样频率越高,音频质量越好,占用空间也越大。
Sign :
音频数据是否是有符号的。通常情况下都是有符号的。若是将有符号的数据当做无符号的数据来处理将会使声音听来很刺
Sample Size :
表示每一个采样数据的大小。通常该值为16-bit。
Byte Ordering :
字节序指的是little-endian还是big-endian。表示音频数据的存储字节序。通常均为little-endian。
Number of Channels :
标识音频是单声道(mono,1 channel)还是立体声(stereo,2 channels)。
通过以上五个数据我们就可以描述一个PCM数据,播放一个PCM数据需要的就是以上五个数据。
2. What does a PCM stream look like?
单声道:
- +------+------+------+------+------+------+------+------+------+
- | 500 | 300 | -100 | -20 | -300 | 900 | -200 | -50 | 250 |
- +------+------+------+------+------+------+------+------+------+
- 1
- 2
- 3
每个整数占据2个字节(16-bit),9个采样也就是18字节的数据。每个采样的整数大小最小为 -32768,最大为 32768 。根据采样数据的位置和值画一个图的话,就会得到像播放器上那样的波浪形图。
我们可以像下面伪代码示例这样将数据读入一个C语言数组 :
- FILE *pcmfile
- int16_t *pcmdata;
- pcmfile = fopen(your pcm data file);
- pcmdata = malloc(size of the file);
- fread(pcmdata, sizeof(int16_t), size of file / sizeof(int16_t), pcmfile);
- 1
- 2
- 3
- 4
- 5
如果我们将这些数据送入声卡,我们就可以听到声音。当然我们需要告诉声卡这些数据的采样率。若我们告知声卡的采样率大于数据本身的采样率,那么这些数据的播放速度会高于其原始的速度。就是快放的功能。
立体声:
- +----------+----------+---------+----------+---------+----------+---------+----------+----------+
- | LFrame1 | RFrame1 | LFrame2 | RFrame2 | LFrame3 | RFrame3 | LFrame4 | RFrame4 | LFrame5 |
- +----------+----------+---------+----------+---------+----------+---------+----------+----------+
- 1
- 2
- 3
每一个frame是一个16-bit的采样点。左右声道的数据交叉存放。
3. Basic Audio Effects – Volume Control
现在让我们来看一下一些真实的波形图。最简单的就是正弦波了。
我们将波形的振幅扩大五倍,图形如下:
所以如果要增加PCM数据的音量,只需要将每一个采样的数据乘以一个系数就行了。如果我们的PCM数据有2048个字节,则包含了1024个采样。我们用如下的伪代码来扩大音量 :
- int16_t pcm[1024] = read in some pcm data;
- for (ctr = 0; ctr < 1024; ctr++) {
- pcm[ctr] *= 2;
- }
- 1
- 2
- 3
- 4
音量控制就是这么简单,但是要注意两点:
- 若采样点的数据乘以扩大系数之后的值 小于 -32768 或 大于 32768 ,则此处采样的数值只能取 -32768 或 32768
- int16_t pcm[1024] = read in some pcm data;
- int32_t pcmval;
- for (ctr = 0; ctr < 1024; ctr++) {
- pcmval = pcm[ctr] * 2;
- if (pcmval < 32767 && pcmval > -32768) {
- pcm[ctr] = pcmval
- } else if (pcmval > 32767) {
- pcm[ctr] = 32767;
- } else if (pcmval < -32768) {
- pcm[ctr] = -32768;
- }
- }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 我们将采样点的数据乘以2并不代表将声音的音量扩大了两倍,事实上也的确如此。声音音量的增益系数与音量的关系如图:
以上内容翻译自:http://www.ypass.net/blog/2010/01/pcm-audio-part-3-basic-audio-effects-volume-control/
4. How to change PCM Sample Rate
根据定义,Sample Rate表示每秒钟的采样个数,所以若是要改变音频的采样频率,我们只需要对采样点做适当的丢弃或者复制就可以。
比如:原始音频为opus编码,单声道,采样率为48kHz,采样点大小为16-bit。如何得到编码为speex,采样率为16kHz,采样大小为16-bit的音频?
我们需要以下几步:
- 将opus解码为PCM格式数据(叫做PCM1),此时的PCM1的采样率为48kHz
- 将PCM1的数据中第 3*n(n为从0开始的自然数) 个位置的采样点,丢弃3*n+1 和3*n+2位置的采样点。得到PCM2,此时的PCM2采样率为48kHz / 3 = 16kHz
- 将PCM2编码为speex数据
PCM音频数据格式介绍的更多相关文章
- SDL开发笔记(二):音频基础介绍、使用SDL播放音频
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 使用AudioTrack播放PCM音频数据(android)
众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...
- PCM文件格式简单介绍
PCM文件格式简单介绍 PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志.Windows的Convert工具能够把PCM音频格式的文件转换成M ...
- Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调
缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ...
- 常用音频协议介绍&&有关音频编码的知识与技术参数
(转载)常用音频协议介绍 会议电视常用音频协议介绍及对比白皮书 一.数字化音频原理:声音其实是一种能量波,因此也有频率和振幅的特征,频率对应于时间轴线,振幅对应于电平轴线.通常人耳可以听到的频率在20 ...
- 视音频数据处理入门:PCM音频采样数据处理
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 使用WindowsAPI实现播放PCM音频的方法
这篇文章主要介绍了使用WindowsAPI实现播放PCM音频的方法,很实用的一个功能,需要的朋友可以参考下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAP ...
- AudioRecord 录制播放PCM音频
AudioRecord 与 MediaRecorder 区别 AudioRecord 基于字节流录制,输出的是pcm数据,未进行压缩,直接保存的pcm文件不能被播放器识别播放. 可以对音频文件进行实时 ...
- iOS 阶段学习第23天笔记(XML数据格式介绍)
iOS学习(OC语言)知识点整理 一.XML数据格式介绍 1)概念:xml是extensible markup language扩展的标记语言,一般用来表示.传输和存储数据 2)xml与json目前使 ...
随机推荐
- SpringCloud基础知识
什么是SpringCloud Spring Cloud是一系列框架的有序集合. 为什么用SpringCloud Spring Cloud涵盖面广,能够与Spring Framework.Spring ...
- 实现RTSP摄像机硬盘录像机NVR网站网页微信H5直播方案EasyNVR部署问题之:ERR_CONTENT_LENGTH_MISMATCH
背景分析 接触到EasyNVR产品的开发者都知道,EasyNVR是一套功能齐全.简洁易用的流媒体解决方案,可作为能力曾前端接入摄像头,后端接入业务系统使用,也可以作为应用层,直接修改为属于企业用户自己 ...
- LeetCode_434. Number of Segments in a String
434. Number of Segments in a String Easy Count the number of segments in a string, where a segment i ...
- net ads join 和net rpc join命令的区别
要将主机加入Active Directory(AD),请输入: #net ads加入-U administrator 输入管理员密码:Passw0rd 使用短域名 - SAMDOM 加入'M1'到dn ...
- Java 8 stream 经典示例
package org.study2.java8.stream; import org.junit.Test; import java.util.*; import java.util.stream. ...
- javascript循环遍历数组输出key value
javascript循环遍历数组输出key value用$.each方法肯定不行的 所以采用如下方法<pre> markers = []; markers[2]=3; markers[3] ...
- LeetCode 331. 验证二叉树的前序序列化(Verify Preorder Serialization of a Binary Tree) 27
331. 验证二叉树的前序序列化 331. Verify Preorder Serialization of a Binary Tree 题目描述 每日一算法2019/5/30Day 27LeetCo ...
- AOP+Token防止表单重复提交
表单重复提交: 由于用户误操作,多次点击表单提交按钮 由于网速等原因造成页面卡顿,用户重复刷新提交页面 避免表单重复提交的方式: 1.页面上的按钮做防重复点击操作 2.在数据库中可以做唯一约束 3.利 ...
- 3. 键值对RDD
键值对RDD是Spark中许多操作所需要的常见数据类型.除了在基础RDD类中定义的操作之外,Spark为包含键值对类型的RDD提供了一些专有的操作在PairRDDFunctions专门进行了定义.这些 ...
- 【scratch3.0教程】1.1 走进编程世界
第一章 认识Scratch 第1课 走进编程世界 大家认识下图中的人物吗? 史蒂夫·乔布斯 比尔·盖茨 ●Elon Musk,特斯拉.Space X火箭公司创始人,9岁学习 ...