Wi-Fi Party 开发笔记

基本思路

1、麦克风录制唱歌声音
2、通过UDP广播把歌声和来自文件的音乐发出去
3、局域网内其他设备接收并播放

这样大家就可以一起听同样的歌,一起唱歌。

难题

1、API

显而易见,我这个app适合用最底层的音频API,直接跟驱动打交道、获取PCM数据就很好,这样子延迟最低。我可是找了好一会才找到iOS AudioUnit的API,官方的文档写的也是特别垃圾,一点例子都没有,例子代码还是别人博客里找的。官方文档写的也比较模糊、不好理解。这里说说我的理解:同一个unit中的多个element之间没有任何关系。 理解了这一点再去看官方文档和别人的博客,应该会好很多。不要被苹果的那张图给骗了。

2、不直观,难调试

我这个app把录制到的音频数据直接用socket发出来,一来不知道发出去的到底是不是录制的声音,而来不知道接收以后的处理到底对不对,因为整个过程都是在处理字节。

signed or unsigned?

我犯了一个很大的错误:用有符号整数的方法来求无符号整数的数据的平均值。我当时还没搞清楚iOS的pcm格式是无符号的。这就导致多个音轨混合时出现莫名其妙的杂音,还很难找出来问题所在。

缓冲区大小这么重要?

还有一个今天才解决的问题,就是嗒嗒嗒的杂音:发送设备发得好好的,接收设备就会自己发出嗒嗒嗒的杂音。我一度认为是:
1、发包/收包的时候没算好地址,把别的东西参杂进去了
2、混合音轨的时候对边界情况处理得不够好
3、UDP+Wi-Fi太tm不靠谱了
于是针对1,2我就各种抓包,针对3我就增加重发次数。
结果最后发现是:缓冲区设小了。
话说是怎么发现的呢?我较为不抱希望地去分析了一下缓冲区的读写情况:有没有经常写不下或者读不出来?然后我发现缓冲区经常读不出来,也经常写不下。

教训

不要偷懒

我一开始觉得:我自己在家里就一个Wi-Fi连接这么两三个设备,别人说的复杂的网络状况我肯定遇不到啦!像什么丢包,那应该很少;我包都没有经过NAT,顺序打乱这种事情更是不可能发生的啦!
结果这些事情都发生了。
对于丢包,我只好加了重发,然后就要在包头部加入序号……越写到后面越觉得自己写了一遍tcp协议
对于顺序打乱,其实我一直都没发现,一直都以为是丢包。既然我有重发,那接收端理应收到好几份同样的包。于是我就让接收端显示一下重复收到了几次。其实我之前还偷了懒:NSNumber比较大小不方便,于是我直接:只要包序号跟上次不一样就认为是新的包。
结果我发现哪怕我重发10次也有很多时候只接受到一次。于是我就猜测:可能是,比如说,第14个包在第15个包之后才到来,但是因为我的智障的判断逻辑,就会认为是新的包,这样子这个“新的包”自然就很可能只重复接收到一次,而且还解释了为什么有很多杂音。
我于是改进了判断逻辑,序号要更大才行。我就顺便让它输出了一下序号小但是到的时间晚的包有多少,结果挺多的,出乎我的意料。看来乱序这种事情不是要多条网络线路才会发生;只有一条线路也会发生!

看官方文档

很多老的API官方文档非常简陋,应该去苹果的文档归档里面看当年对这些API的介绍、文章还有非常重要的示例代码!复制粘贴才是第一生产力!死读文档读到死都不知道怎么写!
我在使用Extended Audio File Services转换格式的时候,总是会报错:

ExtAudioFileSetProperty(song, kExtAudioFileProperty_ClientDataFormat, size, &(self->room->stream_format))
ExtAudioFile.cpp:664:SetClientFormat: about to throw 'fmt?': create audio converter

结果发现是设置目标格式的时候漏了一个:

self->stream_format.mFormatFlags=kAudioFormatFlagIsPacked;

没有这一句的情况下用Audio Unit录音、放音都是没问题的,谁知道解码的时候出问题?而且官方文档里根本没有写。所以说,特别是对于Audio Toolbox这种底层、API不友好、用的人又少(网上有关博客并不多)的东西,就要多看看官方的示例代码。里面的注释也很清楚,对于各种意外情况(如被中断等等)的处理也非常完善,很值得我去学习。(重点:值得=>我还没学)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值