音频媒体文件调用方法

备注

前置知识: 音频转换工具

音频转换工具 AudioConvertTool 生成唯一的 音频资源文件 media.dat ,置于用户工程资源文件夹 ./img 下, 经过工具链后(Build)与CPU代码组合成单一SoC固件文件(.bin),用于上位机向NOR Flash烧录。

由于音频转换工具提供不同格式音乐媒体的混合打包能力,资源文件 media.dat 也设计了针对性的机制用于区分内部音频。

../../_images/kiwi-media-file.png

上图以一个打包有3段 音频内容(Content Block) 的资源文件结构为例,解释资源文件的解析方法:

  • 资源文件从起始位置(offset = 0)起,放置若干连续排列的 信息头(Content Header),数目和顺序与音频内容( Content Block )的数目和排列顺序保持一致。

  • Content Header 区域和 Content Block 区域之间为一段全0分隔区,其大小与一个 Content Header 的大小一致。

  • 每个 Content Header 内含一个预定义的结构体实体,用于携带对应 Content Block 的信息:

struct resource_t

音频内容信息结构体

player_file_attribute_t attribute

音频内容格式,如MP3、S1A、SILK、MIDI等,通过预设的枚举定义赋值和区分

uint8_t name[20]

音频内容名称,如曲名

uint32_t offset

音频内容相对于资源文件起始 offset = 0 位置的偏移

uint32_t size

音频内容的字节数大小

enum player_file_attribute_t

播放文件属性枚举,资源文件参数 attribute 值选择范围

  • FileAttribute_None: 值为0,资源文件,结束属性

  • FileAttribute_MP3: 值为1,资源文件为MP3,不区分采样率,文件后缀MP3

  • FileAttribute_S1A: 值为2,资源文件为S1A,不区分采样率,文件后缀S1A

  • FileAttribute_MIDI: 值为3,资源文件为midi文件,

  • FileAttribute_ADPCM: 值为14,资源文件为ADPCM文件,文件后缀IMA

  • FileAttribute_SILK: 值为15,资源文件为silk,不区分采样率,文件后缀SLK

  • FileAttribute_CBK: 值为32,资源文件为vorbis的codebook,文件后缀CBK

  • FileAttribute_VBS: 值为33,资源文件为vorbis,不区分采样率,文件后缀VBS

  • 用户程序通过全局符号 __media_file_addr 获得音频资源文件 media.dat 在SoC寻址空间的绝对起始地址, 该地址一般被映射至L2-CACHED NOR FLASH空间,用户可以根据需要,套用SDK的宏定义,将其重映射至其他NOR FLASH空间进行访问。

  • 用户程序从音频资源文件的起始地址开始,以轮询的方式遍历 Content Header 区域,直至全0的分隔区。 用以获得 Content Header 的总数。

  • 用户程序从特定 Content Header 获得 offset 信息,并以 __media_file_addr + offset 的方式计算出特定音频内容在SoC寻址空间的绝对位置, 供播放器场景的初始化流程(init)调用。

备注

音频资源文件 media.dat 内部的音频内容排列顺序,与音频转换工具 AudioConvertTool 的打包顺序保持一致。

示例代码

获取资源文件总音频数量

typedef struct
{
  uint32_t attribute; //1:MP3;2:S1A;3:MIDI
  uint8_t name[20];
  uint32_t offset;
  uint32_t size;
}resource_t;

extern char __media_file_addr;
extern char __media_file_size;

/*********************获取资源文件总音频数量*************************/
uint32_t addr,size;
addr = NORC_DATA_UNCACHE_SINGLE((uint32_t)&__media_file_addr);
size = (uint32_t)&__media_file_size;
resource_t * res;
int cnt=0; //记录音频文件数量
int size_total=0; //记录所有音频文件总大小
while(1)
{
  // 根据id获取文件的头的memory地址
  res = (resource_t*)(addr + sizeof(resource_t)*cnt);
  if(res->attribute==0||(sizeof(resource_t)*cnt)>=size)
  {
    break;
  }
  size_total+=res->size;
  debug("%s:%d\n",res->name,res->size);
  cnt++;
}
debug("MusicIDNumber:%d\n",cnt);
debug("size_total:%d byte\n",size_total);
获取某一音频文件信息

/**********************获取某一音频文件信息************************/
uint32_t addr,size_all,len;
addr = NORC_DATA_UNCACHE_SINGLE((uint32_t)&__media_file_addr);
size_all =  (uint32_t)&__media_file_size;
resource_t * res;
if(sizeof(resource_t)*id >=size_all)//XXX !!!!id:表示音频文件在资源文件的序号
{
  return;
}
debug("%s:offset:%x size:%d\n",res->name,res->offset,res->size);