问题背景 有客户因为担心音频存放在flash中会因为没有烧录,导致播放异常,所以希望可以提供播放xip中的音频数据的方法。
问题分析 XRMCU允许使用raw_bin的方式烧录,确保烧录固件时音频也能下载到flash中,请参考(XR806如何添加本地音频到flash)[https://one.allwinnertech.com/#/faq/0/show]。 如果确定要播放xip中的数据,需要把计算出音频数据在flash中的实际地址。
解决步骤
- 使用bin2hex或者HxD等工具把音频文件转变成c文件,并保存在xip中。
__xip_rodata //保存在xip中
const unsigned char testmusic[39197] = {
0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x33, 0x54, 0x53,
0x53, 0x45, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x4C, 0x41, 0x4D,
0x45, 0x20, 0x33, 0x32, 0x62, 0x69, 0x74, 0x73, 0x20, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6F, 0x6E, 0x20, 0x33, 0x2E, 0x31, 0x30, 0x30, 0x2E, 0x31,
......
- 计算音频数据在flash中的地址。 参照xip初始化platform_xip_init();可以知道app_xip.bin在flash中的位置是image_get_section_addr(IMAGE_APP_XIP_ID) IMAGE_HEADER_SIZE static void platform_xip_init(void)
{
uint32_t addr;
addr = image_get_section_addr(IMAGE_APP_XIP_ID); //通过ID获取app_xip.bin在flash中的地址
if (addr == IMAGE_INVALID_ADDR) {
FWK_NX_ERR("no xip sectionn");
return;
}
HAL_Xip_Init(PRJCONF_IMG_FLASH, addr IMAGE_HEADER_SIZE); //IMAGE_HEADER_SIZE为头码地址
}
可以得出音频数据在flash中的地址。
代码语言:javascript复制/*
__xip_start__指xip的入口地址,在appos.ld中定义,数值也在appos.ld中定义为0x400000。
(uint32_t)testmusic - (uint32_t)__xip_start__也就是相对于xip入口的偏移量。
image_get_section_addr(IMAGE_APP_XIP_ID) IMAGE_HEADER_SIZE就是app_xip.bin在flash中的实际地址,会被映射到0x400000
*/
uint32_t music_addr = ((uint32_t)testmusic - (uint32_t)__xip_start__ image_get_section_addr(IMAGE_APP_XIP_ID) IMAGE_HEADER_SIZE);
- 把数值格式化为cedarx能识别的字符串。
char *song_addr = malloc(50);
sprintf(song_addr,"flash://0?addr=%u&length=%u",music_addr,sizeof(testmusic));
- 播放音频
player_base *mAwPlayer;
mAwPlayer = player_create();
mAwPlayer->play(mAwPlayer,song_addr);
原贴链接:https://bbs.aw-ol.com/topic/1056