音乐检索(听歌识曲)实现过程
来源:互联网 发布:ai软件描边 编辑:程序博客网 时间:2024/06/05 15:41
- 序言
- 需要实现的功能
- 算法原理
- 实现
- 准备
- 效果
- Code
序言
- 由于需要做无人机的声音识别,但是现有的做无人机声识别的成果不是很多,机缘巧合下在一篇论文中看到了一篇有关音乐识别的论文,就是这个shazam论文 ,该算法提出的时间比较早,也不是很复杂,而且已经商用了很久:shazam网站 ,当然,这个论文里面的是算法的初级版。所以,就萌生了想要实现它的想法,等复现后,视效果再考虑移植到对无人机声识别的过程中。
需要实现的功能
- 输入一些音乐,提取这些音乐的声纹信息,存放于数据库中,用于识别音频片段
- 输入一个音频片段,大约10s到20s左右,该音频片段相对于原曲,允许混杂一些噪音信号,但是要求原曲子的声纹信息已经存在于声纹信息库中
算法原理
这一部分,仔细看论文的话,其实还是很容易理解的,并不复杂,而且论文本身也描述的很详细了,距离实现,可能就差一层窗户纸。这里我自己做一份梳理和精要,算法主要分为两个部分,提取特征与检索方式:
- 提取特征第一步(这里我只说明结果,并不解释为什么用这个特征,具体解释论文中很详细): 对音频做快速傅里叶变换,得到频谱信息;划分不同的频带,选取每一频带的幅度最大的频率点作为一个特征值的点保留下来。例如:总的频率范围是0-8KHz,那我如果平均划分8个区域:0-1,1-2,2-3…7-8,最后每一帧就会有八个极值点,其余的点就可以舍弃掉,后面我们只需要频谱的极值点。
- 提取特征第二步: 计算哈希值。我们并不是直接将极值点信息不做处理直接放进数据库中,而是需要将极值点信息与其他信息做一些组合,保留时间,频率等特征。这里引入两个概念,两个概念:锚点(
anchor point )与目标区域(target zone )。锚点即当前点,锚点的目标区域是指与每一个锚点相对应的一片区域(例如时间线上排在后面的帧)。之后根据锚点与目标区域的相应特征提取出特征值,表征相应的信息,这个特征值的获取方式为:[f1:f2:Δt:t1](Δt=t1−t2) ,一帧信号可以有多个特征值,因为同一帧内本身就存在不止一个极值点,每个极值点都可以作为锚点,这主要取决于你的组合规则。 - 之后,将所有提取出的信息存放进数据库中,之后检索时使用
检索过程:检索过程比较简单,对待识别片段做同样的特征提取,得到一些特征值,然后用这些特征值去数据库中做匹配,最匹配的歌曲就是识别结果,其实,比较接近的算法就是倒排索引。可以用一个图说明:
如图所示,上面的子图的纵轴是待识别音频片段,横轴为一数据库中完整音频,若该片段来自这个音频,互相匹配的特征值点便能构成一条倾斜的直线,显然线上每一点的横纵坐标之差(可以看作是音频片段的偏移值)相等。由此可以得到一个柱状图,横坐标是一首歌中存在的差值,纵轴表示差值的数量,可以看到差值为40的点最多,也就是说,如果这个音频片段属于这个歌曲,它最有可能是以40为起始点截取下来的。故,把40这个点位置上的数量,作为音频片段与它的匹配值。匹配值最高的就是最后的检索结果。
实现
准备
很费劲的一点就是由于C++中没有普遍的应用广泛的数字信号与音频处理库,但是自己从头造轮子这种事情做起来是很不值当的,于是第一步就是找到相关的第三方库,以下是我的选择:
- Eigen矩阵库,内置KissFFt库或者FFTW库,众所周知,fftw是速度最快的快速傅里叶运算库,不过我直接用的kissfft,没有做过多配置
- Boost, 这个无需多言了
- maximilian, 这个是一个C++的音频库,接口简单使用方便,值得一提的是,C++的音频库是比较多的
- MySQL Connector C++, 这个是mysql提供的C++接口,仿照JDBC标准实现的,在程序控制mysql的过程中,必不可少。尤其要注意win32和x64用的lib、dll是不一样的,这个错误我就犯过,查了好久才发现,而且这套接口问题很多,但是没办法,要连接就需要用,吐槽一句,java这点比C++好太多
- 这里多列一条,原本我打算使用levelDB这样的KV型数据库,因为正在看levelDB的源码,且想实际测试下它使用过程中的性能,无奈,其对windows平台的支持比较弱,而我只想找一个拿来就能用的数据库,于是腿而使用了mysql,后来使用中,mysql的性能有限,也成为了识别过程中的性能瓶颈,后续如果要优化,MySql肯定要被替换。
效果
- 简单的建立了一个二十多首歌的小型库,截取其中某些歌曲的片段加入噪声,进行检测
- 所有测试全部通过,都能够顺利检测出来,看到结果还是很惊讶的,毕竟,做这个只花了两三个星期的时间,而且还有优化空间,可见这一算法的优越性
- 提取特征和识别的计算时间都很短,主要时间都花在了读写数据库上
Code
- 代码整理之后会提供出来,以便移植和本地编译通过,之后还会整理出 how to build的文档
- 音乐检索(听歌识曲)实现过程
- 听歌识曲音乐检索
- 听歌识曲--用python实现一个音乐检索器的功能
- 音乐检索研究现状
- 音乐检索现状
- 音乐检索现状
- 音乐检索简介
- 基于指纹的音乐检索
- 音乐信息检索综述报告
- Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果(二)
- 一般图像检索过程
- Lemur的检索过程
- 一般图像检索过程
- 全文检索索引过程
- 执行分布式检索过程
- 迷你播放器--第一阶段(1)--检索媒体音乐并添加到List播放列表
- 基于指纹的音乐检索原理详述
- 文件检索(C循环双链表实现)
- Android学习日记0_ 环境搭建、单元测试、注解
- LabelEncoder和OneHotEncoder 在特征工程中的应用
- Git版本管理--GitHub
- 1023. 组个最小数 (20)
- 数据结构实验之二叉树六:哈夫曼编码
- 音乐检索(听歌识曲)实现过程
- 数据分析
- SWPU CTF 2017 Web WriteUp
- ros机器人开发概述
- PAT (Basic Level) Practise (中文)1002
- 第十周——项目一(1)(2)
- 体系结构 通过python实现 哈夫曼编码 扩展编码 等长编码
- 计算机常用的存储单位
- 爬虫系列4查看网站所有者