会员登录 立即注册

搜索

不同的乐器他们的频谱有什么不同2

[复制链接]
崎山小鹿 发表于 1 小时前 | 显示全部楼层 |阅读模式
崎山小鹿
1 小时前 10 0 看全部
使用 FFmpeg
1. 安装 Python 库
pip install numpy soundfile matplotlib

同时电脑需要安装 FFmpeg。

Windows 可以检查:

ffmpeg -version

如果能看到版本号,就说明安装好了。

2. 完整代码:直接分析 MP3

假设你的文件叫:

piano.mp3

代码:
import subprocess
import numpy as np
import soundfile as sf
import matplotlib.pyplot as plt
import tempfile
import os


# ============================================================
# 1. 参数设置
# ============================================================

# MP3 文件
mp3_file = "piano.mp3"

# FFT 分析从第几秒开始
start_time = 1.0

# 分析多长时间
analysis_duration = 0.5

# FFT 频谱显示到多少 Hz
max_display_freq = 5000


# ============================================================
# 2. 创建临时 WAV 文件
# ============================================================

# NumPy/soundfile 本身并不负责 MP3 解码。
#
# 所以这里先:
#
#     MP3
#      ↓
#    FFmpeg
#      ↓
#     WAV
#      ↓
#    NumPy
#      ↓
#     FFT
#
# 临时 WAV 文件放到系统临时目录。

temp_wav = os.path.join(
    tempfile.gettempdir(),
    "piano_temp.wav"
)


# ============================================================
# 3. 使用 FFmpeg 将 MP3 转换成 WAV
# ============================================================

command = [
    "ffmpeg",

    # 如果目标文件已经存在,自动覆盖
    "-y",

    # 输入 MP3
    "-i",
    mp3_file,

    # 转换成 44100 Hz
    "-ar",
    "44100",

    # 转换成双声道
    "-ac",
    "2",

    # PCM 16 bit
    "-sample_fmt",
    "s16",

    # 输出 WAV
    temp_wav
]


print("正在使用 FFmpeg 解码 MP3...")

result = subprocess.run(
    command,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True
)


# ============================================================
# 4. 检查 FFmpeg 是否成功
# ============================================================

if result.returncode != 0:

    print("FFmpeg 执行失败:")
    print(result.stderr)

    raise RuntimeError(
        "MP3 转 WAV 失败,请检查 FFmpeg 是否安装"
    )


print("MP3 解码完成")


# ============================================================
# 5. 读取 WAV
# ============================================================

audio, sample_rate = sf.read(
    temp_wav
)

print()
print("采样率:", sample_rate)
print("音频数据形状:", audio.shape)


# ============================================================
# 6. 转换为单声道
# ============================================================

# 如果原 MP3 是立体声:
#
# audio.shape
#
#     (采样点数量, 2)
#
# 第 0 列 = 左声道
# 第 1 列 = 右声道
#
# FFT 分析音色时,这里简单地把左右声道平均。

if audio.ndim == 2:

    audio = np.mean(
        audio,
        axis=1
    )


# ============================================================
# 7. 截取分析片段
# ============================================================

start_sample = int(
    start_time * sample_rate
)

end_sample = int(
    (start_time + analysis_duration)
    * sample_rate
)


if start_sample >= len(audio):

    raise ValueError(
        "start_time 超过 MP3 音频长度"
    )


end_sample = min(
    end_sample,
    len(audio)
)


segment = audio[
    start_sample:end_sample
]


print()
print("分析开始时间:", start_time)
print("分析时长:",
      len(segment) / sample_rate,
      "秒")

print(
    "分析采样点:",
    len(segment)
)


# ============================================================
# 8. 绘制钢琴声音的时域波形
# ============================================================

time_axis = (
    np.arange(len(segment))
    / sample_rate
)


plt.figure(
    figsize=(12, 5)
)

plt.plot(
    time_axis,
    segment
)

plt.xlabel("Time (s)")
plt.ylabel("Amplitude")

plt.title(
    "Piano waveform"
)

plt.grid(
    True,
    alpha=0.3
)

plt.tight_layout()

plt.show()


# ============================================================
# 9. 使用 Hann 窗
# ============================================================

# 直接截取一段声音进行 FFT,
# 会产生频谱泄漏。
#
# Hann 窗可以降低这种影响。

window = np.hanning(
    len(segment)
)


windowed_signal = (
    segment * window
)


# ============================================================
# 10. FFT
# ============================================================

fft_result = np.fft.rfft(
    windowed_signal
)


# ============================================================
# 11. 计算频率轴
# ============================================================

freqs = np.fft.rfftfreq(
    len(windowed_signal),
    d=1 / sample_rate
)


# ============================================================
# 12. 计算 FFT 幅度
# ============================================================

magnitude = np.abs(
    fft_result
)


# 归一化
magnitude = (
    magnitude
    / (magnitude.max() + 1e-12)
)


# ============================================================
# 13. 转换成 dB
# ============================================================

magnitude_db = (
    20
    * np.log10(
        magnitude + 1e-12
    )
)


# ============================================================
# 14. 限制显示范围
# ============================================================

mask = (
    freqs <= max_display_freq
)


display_freqs = freqs[
    mask
]

display_magnitude_db = (
    magnitude_db[mask]
)


# ============================================================
# 15. 绘制 FFT 频谱
# ============================================================

plt.figure(
    figsize=(12, 6)
)

plt.plot(
    display_freqs,
    display_magnitude_db
)

plt.xlabel(
    "Frequency (Hz)"
)

plt.ylabel(
    "Magnitude (dB)"
)

plt.title(
    "Piano MP3 FFT Spectrum"
)

plt.xlim(
    0,
    max_display_freq
)

plt.ylim(
    -100,
    5
)

plt.grid(
    True,
    alpha=0.3
)

plt.tight_layout()

plt.show()


# ============================================================
# 16. 删除临时 WAV
# ============================================================

try:

    os.remove(
        temp_wav
    )

    print()
    print("临时 WAV 已删除")

except OSError:

    pass


使用钢琴曲:时光静好-钢琴曲
https://www.aigei.com/item/shi_guang_jing_28.html
ScreenShot_2026-08-26_130925_559.png
ScreenShot_2026-08-26_131044_454.png
天不生墨翟,万古如长夜!以墨运商,以商助墨。金双石科技长期招聘科技研发人才!微信:qishanxiaolu   电话:15876572365   公司:深圳市金双石科技有限公司
回复

使用道具 举报

  • 您可能感兴趣
您需要登录后才可以回帖 登录 | 立即注册 |

本版积分规则 返回列表

管理员给TA私信
以墨运商,以商助墨。

查看:10 | 回复:0

  • 分析验证双耳节拍的存在

    验证方法是: 读取 piano_binaural_10hz.wav 截取中间一段,例如 10 秒附近的 2 秒

    阅读:0|2026-08-26
  • 不同的乐器他们的频谱有什么不同2

    使用 FFmpeg 1. 安装 Python 库 pip install numpy soundfile matplotlib 同时电脑需

    阅读:0|2026-08-26
  • USBTreeView

    Windows的设备管理器中可以查看USB设备的信息: 驱动程序供应商:FTDI, 数字签名者:

    阅读:2137|2026-05-23
  • 电子电路仿真网站

    https://velxio.dev/ Arduino、ESP32 和 Raspberry Pi。 直接在您的浏览器中即可使

    阅读:2290|2026-05-19
  • ESP32 板子为什么识别为 CP2102

    你的ESP32开发板被电脑识别为“CP2102”,这并不是一个错误,而是完全正常的现象。这

    阅读:2669|2026-05-09
  • 固件如何加密

    做固件加密,本质上是防止别人读取或复制你的程序。常见做法分为“芯片级保护 + 软件

    阅读:2768|2026-04-06
  • 高端神经反馈脑波检测系统

    高端神经反馈脑波检测系统分为脑波检测、脑波分析、脑波解码三个部分。 前端主程序

    阅读:17|2026-01-06
  • 国内第三方量化平台有哪些有什么特点

    好的,我们来详细了解一下国内主流的第三方量化平台。这些平台极大地降低了个人投资者

    阅读:4779|2025-12-09
  • 为什么脑波要去除伪迹

    1. 伪迹不是大脑信号 EEG设备记录的是头皮上非常微弱的电位变化(微伏级别,μV)。

    阅读:24|2025-12-05
  • 便携可视化语音AI耳机

    项目起源: 初先生的聊天记录: 你那边掌握的技术,有办法做一个有摄像头的,墨者机

    阅读:3181|2025-12-01
金双石科技,软件开发20年,技术行业领先,您的满意,就是我们的目标,认真负责,开拓进取,让成品物超所值
关于我们
公司简介
发展历程
联系我们
本站站务
友情链接
新手指南
内容审核
商家合作
广告合作
商家入驻
新闻合作

手机APP

官方微博

官方微信

联系电话:15876572365 地址:深圳市宝安区西乡街道宝民二路宝民花园 ( 粤ICP备2021100124号-1 ) 邮箱:qishanxiaolu@qq.com
QQ|Powered by Discuz! X3.5 © 2001-2026 Discuz! Team.
快速回复 返回顶部 返回列表