Featured image of post 利用spleeter分离歌曲人声并借助Parselmouth绘制声波图像

利用spleeter分离歌曲人声并借助Parselmouth绘制声波图像

利用spleeter分离歌曲人声并借助Parselmouth绘制声波图像

利用spleeter分离歌曲人声并借助Parselmouth绘制声波图像

环境准备

Python >=3.7

Python IDE (本文使用PyCharm)

本次演示采用最快速的方式获取结果

提取人声

软件提取【推荐】

https://makenweb.com/SpleeterGUI

下载

SpleeterGUI下载页

软件自带中文,总的来说还是很方便的。

SpleeterGUI

试试代码?

在线提取(需要科学上网环境)

想试用但不想安装任何东西?官方已为我们建立了一个Google Colab。

首先打开spleeter的GitHub页面

deezer/spleeter

找到向下滑找到Quick start选择底下的Google Colab

spleeter的GitHub页面

会提示授权,直接同意即可。

\[\*\*\]

和绿色对勾,因为我执行过一遍),执行完成后会返回实例音频的分离结果。

spleeter的Google Colab页面

接下来我们分离自己的音频。

打开代码文件夹,删除audio_example.mp3 文件并把你要分离人声的音乐文件(mp3格式)上传到此目录下并重命名为audio_example.mp3 (如下图)

spleeter的Google Colab页面

上传完成后,不用执行Install spleeter 内的的代码(也就是上面那三个),直接从Separate from command line 内的第三个代码开始执行。

等待命令全部执行,音乐和人声就分离出来了,有时会遇到下面问题。

解决方法是打开下方目录, vocals.wav就是你刚才分离的人声文件,accompaniment.wav 是背景音乐文件,直接右键下载即可。

spleeter的Google Colab页面

此时,你已经成功分离了人声和背景音乐。

本地分离

https://github.com/deezer/spleeter/wiki 去他们的wiki看看吧,这里偷个懒,我就不演示了。

φ(* ̄0 ̄)

绘制声波波幅图像

YannickJadoul/Parselmouth

打开PyCharm,假设你会用PyCharm。

新建一个文件夹,在里面,新建一个test.py文件和audio文件夹,把你刚才提取的人声(名字为vocals.wav 不要改名字)放进audio文件夹,venv.idea 不用创建PyCharm会自己创建。

新建文件和文件夹

安装软件包

用PyCharm打开test.py文件,安装下方软件包。

  • praat-parselmouth

  • numpy

  • matplotlib

  • seaborn

最后安装成下面这样就差不多,只用去安装上面四个,他会自动帮你安装下面那一堆。

PyCharm软件包列表

获取音频图像

输入下方代码并执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import parselmouth

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# import math

sns.set()  # Use seaborn's default style to make attractive graphs
snd = parselmouth.Sound(r"audio/vocals.wav")


def draw_pitch(pitch):
    # Extract selected pitch contour, and
    # replace unvoiced samples by NaN to not plot
    pitch_values = pitch.selected_array['frequency']
    pitch_values[pitch_values == 0] = np.nan
    plt.plot(pitch.xs(), pitch_values, 'o', markersize=2, color='w')
    plt.plot(pitch.xs(), pitch_values, 'o', markersize=2)
    plt.grid(False)
    plt.ylim(0, pitch.ceiling)
    plt.ylabel("fundamental frequency [Hz]")


# def draw_spectrogram(spectrogram, dynamic_range=70):
#     X, Y = spectrogram.x_grid(), spectrogram.y_grid()
#     sg_db = 10 * np.log10(spectrogram.values)
#     plt.pcolormesh(X, Y, sg_db, vmin=sg_db.max() - dynamic_range, cmap='afmhot')
#     plt.ylim([spectrogram.ymin, spectrogram.ymax])
#     plt.xlabel("time [s]")
#     plt.ylabel("frequency [Hz]")

# def draw_intensity(intensity):
#     plt.plot(intensity.xs(), intensity.values.T, linewidth=3, color='w')
#     plt.plot(intensity.xs(), intensity.values.T, linewidth=1)
#     plt.grid(False)
#     plt.ylim(0)
#     plt.ylabel("intensity [dB]")


class Tonality:
    base_diff = [0, 2, 4, 5, 7, 9, 11]
    tones = ['A', 'A#', 'B', 'C', 'C#', 'D', "D#", 'E', 'F', 'F#', 'G', 'G#']

    def __init__(self, tone):
        assert tone in self.tones
        self.base_freq = self.tone_to_freq(tone)

    def tone_to_freq(self, tone):
        A_freq = 440
        return A_freq * (2 ** (self.tones.index(tone) / 12))

    def get_freq(self):
        ret = []
        for r in range(-3, 2):
            base = self.base_freq * (2 ** r)
            ret.extend([base * (2 ** (diff / 12)) for diff in self.base_diff])
        return ret


def draw_standard(tone):
    for f in Tonality(tone).get_freq():
        plt.axline((0, f), (1, f), lw=1)


pitch = snd.to_pitch()
# If desired, pre-emphasize the sound fragment before calculating the spectrogram
# pre_emphasized_snd = snd.copy()
# pre_emphasized_snd.pre_emphasize()
# spectrogram = pre_emphasized_snd.to_spectrogram(window_length=0.03, maximum_frequency=8000)
plt.figure()
# draw_spectrogram(spectrogram)
plt.twinx()

tone = 'F#'
draw_standard(tone)
draw_pitch(pitch)
plt.xlim([snd.xmin, snd.xmax])
plt.show()  # or plt.savefig("spectrogram_0.03.pdf")

我们以给自己的歌 (Live) - 李宗盛这首歌来举例,首先我们要知道这首歌是什么调的,直接百度给自己的歌谱子,画圈的便是这首歌的调,可以看到是A调。

或者你可以用QQ音乐的智能曲谱,右键相关歌曲,随便选一个乐器,生成的谱子右上方写了歌曲的原调。

QQ音乐智能曲谱

当我们知道了这首歌的调,接下来修改代码,代码第43行,这是代码可以分析的调。

代码图片

来到代码第75行,我们已经知道了刚才的歌是A调,填入即可。

代码图片

执行成功截图,右键最右边那一溜可以保存图像,由于我用了整首歌,所以这个图看起来特别密集,你可以截取相关片段来进行分析。

代码运行成功截图

Parselmouth当前支持8类:声音,频谱,频谱图,强度,音高,共振峰,谐波和MFCC(以及它们之间的转换),例如:

声音图像

频谱图

频谱图

你可以访问它的GitHub页面获取相关代码。由于本人不懂乐理知识,所以这个图也看不懂,也无法给出建议,教程至此,快去试试吧。

使用 Hugo 构建
主题 StackJimmy 设计