目录
Librosa:用于信号处理的Python库
官方介绍:A python package for music and audio analysis
网址:librosa — librosa 0.11.0 documentation
代码网址:https://github.com/librosa/librosa
安装:https://github.com/librosa/librosa/blob/main/README.md
对Librosa部分函数的MATLAB重现
常用的信号处理特征及指标有均方根(RMS)、谱重心、谱宽度、过零率、滚降频率、梅尔频率倒谱系数(MFCCs)等等。
MATLAB中也有一些用于信号处理的拓展包,例如Audio Toolbox、Signal Processing Toolbox等等,其中是否有和Librosa函数直接对标的函数暂时没有进行调研。
这里对于几个Librosa中的函数进行Matlab重现,并且对于IRMAS数据集中的部分音频进行测试,与Librosa提取得到结果进行比对。
谱重心(Centroid)
Librosa库中调用
spec_cent = librosa.feature.spectral_centroid(y=y, sr=sr)
MATLAB复现
function centroid = getCentroid(y, fs)
framelength = 2048;
hoplength = 512;
nfft = 2048;
if size(y, 2) > 1
y = y(:, 1);
end
numFrames = ceil((length(y) - framelength) / hoplength) + 1;
padLength = (numFrames - 1) * hoplength + framelength - length(y);
y = [y; zeros(padLength, 1)];
centroid = zeros(numFrames, 1);
freqs = (0:(nfft/2)) * (fs / nfft);
for i = 1:numFrames
startIdx = (i - 1) * hoplength + 1;
endIdx = startIdx + framelength - 1;
frame = y(startIdx:endIdx);
frame = frame .* hanning(framelength);
spectrum = abs(fft(frame, nfft));
spectrum = spectrum(1:nfft/2+1);
numerator = sum(freqs.*spectrum);
denominator = sum(spectrum);
if denominator > 0
centroid(i) = numerator / denominator;
else
centroid(i) = 0;
end
end
end
验证结果可视化
滚降频率(Rolloff)
Librosa库中调用
rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr)
MATLAB复现
function rolloff = getRolloff(y, fs, roll_percent)
if nargin < 3
roll_percent = 0.85;
end
if roll_percent < 0 || roll_percent >= 1
error('roll_percent must lie in the range (0, 1)');
end
if size(y, 2) > 1
y = mean(y, 2);
end
n_fft = 2048;
hop_length = 512;
window = hann(n_fft);
[S, f, t] = spectrogram(y, window, n_fft-hop_length, n_fft, fs);
S = abs(S);
total_energy = cumsum(S, 1);
if isempty(f)
f = linspace(0, fs/2, n_fft/2 + 1);
end
threshold = roll_percent * total_energy(end, :);
rolloff = NaN(1, length(t));
for i = 1:length(t)
[~, ind] = find(total_energy(:, i) >= threshold(:, i), 1, 'first');
if ~isempty(ind)
rolloff(i) = f(ind);
end
end
end
验证结果可视化
均方根(RMS)
Librosa库中调用
rms = librosa.feature.rms(y=y)
MATLAB复现
function rms_vals = getRMS(y, fs)
frame_length = 2048;
hop_length = 512;
if size(y, 2) > 1
y = mean(y, 2);
end
y = y / max(abs(y));
num_frames = ceil((length(y) - frame_length) / hop_length) + 1;
padded_length = (num_frames - 1) * hop_length + frame_length;
y_padded = [y; zeros(padded_length - length(y), 1)];
rms_vals = zeros(1, num_frames);
for i = 1:num_frames
frame_start = (i - 1) * hop_length + 1;
frame_end = frame_start + frame_length - 1;
frame = y_padded(frame_start:frame_end);
rms_vals(i) = sqrt(mean(frame.^2));
end
end
验证结果可视化
过零率(ZeroCrossingRate)
Librosa库中调用
zero_cross = librosa.feature.zero_crossing_rate(y=y)
MATLAB复现
function zcr = getZeroCrossing_rate(y)
frame_length = 2048;
hop_length = 512;
center = true;
if size(y, 2) > 1
y = mean(y, 2);
end
if ~isvector(y)
error('y should be a vector (signal)');
end
if center
padding_length = floor(frame_length / 2);
y = [repmat(y(1), padding_length, 1); y; repmat(y(end), padding_length, 1)];
end
frames = buffer(y, frame_length, frame_length - hop_length);
num_frames = size(frames, 2);
zcr = zeros(1, num_frames);
for i = 1:num_frames
frame = frames(:, i);
crossings = sum(abs(diff(sign(frame))) > 0);
zcr(i) = crossings / frame_length;
end
end
验证结果可视化
END