OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4793|回复: 10

网络传输音频数据的疑问求解答

[复制链接]

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
发表于 2022-9-19 15:44:19 | 显示全部楼层 |阅读模式
1金钱
核心代码如下
if(err==ERR_OK)  //接收到数据
                {
                        //printf("接收到不为空的数据");
                        LED0 = !LED0;
                        OS_ENTER_CRITICAL(); //关中断                                       
                        memset(udp_demo_recvbuf,0,NET_RMEMO_MAXLEN);  //数据接收缓冲区清零
                        for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
                        {
                                //判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于
                                //的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
                                if(q->len > (NET_RMEMO_MAXLEN-data_len))
                                        memcpy(udp_demo_recvbuf+data_len,q->payload,(NET_RMEMO_MAXLEN-data_len));//拷贝数据
                                else
                                        memcpy(udp_demo_recvbuf+data_len,q->payload,q->len);
                                data_len += q->len;         
                                //printf("data_len = %d",data_len);
                                //printf("q->len = %d",q->len);
                                //printf("buf长度:%d",strlen(udp_demo_recvbuf));
                                if(data_len > NET_RMEMO_MAXLEN) break; //超出UDP接收数组,跳出       
                        }
                        OS_EXIT_CRITICAL();  //开中断
                        data_len=0;  //复制完成后data_len要清零。               
                        do
                        {
                                VS_Send_MusicData(udp_demo_recvbuf+n);
                                n+=32;
                        }                                       
                        while(n<256);
                        n=0;
                        netbuf_delete(recvbuf);
                }


从网络接收音频数据再传送给VS1053,结果能播放出音乐。
问题是我用软件查看了音乐文件的16进制形式,发现有00即空字符,我想如果把空字符传给udp_demo_recvbuf的话udp_demo_recvbuf后面就不会有数据了,因为字符串总是以'\0'作为结束符,那么会造成00后面的数据会被漏掉导致数据没有正确传输。但实际情况是能正常听到音乐,这是为什么?

最佳答案

查看完整内容[请看2#楼]

你提醒我了,我猜到应该是利用了数组越界,00后面并没有丢数据,那个函数使用数组下标来一个个传数据,越界访问 u8 VS_Send_MusicData(u8* buf) { u8 n; if(VS_DQ!=0) //送数据给VS10XX { VS_XDCS=0; for(n=0;n
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-9-19 15:44:20 | 显示全部楼层
驭剑的秘密 发表于 2022-9-20 09:39
你放出来的这段代码我也用过,我昨天看了下,得到的结论是就算是前几个字节有00,后面的200多个字节也是 ...

你提醒我了,我猜到应该是利用了数组越界,00后面并没有丢数据,那个函数使用数组下标来一个个传数据,越界访问
u8 VS_Send_MusicData(u8* buf)
{
        u8 n;
        if(VS_DQ!=0)  //送数据给VS10XX
        {                                    
                VS_XDCS=0;  
        for(n=0;n<32;n++)
                {
                        VS_SPI_ReadWriteByte(buf[n]);        //这里应该越界了,就算中间有00,也能通过数组下标强制访问                       
                }
                VS_XDCS=1;                                       
        }else return 1;
        return 0;//成功发送了
}
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-9-19 16:21:41 | 显示全部楼层
粗看了一下,你设定拷贝数据长度的时候使用strlen(udp_demo_recvbuf),00后面的不计算长度了,就可以漏掉后面的数据
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-9-19 17:28:37 | 显示全部楼层
驭剑的秘密 发表于 2022-9-19 16:21
粗看了一下,你设定拷贝数据长度的时候使用strlen(udp_demo_recvbuf),00后面的不计算长度了,就可以漏掉后 ...

我不是想漏掉数据,按照代码的逻辑来看是要漏掉数据的,理应放不出来音乐,可是跑起来是能播放的,这是我不懂的
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-9-19 17:35:20 | 显示全部楼层
laugh0 发表于 2022-9-19 17:28
我不是想漏掉数据,按照代码的逻辑来看是要漏掉数据的,理应放不出来音乐,可是跑起来是能播放的,这是我 ...

我知道你的意思,他能放出音乐是因为VS_Send_MusicData你这里每次都是32个字节进去,一小段00对解码出来的效果影响不大,大概的解释就是如果一秒钟播放100段32个字节解码出的音频,其中99段没被你的00打乱,那你在这一秒内肯定听不出区别,你多弄几段00来打乱他的解码,就会听见风声或者是哗啦啦的水声一样的音效
又菜又爱指点
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-9-19 17:37:32 | 显示全部楼层
laugh0 发表于 2022-9-19 17:28
我不是想漏掉数据,按照代码的逻辑来看是要漏掉数据的,理应放不出来音乐,可是跑起来是能播放的,这是我 ...

至于为什么没有漏掉数据,我觉得是因为拷贝长度并没有因为遇到00而改变,我看代码里的拷贝长度跟遇不遇到00好像没关系
又菜又爱指点
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-9-20 09:29:01 | 显示全部楼层
驭剑的秘密 发表于 2022-9-19 17:35
我知道你的意思,他能放出音乐是因为VS_Send_MusicData你这里每次都是32个字节进去,一小段00对解码出来 ...

但是我想00后面的数据会影响吧,比如每次收256byte数据,这段数据里如果前几个字节有00的话,那么buf就只会保留前几个字节,后面200多个字节就丢了,这丢的200多个字节难道影响不大吗
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-9-20 09:39:10 | 显示全部楼层
laugh0 发表于 2022-9-20 09:29
但是我想00后面的数据会影响吧,比如每次收256byte数据,这段数据里如果前几个字节有00的话,那么buf就只 ...

你放出来的这段代码我也用过,我昨天看了下,得到的结论是就算是前几个字节有00,后面的200多个字节也是不会丢失的,因为他拷贝的长度始终是固定的,除非把两条拷贝数据的代码换成memcpy(udp_demo_recvbuf+data_len,q->payload,strlen(udp_demo_recvbuf));,才会导致长度因为00所在的位置产生变化,从而丢失00之后的数据,我昨天回复的影响不大是因为数据没有丢失,你手动加入的00字节影响了原本的解码,这个00所在的那一小段数据会解码出不一样的声音,但由于你手动加入的00并没有分散占据所有的数据小段,也就导致前后的数据解码出的声音都是正常的,只有这一小段声音不正常,播放的速度特别快,不足以被听出来
又菜又爱指点
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-9-20 10:21:56 | 显示全部楼层
u8 VS_Send_MusicData(u8* buf)
{
        u8 n;
        if(VS_DQ!=0)  //送数据给VS10XX
        {                                    
                VS_XDCS=0;  
        for(n=0;n<32;n++)
                {
                        VS_SPI_ReadWriteByte(buf[n]);        //这里越界访问               
                }
                VS_XDCS=1;                                       
        }else return 1;
        return 0;//成功发送了
}
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-9-20 10:24:22 | 显示全部楼层
应该是越界,我打印buf确实00后面肯定没有,但用buf[n]就能访问00后面的数据了
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-9-20 16:03:12 | 显示全部楼层
laugh0 发表于 2022-9-20 10:24
应该是越界,我打印buf确实00后面肯定没有,但用buf[n]就能访问00后面的数据了

你打印的那条00后面没有是因为你使用的strlen(udp_demo_recvbuf),strlen遇到0就不计算长度了,你拷贝的长度不是用的strlen,所以打印出来的长度不是最终参与解码的数据长度,要打印出最终参与解码的buf长度得用sizeof(udp_demo_recvbuf)/sizeof(udp_demo_recvbuf[0])
又菜又爱指点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 04:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表