使用光谱质心或通过其他方式为波形着色

信息处理 fft 声音的 颜色
2022-01-09 22:07:46

更新 8

不满意必须将曲目上传到服务并查看 RekordBox 3 的新版本,我决定再次寻找离线方法和更精细的分辨率:D

听起来很有希望,但仍处于非常 alpha 的状态:

约翰尼克 - 好时光

在此处输入图像描述

在此处输入图像描述

请注意,没有对数刻度或调色板调整,只是从频率到 HSL 的原始映射。

想法:现在波形渲染器有一个颜色提供程序,用于查询特定位置的颜色。您在上面看到的那个获得了该位置旁边 1024 个样本的过零率。

显然,在获得强大的东西之前还有很多工作要做,但这似乎是一条好路……

来自RekordBox 3

在此处输入图像描述

在此处输入图像描述

更新 7

我将采用的最终形式,就像在更新 3 中一样

在此处输入图像描述

(为了获得颜色之间的平滑过渡,我们进行了一些 Photoshop 处理)

结论是我几个月前很接近,但没有考虑到结果认为它很糟糕 X)

更新 6

我最近发现了这个项目,所以我想在这里更新:D

歌曲:Chic - Good Times 2001 (Stonebridge Club mix)

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

IMO 更好,节拍具有恒定的颜色等......虽然它没有优化。

如何 ?

仍然与http://developer.echonest.com/docs/v4/_static/AnalyzeDocumentation.pdf(第 6 页)

对于每个段:

public static int GetSegmentColorFromTimbre(Segment[] segments, Segment segment)
{
    var timbres = segment.Timbre;

    var avgLoudness = timbres[0];
    var avgLoudnesses = segments.Select(s => s.Timbre[0]).ToArray();
    double avgLoudnessNormalized = Normalize(avgLoudness, avgLoudnesses);

    var brightness = timbres[1];
    var brightnesses = segments.Select(s => s.Timbre[1]).ToArray();
    double brightnessNormalized = Normalize(brightness, brightnesses);

    ColorHSL hsl = new ColorHSL(brightnessNormalized, 1.0d, avgLoudnessNormalized);
    var i = hsl.ToInt32();
    return i;
}

public static double Normalize(double value, double[] values)
{
    var min = values.Min();
    var max = values.Max();
    return (value - min) / (max - min);
}

显然,在您到达这里之前需要更多代码(上传到服务、解析 JSON 等),但这不是本网站的重点,所以我只是发布相关内容以获得上述结果。

所以我使用了分析结果的前2个函数,当然还有更多的事情要做,但我仍然需要测试。如果我发现比上面更酷的东西,我会回来并在这里更新。

与往常一样,任何关于该主题的提示都非常受欢迎!

更新 5

使用谐波级数的一些梯度

在此处输入图像描述

颜色平滑是比率敏感的,否则看起来很糟糕,需要进行一些调整。

更新 4

使用具有 0.08 和 0.02 值的Alpha beta 过滤器重写了在源处发生的着色和平滑颜色。

在此处输入图像描述

缩小的时候稍微好一点

在此处输入图像描述

下一步是获得一个很棒的调色板!

更新 3

在此处输入图像描述

黄色代表媒介 在此处输入图像描述

未缩放时还不是很好。 在此处输入图像描述

(调色板需要一些认真的工作)

更新 2

使用来自pichenettes的第二个“音色”系数提示进行初步测试 在此处输入图像描述

更新 1

使用来自EchoNest服务的分析结果进行的初步测试,请注意它的对齐不是很好(我的错),但它比上述方法更连贯。

在此处输入图像描述

对于有兴趣使用这个伟大的 API 的人,从这里开始:http: //developer.echonest.com/docs/v4/track.html#profile

此外,不要对这些波形感到困惑,因为它们确实代表了 3 首不同的歌曲。

最初的问题

到目前为止,这是我使用 256 个样本 FFT 并计算每个块的光谱质心得到的结果。

计算的原始结果 在此处输入图像描述

应用了一些平滑(使用它的形式看起来好多了) 在此处输入图像描述

产生的波形 在此处输入图像描述

理想情况下,它应该是这样的(取自Serato DJ软件) 在此处输入图像描述

你知道当平均频率随时间变化时我可以使用什么技术/算法来分割音频吗?(如上图)

1个回答

您可以先尝试以下方法(不分段):

  • 以小块处理信号(例如持续时间为 10 毫秒到 50 毫秒) - 如有必要,它们之间有 50% 的重叠。
  • 计算每个块的光谱质心。
  • 将非线性函数应用于光谱质心值以获得所用调色板颜色的均匀分布。对数是一个好的开始。另一种选择是首先计算整个文件之外的质心值的分布,然后根据该分布的百分位数 ( CDF ) 进行着色。这种自适应方法保证调色板中的每种颜色都以相等的比例使用。缺点是,如果使用这种自适应方法,一个文件中以蓝色绘制的内容听起来与另一个文件中以蓝色绘制的内容不同!

从图片中不清楚 Serato 是否这样做,或者确实更进一步并尝试分割信号 - 这样做可能并不令人惊讶,因为知道音乐信号中存在音符的时刻可以帮助同步它们!步骤是:

  • 计算信号的短期傅立叶变换(频谱图) - 在短重叠段上使用 FFT(从 1024 或 2048 的 FFT 大小开始,44.1kHz 音频)。
  • 计算一个发病检测函数。我建议你看一下这篇论文——所提出的方法非常有效,甚至 C++ 实现也只需要不到 10 行代码。你可以在Yaafe -as中找到一个实现ComplexDomainOnsetDetection
  • 检测起始检测函数中的峰值以获取音符起始的位置。
  • 计算由检测到的起始点分隔的所有时间段的光谱质心(不要忘记窗口和/或零填充!)
  • 不要忘记非线性地图!请注意,出现在 Serato 波形上每个音符之间的渐变效果可能是人为生成的。

一旦你得到这个工作,一个“低悬的果实”将是计算每个片段上的一些其他特征(时刻,少数 MFCC ......),在这些特征向量上运行 k-means,并决定颜色使用集群索引的段。参见Ravelli 论文的第二部分。