我想知道如何获取每个声音持续时间中的包络数组。 每个声音持续时间意味着第一个声音事件为 0.79 秒,第二个声音事件为 0.21 秒,第三个声音事件为 0.9 秒,依此类推。
当前代码提取自获取信封数组:
debussy_file = "1-01-1.wav"
debussy, sr = librosa.load(debussy_file)
FRAME_SIZE = 1024
HOP_LENGTH = 512
def amplitude_envelope(signal, frame_size, hop_length):
"""Calculate the amplitude envelope of a signal with a given frame size nad hop length."""
amplitude_envelope = []
# calculate amplitude envelope for each frame
for i in range(0, len(signal), hop_length):
amplitude_envelope_current_frame = max(signal[i:i+frame_size])
amplitude_envelope.append(amplitude_envelope_current_frame)
return np.array(amplitude_envelope)
# number of frames in amplitude envelope
ae_debussy = amplitude_envelope(debussy, FRAME_SIZE, HOP_LENGTH)
#Visualising amplitude envelope
frames = range(len(ae_debussy))
t = librosa.frames_to_time(frames, hop_length=HOP_LENGTH)
ax = plt.subplot(3, 1, 1)
librosa.display.waveplot(debussy, alpha=0.5)
plt.plot(t, ae_debussy, color="r")
plt.title("Debusy")
显示如下。 但我想查看声音事件每个持续时间的值(我已经有了持续时间信息),而不是整个音频。 也许这是一个简单的问题,但我不知道如何从代码中纠正。 如果有人愿意帮助我,我将不胜感激。!
P.s.如果我需要解释更多,请告诉我!谢谢
在您的代码中,您有一些用于计算信封值和信封时间戳的代码。所以这主要是关于使用时间戳来删除相关值。
我建议使用 pandas.Series 将值和时间戳合并到一个对象中。这使得使用
.loc[start_time:end_time]
来索引时间戳变得非常容易。
完整的代码示例如下。它将给出这样的图,其中我们仅显示事件指定时间的信封(红色)。
import librosa
import pandas
import numpy
from matplotlib import pyplot as plt
def amplitude_envelope(signal, frame_size, hop_length, sr) -> pandas.Series:
"""Calculate the amplitude envelope of a signal
Returns the envelope values and timestamps
"""
amplitude_envelope = []
# calculate amplitude envelope for each frame
for i in range(0, len(signal), hop_length):
amplitude_envelope_current_frame = max(signal[i:i+frame_size])
amplitude_envelope.append(amplitude_envelope_current_frame)
values = numpy.array(amplitude_envelope)
times = librosa.frames_to_time(numpy.arange(1, len(values)+1), hop_length=hop_length, sr=sr)
series = pandas.Series(values, index=times, name='envelope')
return series
# load audio file
path = librosa.example('sweetwaltz')
audio, sr = librosa.load(path, duration=5.0)
# compute envelope
envelope = amplitude_envelope(audio, frame_size=1024, hop_length=512, sr=sr)
# extract only a certain time
event_envelope = envelope.loc[0.37:0.600]
ax = plt.subplot(3, 1, 1)
librosa.display.waveshow(audio, alpha=0.5)
plt.plot(event_envelope.index, event_envelope.values, color="r")
plt.savefig('event-env.png', bbox_inches='tight')