目录java
傅里叶变换git
matlab代码实现&&仿真github
基频提取比对spa
距离上一次更新博客,已经很久了,相信看了我上一篇文章的,如今对个人这篇文章可能比较期待了,这个更新晚的缘由一个是因为最近课程比较紧,因此对于乐音识别的研究搁置了一段时间,再就是其中也出现了一些问题,致使咱们改变了一下本身的策略。code
进入正题,学太高数的同窗,对傅里叶变化这个概念应该都不会陌生,可是具体是作什么的呢?知乎上以前看到一篇文章,关于傅里叶变换的,讲的很是详细,附带个地址。傅里叶分析之掐死教程(完整版)对于咱们以前的信号,咱们的分析都是在时域上的,对于在时域上的信号
只是根据咱们的量化程度,对于幅度所采起的一个表示方式,可是对于咱们肯定它具体是哪个音阶是没法实现的,因此须要咱们对其进行傅里叶变化,将其从时域信号图转化到咱们的频域上来,而后根据相关的频域参数来肯定咱们其具体是属于哪个音阶。在作傅里叶变化的时候遇到了一个小坑,致使在这上面纠结了好久,一个是由于对于matlab不是很熟悉,再就是自己如今在作的事情就是点歪的一个技能点。经过对声音进行傅里叶变化,咱们也能够作一些颇有趣的事情,好比根据电话按键的声音对于相应的按键的监听,由于在电话出现时,没有数字信号这回事,因此也就不存在一些数字处理器,因此对于电话的按键,是对于电话按键的声音的模拟信号进行监听来肯定的,每个按键都是由两个不一样的频率进行叠加来获得的,因此咱们能够对电话的按键音,进行一个切割,将有声段拿出来以后,作一个傅里叶变化获得其中的两个频率,而后和相依的频率表进行一个比对,这也是以前新闻上说的某少年获取周鸿祎手机号的方法。blog
[y, Fs] = audioread('/Users/chenjensen/Desktop/record.mp3'); plot(abs(fft(y)))
经过audioread来读取咱们的音频文件,这里的y是关于音频的数字信号序列,Fs是咱们的采样频率,经过利用fft获得以下图
咱们以前讲过经过傅里叶变化,咱们能够获得这个声音的频率,彷佛咱们的事情已经结束了,获得一个接近1600的值,这也是以前犯得一个错误,这里提供的声音是咱们中音D,其频率523.25,可是这里获得确实这么大,公式也是没有错的,开始这让我怀疑我才去这种提取基频的方式不对,最终被同窗发现了错误,就是x轴单位的问题,咱们经过fft变化,x轴的最大范围是咱们的采样频率,而其每一个单位确并非1,而是咱们的采样频率/采样点数,按照这种思路再来作一个计算教程
z=44100/length(y)
z = 0.3300图片
经过对原图形进行放大,最后发现该值接近于1590
计算咱们的这两个值的乘积:1590*0.3300=524.7000
和咱们的原始数据523.25很是接近了,咱们经过这个大概能够估计出咱们的音阶了。
固然这里还存在的一个疑问是咱们获得的一个口琴的音,不可能只是单纯的存在一个频率的,一个声音确定是由多个音叠加而成的,只是在该音阶,该种频率表达的更为充分,而后咱们能够利用这个频率来表示这个音阶,咱们要取的频率是其在y轴上的值最大的。同时对于傅里叶的变化咱们获得图形是对称的,咱们只须要取其前面一部分。get
经过对于基频的提取和比对,咱们能够获得咱们的当前的音阶。博客
该文只是单纯针对傅里叶变化展开,链接上篇文章,咱们提取出来有声段以后,就能够对这些有声段进行一个傅里叶变化来获取其频率值,而不是像对其所有进行傅里叶变化。
具体的实现细节,将会在后续文章更新,欢迎各位一块儿交流提高。
下篇更新Android中java代码的具体实现,项目也会在github开源。