怎样在设计网站做图赚钱省建设厅网站梁作庆
news/
2025/9/23 12:07:23/
文章来源:
怎样在设计网站做图赚钱,省建设厅网站梁作庆,html菜鸟教程首页,报价单通用模板文章目录1 概述2 总体框架3. 计算Onset Strength Envelope4 计算全局的Tempo5 基于动态规划计算beats6 参考文献1 概述
有背景音乐的短视频拼接时#xff0c;如果两个视频的拼接点刚好在背景音乐的某个节拍点上#xff0c;那么合成的视频看起来#xff0c;听起来#xff0…
文章目录1 概述2 总体框架3. 计算Onset Strength Envelope4 计算全局的Tempo5 基于动态规划计算beats6 参考文献1 概述
有背景音乐的短视频拼接时如果两个视频的拼接点刚好在背景音乐的某个节拍点上那么合成的视频看起来听起来都会非常舒服这是短视频合成的一个加分项这种视频也就是我们经常说的卡点视频。要做卡点视频的前提是找到背景音乐中可以卡的点beats是其中一种可以卡的点本文就是用大白话来讲讲论文Beat Tracking by Dynamic Programming是怎么找beats的。常用的音频信号处理库librosa中的librosa.beat.beat_track用的就是这种方法。这个任务的名字叫做beat tracking下文中都将这样称呼。
2 总体框架
论文中介绍的beat tracking可以分为三个步骤
1计算Onset Strength EnvelopeOnset的能量包络
2计算全局的Tempo
3基于动态规划计算beats
我第一次看到这三步也是一头雾水如果是专门做信号处理的人可能已经知道怎么回事了但这篇文章的的目标受众是像我一样学过或者了解过信号处理却已经忘的差不多的小伙伴。所以下面会针对这三个步骤详细解析。
如果只想知道怎么使用的话librosa已经为我们包装好了一切三行代码就搞定了。
import librosay, sr librosa.load(“your/music/file/path”)
tempo, beats librosa.beat.beat_track(yy, srsr)3. 计算Onset Strength Envelope
onset指的就是某个音符发出声音的起点比如按下钢琴键的那个时刻又比如拨动琴弦的那个时刻下图示意了onset的位置。在这个环节中就是要把一段音频中所有的onset的能量包络找出来。给到的音频可能是有鼓的音轨钢琴的音轨小提琴的音轨人声的音轨等混合在一起的。不管哪个音轨的都会被我们找出来。
图1onset示意图找onset能量包络的方法不是这篇论文提出来的用的是一个已有的常用的方法叫做crude perceptual model。其步骤如下所示
1用8kHz的采样率读取音频文件。
2用32ms的window_size和4ms的step_size进行短时傅立叶变换(STFT)得到图2中最上方的图。
3将频谱图映射到梅尔频谱上纵轴分为40个bands得到图2中中间的图。
4沿时间轴对每个band做一阶差分并把所有的负值置0再把每个时间点的所有band差分后的正值累加。
5对4中得到的结果进行高通滤波过滤掉0.4kHz以下的信息使其局部零均值再用window_size为20ms高斯窗做平滑处理得到图2中最下方的图也就是onset strength envelope记作O(t)O(t)O(t)。
图2频谱梅尔频谱和onset strength envelope的对比图O(t)O(t)O(t)中的各个局部峰值就是能量突增的地方为什么会能量变化剧烈当然是因为有新的音符发声了。注意这里的波峰我认为不是onsets的精确时间而是onsets产生的波峰的时间。不过不同的文章中好像都是把这个onsets的候选了。不过我们不关心onsets具体到底在哪里只要有O(t)O(t)O(t)就够了所以不纠结定义问题了。
还有一个就是我比较奇怪论文的作者为什么要用5这样的归一化方式这样得到的O(t)O(t)O(t)就会有很多负值但是这些负值我们是不要的。Tempo and Beat Tracking中的归一化方式我觉得更合理一些直接减去local average就可以了。下图3中的最上方红线就是local average减去后得到的结果为图3中间的那个图图3下方的图标出了局部峰值和onsets。
图3onset strength envelope归一化处理4 计算全局的Tempo
Tempo指的是音乐的节拍通常用bpm(beats per minute)来度量比如120bpm就表示一分钟有120个beats拍子的周期为0.5s。本文中用拍子的周期来表示Tempo。一首音乐的Tempo有可能是随时间变化的但这种情况很少我们这里只讨论整个音频的tempo都保持一致的情况。变化的Tempo检测可以参见predominant local pulse大致思想就是分段处理这里不讨论。
节拍就是一个调子在不断循环我们要找出这个循环的周期。自相关函数用来找周期是在适合不过的了我们会计算不同延迟时间下O(t)O(t)O(t)的自相关函数值值最高的对应的延迟时间就是一个beat的长度。
但是这里有一个问题如图4的raw autocorrelation所示周期函数的在他基周期的倍数上的自相关函数值都是很大的。为了解决这个问题论文引入了一个权重系数使得周期结果偏向于某个经验值。这个计算自相关系数的计算公式为
TPS(τ)W(τ)∑tO(t)O(t−τ)TPS(\tau)W(\tau)\sum_t O(t)O(t-\tau) TPS(τ)W(τ)t∑O(t)O(t−τ)
其中τ\tauτ是延迟的时间TPS为Tempo Period Strength的缩写是论文作为给这个自相关计算方法取的名字使得TPS(τ)TPS(\tau)TPS(τ)最大的那个τ\tauτ就是我们要找的周期。
W(τ)W(\tau)W(τ)是一个高斯权重系数表示为
W(τ)exp{−12(log2τ/τ0στ)2}W(\tau) exp\{-\frac{1}{2}(\frac{log_2 \tau / \tau_0}{\sigma_\tau})^2\} W(τ)exp{−21(στlog2τ/τ0)2}
其中τ0\tau_0τ0就是默认偏向的周期大小στ\sigma_\tauστ是表示偏重程度的一个系数。τ0\tau_0τ0和στ\sigma_\tauστ都是经验值论文从MIREX-06 Beat Tracking训练集中统计得来的。统计的方法是填入不同的τ0\tau_0τ0和στ\sigma_\tauστ使得TPS(τ)TPS(\tau)TPS(τ)的得出的最大值和数据中标注的Tempo一致性最高的那组τ0\tau_0τ0和στ\sigma_\tauστ就是了。
最终得出的τ0\tau_0τ0为0.5s也就是120bpmστ\sigma_\tauστ为1.4。在该组参数下的TPS(τ)TPS(\tau)TPS(τ)如图4中最下方的图所示。图中的Primary Tempo Period就是最终的周期。
图4onset strength envelope原始自相关函数和TPS的对比图librosa.beat.beat_track中有一个输入参数为start_bpm指的就是τ0\tau_0τ0可以人为传入修改默认为120。
在实际的使用中会对TPS(τ)TPS(\tau)TPS(τ)做一些优化变成
TPS2(τ)TPS(τ)0.5TPS(2τ)0.25TPS(2τ−1)0.25TPS(2τ1)TPS2(\tau) TPS(\tau) 0.5 TPS(2\tau) 0.25 TPS(2\tau - 1) 0.25 TPS(2\tau 1) TPS2(τ)TPS(τ)0.5TPS(2τ)0.25TPS(2τ−1)0.25TPS(2τ1)
或是
TPS3(τ)TPS(τ)0.33TPS(3τ)0.33TPS(3τ−1)0.33TPS(3τ1)TPS3(\tau) TPS(\tau) 0.33 TPS(3\tau) 0.33 TPS(3\tau - 1) 0.33 TPS(3\tau 1) TPS3(τ)TPS(τ)0.33TPS(3τ)0.33TPS(3τ−1)0.33TPS(3τ1)
不管用哪种方法TPS(τ)TPS(\tau)TPS(τ)的峰值对应的τ\tauτ就是我们要找的周期。
5 基于动态规划计算beats
论文以4ms一个步长250Hz将时间分段利用了第3节和第4节的结果设计了如下的目标函数 C({ti})∑i1NO(t)α∑i2NF(ti−ti−1,τp)C(\{t_i\}) \sum_{i1}^N O(t) \alpha \sum_{i2}^N F(t_i - t_{i-1}, \tau_p) C({ti})i1∑NO(t)αi2∑NF(ti−ti−1,τp)
其中{ti}\{t_i\}{ti}为找到的NNN个beatsO(t)O(t)O(t)就是第3节中的Onset Strenghth Envelopeα\alphaα为平衡两个目标项的系数τp\tau_pτp就是第4节中得到的周期F(△t,τp)F(\triangle t, \tau_p)F(△t,τp)是用来衡量每两个相邻的beats的间距和τp\tau_pτp的差距这个可以自己定义论文中表示为
F(△t,τp)−(log△tτp)2F(\triangle t, \tau_p) -(log \frac{\triangle t}{\tau_p})^2 F(△t,τp)−(logτp△t)2
可见当△t\triangle t△t和τp\tau_pτp越接近F(△t,τp)F(\triangle t, \tau_p)F(△t,τp)越大最大为0否则越小。除此之外该式是log对称的比如F(kτp,τp)F(τp/k,τp)F(k\tau_p, \tau_p) F(\tau_p / k, \tau_p)F(kτp,τp)F(τp/k,τp)。
我们的目标是使得C({ti})C(\{t_i\})C({ti})越大越好分析一下当α0\alpha0α0时把所有的时间点全部选上C({ti})C(\{t_i\})C({ti})就最大了当α∞\alpha\inftyα∞时选择时间间隔为τp\tau_pτp的一组点就可以使得C({ti})C(\{t_i\})C({ti})最大了。不难看出有了α\alphaα的平衡最终得到的点列就是间隔在τp\tau_pτp左右微调且使得点落O(t)O(t)O(t)局部峰值附近的一组点。
论文用动态规划的方法以线性的时间复杂度解决了这个问题。首先定义了C∗(t)C^*(t)C∗(t)表示只考虑时间点不大于时刻ttt时以时刻ttt为一个beat的C({ti})C(\{t_i\})C({ti})的最大值这也就是动态规划中的状态转移函数其表达式为
C∗(t)O(t)maxτ0...t−4ms{αF(t−τ,τp)C∗(τ)}C^*(t) O(t) \max_{\tau0...t-4ms} \{\alpha F(t-\tau, \tau_p) C^*(\tau)\} C∗(t)O(t)τ0...t−4msmax{αF(t−τ,τp)C∗(τ)}
这个和标准的动态规划还是有点区别要细细品味一下这个地方我思考了挺久这种做法可以避免在计算状态转移时之前的最优beats序列发生变化。这个C∗(t)C^*(t)C∗(t)还有一个好处就是可以用来找结尾当C∗(t)C^*(t)C∗(t)的增量骤减时就是音乐转弱也就是结尾的地方了。
同时也会记录使得C∗(t)C^*(t)C∗(t)最大的那个序列在ttt之前的那个beat为
P∗(t)argmaxτ0...t−4ms{αF(t−τ,τp)C∗(τ)}P^*(t) arg\max_{\tau0...t-4ms} \{\alpha F(t-\tau, \tau_p) C^*(\tau)\} P∗(t)argτ0...t−4msmax{αF(t−τ,τp)C∗(τ)}
也就是说取的τ\tauτ是多少。通过P∗(t)P^*(t)P∗(t)可以回溯选择的beats路径得到最终的beats序列。
在实际搜索τ\tauτ的时候不会从0到t-4ms去做的这样会计算很多不必要的情况。有F的惩罚在我们只要搜索τt−2τp...t−τp/2\tau t - 2\tau_p ... t - \tau_p / 2τt−2τp...t−τp/2。
我们把从0到总时长所有的时刻ttt对应的C∗(t)C^*(t)C∗(t)都算出来之后取其中最大的那个C∗(tN)C^*(t_N)C∗(tN)tNt_NtN就是最后一个beat点然后tN−1P∗(tN)t_{N-1} P^*(t_N)tN−1P∗(tN)然后由此一直回溯出整条序列{ti}\{t_i\}{ti}。有一点可以确定的是tNt_NtN必然在[总时长−τp,总时长][总时长-\tau_p, 总时长][总时长−τp,总时长]的范围内不然就还可以再加入一个beat。
说到这里正文已经说完了。这里再简单说一下为什么不能按标准的动态规划的做法不然下次自己来看可能又要想半天。按标准的做法会定义C∗(tj)C^*(t_j)C∗(tj)为时间点不大于时刻tjt_jtj时C({ti})C(\{t_i\})C({ti})的最大值。状态转移函数为
C∗(tj)max{O(tj)maxτ0...tj−1{αF(tj−P∗(τ),τp)C∗(τ)},C∗(tj−1)}C^*(t_j) \max \{ O(t_j) \max_{\tau0...t_{j-1}} \{\alpha F(t_j-P^*(\tau), \tau_p) C^*(\tau)\}, C^*(t_{j-1}) \} C∗(tj)max{O(tj)τ0...tj−1max{αF(tj−P∗(τ),τp)C∗(τ)},C∗(tj−1)}
解释一下就是有两种选择前一种是把tjt_jtj作为一个beat另一种是不把tjt_jtj作为一个beat。问题就处在这个P∗(τ)P^*(\tau)P∗(τ)当我们把tjt_jtj作为一个beat使得C∗(tj)C^*(t_j)C∗(tj)尽可能大的前一个beat不一定是P∗(τ)P^*(\tau)P∗(τ)。换而言之把tjt_jtj作为一个beat后前面的最优beats可能会发生变化。如果按标准的做法来会漏掉许多时间点作为beat的情况。细品细品。
6 参考文献
[1] Beat Tracking by Dynamic Programming [2] Tempo and Beat Tracking
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912487.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!