将变量与音频文件同步
Posted
技术标签:
【中文标题】将变量与音频文件同步【英文标题】:Sync variable with audio file 【发布时间】:2016-07-10 03:33:02 【问题描述】:我有一个音频文件,我想要一个浮点变量与之同步。然后,浮点变量将用于创建正在播放的音频文件的图形指示。
我希望发生的事情:
音频文件中的每隔一个节拍(第一拍、第三拍、第五拍等),变量应为 0.0f。 其他节拍(二拍、四拍、六拍等),变量应为1.0f。
最重要的是,我希望随着时间的推移,节拍之间的变量在 0.0 和 1.0 之间“滑动”,我的第一个想法是使用 C++ 标准库中的 sin 函数。
关于音频文件的信息:
文件的速度/BPM 文件的长度(以秒为单位) 音频文件总共包含多少节拍 文件在播放时的位置。 我知道歌曲中的位置,几秒钟后,我现在在哪里。例如,如果歌曲播放了 3 秒半,我从我正在使用的函数中得到 3.5f除此之外,我还有一个 deltatime 和一个生命周期,它表明应用程序执行了多长时间(以秒为单位)。
由于 sin 函数采用浮点数(或双精度数)作为参数,我需要帮助的是计算,然后可以将其作为参数传递给函数,然后用于生成同步的正弦波与音频文件。
【问题讨论】:
您是否可以访问文件的采样率和以字节为单位的采样大小?(通常位于标题中)如果您可以读取音频数据块并提取立体声/单声道值,然后您可以分析(使用您的 BPM 信息),以便您可以在播放音乐期间更新您的浮点变量 是的,我可以访问采样率(44.100Hz)和样本大小(16)。在我使用的音乐程序中,他们称其为“位深度”,但我认为这与您所指的样本大小相同。关于如何创建/计算数据块分析的任何提示?我有机会从音频文件中获取称为 FFT 数据的东西,这对我有什么帮助吗? 我还有机会获得一个浮点指针,其中包含“当前播放声音的 256 个样本(剪辑后)”。 这确实是它的实际名称,我相信 FFT 数据只是二进制数据块,包括您需要的音频值。为了正确同步您的正弦波,您需要知道第一个节拍的确切“峰值”,这样您就可以通过添加偏移量并根据给定的 BPM 修改频率来修改您的正弦函数。检测第一个节拍是棘手的部分,因为仅检测音频文件中的高音(谈论音量)并不总是足够的。顺便说一句,您指的是某种程序:这实际上是关于 c++ 实现吗? 听起来有点棘手,是的。当我谈论一个程序时,我只是指我用来创作歌曲的音乐程序。在我的项目(c++ 项目)中,我使用了一个名为 SoLoud 的音频库,它具有返回歌曲长度、当前播放歌曲的位置、FFT 数据等的函数。浮点值(即,正弦波变量) 然后将用于我目前正在制作的游戏中。不确定我是否误解了您的问题,但它确实是我正在研究的 C++ 实现。 【参考方案1】:虽然这个解决方案并不可靠,但它应该能够检测到简单音频文件的节拍: 在这里您可以看到一个简单的音频文件,您可以清楚地看到节拍。我们的目标是找到偏移值,以便我们可以创建我们的 cos 函数。找到偏移值的一种方法是首先计算文件的平均音量(通过获取音频数据的绝对值,因为值会低于零,如下所示)。我们计算这个平均音量是为了消除可能的噪音。接下来,我们遍历所有样本(您可能只选择一个音频通道)并找到绝对值高于此平均值的第一个样本。这会产生样本中的偏移值(不是秒)。
由于我们知道当前播放的是哪一秒,我们现在可以通过填充我们之前计算的函数的频率和偏移量来计算可视化音频的 cos 函数的值。
请纠正我,我数学很烂
具有给定 BPM 的常规节拍应如下所示。
BPS=BPM/60
g(x)=cos((x*BPS)*360)
带有偏移的节拍应如下所示:
OFFSET_IN_SECONDS=OFFSET_IN_SAMPLES/SAMPLERATE
g(x)=cos((x*BPS+OFFSET_IN_SECONDS)*360)
重要提示:这些函数使用的度数与 C++ 使用的弧度相反
【讨论】:
真的很酷,谢谢!一个问题:g(x) 和 cos-function(s) 中的 x 是什么? @Naith X 是以秒为单位的歌曲中的当前位置,g(x) 可以是(如果它实际上是 vald)您用来生成可视化所需的浮点数的函数(float g(浮动时间);在代码中) 您应该计算均方根 (RMS),而不是使用绝对值计算体积。这给出了一个更合理的值,并且对于被瞬变(节拍是瞬变,顺便说一句)引起的反应也很稳健。 @datenwolf 在我查阅了一些有关 RMS 的信息后,似乎最终函数的 RMS 等于 2^-0.5。这是正确的还是我做错了? @thomw2o0o:您将在传入的音频信号上应用 RMS。对于正弦,RMS 是幅值·sqrt(1/2)——注意幅值不是峰到峰而是峰到零。确定最终函数的 RMS 可能意义不大。以上是关于将变量与音频文件同步的主要内容,如果未能解决你的问题,请参考以下文章