非负矩阵分解旨在将矩阵分解为两个矩阵的乘积,,其中表示一组基向量,表示它们的激活或权重。应用于音频源分离,是频谱图(我们已知),是基础非负频谱,是它们的时间激活。
这似乎是我能够将频谱图表示为不同频率区间及其幅度的总和 - 这将有助于过滤或分离不同的音高(似乎在做普通带通滤波器的工作?)。我不明白这实际上是如何将钢琴和演唱相同或相似音高的歌手分开的。
非负矩阵分解旨在将矩阵分解为两个矩阵的乘积,,其中表示一组基向量,表示它们的激活或权重。应用于音频源分离,是频谱图(我们已知),是基础非负频谱,是它们的时间激活。
这似乎是我能够将频谱图表示为不同频率区间及其幅度的总和 - 这将有助于过滤或分离不同的音高(似乎在做普通带通滤波器的工作?)。我不明白这实际上是如何将钢琴和演唱相同或相似音高的歌手分开的。
回想一下的列可以被认为是“基础”向量(或字典的元素 - 任何信号的构建块),中每一列中的元素给出相应的权重(即随时间变化)。这允许我们不仅基于频率分量而且基于时间起始信息来分解频谱图;所以它比简单的带通滤波器或梳状滤波器做得更多。
频谱图的非负矩阵分解不会神奇地将钢琴和歌手以相同的音高分开。然而,它给出了一个有用的近似值,加权基向量的总和(希望)可以分成来自不同源的贡献,因为每个源不太可能在完全相同的时刻占据完全相同的频率仓。
更具体地说,设为,为,为。所以我们有个频率箱,个时间样本和个分解的分量。如果是的列并且是的行,我们可以写成:
实际上,我们最终可能会得到一个从未完全实现这种分离的分解。也就是说,将有来自歌手和钢琴的贡献,因此很难将两者分开。
这是一个 Python 笔记本,显示了混合鼓和吉他的此过程:http: //nbviewer.jupyter.org/gist/ingle/93de575aac6a4c7fe9ee5f3d5adab98f(或者如果这不起作用,请点击此处:https ://gist.github.com /ingle/93de575aac6a4c7fe9ee5f3d5adab98f )
请注意,NMF 算法仅生成分解。它不能选择与每个源对应在 Python 示例中,有一个手动步骤可以确定哪个的声音最像吉他和鼓。注意到鼓的向量在较低频率下有更多的东西,也许可以使这一步骤自动化。
使用一组带通滤波器分析频谱图的每一列(帧)是分解频谱图的另一种方法。但是,请注意,NMF 生成的分解是低秩的,即简约。在 Python 示例中,手动选择与两个源对应的 16 列的子集要容易得多。使用一组带通滤波器,我们将不得不转动更多的旋钮(# 个滤波器,每帧的通带位置),参数组合的数量会增长得非常快。
参考:
https://ccrma.stanford.edu/~njb/teaching/sstutorial/part2.pdf
目标:很好地将一位歌手与一架钢琴分开。现在考虑到准确分离声源的一些要求,因为不太可能有所有需要的输入信息来进行准确分离(可能是你的“基础向量”):
- 对于钢琴每个音符的每个音量,结果随着时间的推移采样的频率分布(因为它攻击然后消失)。-- 歌手声音的每个音符 X 音量 X 音素的频率分布(以及它随不同颤音级别的变化)。-- 对于上述所有情况,都应考虑混响效果。-- 歌曲的歌词(与歌手的音素相匹配)
还有时域限制,例如每个钢琴音符必须从起音开始,以及钢琴延音踏板的效果(尽管已释放相应的键,但“响铃”的音符突然几乎同时衰减)
鉴于上述情况,搜索是寻找一组钢琴音符的频谱和歌手的单个音符-音量-音素频谱的“最佳拟合”总和,以近似得到的声音。