我觉得 Librosa.effect.split 有问题?

I think Librosa.effect.split has some problem?

首先,这个功能是消除音频的静音。 这是官方描述:

https://librosa.github.io/librosa/generated/librosa.effects.split.html

librosa.effects.split(y, top_db=10, *kargs)

Split an audio signal into non-silent intervals.

top_db:number > 0 The threshold (in decibels) below reference to consider as silence

return: intervals:np.ndarray, shape=(m, 2) intervals[i] == (start_i, end_i) are the start and end time (in samples) of non-silent interval i.

所以这很简单,对于任何低于 10dB 的声音,都将其视为静音并从音频中删除。它会 return 给我一个间隔列表,这些间隔是音频中的非静音片段。

所以我做了一个非常简单的例子,结果让我很困惑: 我在此处加载的音频是一段 3 秒的人类对话,非常正常。

y, sr = librosa.load(file_list[0]) #load the data
print(y.shape) -> (87495,)

intervals = librosa.effects.split(y, top_db=100)
intervals -> array([[0, 87495]])

#if i change 100 to 10
intervals = librosa.effects.split(y, top_db=10)
intervals -> array([[19456, 23040],
                    [27136, 31232],
                    [55296, 58880],
                    [64512, 67072]])

这怎么可能...

我跟librosa说,好吧,任何低于100dB的声音,都当成静音处理。 在这个设置下,整个音频应该被视为静音,并且根据文档,它应该给我 array[[0,0]] 一些东西......因为在删除静音之后,什么都没有了......

但似乎 librosa return让我沉默的部分而不是非沉默的部分。

librosa.effects.split() 它在文档中说它 return 是一个包含 间隔的 numpy 数组,间隔包含非静音音频 。这些间隔当然取决于您分配给参数 top_db 的值。 它没有 return 任何音频,只有波形非静音片段的起点和终点

在你的情况下,即使你设置 top_db = 100,它也不会将整个音频视为静音,因为他们在文档中声明他们使用 The reference power. By default, it uses **np.max** and compares to the peak power in the signal. 所以设置你的 top_db 高于音频中存在的最大值实际上会导致 top_db 没有任何效果。 这是一个例子:

import librosa
import numpy as np
import matplotlib.pyplot as plt

# create a hypothetical waveform with 1000 noisy samples and 1000 silent samples
nonsilent = np.random.randint(11, 100, 1000) * 100
silent = np.zeros(1000)
wave = np.concatenate((nonsilent, silent))
# look at it
print(wave.shape)
plt.plot(wave)
plt.show()

# get the noisy interval
non_silent_interval = librosa.effects.split(wave, top_db=0.1, hop_length=1000)
print(non_silent_interval)

# plot only the noisy chunk of the waveform
plt.plot(wave[non_silent_interval[0][0]:non_silent_interval[0][1]])
plt.show()

# now set top_db higher than anything in your audio
non_silent_interval = librosa.effects.split(wave, top_db=1000, hop_length=1000)
print(non_silent_interval)

# and you'll get the entire audio again
plt.plot(wave[non_silent_interval[0][0]:non_silent_interval[0][1]])
plt.show()

你可以看到非静音音频是从0到1000,静音音频是从1000到2000个样本:

这里它只为我们提供了我们创建的波浪的嘈杂部分:

此处 top_db 设置为 1000:

这意味着 librosa 做了它在文档中承诺要做的所有事情。希望这会有所帮助。