音频文件PCM代码走读

紧接上篇文章音频格式PCM介绍,本文介绍PCM代码相关内容,废话不多说,干活奉上。

PCM采集

首先需要了解模拟信号采集过程。通过ADC(模数转换器)将模拟信号转换成数字信号。然后通过PCM(脉冲编码调制)对连续变化的模拟信号进行采样、量化和编码,将其转换成离散的数字信号。这样,我们才能实现音频信号的采集,如下图所示:

音频文件PCM代码走读

模拟信号采集过程通常涉及以下几个步骤:

  • 信号源:首先,需要有一个能够产生所需信号的设备或系统。信号源可以是各种类型的传感器、发生器或其他模拟设备。
  • 前置放大器:为了增强信号的幅度和清晰度,通常需要使用前置放大器对信号进行放大。前置放大器可以将微弱的信号放大到合适的水平,以便后续处理。
  • 滤波器:在放大信号之前,可能需要对其进行滤波以去除不需要的频率成分。滤波器可以是低通、高通或带通滤波器,具体取决于所需的信号特性。
  • 模数转换(ADC):将模拟信号转换为数字信号的过程称为模数转换。ADC将连续的模拟信号转换为离散的数字值。ADC的精度取决于其分辨率,即它能表示多大的输入变化范围。
  • 控制与播放:根据实际应用需求,可能需要播放。例如,可以使用计算机软件对数据进行处理和播放输出。

 

实际工作场景

PCMU 和 PCMA 也称为 g711 编解码器(PCM 代表脉冲编码调制)。PCMU(µ-Law)主要用于北美,PCMA(A-Law)主要用于北美以外的其他国家。

https://datatracker.ietf.org/doc/html/rfc3551#section-4.5

定义了audio相关的编码类型

音频文件PCM代码走读

PCMA和PCMU在ITU-T建议G.711中有具体规定。音频数据经过对数缩放后,每样本为8位编码。PCMU表示无符号幅度调制,PCMA表示有符号幅度调制。Jayant和Nol提供了详细的描述。每个G.711 octet应在RTP包中按字节对齐。每个G.711 octet的符号位应对应RTP包中该octet的最高位(即假设G.711样本在主机机器上以octets处理,则符号位应根据主机机器格式定义为该octet的最高位)。G.711的56kb/s和48kb/s模式不适用于RTP,因为PCMA和PCMU必须始终以8位样本传输。

音频文件PCM代码走读

FFMPEG代码走读

由于个人经常处理网络端音视频流,所以从这边入手分析相关代码,我们仍然在FFMPEG中完成相关内容学习。

音频文件PCM代码走读

PCM 数据

PCM数据结构大概如下:

音频文件PCM代码走读

PCM接口

音频文件PCM代码走读

pulse_write_header

函数 pulse_write_header() 用于将音频文件的标头写入 PulseAudio 流。以下是该函数执行步骤的更详细说明:

  • 检查输入文件是否为音频文件。
  • 获取音频流的流信息。
  • 创建 PulseAudio 上下文和流。
  • 将流连接到 PulseAudio 服务器。
  • 设置流的缓冲区属性。
  • 将流的状态设置为 PA_STREAM_READY。
  • 返回 0。

音频文件PCM代码走读

pulse_write_packet

函数 pulse_write_packet() 用于将音频数据包写入 PulseAudio 流。该函数将 AVFormatContext 对象和 AVPacket 对象作为输入。

主要完成的内容:数据有效性判断,获取当前stream状态,从而将输入数据包中的数据写入 PulseAudio 流,完成控制信息的更新。

音频文件PCM代码走读

pulse_write_frame

函数 pulse_write_frame() 用于将音频帧写入 PulseAudio 流。该函数将一个 AVFormatContext 对象、一个表示流索引的整数和一个指向 AVFrame 对象的指针作为输入。该函数首先检查以确保输入帧不为空。如果是,该函数将返回一个错误。

音频文件PCM代码走读

pulse_get_output_timestamp

函数 pulse_get_output_timestamp() 用于获取 PulseAudio 流将播放的下一个音频帧的时间戳。该函数将一个 AVFormatContext 对象、一个表示流索引的整数和指向两个 int64_t 变量的指针作为输入。该函数首先检查以确保输入流不为空。如果是,该函数将返回一个错误。

音频文件PCM代码走读

pulse_get_device_list

函数 pulse_get_device_list() 用于获取可用 PulseAudio 设备的列表。该函数将 AVFormatContext 对象和 AVDeviceInfoList 对象作为输入。该函数首先检查以确保输入流不为空。如果是,该函数将返回一个错误。

音频文件PCM代码走读

pulse_control_message

函数 pulse_control_message() 用于处理来自应用程序的控制消息。该函数采用 AVFormatContext 对象、表示控制消息类型的整数、指向包含控制消息数据的缓冲区的指针以及数据缓冲区的大小作为输入。该函数首先检查以确保输入流不为空。如果是,该函数将返回一个错误。

音频文件PCM代码走读

其中app到设备的消息类型包括如下几种:

音频文件PCM代码走读

以上代码在FFMPEG中都可以查阅到,有兴趣想要深入学习的童鞋们可以自行查阅相关代码。

作者信息:我是一枚爱跑步的程序猿,维护公众号和知乎专栏《MediaStack》,有兴趣可以关注,一起学习音视频知识,时不时分享实战经验。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论