解释
我希望能够根据以下内容对列表中的声音集合进行排序音色(音调)的声音。这是一个玩具示例,其中我手动对我创建的 12 个声音文件的声谱图进行了排序,上传到这个仓库 https://github.com/samgermain/sort-sounds-by-similarity-from-sound-file/tree/bare-example/assets/transients_1。我知道这些已正确排序,因为每个文件生成的声音与之前文件中的声音完全相同,但添加了一个效果或过滤器。
例如,正确的声音排序x
, y
and z
where
- 声音x和y是相同的,但y有失真效果
- 声音 y 和 z 是相同的,但 z 过滤掉高频
- 声音x和z是一样的,但是z有失真效果,z过滤掉高频
将会x, y, z
只需查看声谱图,我就可以看到一些视觉指示器,暗示应如何对声音进行排序,但我希望通过让计算机识别这些指示器来自动化排序过程。
上图中声音的声音文件
- 长度都相同
- 所有相同的音符/音高
- 一切都在同一时间开始。
- 所有相同的幅度(响度级别)
即使所有这些条件都满足,我也希望我的排序能够进行not是的(但即使它不能解决这个问题,我也会接受最佳答案)
例如,在下图中
- 与第一幅图像中的 MFCC_8 相比,MFCC_8 的开头发生了偏移
- MFCC_9 与第一张图像中的 MFCC_9 相同,但有重复(因此长度是其两倍)
如果第一张图片中的 MFCC_8 和 MFCC_9 替换为下图中的 MFCC_8 和 MFCC_9,我希望声音的排序保持完全相同。
对于我的真实程序,我打算通过声音更改来分解 mp3 文件像这样 https://www.youtube.com/watch?v=Vedm2WbFkwQ
到目前为止我的计划
这是产生的程序这篇文章中的第一张图片 https://i.stack.imgur.com/A0CHb.png。我需要函数中的代码sort_sound_files
替换为一些实际上根据音色对声音文件进行排序的代码。需要做的部分是靠近底部和声音文件在此存储库上 https://github.com/samgermain/sort-sounds-by-similarity-from-sound-file/tree/bare-example/assets/transients_1。我也有这个代码Jupyter笔记本 https://github.com/samgermain/sort-sounds-by-similarity-from-sound-file/blob/bare-example/src/example.ipynb,其中还包括第二个示例,该示例更类似于我实际希望该程序执行的操作
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
import math
from os import path
from typing import List
class Spec:
name: str = ''
sr: int = 44100
class MFCC(Spec):
mfcc: np.ndarray # Mel-frequency cepstral coefficient
delta_mfcc: np.ndarray # delta Mel-frequency cepstral coefficient
delta2_mfcc: np.ndarray # delta2 Mel-frequency cepstral coefficient
n_mfcc: int = 13
def __init__(self, soundFile: str):
self.name = path.basename(soundFile)
y, sr = librosa.load(soundFile, sr=self.sr)
self.mfcc = librosa.feature.mfcc(y, n_mfcc=self.n_mfcc, sr=sr)
self.delta_mfcc = librosa.feature.delta(self.mfcc, mode="nearest")
self.delta2_mfcc = librosa.feature.delta(self.mfcc, mode="nearest", order=2)
def get_mfccs(sound_files: List[str]) -> List[MFCC]:
'''
:param sound_files: Each item is a path to a sound file (wav, mp3, ...)
'''
mfccs = [MFCC(sound_file) for sound_file in sound_files]
return mfccs
def draw_specs(specList: List[Spec], attribute: str, title: str):
'''
Takes a list of same type audio features, and draws a spectrogram for each one
'''
def draw_spec(spec: Spec, attribute: str, fig: plt.Figure, ax: plt.Axes):
img = librosa.display.specshow(
librosa.amplitude_to_db(getattr(spec, attribute), ref=np.max),
y_axis='log',
x_axis='time',
ax=ax
)
ax.set_title(title + str(spec.name))
fig.colorbar(img, ax=ax, format="%+2.0f dB")
specLen = len(specList)
fig, axs = plt.subplots(math.ceil(specLen/3), 3, figsize=(30, specLen * 2))
for spec in range(0, len(specList), 3):
draw_spec(specList[spec], attribute, fig, axs.flat[spec])
if (spec+1 < len(specList)):
draw_spec(specList[spec+1], attribute, fig, axs.flat[spec+1])
if (spec+2 < len(specList)):
draw_spec(specList[spec+2], attribute, fig, axs.flat[spec+2])
sound_files_1 = [
'../assets/transients_1/4.wav',
'../assets/transients_1/6.wav',
'../assets/transients_1/1.wav',
'../assets/transients_1/11.wav',
'../assets/transients_1/13.wav',
'../assets/transients_1/9.wav',
'../assets/transients_1/3.wav',
'../assets/transients_1/7.wav',
'../assets/transients_1/12.wav',
'../assets/transients_1/2.wav',
'../assets/transients_1/5.wav',
'../assets/transients_1/10.wav',
'../assets/transients_1/8.wav'
]
mfccs_1 = get_mfccs(sound_files_1)
##################################################################
def sort_sound_files(sound_files: List[str]):
# TODO: Complete this function. The soundfiles must be sorted based on the content in the file, do not use the name of the file
# This is the correct order that the sounds should be sorted in
return [f"../assets/transients_1/{num}.wav" for num in range(1, 14)] # TODO: remove(or comment) once method is completed
##################################################################
sorted_sound_files_1 = sort_sound_files(sound_files_1)
mfccs_1 = get_mfccs(sorted_sound_files_1)
draw_specs(mfccs_1, 'mfcc', "Transients_1 Sorted MFCC-")
plt.savefig('sorted_sound_spectrograms.png')
EDIT
直到后来我才意识到这一点,但另一件非常重要的事情是,会有很多属性在振荡。例如,声音 5 和声音 6 与第一组的区别在于,声音 6 是声音 5,但在音量上有振荡(LFO),这种类型的振荡可以放置在频率滤波器上,效果(如失真)甚至投球。我意识到这使问题变得更加棘手,并且超出了我要求的范围。你有什么建议吗?我什至可以使用几种不同的类型,并且一次只查看一种属性。