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?

单声道:

  1.  
    +------+------+------+------+------+------+------+------+------+
  2.  
    | 500 | 300 | -100 | -20 | -300 | 900 | -200 | -50 | 250 |
  3.  
    +------+------+------+------+------+------+------+------+------+
  • 1
  • 2
  • 3

每个整数占据2个字节(16-bit),9个采样也就是18字节的数据。每个采样的整数大小最小为 -32768,最大为 32768 。根据采样数据的位置和值画一个图的话,就会得到像播放器上那样的波浪形图。

我们可以像下面伪代码示例这样将数据读入一个C语言数组 :

  1.  
    FILE *pcmfile
  2.  
    int16_t *pcmdata;
  3.  
    pcmfile = fopen(your pcm data file);
  4.  
    pcmdata = malloc(size of the file);
  5.  
    fread(pcmdata, sizeof(int16_t), size of file / sizeof(int16_t), pcmfile);
  • 1
  • 2
  • 3
  • 4
  • 5

如果我们将这些数据送入声卡,我们就可以听到声音。当然我们需要告诉声卡这些数据的采样率。若我们告知声卡的采样率大于数据本身的采样率,那么这些数据的播放速度会高于其原始的速度。就是快放的功能。

立体声:

  1.  
    +----------+----------+---------+----------+---------+----------+---------+----------+----------+
  2.  
    | LFrame1 | RFrame1 | LFrame2 | RFrame2 | LFrame3 | RFrame3 | LFrame4 | RFrame4 | LFrame5 |
  3.  
    +----------+----------+---------+----------+---------+----------+---------+----------+----------+
  • 1
  • 2
  • 3

每一个frame是一个16-bit的采样点。左右声道的数据交叉存放。

3. Basic Audio Effects – Volume Control

现在让我们来看一下一些真实的波形图。最简单的就是正弦波了。 

我们将波形的振幅扩大五倍,图形如下: 

所以如果要增加PCM数据的音量,只需要将每一个采样的数据乘以一个系数就行了。如果我们的PCM数据有2048个字节,则包含了1024个采样。我们用如下的伪代码来扩大音量 :

  1.  
    int16_t pcm[1024] = read in some pcm data;
  2.  
    for (ctr = 0; ctr < 1024; ctr++) {
  3.  
    pcm[ctr] *= 2;
  4.  
    }
  • 1
  • 2
  • 3
  • 4

音量控制就是这么简单,但是要注意两点:

  1. 若采样点的数据乘以扩大系数之后的值 小于 -32768 或 大于 32768 ,则此处采样的数值只能取 -32768 或 32768
  1.  
    int16_t pcm[1024] = read in some pcm data;
  2.  
    int32_t pcmval;
  3.  
    for (ctr = 0; ctr < 1024; ctr++) {
  4.  
    pcmval = pcm[ctr] * 2;
  5.  
    if (pcmval < 32767 && pcmval > -32768) {
  6.  
    pcm[ctr] = pcmval
  7.  
    } else if (pcmval > 32767) {
  8.  
    pcm[ctr] = 32767;
  9.  
    } else if (pcmval < -32768) {
  10.  
    pcm[ctr] = -32768;
  11.  
    }
  12.  
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. 我们将采样点的数据乘以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的音频? 
我们需要以下几步:

    1. 将opus解码为PCM格式数据(叫做PCM1),此时的PCM1的采样率为48kHz
    2. 将PCM1的数据中第 3*n(n为从0开始的自然数) 个位置的采样点,丢弃3*n+1 和3*n+2位置的采样点。得到PCM2,此时的PCM2采样率为48kHz / 3 = 16kHz
    3. 将PCM2编码为speex数据

PCM音频数据格式介绍的更多相关文章

  1. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  2. 使用AudioTrack播放PCM音频数据(android)

    众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...

  3. PCM文件格式简单介绍

    PCM文件格式简单介绍 PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志.Windows的Convert工具能够把PCM音频格式的文件转换成M ...

  4. Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调

    缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ...

  5. 常用音频协议介绍&&有关音频编码的知识与技术参数

    (转载)常用音频协议介绍 会议电视常用音频协议介绍及对比白皮书 一.数字化音频原理:声音其实是一种能量波,因此也有频率和振幅的特征,频率对应于时间轴线,振幅对应于电平轴线.通常人耳可以听到的频率在20 ...

  6. 视音频数据处理入门:PCM音频采样数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  7. 使用WindowsAPI实现播放PCM音频的方法

    这篇文章主要介绍了使用WindowsAPI实现播放PCM音频的方法,很实用的一个功能,需要的朋友可以参考下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAP ...

  8. AudioRecord 录制播放PCM音频

    AudioRecord 与 MediaRecorder 区别 AudioRecord 基于字节流录制,输出的是pcm数据,未进行压缩,直接保存的pcm文件不能被播放器识别播放. 可以对音频文件进行实时 ...

  9. iOS 阶段学习第23天笔记(XML数据格式介绍)

    iOS学习(OC语言)知识点整理 一.XML数据格式介绍 1)概念:xml是extensible markup language扩展的标记语言,一般用来表示.传输和存储数据 2)xml与json目前使 ...

随机推荐

  1. 013-centos7 常用命令--查看当前用户的4种方法

    一.概述 4种查看系统用户信息(通过编号(ID))的方法. 1.1. 使用w命令查看登录用户正在使用的进程信息 w命令用于显示已经登录系统的用户的名称,以及他们正在做的事.该命令所使用的信息来源于/v ...

  2. python提取mysql中指定列参数,并循环打印

    试验环境: Python 3.7.0 Mysql 5.0 实验目的: 使用python将数据库中指定的列中的数值取出来,并循环遍历,用以当成参数传递给需要它的方法. 本次实验取的是para列的数据 实 ...

  3. 基于EasyNVR摄像机无插件直播方案二次开发实现自己的摄像机IPC-NVR无插件化直播解决方案

    背景介绍 在之前的博客中<基于EasyNVR实现RTSP/Onvif监控摄像头Web无插件化直播监控>,对EasyNVR所实现的功能我们已经有较多描述,这些也在方案地址:http://ww ...

  4. net ads join 和net rpc join命令的区别

    要将主机加入Active Directory(AD),请输入: #net ads加入-U administrator 输入管理员密码:Passw0rd 使用短域名 - SAMDOM 加入'M1'到dn ...

  5. filter和map内置函数

    filter filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回 ...

  6. 谈谈php里的IOC控制反转,DI依赖注入(转)

    转自:http://www.cnblogs.com/qq120848369/p/6129483.html 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和" ...

  7. STL源码剖析——Iterators与Traits编程#5 __type_traits

    上节给出了iterator_traits以及用到traits机制的部分函数的完整代码,可以看到traits机制能够提取迭代器的特性从而调用不同的函数,实现效率的最大化.显然这么好的机制不应该仅局限于在 ...

  8. Linux忘记root密码操作方法

    此方法为:进入单用户模式,直接修改新密码覆盖掉以前的root密码. 操作步骤: 1.进入单用户模式 2.修改root密码 1.进入单用户方法: 1)启动Linux时,通过按上下键(其他键也可以)让Li ...

  9. 使用 Angular RouteReuseStrategy 缓存(路由)组件

    使用 Angular RouteReuseStrategy 缓存组件 Cache components with Angular RouteReuseStrategy RouteReuseStrate ...

  10. Ubuntu修改文件权限以及更换文件所有者

    参数 -R 用来递归实现更改所有子文件和子目录的权限. 1.利用chmod修改权限: 对Document/目录下的所有子文件与子目录执行相同的权限变更: chmod -R 700 文件名 700是变更 ...