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. [LeetCode] 45. Jump Game II 跳跃游戏 II

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  2. [LeetCode] 127. Word Ladder 单词阶梯

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  3. [LeetCode] 326. Power of Three 3的次方数

    Given an integer, write a function to determine if it is a power of three. Follow up:Could you do it ...

  4. MySQL之表日志管理

    MySQL日志管理 mysql日志(默认存放在datadir): 同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志, ...

  5. springcloud 连接docker中运行的RabbitMQ消息中间件。

    参考:https://blog.51cto.com/zero01/2173288 主要是记录几个坑: 第一个坑:开始订单服务中配置文件是: #配置rabbitmq 2019.5.17 added by ...

  6. Oracle Spatial 中的弧段及弧相关拓扑错误

    1.报告说明 此报告用于验证下列问题: ORACLE SPATIAL 0.05m的最小拓扑容差值是否可以被修改 原始数据通过ARCGIS入库数据精度是否有损失 修改ORACLE SPATIAL图层的最 ...

  7. JIRA学习

    Jira是Atlassian公司出品的一款事务管理软件.无论是“需求”,还是“BUG”,或是“任务”,都是“事务”的一种,所以Jira可以胜任非常多的角色:需求管理.缺陷跟踪.任务管理等等……因为Ji ...

  8. 【C++面试】关于虚函数的常见问题

    1.虚函数的代价 1)带有虚函数的每个类会产生一个虚函数表,用来存储虚成员函数的指针 2)带有虚函数的每个类都会有一个指向虚函数表的指针 3)不再是内敛函数,因为内敛函数可以在编译阶段进行替代,而虚函 ...

  9. 基于卷积神经网络的面部表情识别(Pytorch实现)----台大李宏毅机器学习作业3(HW3)

    一.项目说明 给定数据集train.csv,要求使用卷积神经网络CNN,根据每个样本的面部图片判断出其表情.在本项目中,表情共分7类,分别为:(0)生气,(1)厌恶,(2)恐惧,(3)高兴,(4)难过 ...

  10. SQL Server 索引优化-----数据库引擎优化顾问

    本文将根据“数据库引擎优化顾问”(DTA)来发现无用或缺失的索引. 要使用“数据库引擎优化顾问”,首先需要对数据库负载进行监控,为数据库负载分析准备数据.从SSMS的工具中,打开SQL Server  ...