liu2guang
liu2guang - 认证专家

注册于 3 years ago

回答
9
文章
0
关注者
3

点赞,分析没有问题的,还是按照使用场景来分析:

场景

  1. 暂停播放:暂停播放会将最后不满一帧的数据缓存到audio框架的缓存中,但是接着播放写入数据时就可以将不满的数据和后续的一起写入到硬件codec中,这样数据是连贯的不会出现pop音
  2. 停止播放:停止播放后不满一帧的没有写入,没有关系,因为用户主观上已经停止掉了,不需要flush这样的操作,这样停止更快
  3. 暂停播放 + 切换歌曲:这里其实就有问题了,不满的数据+另外一首歌曲的数据,就会出现音频的不连续性,这样从听感上来说就是 pop 一声,所以切换歌曲的情况下需要有一个类似 clean 的操作,或者是暂停的时候 flush 下

还有标题中“audio的replay模式不能播放长度小于内存块大小的数据吗”其实没有什么意义,因为你的缓存一般都是配置程20ma大小的缓存区,实际使用是没有这么短的音频的。

没啥考虑,就是设计的时候没有想这么多。但是这并不是说明实际会产生什么严重的后果,向DMA传入0数据,其实是不会发出声音的。在实际使用的场景下,一般是开始播放歌曲,或者是长时间暂停后恢复(短时间暂停一般是不write数据这种方式处理, 长时间一般是stop再start),那么针对这2种场景分析:

  1. 开始播放,由于0数据,其实是不会发出声音的,等一个中断后就会真实的搬运数据,其实没有什么影响
  2. 长时间暂停后恢复,虽然在整个音乐播放过程中插入一帧的0数据,但是由于是长时间暂停后恢复,人的听感上无法感知,所以问题也不大

会的,需要做互斥操作,保证每一个线程最小发送数据单位

(mem->used) assertion failed at function:rt_free, line number:599

这句话的意思是 rt_free 传入的地址, 其对应的管理块中有一个标志是否使用的字段,在小内存管理算法下面会判断这个字段是否是已经被使用的,对应没有使用的情况有2种:

  1. 内存写穿,上一块内存写入数据越界导致数据被破坏
  2. 释放过的内存再次释放(释放一次后used会被标注为已经释放)

正对以上2种问题,一般断定和解决方法:

  1. 对应第一种内存写穿,可以开启memtrace功能,直接遍历一次内存使用的情况,内存管理块采用的链表结构,如果是内存写穿基本上链表就会被破坏,所以memtrace出来的有一个内存大小地址均是一个异常数据,那么基本这个异常的地址之前的一个或者n个地址有数据写穿。只需要debug找出谁分配的这块,分析前后关系即可解决这种问题;
  2. 针对于再次释放的问题,比较简单释放后将指针赋值为NULL,rt_free 释放空指针就会退出。当然找出重复释放的地方更好

ulog貌似可以将输出日志定向到后端,后端可以是DFS下管理的文件。当然也可以是终端或者网络等等。

系统参数可以使用.ini, 软件包有对应的软件包,但是具体的我没有用过,你可以了解下。

移植的海思芯片,可以参考,不过是A5的,A7 A5基本移植区别不大
https://gitee.com/liu2guang/DOPI_Hi3516EV200_RTT

系统的支持的话联系下andy?

Crazy 发表于 2020-6-24 10:19
大佬好,请问下你这个图的资料和相关RTT音频框架组件从哪里可以获取到?以及如何获取呢?

非常感谢你能 ...


商业不对外,如果只是简单的使用,用wavplayer播放器也可以播放的,github上有对外开源,商用有RTT player播放器,有需要联系睿赛德深圳团队把,或者你私聊我也行

Crazy 发表于 2020-6-24 09:55
/components/drivers/audio只有audio.c/audio_pipe.c几个文件,不能满足音频框架的要求,你说的移植到H7 ...


这个只是驱动框架,音频框架是商业组件,我这边给你丢个音频组件的图。
RTT音频.png

在qemu中测试,证书DIGICERT_ROOT_CA.cer放到 ./ 目录下调用 curl --verbose -k --capath ./ 是没有问题的。你试试qemu跑把
111.png

    本帖最后由 aozima 于 2020-1-20 09:54 编辑


[indent]
int webclient_set_nonblock(struct webclient_session *session)
{
RT_ASSERT(session);
fcntl(session->socket, F_SETFL, O_NONBLOCK);
return 0;
}
[/indent][indent]
fd_set readset;
int i, maxfdp1;
struct timeval timeout;

while (1)
{
timeout.tv_sec = 2;
timeout.tv_usec = 0;
maxfdp1 = session->socket + 1;

FD_ZERO(&readset); /* 清空可读事件描述符列表 */
FD_SET(session->socket, &readset); /* 将需要监听可读事件的描述符加入列表 */
i = select(maxfdp1, &readset, RT_NULL, RT_NULL, &timeout); /* 等待设定的网络描述符有事件发生 */

if (i == 0) continue; /* 至少有一个文件描述符有指定事件发生再向后运行 */

/* 查看 sock 描述符上有没有发生可读事件 */
if (FD_ISSET(session->socket, &readset))
{
length = webclient_read(session, ptr, WEBCLIENT_RESPONSE_BUFSZ);
if (length > 0)
{
total_length += length;
}
else if (length == -WEBCLIENT_TIMEOUT)
{
LOG_I("WEBCLIENT_TIMEOUT");
continue;
}
else if (length == 0)
{
break;
}
}
}

[/indent]这样试试看看

发布
问题