第四章(音频数据处理程序设计)

音频数据处理程序设计

Media Session(媒体会话):管理媒体数据、实现播放、暂停操作。

WAVE文件由4个块组成:
  1. RIFF WAVE Chunk

  2. Format Chunk

  3. Fact Chunk(可选)\longrightarrow一般当wav文件由某些软件转化而成时,则需要包含该Chunk

  4. Data Chunk

    • 双声道的采样数要加倍
    • 小端序:低位字节存在地址空间中的低位(比如:Ox0782中的低位字节82存储在地址空间中的低位)
    • 大端序:低位字节存在地址空间中的高位
image-20230307151517811
  1. ID都是4个字节,比如ID='fmt '中fmt之后还有一个空字符(用“四字符码”作块ID,是RIFF文件的重要特点)

四个块的关系
WAVE文件的地址空间
WAVE文件的地址空间

将10进制转换为16进制来存储到地址空间中。

  1. 每个块的ID和RIFF块的Type(WAVE)的端序是大端存储,其他都是小端存储

  2. 16进制存储

音频播放与编程接口

方法1:使用PlaySound函数播放音频文件

方法2:使用MCI(Multimedia Control Interface)函数

方法3:基于DirectShow开发包的应用程序

方法4:基于Media Foundation开发包的应用程序

基于MF Media Session的音频

基于Media Session的媒体播放应用的基本框架
播放音频文件

利用 Media Session播放音频文件的基础过程如下:

  1. 调用MFStartup函数进行Media Foundation platform的初始化;

  2. 调用MFCreateMediaSession函数创建一个Media Session对象实例;

  3. 利用Source Resolver创建媒体源。

  4. 创建Topology,并将媒体源节点与SAR节点连接起来。实际上,应用程序在这里只需要创建一个Partial Topology(部分拓扑),然后将媒体源与输出节点SAR连接,这时,Partial Topology能够自动在两者之间插入必要的解码器,这体现出Media Foundation的智能性;

  5. 调用IMFMediaSession::SetTopology将Topology设置到Media Session;

  6. 使用IMFMediaEventGenerator接口从Media Session取得事件;

  7. 调用IMFMediaSession::Start启动播放。之后,可以调用IMFMediaSession::Pause、IMFMediaSession::Stop暂停、停止播放。

  8. 退出应用程序时,需调用IMFMediaSession::Close关闭Media Session。该方法是异步的,因此,当调用完毕,Media Session发送MESessionClosed事件,并能够安全处理后面的操作。

如果需要对3个音频文件进行(同时)播放则需要创建3个媒体会话。

基于MF的音频转码程序设计

程序模块结构设计
程序模块结构设计

采用的是数据源模式(MF架构之一):

数据源模式

相关函数分析

1、WriteWaveFile函数

WriteWaveFile(IMFSourceReader*, HANDLE, LONG)函数

  • 调用ConfigureAudioStream(IMFSourceReader*, IMFMediaType **)函数,从输入源文件中挑选出音频流,然后设置目标音频的格式,从而告知源阅读器调用相应的解码器;

  • 调用WriteWaveHeader(hFile, pAudioType, &cbHeader)函数,将任意输入的音频文件中的数据流或多媒体文件中的音频流,转码成未压缩的PCM格式的Wave文件;

  • 调用CalculateMaxAudioDataSize(pAudioType, cbHeader, msecAudioData)函数,计算准备写入到输出文件中的音频片断的最大数据量;

  • 调用WriteWaveData(hFile, pReader, cbMaxAudioData, &cbAudioData)函数,写入音频数据;

  • 调用FixUpChunkSizes(hFile, cbHeader, cbAudioData)函数,对输出文件进行数据补充;

2、CalculateMaxAudioDataSize函数
  • 计算原理:

    • 计算原理
3、ConfigureAudioStream函数

ConfigureAudioStream(IMFSourceReader*, IMFMediaType**)函数

4、WriteWaveHeader函数
  • 定义了一个WAVEFORMATEX的结构指针pWav:

    • WAVEFORMATEX的结构:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //WAVEFORMATEX结构
    typedef struct {
    WORD wFormatTag; //格式标识
    WORD nChannels; //声道数
    DWORD nSamplesPerSec; //采样频率
    DWORD nAvgBytesPerSec; //数据率
    WORD nBlockAlign; //样本对齐单位
    WORD wBitsPerSample; //样本的量化深度
    WORD cbSize; //附加数据:存储非PCM格式音频的补充信息,如果没有附加信息,该数据需要置为0
    } WAVEFORMATEX
5、WriteWaveData函数
6、FixUpChunkSizes函数
7、WriteToFile函数

7个函数的作用:

  1. 调用WriteWaveFile(IMFSourceReader*, HANDLE, LONG)函数,建立在其它含有实际动作的函数基础之上的控制性模块;

  2. 调用ConfigureAudioStream(IMFSourceReader*, IMFMediaType **)函数,从输入源文件中挑选出音频流,然后设置目标音频的格式,从而告知源阅读器调用相应的解码器;

  3. 调用WriteWaveHeader(hFile, pAudioType, &cbHeader)函数,将任意输入的音频文件中的数据流或多媒体文件中的音频流,转码成未压缩的PCM格式的Wave文件;

  4. 调用CalculateMaxAudioDataSize(pAudioType, cbHeader, msecAudioData)函数,计算准备写入到输出文件中的音频片断的最大数据量;

  5. 调用WriteWaveData(hFile, pReader, cbMaxAudioData, &cbAudioData)函数,写入音频数据;

  6. 调用FixUpChunkSizes(hFile, cbHeader, cbAudioData)函数,对输出文件进行数据补充;

  7. 调用WriteToFile函数,完成数据的最后输出。

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信