从mp3绘制频谱图

6 投票
2 回答
14868 浏览
提问于 2025-04-17 18:30

我想在 Python 2.7.3(使用 Ubuntu)中直接从一个 mp3 文件绘制声谱图。我可以通过以下方式从 wav 文件绘制。

#!/usr/bin/python
from scikits.audiolab import wavread
from pylab import *

signal, fs, enc = wavread('XC124158.wav')
specgram(signal)
show()

那么,有什么简单的方法可以直接从 mp3 文件做同样的事情,而不是先转换成 wav 文件呢?我不想把所有的 mp3 文件都转换成 wav,如果可以避免的话。

2 个回答

13

另一种非常简单的方法来绘制mp3文件的声谱图。

from pydub import AudioSegment
import matplotlib.pyplot as plt
from scipy.io import wavfile
from tempfile import mktemp

mp3_audio = AudioSegment.from_file('speech.mp3', format="mp3")  # read mp3
wname = mktemp('.wav')  # use temporary file
mp3_audio.export(wname, format="wav")  # convert to wav
FS, data = wavfile.read(wname)  # read wav file
plt.specgram(data, Fs=FS, NFFT=128, noverlap=0)  # plot
plt.show()

这个方法使用了 pydub 库,相比于调用外部命令,它更加方便。这样你就可以直接处理所有的 .mp3 文件,而不需要先把它们转换成 .wav 格式再进行绘图。

在这里输入图片描述

9

我会安装Debian/Ubuntu的一个软件包libav-tools,然后用avconv这个工具把mp3文件解码成一个临时的wav文件:


补充一下:你之前问的另一个问题被关闭了,所以我在这里稍微扩展一下我的回答,给你一个简单的带通滤波的例子。在你链接的文件中,鸟鸣声主要集中在4 kHz到5.5 kHz之间。

import os
from subprocess import check_call
from tempfile import mktemp
from scikits.audiolab import wavread, play
from scipy.signal import remez, lfilter
from pylab import *

# convert mp3, read wav
mp3filename = 'XC124158.mp3'
wname = mktemp('.wav')
check_call(['avconv', '-i', mp3filename, wname])
sig, fs, enc = wavread(wname)
os.unlink(wname)

# bandpass filter
bands = array([0,3500,4000,5500,6000,fs/2.0]) / fs
desired = [0, 1, 0]
b = remez(513, bands, desired)
sig_filt = lfilter(b, 1, sig)
sig_filt /=  1.05 * max(abs(sig_filt)) # normalize

subplot(211)
specgram(sig, Fs=fs, NFFT=1024, noverlap=0)
axis('tight'); axis(ymax=8000)
title('Original')
subplot(212)
specgram(sig_filt, Fs=fs, NFFT=1024, noverlap=0)
axis('tight'); axis(ymax=8000)
title('Filtered')
show()

play(sig_filt, fs)

鸟鸣声频谱图

撰写回答