c++ - 在 iOS 中生成 AcoustID/Chromaprint 声学指纹

标签 c++ ios iphone audio ffmpeg

Chromaprint是一个用于计算 AcoustID 的开源软件库音频文件的音频指纹。

我正在尝试从 iOS 上的本地文件生成此音频指纹。

该库可以在 Windows、Linux 和 OS X 上构建,它创建一个动态库以及一个独立程序 (fpcalc),该程序接受音频文件、解码音频并将其传递给 chromaprint 库以计算指纹。由于以下原因,它在 iOS 上实际上不起作用:

  1. 独立的 fpcalc 程序无法在 iOS 上运行,因为您无法从应用程序运行可执行文件
  2. fpcalc 程序的源代码使用 chromaprint 和 ffmpeg。据我所知,ffmpeg 很难在 iOS 上编译。 chromaprint 文档指出 Accelerate 框架可以在 OS X/iOS 中使用,但是没有示例代码可以做到这一点,我也不知道从哪里开始。

我在实际为 iOS 构建库时遇到了一些麻烦(CMake 讨厌我),但我觉得上述问题更相关,因为即使编译了库,它也不会仅仅解决盒子。

我试图避免这是一个“为我编写代码”的问题,但我基本上坚持为 iOS 生成色度指纹的每个方面。

我认为,我的目标是在 iOS 上重新创建 fpcalc 程序的功能 - 解码音频文件(存储在设备上的任何音频类型)并将其传递给 chromaprint 库以生成指纹。

我找到了 this question关于 iOS 上的声学指纹识别,但它与 chromaprint/AcoustID 无关,答案也没什么帮助。 Echoprint Codegen 很有趣,但我需要一个 chromaprint 指纹。

最佳答案

我做到了!我真的做到了!免责声明:这有效,但我不知道我在做什么。肯定有更好的方法来做到这一点。

构建问题:一开始,CMake 没有任何效果。我发现并使用了 this toolchain file来自 ios-cmake 项目,大多数事情都有效。正如他们的 wiki 上所述,您必须使用源代码中的最新版本文件,而不是下载部分。 CMake 提示 Boost,Xcode 提示 Boost,但这两个问题在许多小时后神奇地自行修复。

构建 fpcalc 功能(指纹生成)是一个棘手的部分,因为它使用 ffmpeg,而我还没有准备好尝试在 iOS 上使用我的应用构建它。还好苹果的Audio File Services (AudioToolbox 的一部分)具有相同类型的低级音频功能。

我开始查看 this code从 NSData 播放 MP3 文件。 Audio Queue Services Programming Guide还有关于打开和读取音频文件及其属性的非常有用的信息。但是,使用 mp3 文件(或任何压缩格式)时,您从数据中读取的帧不是 chromaprint 所需的原始 PCM 数据。

幸运的是,this sample project来自 Apple 的将音频文件转换为另一种格式。尽管在我的应用程序中编译该项目需要一些技巧(很多奇怪的 C++/Objective-C 混合),但这正是我所需要的——它包含一个 DoConvertFile 方法。

基本上,我的最终代码使用了这两种方法。首先,它使用 DoConvertFile 将任何输入文件转换为线性 PCM 格式,然后使用 AudioFileOpenURLAudioFileReadPackets 读取转换文件的内容。 AudioFileGetProperty 为我们提供了需要传递给 chromaprint_new 的值。然后,我们会收到相同的逐帧音频数据,这些数据可以传递给 chromaprint_feed,一旦您到达文件末尾,就是这样! chromaprint_finishchromaprint_get_fingerprint 完美运行。删除转换后的文件,然后用指纹做任何你想做的事。

这就是您在 iOS 应用程序中实现 AcoustID 的方式!我的解释现在看起来有点简单,但这确实花了几个小时。 :'(

关于c++ - 在 iOS 中生成 AcoustID/Chromaprint 声学指纹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26032379/

相关文章:

c++ - 连接字符串并作为参数传递?

c++ - 如何在 Qt 5 中写入和读取 QResource 文件?

c++ - 老鼠捡小姐

ios - 使用 IOS 相机预览层填充 View

iphone - UIPageViewController 的 NavigationBar 不显示标题

c++ - UE4因为简单的旋转脚本崩溃

ios - Admob 插页式广告不显示

ios - 根据 objective-c 中内部数组的总和对多维数组进行排序

ios - Swift SKSpriteNode 位置 iPhone V iPad

iphone - 是否可以在同一 View 中同时播放 2 个视频文件?