≡
导航
搜索
教程
插件
模型
模板
博客
交易
朋友
编程语言分享讨论总汇吧
已关注 | 取消
+关注
关注:
10
帖子:
1,222
签到
06月20日 尚未签到
看帖
图片
精品
视频
共有回帖数
0
个
播放器频谱可视化与语音的智能识别思想 Part3
只看楼主
收藏
回复
幻梦如戏
等级:
阅读须知:
1.本教程送给那些想做个音乐播放器或者想在XX创新赛XX机器人赛上混个奖的
2.本篇我不打算再用教程这两个字了,因为教程就要一步一步地告诉你这里为什么要这么写,这段代码的这行是什么意思,神马是临界区之类的七七八八的东西,这里传达的更多的是一种思想,我将贴出关键的代码与API并解释其中的意义,不过具体是怎么实现的请看代码,我相信我的代码写的并不奇葩
3.傅立叶变换是本篇的灵魂,假如非工科出生或没有高等数学基础可能对DFT(离散傅立叶变换)FFT(快速傅立叶变换)并不感冒,你可以去百度看看,如果你觉得实在困难本篇将粗略地解析傅立叶变化的意义与作用还有就是一些关键的参数(没有这个也许看一些代码就是一头雾水了),对于音乐频谱分析应该能够凑活用了,要是你觉得还是麻烦,你可以直接调用我封装好的类
4.请认真阅读本菜菜前两篇教程(非常重要)
5.阅读本篇需要c/c++与一些声学基础,额,那句老话,不保证全部人都能看懂
现场直播,现场码字,更新较慢,稍安毋躁,记忆讲解,并非全对
第一部分:关于声音的一些关键知识
我们生活中存在各种声音,这点我们都知道,高中物理告诉我们,声音在介质中传播,不同的声波相互进行叠加,相同频率的波形叠加形成共振,空气中存在有各种的波动,然后传递到我们的耳朵当中,我们就能听到其中的声音
但是我们知道,两个人同时对我们讲话,只要不说的太快以至于我们不会一心二用,我们都能够知道他们俩说的是什么而不会混淆,why,因为每个人的声带长得都不一样,他们发出来的声音的频率不一样,我们才能够区分出这个声音是谁发出的,现实生活中你也许不需要看到一个人只要远远地听到这个人的讲话你就知道是这个人来了而不是别人,交响乐中你也能识别出至少几种乐器在这场交响乐中是有的,而这来源就是频率不同
但现在问题也来了,在上一章讲到的计算机采样我们知道,计算机每间隔一段时间对声波进行采样,而这声波是叠加过的,这种采样方法无法专门的记录某一特定频率的声波(当然有采集特定频率声波的电子元件,用的好像是共振的方法,扯远不讨论),这样,也许你能听到计算机把声音放出来却不知道是怎么回事,怎么办,傅立叶大神给了我们答案
第二部分:说说傅立叶大神
傅立叶大神对波有了新的理解,他认为,任何波形都可以分解成正弦信号与余弦信号的叠加形式,话句话说,他将一段信号分解成了不同周期不同振幅的正余弦叠加,不同的周期也就是不同的频率,那么只要将那些频率相同的正余弦进行叠加(共振)我们就能够在一段时域信号中区分出这一段时域信号中X频率的强度是多少,可以用来判定这段时域信号中存不存在该频率的声波,也许你认为这没什么,但是这个理念相当的NB,当你知道这能用来干什么后,只不过当时的拉格朗日大神觉得这个是不可能的,因为正余弦波无法表示出一个带尖角的波形,关于这点,确实如此,但是我们采用极限的思想,就是所谓的无限接近到几乎可以忽略不计,傅立叶大神是对的(不知道为什么,似乎每一本介绍傅立叶变换的书都有这个小故事)
关于傅立叶变换的意义
就说和本篇有关的两点
1.截取一段PCMBuffer中的数据进行傅立叶变换,得到的是不是这段音频的不同频率声波的强度?-----是,然后将不同频率的声波强度转换不同位置的柱形不同位置的高度是不是就是我们见到的音乐播放器中的频谱分析-----是!第一点解决
2.计算机对一个人进行录音,不同人发出的声音频率是不是不同-----是(语音识别身份),说不同的字是不是有不同的声波强度(就是我们说的你讲话大声小声)----是(语音文字识别),实际上语音识别身份听上去是一个很碉的技术,依靠他你可以为你电脑加一个声控锁,后面那个更碉,但其中又涉及了更多更碉的东西,而本篇无能为力,但看完本篇后你可以尝试写一个语音识别身份的程序或者将它嵌入到你的单片机中,这绝对可以让你在同学中装X一番
网上找个免费音乐播放与频谱分析的第三方库真心难找,不知是不是本菜菜无能,至今未找到,那么现在我们不多废话直接上代码实战,假如你信得过本菜菜的话,你可以直接将代码调用到你的项目中,当然我鼓励你自己写一遍。
在上代码之前,我先吃个饭
Next:说说龟速的DFT
吃饱继续
DFT的共振思想
正弦波是一个周期函数,换句话说,要是你把正弦波上的点全部加起来,它的最终的和是0,在数学中,如果从声音波形的某一个点(假设它大于0)开始采样,那么,下次采样的时候也会在同样的位置采样,经过叠加后,最后的值会越来越大,这很像声音中的共振
也就是说,想判断一个声音波形是否存在某个频率的声波,就用一个特定频率的波与另一个待测声波的点相乘起来,然后叠加后的结果就是最终的振幅的值,依靠这个值的大小来判断该波段该频率的强度到底有多少
但仅仅只有正弦波是不够的,因为待测波的相位可能会影响到结果(波峰波谷不能穿透每一个点),因此我们还需引入余弦波来弥补,避险错过待测波的波峰
那么知道了如何测是否存在该频率的波,我们能得到多高的频率
其实在上上章节的香农采样定理我们知道“在不会混淆结果的情况下,可采样的最高频率是采样频率的一般”,那么对于我们常见的44100hz的采样频率而言,最高的采样频率的22050,也就是说你仅仅需要对该范围的频率进行检测。那么我们贴上DFT的计算代码
DFT在实际中并不适用,当buffersize(这个buffer指的就是之前的SoundBuffer中的数据,因为SoundBuffer中的每一个字节(signed char)就代表着采样声波某一点的振幅(假如是16位的采样质量那就代表高/低位)(强度) 稍微大点 ,就会让你的频谱分析成为一个悲剧,
之后图灵大犇和另一个某大神共同发明了信息学工学数学界内被膜拜的FFT,也就是快速傅里叶变换,这种变换对于DFT来说并没有什么改进,本质上还是傅里叶大犇的理论,然而这种算法对于计算机而言,常常是快了几个数量级, 而且数据量越大,节省的计算量越多
但是,这里不是数学吧,本菜菜也不打算讲这种算法,有兴趣的话可以在网上查找相关资料,你可以将它当作DFT来用,我着重讲解函数功能
step1:善用初始化让变换更快
切记,开平方,sin,cos,tan甚至对自己严格要求时的对浮点数的操作都是龟速的,大凡需要多次循环对运行效率要求很高的尽量避免,必须使用可以考虑创建一个表在初始化时候就计算完成,在需要使用的时候查表调用
本函数作用:实现上面的方案,创建一个表在初始化的时候计算好那些复用度很高的数据,之后只要查表就能得到相应的数据了。
step2:计算
其中,psample就是指向我们需要做FFT的数据指针,SampleSize就是指这段数据的大小,本函数返回一个float指针,指向一个一维数组,里面转载着不同频率的波的强度,大小在讨论DFT中讲到过了,是pSample的二分之一
关于这个类的使用
1.声明该类的一个指针,new一个实例,参数是你期望分析的数据的长度
2.在需要的地方调用计算并放在你需要的地方,假如你需要计算相应的频率是多少,请运用该公式
fn=i*Fs/N其中,i是对应数组下标,Fs是采样频率(音乐播放中就是SampleRate),N是该次样本的数目。fn就是其对应频率了
楼主 2015-11-12 20:50
回复
共有回帖数
0
个
回 帖
表情
图片
视频
欢迎来到本吧,您可以在此发帖和众多大咖交流学习.
选择或直接输入昵称
Tips:支持QQ截图直接粘贴
发表
登录直线网账号
自动登录
忘记密码
免费注册
本吧信息
查看详情
吧主:
禾木
本吧公告
好好学习,天天向上!
我常逛的吧
我管理的吧
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈
|
关于直线
|
版权声明
|
会员须知