我正在做一个项目,比较一个人的演唱和原来的艺术家有多相似。最感兴趣的是声音的音高,看他们是否合拍。
音频文件是.wav格式的,我已经能够用波形模块加载它们,并将它们转换为Numpy数组。然后,我建立了一个频率和一个时间向量来绘制信号。
raw_audio = wave.open("myAudio.WAV", "r")
audio = raw_audio.readframes(-1)
signal = np.frombuffer(audio, dtype='int16')
fs = raw_audio.getframerate()
timeDelta = 1/(2*fs)
#Get time and frequency vectors
start = 0
end = len(signal)*timeDelta
points = len(signal)
t = np.linspace(start, end, points)
f = np.linspace(0,fs,points)如果我有另一个相同持续时间的信号(他们在5-10秒左右着陆)。比较这两种信号的相似性最好的方法是什么?
我曾经想过比较频域和自相关,但我觉得这两种方法都有很多缺点。
发布于 2022-05-19 20:46:39
我面临着一个类似的问题:评估两个音频信号的相似性(一个是真实的,一个是由机器学习管道产生的)。我有信号部分,其中比较是非常关键的(代表不同早期反射到达的峰值之间的时间差),为此,我将尝试计算信号之间的互相关系(这里将更详细地介绍:https://www.researchgate.net/post/how_to_measure_the_similarity_between_two_signal )。
由于两种不同声音的自然录音在时间域上会有很大的不同,这可能对你的问题不太理想。
对于频率信息(如音高和音色)更感兴趣的信号,我将在频域工作。例如,您可以为这两个信号计算短时间ffts (stft)或cqt (映射到八度时频谱的音乐表示),然后通过计算两个信号的时间窗口之间的均方误差(MSE)来比较两者的相似之处。在转换之前,你应该偏离正规化的信号。STFT、CQT和规范化可以很容易地用librosa实现和可视化。
看这里:https://librosa.org/doc/latest/generated/librosa.util.normalize.html这里:https://librosa.org/doc/latest/generated/librosa.cqt.html?highlight=cqt这里:https://librosa.org/doc/latest/generated/librosa.stft.html和这里:https://librosa.org/doc/main/generated/librosa.display.specshow.html)
这种方法有两样东西:
(1 / 350 Hz) *采样频率
因此,如果你的录音有44100赫兹的采样频率,你的时间窗口必须至少是
(1 / 350 Hz) * 44100 Hz =0.002857.44100个样本/秒=126个样本长。
让它128,这是一个更好的数字。这样你就可以保证一个基本频率为350赫兹的声波在一个窗口中至少能被“看到”整整一段时间。当然,更大的窗口会给你更精确的光谱表示。
在转换之前,
当然,您可以为整个长度内的每个信号生成一个fft,但是如果您在等长、短时间窗口上生成stft或cqts (或其他更适合人类听觉的转换),然后计算每个时间窗口的mse (信号1的第一时间窗口和信号2的第一窗口,然后是第二窗口对,然后是第三窗口,等等),则结果会更有意义。
希望这能有所帮助。
https://stackoverflow.com/questions/71712529
复制相似问题