音频软件开发中的debug方法和工具

本文系作者原创。如转载,请注明出处。 谢谢!

音频软件开发同其他软件开发一样,都需要去调试。音频软件调试同其他软件调试方法有相同的地方,也有不同的地方,同时调试时还需要借助一些专门的工具,有了这些方法和工具,就能快速的定位问题和解决问题。下面我们就谈谈这些方法和工具。

1,方法

1)log

这是软件调试中最常用的方法,音频调试也不例外。在写代码时加上一定的log, 在出问题时就打开这些log,通过log分析问题出在什么地方。一个好的log体现在如下几点:

a)    要有时间和日期,有时候时间戳对分析问题很重要。

b)    函数入口处和出口处要加上log,有了这就能很快看出函数调用流程。

c)    发生问题时的相关变量值要打印出来,这对分析问题至关重要。

d)    log要分级别,常见级别有error/warning/debug/info等。有时候log打印太多会导致load大从而出现不同的结果影响分析。

2)二分法

当前版本有问题,而以前的某个版本没问题,这说明是近期的某个改动引起的。这时我们就需要用二分法快速找出哪个版本开始出问题的。先把当前版本和那个好的版本中间一分为二,取中间那个版本,看有没有问题,有的话说明这个中间版本之前就有问题了,没有的话说明是这个中间版本后面的改动引入的。这样的话就把范围缩小一半了。在这样继续二分下去,直到最后找到最初出问题的版本。找到版本后再看这个版本加入了几个改动,分析哪个改动最可能引起这个问题,直到最后找到根本原因解决问题。

3)crash的分析方法

写代码crash是难免的,关键是crash后能快速找到原因并最好后面不犯这个错误。通常crash主要有这几种原因:空指针,除零,越界,死循环,当然还有其他的原因。在Linux下有好的工具,很容易查。有些小众的OS没什么工具查crash问题,如果是做底层的可以借助JTAG工具,不然的话还得靠log。Log是实时的还好办,多加点打印总能找出crash的地方。就怕log非实时,这时只能具体问题具体分析了。记得在一个OS下log非实时,一个模块相对独立,只能把函数调用关系和输入参数值都保存在文件里,在Linux下做一个应用程序去读这个保存的文件从而模拟当时的过程,再借助Linux的工具找到crash的地方,最终这个应用程序成了一个工具,以后再遇到类似的问题就能很快解决了。

4)最小系统法

做一个软件系统时刚开始是一个最小系统,即缺了任何一个模块,系统不能用。后来加上一个个功能使系统完备。在写代码时我们可以加上一些标志位使这些后加的功能enable或者disable。这有助于后面出现问题时排查。下图是语音通信的软件框图,最小系统是采集播放编解码网络发送接收等,没有这些不能通话。而前处理的一些模块(AEC/ANS/AGC等)则不是最小系统里面的,它们是后来一步步加上去的。假设系统出问题了,我们先disable前处理的诸多模块,形成最小系统,看有没有问题,有说明问题在最小系统里,再继续调查。没有的话先把AEC使能看有没有问题,有说明问题在AEC里,没有说明问题在ANS或者AGC里。如没有问题继续使能ANS看是否有问题,有说明问题在ANS里,没有说明问题在AGC里。经过这几步基本定位问题在哪个模块里,后面再结合其他方法直到找到根本原因。

音频开发时不管是voice还是music好多问题是音频听下来不对,这时就要用音频特有的debug方法了。

5)dump音频数据

Dump音频数据就是把音频数据dump出来用工具(比如CoolEdit, 后面讲工具时会具体讲)播放,或者看波形,或者看频谱,看是否正确。一般是找几个可能的dump点,进模块前一个dump点, 出模块后一个dump点。如果进模块前dump出来的数据是好的,而出模块后的音频数据是坏的,那么问题就出在这个模块了,再一步步排查,最终找到把音频数据写坏的地方。还是以上面的语音通信软件框图为例,在AEC前设一个dump点,AEC后再设一个dump点,如果AEC前的音频数据是好的,AEC后的音频数据不好了,问题肯定出在AEC里。

Dump音频数据也有几种不同的方法,在不同的场合用不同的方法。

a)把音频数据写进指定的文件里,问题复现后把这个文件导出来用工具分析。

b)把音频数据放进RTP包里发送到指定的IP地址上,用抓包工具(比如wireshark, 后面讲工具时具体讲)抓到这些包。由于是PCM数据,在wireshark上可以直接听或者看波形。这多用于语音通信场景。

c)有时候有些模块对自己是黑盒的,比如在linux下kernel space的音频驱动对做use space的来说就是黑盒。在use space里调查下来音频数据没问题,但是最终从扬声器或者耳机出来的音频是有问题的,这时可以用一根音频线一头连着出问题的设备的耳机,另一头连着电脑,复现问题,用CoolEdit把出问题时的音频录下来,先听确认问题出在这个黑盒模块里,然后看波形,是否有规律,如果有规律,好查一些,没规律再具体问题具体分析。

6)loopback音频数据

loopback音频数据就是形成回环,从而来排查问题。还是以上面的语音通信软件框图为例,有几种不同层次的loopback,见下图:

1)    把采集和播放形成loopback,即把采集到的音频数据立刻payback出来,听下来是好的说明音频驱动没问题,不好说明问题在音频驱动里面。

2)    把前处理后的数据和播放形成loopback,即把ANS后的PCM数据直接播放出来,听下来是好的说明前处理没问题,不好说明问题在前处理里面。

3)    把编码和解码形成loopback,即把编码后的码流立刻放进解码器得到pcm数据再playback出来,听下来是好的说明问题出在网络侧,不好说明问题出在编解码里面。

通过上面几个loopback基本上可以定位问题出在哪个模块里,再在这个模块里仔细调查直到找到根本原因。

2,工具

上面讲方法时提到了几个工具,如CoolEdit,下面具体讲。

1)CoolEdit / Audition

这应该算是做音频开发的必备工具了。以前叫CoolEdit,后来被Adobe收购重新包装后形成了Audition。我个人还是习惯于用CoolEdit,原因一是用习惯了,二是CoolEdit可以保存成PCM文件,而Audition却不可以,做音频开发的保存成PCM文件最方便。

用CoolEdit可以听音频是否正常,也可以看波形,在出问题时看波形是否有规律,还可以看频谱。同时还可以生成一些特定的音频文件用于去调试。比如调试音频算法时用一个时间相对较长的(> 1秒)的音频文件会很不方便,主要是因为log多,不便于分析。算法通常一帧为10ms或者20ms,需要几帧就可以调试算法了。这时用CoolEdit做一个几十ms的PCM文件给算法调试用。再比如用CoolEdit做一个20HZ到20000HZ的扫频文件作为某个算法或者某个系统的输入,看这个算法或者系统的频响如何。

CoolEdit的具体使用可以看help文件,或者看网上的文章,这里就不详细讲了。

2)Wireshark

Wireshark主要用于语音通信场景,抓网络上的语音包。当然它也可以抓其他类型的包,在做音频开发时就是抓语音相关的RTP/RTCP包了。抓到包后可以看某个具体包的RTP/RTCP属性,比如sequence number/time stamp等,从而去分析定位问题等。Wireshark也可以分析丢包率等,还可以播放codec 为g711的语音包,当然还有其他用途,这里就不一一说了,有需求的可以到网上看具体的文章。

3)mediainfo

Mediainfo主要用于音乐场景,用它可以看到一个音乐文件(例如MP3)的属性,有采样率/声道数/codec类型/码率等。如果在log中看到的打印值和mediainfo中显示的值对不上,说明读取音乐文件属性的代码有问题。

4)GoldWave

GoldWave也主要用于音乐场景,用它来做采样率/codec/码率等的转换。支持的采样率、codec、码率都特别多,对调试有不少帮助。例如某个系统要支持采样率为11025HZ的音乐文件,但是市面上的音乐文件一般为44.1KHZ或者48KHZ的,这就需要专门的工具去做转换,从而得到想要的文件。然后拿这个文件去调试测试看系统是否支持采样率为11025HZ的音乐文件。

关于音频debug的方法和工具暂时就先谈这么多,以后想到了被遗忘的以及有新的会及时补充。也欢迎大家补充,形成一个好的debug方法和工具集,对大家都是益处多多。谢谢!

时间: 2024-12-18 20:14:31

音频软件开发中的debug方法和工具的相关文章

Atitit 软件开发中 瓦哈比派的核心含义以及修行方法以及对我们生活与工作中的指导意义

Atitit 软件开发中 瓦哈比派的核心含义以及修行方法以及对我们生活与工作中的指导意义 首先我们指明,任何一种行动以及教派修行方法都有他的多元化,只看到某一方面,就不能很好的评估利弊,适不适合自己使用,犹如盲人摸象,虽然都对,但是并不完整 1. 瓦哈比教派的核心思想1 1.1. 归一化,反对多神..反对邪教与不良的 修炼方式1 1.2. 规范化,标准化最佳实践 圣训立国,依法治国1 1.3. 主张整肃社会风尚,净化人们的"心灵1 1.4. 倡导团结,团队建设1 1.5. 回归传统,轻量化1 2

对软件开发中uml建模的理解和图形整理(一)

由于uml(统一建模语言)在开发中经常会用到,特别是在软件开发中的OOAD阶段,因此要理解和使用uml显得尤为重要.在uml开始之前,咱先回顾一个OOAD.OOP的主要特征. OOAD:根据面向对象的方法学来对软件系统进行分析和设计的过程.它包括OOA 分析阶段和OOD设计阶段.其中分析阶段主要解决"What to do?"的问题,而设计阶段主要解决"How to do?"的问题.具体来说就是:在OOA分析阶段咱要做的主要工作就是建立对业务问题域的视图(建立模型).

软件开发中的自测及C代码示例

在软件开发中,程序自测是一个永远都绕不开的话题.很多开发人员以写出有难度的代码为荣,但却不重视对自己编写的代码进行测试,这导致了最终到达客户手中的产品质量不高,bug频发,损害了公司的形象.对于一个开发人员来说,我们应该将开发和自测置于同等重要的地位,我们花在自测上的时间要不比开发少.能否对自己编写的代码进行充分的自测也是检验一个开发人员水平高低的标准之一. 自测方法 根据所编写的程序的特点,自测方法大致有如下几种: 第一种,利用模拟工具进行自测.这种方法适用于需要其他模块(尚不具备)发过来的消

IOS开发中重写init方法使用需谨慎

IOS开发中重写init方法使用需谨慎 今天在写一个小软件的时候出现一点问题,这个软件的功能是搜索全国学校,首页就是搜索输入框,在框中输入完要查询的学校所在省份,点击buttom后就会跳转到对应的视图控制器中,然后把搜索结果呈现在一个TableView上,但是我在调试时,每次输入完然后点击搜索按钮时,弹出结果列表总是空的,我需要返回到首页再点击一次搜索才会出现结果,而且我在首页更改搜索关键字之后,点击搜索,结果还是上次的搜索结果,必须返回点击一次才会出现这次的搜索结果. 经过大神指点,原来这个问

软件开发中的工作事务与微技能分级评估

工作三四年后,是否感觉自己开始做一些没有提升的事情?是否在做一些低水平重复建设的事情呢? 通过对软件开发中的工作事务与微技能进行评估和分级,可以清晰地理解自己的工作构成.评估自己的当前水平.定位下一步发展的方向和思路. 难度系数 *** 1 1.  完成初级的页面测试: 2.  编写简单非专业的文档: 3.  能够理解基本业务: 4.  日常普通的交流: 难度系数 *** 2 1.  完成一个简单的脚本实现临时需求, 15-20 min: 2.  完成一个函数或方法的单测, 5-15 min ;

软件开发中 SQL SERVER 任务的用法

在软件开发中,经常性会用到定时任务.这个时候你可能会想到线程.但是事实中,线程方法比较麻烦.容易出错,资源竞争等问题,设计起来让你很头痛. 现在给大家提供一个新的思路,用SQL SERVER 的任务管理器来解决问题. 解决下列问题: 1.商品有购买时间限制.比如定时上线,下线.竞拍结束自动通知用户. 2.数据库中某个数据发生了变化,需要执行一段代码块(这里面的代码并不是存储过程代码,意指c#,JAVA等代码). 3.某个数据发生了变化,需要执行某个动作.(不是立马执行) 针对上面的问题,我们总结

软件开发中部分代码的注解

初次接触软件开发,先是阅读别人的代码.学习别人的一些经验!下面是遇到的一些代码及注解! @ParentPackage("basePackage")    // 默认继承struts.xml文件的<package name="basePackage" extends="struts-default"> /* * 函数功能:将对象转换成Json字符串,并响应回前台. * 转换的原因:页面使用的数据格式为JSON * 一般我们在服务端中使用

Atitit. 软件开发中的管理哲学--一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向

Atitit. 软件开发中的管理哲学--一个伟大的事业必然是过程导向为主    过程导向 vs 结果导向 1. 一个伟大的事业必然是过程导向为主 1 1.1. 过程的执行情况(有明确的执行手册及标准) 2 1.2. 麦哲伦的事例证明了过程导向的重要性 2 1.3. 婆罗门教大师商接罗所 过程导向,属于上梵,结果导向,属于下梵 2 1.4. 罗马皇帝诚思录上,说人生本身就是过程导向, 2 1.5. 过程导向基本属于战略层面,侧重与长期,而结果导向只是战术级别,短期容易短视 3 1.6. 任何组织的

现代软件开发中现代软件工程的合理运用

进入新时期以来,我国的社会经济水平与科学技术发展水平都上升到了一个新的高度,不论是在社会生产中还是在日常生活中,计算机信息技术都得到了普遍的运用.而计算机信息技术主要是在软件的支持下进行系统运行的现代科学技术,在现代软件开发中,现代软件的整体特点与结构都会对现代软件工程在其中的应用产生重大的影响,因此,必须要采用最合适的软件工程方法,让现代软件工程在现代软件开发中得到更加合理的应用.