wav2midi 音乐旋律提取算法 附可执行demo
前面提及过,音频指纹算法的思路。
也梳理开源了两个比较经典的算法。
https://github.com/cpuimage/shazam
https://github.com/cpuimage/AudioFingerprinter
后来一段时间,稍微看了下这两个算法,还有不少可以精简优化的空间。
例如抗噪,特征有效性等优化思路。
音频指纹切片后的hash特征信息还是太多了,
不过作为哼唱搜歌的基本应用,是足够的了。
不过我觉得还是可以再进一步提取歌曲的旋律特征的,在音频指纹的基础上更进一步。
旋律是最重要的音乐要素之一,多应用于音乐内容分析、音乐创作、音乐教育、抄袭检测等方面。
主旋律提取旨在从一段音乐中自动估计对应于主旋律单音音符序列的音高或基频。
流行音乐一般属于复杂的多音音乐,因此主旋律提取面临着许多挑战。
在这里要特别说一下,音频处理领域碰到的问题都是相似的。首当其冲主要是噪声,其次是音量和语速。
特别是在一些场景下的asr识别,例如实时对话,同声传译之类环境下,语速和音量的干扰影响很多时候多过于噪声。
而很多提供asr服务的厂商对这类情况支持不佳,而据我所知,讯飞的asr中是有内置前处理算法的。
好像有点偏题了,回到主题上来。
也就是说不管做音频还是音乐 上面提到的问题都会造成一定精度影响。
音频前处理算法是非常重要的,一直在做这方面的研究工作,前面着重于降噪和增益方向,下一步应该会着重在语速方面的研究。
而刚才提到的旋律,也可以认为是语速的一个点。
旋律,节奏,节拍,精确准确度从另一个侧面就可以评估语速,以及风格内容。
所以提取旋律节奏是一个非常值得研究的课题。
也许大家最熟悉的应用场景应该是 游戏节奏类app或者唱K的旋律评分系统。
关于旋律提取这方面的资料比较有限。
在这方向上面,一开始我也是有点蒙圈。
直到我看到一个思路,我突然间豁然开朗。
那就是将歌曲音频 转换为midi电子音乐。
众所周知,midi电子音乐体积非常非常小,在游戏领域应用非常广,几乎是标配。
例如超级玛丽的背景音乐,经典中的经典。
那么是不是可以实现一种算法,将音频转为midi,作为此段音频的指纹呢?
理论上,完全可行,而且刚才提到的唱K的评分系统就是类似的实现。
参照下图:

上面是一段音乐,下面是其对于的midi。
把这个图放大给大家感受一下。

是不是有似曾相识的感觉。
KTV 的节奏条。
所以毫无疑问,KTV的评分系统极其有可能就是采用了MIDI作为声纹进行相似度匹配,
最后给出评分。
当然关于旋律提取有很多不同的实现,不过,大多数算法都有3个共同的目的,
分别是算法的速度性能(复杂度),最终效果,抗噪抗干扰。
针对这三个方面,各有各的技巧。
如果能兼顾三者,无疑是最佳的。
而关于wav转midi的资料,真的是极其稀少。
大概有:
1. https://github.com/mrk21/wav2midi
https://mrk21.kibe.la/shared/entries/3931bfea-0f31-4aa1-9e72-b7cd6f010697
2.https://github.com/justinsalamon/audio_to_midi_melodia
http://www.justinsalamon.com/melody-extraction.html
等
仔细学习查阅之后,你会跟我一开始一样,一脸懵逼。
首先,第三方依赖特别多,也就意味着,这个算法并不简单。
就效果对比而言,audio_to_midi_melodia 更佳,当然深度学习大火之后
也有人在尝试通过深度学习的方式,建立wav 到 midi的映射。以寻求新的突破。
当然还在试验阶段,暂时还没看到有特别优秀的模型放出。
不过可以拭目以待。
而这个算法有多复杂,看下算法的流程图:

说难也不难,说简单也不简单。
大部分环节是为了解决语速,音量,噪音所造成的误差问题,使得算法更佳稳定,更鲁棒。
根据这个思路,自行实现算法并不困难。
改进算法思路的首要前提,理解算法的核心思想,
所以至少你要把整个算法思路实现一遍,加深理解,不管能否理解到精髓。
然后站在巨人的肩膀上,继续改进。
这个算法花了我一段时间去实现,原本预计几个星期可以搞定,
但是后来因为其他原因搁置了。
趁国庆假期,捡起来,把一些工作继续推进,复现了该算法。
这个过程挺漫长的,有不少环节还可以进一步改进优化。
不过这是后面的工作了。
算法暂没有开源计划,放出demo 供大家评测。
预处理算法,等响度滤波已经开源:
项目地址:
https://github.com/cpuimage/EqualLoudness
其他相关算法也将陆续开源.
这个方向的算法,
有一个专用名词叫做mir, 全称 为 music/audio information retrieval/signal processing 。
有兴趣的朋友,可以查阅一下相关资料。
基本上都是dsp(数字信号处理)。
学习dsp必须把傅里叶变换好好理解一下。
为了理解傅里叶变换的算法思路,我把市面上能找到的实现,都过了一遍。
用纯c 进行学习复现,也足足花了我1个多月的业余时间,
就差喷一口老血出来。
可执行demo下载地址:
https://files.cnblogs.com/files/cpuimage/wav2midi.zip
使用方法:拖放wav文件到可执行文件上即可。
或者采用命令行 wav2midi.exe demo.wav
执行后生成 demo.mid 文件。
目前仅支持wav的1通道和2通道格式,其他的格式暂没做支持。
在学习音频算法的时候,经常会联系到图像方面的算法,进行类比,举一反三。
都有共通的地方,就看你怎么应用了,温故而知新。
用以前说过的一句话来总结就是,
任何算法都有缺点,但是一定要用它最优秀的思路。
就好比说,用人只要用其长处,天下皆是可用之才。
若有其他相关问题或者需求也可以邮件联系俺探讨。
邮箱地址是:
gaozhihan@vip.qq.com
wav2midi 音乐旋律提取算法 附可执行demo的更多相关文章
- 音频降噪算法 附完整C代码
降噪是音频图像算法中的必不可少的. 目的肯定是让图片或语音 更加自然平滑,简而言之,美化. 图像算法和音频算法 都有其共通点. 图像是偏向 空间 处理,例如图片中的某个区域. 图像很多时候是以二维数据 ...
- PIE SDK水深提取算法
1.算法功能简介 水深提取算法就是根据输入的水位设为d,dem设为h 这两个数据做一个差值运算,则水深计算公式为d-h;本示例中的是基于洞庭湖提取的水体矢量文件的范围来计算dem和水位25米的差值. ...
- 磨皮美颜算法 附完整C代码
前言 2017年底时候写了这篇<集 降噪 美颜 虚化 增强 为一体的极速图像润色算法 附Demo程序> 这也算是学习过程中比较有成就感的一个算法. 自2015年做算法开始到今天,还有个把月 ...
- 三维等值面提取算法(Dual Contouring)
上一篇介绍了Marching Cubes算法,Marching Cubes算法是三维重建算法中的经典算法,算法主要思想是检测与等值面相交的体素单元并计算交点的坐标,然后对不同的相交情况利用查找表在体素 ...
- TextRank:关键词提取算法中的PageRank
很久以前,我用过TFIDF做过行业关键词提取.TFIDF仅仅从词的统计信息出发,而没有充分考虑词之间的语义信息.现在本文将介绍一种考虑了相邻词的语义关系.基于图排序的关键词提取算法TextRank [ ...
- mser 最大稳定极值区域(文字区域定位)算法 附完整C代码
mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...
- 人脸姿态校正算法 附完整C++示例代码
在一些特殊情况下,经常需要依据图像中的人脸,对图片进行倾斜矫正. 例如拍照角度幅度过大之类的情况,而进行人工矫正确实很叫人头大. 那是不是可以有一种算法,可以根据人脸的信息对图片进行角度的修复呢? 答 ...
- 关键词提取算法TextRank
很久以前,我用过TFIDF做过行业关键词提取.TFIDF仅仅从词的统计信息出发,而没有充分考虑词之间的语义信息.现在本文将介绍一种考虑了相邻词的语义关系.基于图排序的关键词提取算法TextRank. ...
- 关键字提取算法TF-IDF和TextRank(python3)————实现TF-IDF并jieba中的TF-IDF对比,使用jieba中的实现TextRank
关键词: TF-IDF实现.TextRank.jieba.关键词提取数据来源: 语料数据来自搜狐新闻2012年6月—7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据 数据处 ...
随机推荐
- 沉淀,再出发:jQuery的初步了解和入门
沉淀,再出发:jQuery的初步了解和入门 一.前言 对于后端开发者来说,是不是真的不需要了解前端的开发经过和相关技术,从我个人的角度来说,我觉得如果不了解或者接触很少,极有可能造成开发的时候 ...
- T-SQL批处理
批处理简介 批处理是作为一个逻辑单元的T-SQL语句.如果一条语句不能通过语法分析,那么不会运行任何语句.如果一条语句在运行时失败,那么产生错误的语句之前的语句都已经运行了. 为了将一个脚本分为多个批 ...
- unittest:2 执行多条用例,仅执行一次setUp和tearDown
对象方法setUp()和tearDown() 每个用例执行前后都会被调用.但是有另外一种场景:setUp之后执行完所有用例,最后调用一次tearDown.比如打开网页,多条用例分别验证网页上的元素正确 ...
- CSS3动画中的位置设定问题
水平居中的不同方法实现: position: absolute; margin: auto; left:; right:; position: absolute; left:%; -webkit-tr ...
- python中的BaseManager通信(一)文件三分
可以在windows下单机运行 主部分(提供服务器) #mainfirst.py from multiprocessing.managers import BaseManager import Que ...
- [19/04/20-星期六] Java的动态性_字节码操作(Javassist类库(jar包),assist:帮助、援助)
一.概念 [基本] /** * */ package cn.sxt.jvm; import javassist.ClassPool; import javassist.CtClass; import ...
- [Python 多线程] RLock可重入锁 (九)
RLock 可重复锁,是线程相关的锁.同样是线程相关的还有threading.local. 线程A获得可重用锁,并可以多次成功获取,不会阻塞.最后要再线程A中和acquire次数相同的release. ...
- EF直接的一對多多對多多對一的關係----也即是鏈錶查詢
基于EF4.1 code first 简单的CRUD 园子中已经有很多了 ~~ 真不想再写这个了 可是为了做一个完整的小demo 从开始 到后面的一些简单重构 还是决定认真把这个写出来 争取写些别人 ...
- iOS获取当前连接的wifi信息
导入框架CaptiveNetwork #import <SystemConfiguration/CaptiveNetwork.h> 获取当前连接的wifi信息 // 只能获取当前的SSID ...
- Unity3D-制作火焰效果
1.插件的准备 随着官网上的迭代更新,连下载按钮都找了好久,今天制作的火焰效果要依赖一个插件,LowPoly Environment Pack 输入网址unity3d.com在Assert Store ...