android wma2

来源:互联网 发布:苹果基因组数据库 编辑:程序博客网 时间:2024/06/15 19:25

  2 多媒体系统增加WMA 音频格式的设计

 

  从多媒体系统具体实现的角度来看,WMA 音频格式播放主要经过WMA 格式文件解析、WMA 编码流解码、PCM 输出播放3 个阶段。WMA 音频播放器的结构如图2 所示。

 

  图2 WMA 音频播放器的结构

  图2 WMA 音频播放器的结构

 

  基于Android 多媒体系统音频播放流程, 在WMA 音频格式开发过程中主要有4 项工作:

  (1) WMA文件的识别;

  (2) WMA 文件的解析;

  (3) 编码数据的读取;

  (4) 编码数据的解码和输出。

  2. 1 WMA 格式音频播放功能流程设计

  通过调用AwesomePlayer 的setDataSource 函数来设置数据源; AwesomePlayer 通过调用MediaExtractor的Create 函数来识别该文件的格式,MediaPlayer 判断该文件为WMA 格式后,会创建一个WMAExtractor,在创建WMAExtractor 的同时,WMAExtractor 会解析文件头,获取文件中的相关信息。然后调用WMAExtractor的getTrack 函数创建一个WMASource;AwesomePlayer通过OMXCodec 创建一个WMADecoder;AwesomePlayer 接着创建一个audioPlayer,并把WMADecoder 做为数据源传给AudioPlayer,并调用AudioPlayer 的start 函数; AudioPlayer 获取WMADecoder中的相关参数: 文件类型、采样率、声道数,并根据该数据开启AudioSink,并把AudioSinkCallback做为回调函数传给AudioSink.AudioPlayer 先调用WMADecoder 解第一帧数据, 并把该数据传给AudioSink去播放,当播放完成后AudioSink 会调用回调函数AudioSinkCallback 再取解码后的数据,AudioSinkCallback又会调用FillBuffer 函数获取解码后的原始数据,解码后数据如果被取完后,AudioPlayer又会调用WMADecoder 解下一帧数据给AudioSink,来回反复,直到文件中数全部被播放,播放流程如图3所示。在拉动滚动条时,上层会传来SeekTime,经AudioPlayer 传给WMADecoder 再传给WMAExtractor,WMAExtractor 根据上层传来的SeekTime 判断出要播放的原始数据的起始位置,然后从该位置读取一个数据包传给WMADecoder 解码。

 

  图3 音频播放流程图

  图3 音频播放流程图

 

  在整个WMA 格式解码播放过程中,主要设计有两个模块: WMAExtractor 和WMADecoder.WMAExtractor主要执行WMA 格式文件解析和数据读取功能。

  WMADecoder 主要执行解码功能; WMA 格式音频播放功能实现。

  (1) WMA 文件的识别。

  在判断播放文件格式前,AwesomePlayer 会提前把所支持的格式通过DataSource 中的RegisterDefault-Sniffers 函数注册进来。判断播放文件格式时,会逐一按次序把该文件和所支持的格式进行匹配,最匹配的格式就是该文件的格式,所以在Datasource 中的RegisterDefaultSniffers 函数中应添加如下代码:

  void DataSource: : RegisterDefaultSniffers( ) {

  ……

  RegisterSniffer( SniffWMA) ;

  }

  WMA 文件开始有一个16 Byte 的标识,表示是WMA: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 62 CE6C.如果音频文件的前16 个字符和这16 Byte 相符,那么就可以判断该文件为WMA 文件。WMAExtractor中的SniffWMA 函数就是通过读取文件前16 Byte 来判断该文件是不是WMA 文件。在SniffWMA 函数中,如果判断前16 Byte 和WMA 的16 个标识字节相等,就会把MEDIA_MIMETYPE _AUDIO_WMA 给mime-Type 指针,标志着该音频文件类型为WMA 格式。

  MEDIA_MIMETYPE_AUDIO_WMA 是在MediaDefs. h文件中定义,在MediaDefs. cpp 文件中赋值:

  Extern const char * MEDIA_MIMETYPE_AUDIO_WMA; / /在MediaDefs. h 头文件中

  const char * MEDIA_MIMETYPE_AUDIO_WMA =“audio /wma”; / /MediaDefs. cpp 头文件

  (2) WMA 文件的解析。

  WMAExtractor 从WMA 文件的第31 Byte 开始取16 Byte,然后依次和file_header、stream_header、data_header、comment_header、extended_content_header 对比,如果和file_header 相等,则从下个Byte 开始依次获取文件大小、创建时间、数据包个数、…数据包大小。然后再从下个Byte 开始读取16 Byte 再进行对比,如果和extended_content_header 相等,则可以从下个Byte 中依次获取名称、艺术家、版权、注释等非音频信息。然后再接着读取16 Byte 进行比对,直到和data_header 相等。data_header 后就是音频文件解码数据,data_header 的结束位置就是第一个数据包在文件中的偏移量。WMAExtractor 会创建一个MetaData,并把文件头中获取的sample_rate、Byte_rate、channels、duration都存入MetaData 中。在WMAExtractor 的getMeta-Data 函数中,把之前获取的非音频信息放入MetaData中, 最后返回该MetaData.在WMAExtractor 的getTrack 函数中,创建一个WMASource,并把WMA 数据和MetaData 传给WMASource.

1  2  3