关于音乐指纹技术

最近识别音乐技术比较流行,其实国外03年就开始陆续出现了很多算法和产品。国内最近盛大和百度才发布这种产品。其实声音指纹最核心的技术就是从原始声音文件中采集fingerprinter,然后通过算法分析fingerprinter,获取音乐的唯一标识,然后再去数据库中把这个音乐关系信息查询出来。


2. 安装配置MusicBrainZ
MusicBrainZ中使用了Amplifind来分析一段音乐的指纹,并有一个音乐数据库对外提供服务器。MusicBrainZ包含多种产品,例如picard,通过这些产品可以使用界面查询出歌曲已经关联的信息。但作为开发者更关注的是调用接口,这样可以在我们的应用中使用到musicBrainZ。我们使用libmusicbrainz最新版本是09-11发布的libmusicbrainz-3.0.2.tar.gz。

Libmusicbrainz3使用WebService对外提供服务,提供ruby、perl、python、C#/.Net 几种binding。

下载perl版本binding : http://search.cpan.org/~bfaist/WebService-MusicBrainz-0.93/以及依赖的一些模块:
XML::LibXML
LWP::UserAgent
Class::Accessor
URI
Test::More

执行安装
perl Makefile.PL
make
make test
make install


查看接口文档:http://users.musicbrainz.org/~luks/docs/libmusicbrainz3/
http://musicbrainz.org/doc/HowPUIDsWork


Musicbrainz3接口中并没有直接处理音乐文件的接口。目前找到的直接分析音乐文件的开发包只有musicIP(现在叫amplifind)公司的libofa和libsndfile ,这两款工具都是C开发的,后来在其他网站找到一个libofa的perl调用接口,叫做Audio::Ofa

Audio::Ofa::Util - Retrieve audio fingerprints and metadata for unknown audio files

安装Audio::Ofa::Util

安装过程一直报错,安装module:build 、xtUtils::PkgConfig,继续安装Audio:Ofa继续报错:

[code="java"]# perl Makefile.PL
# running Build.PL
Package libofa was not found in the pkg-config search path.
Perhaps you should add the directory containing `libofa.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libofa' found
at Build.PL line 8
*** can not find package libofa
*** check that it is properly installed and available in PKG_CONFIG_PATH
at Build.PL line 8
Couldn't run Build.PL: at /usr/lib/perl5/site_perl/5.8.5/Module/Build/Compat.pm line 335.[/code]


查看Build.PL,发现这句报错 my %pkg_info = ExtUtils::PkgConfig->find('libofa');
从googlecode中下载libofa代码,

安装碰到问题,尝试使用genPUID ,并搞清楚genPUID和libofa的关系。
able to be done by Picard, genPUID, MusicIP Mixer and other tools based around libofa
http://lists.musicbrainz.org/pipermail/musicbrainz-devel/2010-February/003708.html
http://wiki.musicbrainz.org/Talk:MusicIP


www.musicip.com redirects to www.amplifiedmusicservices.com and appears to 404 any other links that don't go to the ones as links on the main page. So what does this mean? 71.2.179.49 19:26, 1 December 2009 (UTC) 
MusicIP has been [sold/merged/changed/acquired/foo] into Amplified Music Services. From what I understand Amplified Music Services has continued supporting the PUID technology that MusicBrainz uses, so the change has been fairly seamless to MusicBrainz' users. --navap 21:05, 1 December 2009 (UTC)
Caveat to the above: libofa still works, and genPUID still works, but they're no longer distributing genPUID, no longer creating new genPUID keys, and though they're still distributing it, they've recently updated the Mixer page to state that they're not going to support it.

proprietary closed source AmpliFIND "stuff" done only to generate a new PUID


一篇老文章:[url]http://blog.musicbrainz.org/?p=160[/url] written by RobertKaye


安装文档:[url]http://cblfs.cross-lfs.org/index.php/Libofa[/url]

安装libofa之后,安装Audio:ofa过程出错:无法安装成功。Musicdns.org已经不存在,安装时url找不到 = 、
[code="java"]Unknown keyword 'URL' in '/usr/lib/pkgconfig/libofa.pc'

# vi /usr/lib/pkgconfig/libofa.pc

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libofa
Description: The Open Fingerprint Architecture Library
URL: http://www.musicdns.org/
Version: 0.9.3
Requires: fftw3
Libs: -L${libdir} -lofa -lexpat -lm
Cflags: -I${includedir}[/code]

2.1 获取PUID
在musicbrainz.org的论坛上看到一篇2010年7月份的帖子,帖子内容是关于PUID问题,大家都没办法解决。
[url]http://forums.musicbrainz.org/viewtopic.php?id=2275[/url]

之前我们知道 genPUID是调基于libofa开发包来实现的,决定直接调用genPUID来实现,但musicip网站已经不存在了,在使用genPUID开发包之前,必须去网站注册一个key,在googlecode.com中libofa项目中发现了keys.txt,尝试着找出一个key,放在genPUID命令中使用,居然可以!下面黑体字就是我所需要的PUID.
[code="java"]# ./genpuid 57aae6071e74345f69143baa210bda87 -r \[beyonce\]Crazy\ in\ Love-Beyonce.mp3
GenPUID Version 1.4 - 31 October 2008
Copyright (C) MusicIP Corporation 2006-2008.

Checking files to be processed...
Songs to be scanned: 1
/home/xj_fingerprinter/module/genPUID-1.4/[beyonce]Crazy in Love-Beyonce.mp3
PUID: 52a317a6-c029-cd70-e0cf-462097bf8060[/code]

2.2 通过PUID调用meta Database

通过PUID获取Musicbrainz的元数据库中信息,有两种方式。一种是直接通过web service服务来获取;另一种为直接使用MusicBrainz提供的开发包,目前支持perl、python、rails、C#。
2.2.1 Web service 方式调用
Web Service 查询元数据库中信息,可以参考文档:
http://wiki.musicbrainz.org/Xml_Web_Service#Searching_Tracks

例如,通过上面文档中,我们了解到,根据PUID查询track信息,可以使用下面这个service
[url]http://musicbrainz.org/ws/1/track?type=xml&puid=52a317a6-c029-cd70-e0cf-462097bf8060[/url]查询结果如下图所示,查询出PUID为“52a317a6-c029-cd70-e0cf-462097bf8060”的歌曲信息,歌名为”Crazy in love”,但有多个版本。



2.2.2 Perl module 方式调用
MusicBrainz公司提供了一套perl调用的方式,简化了分析数据的过程。模块名是:WebService::MusicBrainz 。


#!/usr/bin/perl


use WebService::MusicBrainz::Track;

my $ws = WebService::MusicBrainz::Track->new();

#my $response = $ws->search({ TITLE => 'Same in any language' });

my $response = $ws->search({ PUID => '52a317a6-c029-cd70-e0cf-462097bf8060' });

my $track = $response->track(); # grab the first one from list

print $track->title(), " - ", $track->artist()->name(), "\n";

上面这个例子,实现了跟web service一样的查询:通过PUID获取track信息。执行结果为下图显示。Web Service返回结果中Beyoncé是法文,UTF8转码不成功,看了下perl接口源代码,好像有点问题,待最后确认。
[xj_fingerprinter@cms5 ~]$ perl finger.pl 
Crazy in Love (feat. Jay-Z) - Beyonc?



3. 大数据量测试
之前我们测试时使用的是一首英文歌曲,所以生成PUID,查询元数据库都很顺利。
接下来准备测试一些中文歌曲,观察结果。查询PUID时,歌曲名不能为中文,转为unicode也不行。相同歌曲文件用英文名可以查询到PUID的,中文就查不到。这个不是大问题,暂时忽略掉。下面测试都用非汉字歌曲名进行。

1、rain.wma(汪峰-在雨中)
结果:查询PUID失败。
2、chaorenbuhuifei.mp3(周杰伦新歌超人不会飞)
结果:查询PUID失败。
3、mir.mp3(王菲-传奇)
结果:查询到PUID为dd8505c1-9129-a864-48cb-1f15de4a160b
查询MusicBrainZ元数据库,内容为空。
[url]http://musicbrainz.org/ws/1/track?type=xml&puid=dd8505c1-9129-a864-48cb-1f15de4a160b[/url]


4、pride.wma(梁静茹-勇气)
结果:查询PUID失败。但是用MusicBrainZ公司的picard产品就可以查询到元数据库中数据。

5、song.mp3(梁静茹-情歌)
结果:查询PUID为3f4e9986-983b-0437-d638-fce6b1471c36,元数据库中也有结果
[url]http://musicbrainz.org/ws/1/track?type=xml&puid=3f4e9986-983b-0437-d638-fce6b1471c36[/url]

6、目前所有非mp3文件全部查询失败,选择一首英文wma歌曲,继续测试。
[black eyed peas]Sexy-Black Eyed Peas.wma
结果:未查询到PUID,genPUID目前不能直接处理非mp3格式文件。

7、移除第5个测试用例的ID3信息
结果:没有ID3信息的mp3格式歌曲,一样可以被查询到PUID,音乐文件被分析的过程跟ID3没有关系。

8、pretend you don’t see her(一首很老的英文歌)
结果:没有查找到PUID。

4. 解决中文文件名和非mp3文件问题
Genpuid目前不支持中文文件名和非mp3格式数据。接下来对这两个问题进行处理。
Mplayer可以把wma、wav、以及其他很多格式数据转为MP3,使用前需要安装Mplayer、Lame两个插件。分别安装lame、win32code、Mplayer:
1、lame下载
http://rpm.pbone.net/index.php3/stat/4/idpl/1807604/com/lame-3.96.1-2.guru.suse93.i686.rpm.html
2、win32code下载
http://rpm.pbone.net/index.php3/stat/4/idpl/1807644/com/w32codec-all-20050412-0.pm.0.i386.rpm.html
3、Mplayer
MPlayer-1.0rc2.tar.bz2
安装完毕后:

执行下面命令先把wma文件转为wav文件
/usr/local/MPlayer/bin/mplayer pride.wma -ao pcm -ao pcm:file=pride.wav

执行下面命令把wav文件转为MP3格式
lame -h pride.wav pride.mp3

注意:直接从wma转为MP3文件,会有严重失真现象,除了噪音什么都没了。

以后可以参考使用下面这个脚本来处理文件格式转换和中文文件名问题。
#!/bin/bash
DATE=$(date '+%m-%d-%Y')
TIME=$(date '+%H:%M:%S')
STARTLOCATION="$1"
# Start a new file
echo "Start converting at $DATE $TIME with PID $$" > /tmp/wma2mp3.$$
echo "OGG is better and free (SCNR)">> /tmp/wma2mp3.$$
# For encoding wma to mp3 (but ogg is much better ;-) )
for i in "`find "${STARTLOCATION}" -name *.wma -print `"
do
mplayer -ao pcm -aofile "${i%.wma}.wav" "$i" && lame -h "${i%.wma}.wav" "${i%.wma}.mp3"
# Use this for ogg:
#mplayer -ao pcm -aofile "${i%.wma}.wav" "$i" && oggenc "${i%.wma}.wav"
# If returncode == 0
if [ $? -eq 0 ];then
echo "\"${i}\" convertet to \"${i}.mp3\"" >> /tmp/wma2mp3.$$
rm "${i%.wma}.wav" && rm "${i}"
else
echo "failed decoding \"${i}\"" >> /tmp/wma2mp3.$$
fi
done
echo "Finished converting at $DATE $TIME with PID $$" >> /tmp/wma2mp3.$$
cat /tmp/wma2mp3.$$|mail -s "Files converted on ${DATE}" root


回顾之前碰到的所有wma格式文件查找PUID都失败的情况,现在我们可以把wma文件格式转换为MP3,继续查找PUID,结果查找到了!例如上面这个刚转换的pride.mp3文件。
PUID为:2691ef0a-6210-20b1-7172-f4dfd98843e3 ,(查询时间比较慢,花了10s)。通过web service 查看track 信息:

5. 总结
我们可以通过获取到不同格式音乐文件的PUID,音乐文件长度必须够长,测试过30s长度文件查找不到PUID,完整文件可以找到的情况。然后去MusicBrainZ的元数据库中查询出当前PUID关联的一些专辑、歌手等信息。整个调研过程有3个转折点
① 获取PUID过程
这步最为关键,没有PUID,什么都干不了。在MusicIP被AmpliFind公司收购以后,原有查询方法全部失效,官网上面已经找不到查询PUID服务的方法了。临时找的那个key暂时还可以访问查询PUID的服务,但新歌已经不能分配新的PUID了。根据一些相关新闻显示,很有可能某个时候AmpliFind公司彻底停止使用查找PUID的服务。因为AmpliFind提供PUID服务给MusicBrainZ公司,并从MusicBrainZ公司拿10%利润。
而MusicBrainZ公司的产品Picard,我们已经通过之前的流程实现了,不过不是GUI的。

② 调用MusicBrainZ的Web Service 或者直接使用Perl开发包,Perl开发包封装了 调用Web Service过程。通过上面两种方式可以查询PUID对应的专辑、歌手等信 息。这部分工作暂时没碰到什么障碍,都很简单实现,唯一未解决问题是处理一个法语歌手名时,会有乱码,中文、英文都没问题。这个问题我已经发信给开发包的作者,暂无回复,有时间尝试自己修改对方源代码确认一下原因。


③ 歌曲格式转换和中文文件名处理
这部分工作解决了命中率的问题。如果中文文件名或者wma格式都不能被GenPUID 处理,会大大降低使用的效果。


值得注意的问题是在转换音乐文件格式为mp3格式时,过程比较慢,大概需要消耗10s,有时候查询PUID的过程也比较慢,能查找到PUID情况下,查询速度在1-15s之间。如果查找不到PUID,等待时间更长,大概30s。


Shazam算法:
[url]http://laplacian.wordpress.com/2009/01/10/how-shazam-works/[/url]

哥伦比亚大学的matlab提供的另外一种类似shazam的算法:
[url]http://labrosa.ee.columbia.edu/~dpwe/resources/matlab/fingerprint/#1[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值