基于频谱处理的音频分离方法

news2024/12/27 19:51:50

基于频谱处理的音频分离方法

在音频处理领域,音频分离是一个重要的任务,尤其是在语音识别、音乐制作和通信等应用中。音频分离的目标是从混合信号中提取出单独的音频源。通过频谱处理进行音频分离是一种有效的方法,本文将介绍其基本原理、公式以及如何通过降噪作为一个具体的例子来实现音频分离。

1. 频谱处理音频分离的原理

频谱处理音频分离的基本思想是将音频信号从时间域转换到频率域,通过分析频谱中的成分,去除或抑制不需要的成分,从而恢复目标音频信号。常用的频谱分析方法是短时傅里叶变换(STFT)。

1.1 短时傅里叶变换(STFT)

短时傅里叶变换将时间域信号分成多个短时间段,并对每个段进行傅里叶变换。对于离散时间信号 (x[n]),STFT 的离散形式可以表示为:

X [ m , k ] = ∑ n = − ∞ ∞ x [ n ] w [ n − m ] e − j 2 π N k n X[m, k] = \sum_{n=-\infty}^{\infty} x[n] w[n - m] e^{-j \frac{2\pi}{N}kn} X[m,k]=n=x[n]w[nm]ejN2πkn

其中:

  • X [ m , k ] X[m, k] X[m,k] 是在时间帧 (m) 和频率 (k) 的复数频谱。
  • x [ n ] x[n] x[n] 是输入信号。
  • w [ n ] w[n] w[n] 是窗函数,用于限制信号的时间范围。
  • N N N是窗的长度。

1.2 逆短时傅里叶变换(ISTFT)

逆短时傅里叶变换用于将频谱信息转换回时间域信号。对于离散时间信号,ISTFT 的离散形式可以表示为:

x [ n ] = ∑ m = − ∞ ∞ X [ m , k ] w [ n − m ] e j 2 π N k n x[n] = \sum_{m=-\infty}^{\infty} X[m, k] w[n - m] e^{j \frac{2\pi}{N}kn} x[n]=m=X[m,k]w[nm]ejN2πkn

其中:

  • x [ n ] x[n] x[n] 是恢复后的离散时间信号。
  • X [ m , k ] X[m, k] X[m,k]是去噪后的频谱。

1.3 音频分离算法

在频谱域中,音频分离的基本步骤如下:

  1. 计算 STFT:对混合信号(包含多个音源)进行 STFT,得到频谱表示。
  2. 源信号估计:通过分析混合信号的频谱,估计各个源信号的频谱成分。
  3. 频谱相减或掩码:从混合信号的频谱中减去或应用掩码来提取目标音源的频谱。
  4. 逆 STFT:对提取后的频谱进行逆 STFT,恢复到时间域信号。

2. 降噪作为音频分离的例子

降噪是音频分离中的一个具体应用场景。在降噪过程中,我们的目标是从包含噪声的混合信号中提取出干净的音频信号。降噪的基本步骤如下:

2.1 完全降噪

在完全降噪的情况下,我们假设噪声的频谱可以被准确估计并完全从混合信号中去除。此时,频谱相减的公式为:

Y ( f ) = X ( f ) − N ( f ) Y(f) = X(f) - N(f) Y(f)=X(f)N(f)

在这种情况下,重建的音频信号将尽可能接近原始的干净信号。

2.2 不完全降噪

在不完全降噪的情况下,噪声的频谱可能无法完全准确地估计,或者在去噪过程中可能会对语音信号造成一定的抑制。此时,我们可以引入一个随机因子来模拟这种情况:

Y ( f ) = X ( f ) − N ( f ) ⋅ factor Y(f) = X(f) - N(f) \cdot \text{factor} Y(f)=X(f)N(f)factor

其中,factor 是一个在 0.8 到 1.2 之间的随机值。这个因子可以模拟噪声没有完全消除的情况,或者在去噪过程中对语音信号的抑制。
在这里插入图片描述
在这里插入图片描述

3. 代码实现

import numpy as np
import librosa
import matplotlib.pyplot as plt
import soundfile as sf
import librosa.display

# 1. 读取两个文件并进行时域混合
def load_and_mix(audio_file, noise_file, duration):
    audio, sr_audio = librosa.load(audio_file, sr=None)
    noise, sr_noise = librosa.load(noise_file, sr=None)

    if sr_audio != sr_noise:
        raise ValueError("Sampling rates of the audio and noise files must be the same.")

    min_length = min(len(audio), len(noise), duration * sr_audio)
    audio = audio[:min_length]
    noise = noise[:min_length]

    mixed_signal = audio + noise
    return audio, noise, mixed_signal, sr_audio

# 2. 计算 STFT
def compute_stft(signal):
    return librosa.stft(signal)

# 3. 计算噪声的 STFT
def compute_noise_stft(noise):
    return librosa.stft(noise)

# 4. 频谱相减
def subtract_stft(mixed_stft, noise_stft, factor):
    return mixed_stft - (noise_stft * factor)

# 5. ISTFT 重新生成语音
def reconstruct_audio(subtracted_stft):
    return librosa.istft(subtracted_stft)

# 6. 可视化过程
def visualize_process(original, noise, mixed, reconstructed_best, reconstructed_partial, sr):
    plt.figure(figsize=(12, 10))

    plt.subplot(5, 1, 1)
    plt.title('Original Audio Signal')
    librosa.display.waveshow(original, sr=sr, alpha=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude')

    plt.subplot(5, 1, 2)
    plt.title('Noise Signal')
    librosa.display.waveshow(noise, sr=sr, alpha=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude')

    plt.subplot(5, 1, 3)
    plt.title('Mixed Audio Signal')
    librosa.display.waveshow(mixed, sr=sr, alpha=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude')

    plt.subplot(5, 1, 4)
    plt.title('Reconstructed Audio Signal (Best Case)')
    librosa.display.waveshow(reconstructed_best, sr=sr, alpha=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude')

    plt.subplot(5, 1, 5)
    plt.title('Reconstructed Audio Signal (Partial Case)')
    librosa.display.waveshow(reconstructed_partial, sr=sr, alpha=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude')

    plt.tight_layout()
    plt.show()

    # 绘制语谱图
    plt.figure(figsize=(12, 10))

    original_stft = compute_stft(original)
    noise_stft = compute_noise_stft(noise)
    mixed_stft = compute_stft(mixed)
    reconstructed_best_stft = compute_stft(reconstructed_best)
    reconstructed_partial_stft = compute_stft(reconstructed_partial)

    plt.subplot(5, 1, 1)
    plt.title('Original Audio Spectrogram')
    librosa.display.specshow(librosa.amplitude_to_db(np.abs(original_stft), ref=np.max), sr=sr, y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.subplot(5, 1, 2)
    plt.title('Noise Spectrogram')
    librosa.display.specshow(librosa.amplitude_to_db(np.abs(noise_stft), ref=np.max), sr=sr, y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.subplot(5, 1, 3)
    plt.title('Mixed Audio Spectrogram')
    librosa.display.specshow(librosa.amplitude_to_db(np.abs(mixed_stft), ref=np.max), sr=sr, y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.subplot(5, 1, 4)
    plt.title('Reconstructed Audio Spectrogram (Best Case)')
    librosa.display.specshow(librosa.amplitude_to_db(np.abs(reconstructed_best_stft), ref=np.max), sr=sr, y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.subplot(5, 1, 5)
    plt.title('Reconstructed Audio Spectrogram (Partial Case)')
    librosa.display.specshow(librosa.amplitude_to_db(np.abs(reconstructed_partial_stft), ref=np.max), sr=sr, y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.tight_layout()
    plt.show()

# 主程序
def main():
    audio_file = '1.wav'  # 语音文件
    noise_file = '3.wav'  # 噪声文件
    duration = 20  # 取样长度(秒)

    original_audio, noise, mixed_signal, sr = load_and_mix(audio_file, noise_file, duration)

    mixed_stft = compute_stft(mixed_signal)
    noise_stft = compute_noise_stft(noise)

    # 完全降噪
    subtracted_stft_best = subtract_stft(mixed_stft, noise_stft, factor=np.ones_like(noise_stft))
    reconstructed_best_audio = reconstruct_audio(subtracted_stft_best)

    # 不完全降噪
    random_factor = np.random.uniform(0.8, 1.2, noise_stft.shape)
    subtracted_stft_partial = subtract_stft(mixed_stft, noise_stft, factor=random_factor)
    reconstructed_partial_audio = reconstruct_audio(subtracted_stft_partial)

    sf.write('mixed_signal.wav', mixed_signal, sr)
    sf.write('reconstructed_audio_best.wav', reconstructed_best_audio, sr)
    sf.write('reconstructed_audio_partial.wav', reconstructed_partial_audio, sr)

    visualize_process(original_audio, noise, mixed_signal, reconstructed_best_audio, reconstructed_partial_audio, sr)

if __name__ == "__main__":
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI技术在电商行业中的应用与发展

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

微信小程序3-显标记信息和弹框

感谢阅读,初学小白,有错指正。 一、实现功能: 在地图上添加标记点后,标记点是可以携带以下基础信息的,如标题、id、经纬度等。但是对于开发来说,这些信息还不足够,而且还要做到点击标记点时&a…

LeetCode 力扣 热题 100道(十四)二叉树的中序遍历(C++)

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 如下为代码: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullpt…

极兔速递开放平台快递物流查询API对接流程

目录 极兔速递开放平台快递物流查询API对接流程API简介物流查询API 对接流程1. 注册用户2. 申请成为开发者3. 企业认证4. 联调测试5. 发布上线 签名机制详解1. 提交方式2. 签名规则3. 字段类型与解析约定 物流轨迹服务极兔快递单号查询的其他方案总结 极兔速递开放平台快递物流…

SpringBoot3如何基于ServletRequestHJandledEvent检测接口响应时间以及对应的参数

在 Spring Boot 3 中,可以通过实现 ServletRequestHandledEvent 事件来监测接口的响应时间以及相关的参数。ServletRequestHandledEvent 是 Spring 的应用事件之一,它在请求处理完成时发布,包含有关请求的信息。 以下是一个步骤指南&#xff…

44 基于32单片机的博物馆安全监控系统设计

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 检测 分别是温湿度 光照 PM2.5、烟雾、红外,然后用OLED屏幕显示, 红外超过阈值则蜂鸣器报警,这是防盗报警;温度或烟雾超过阈值,则蜂鸣器…

视频 的 音频通道提取 以及 视频转URL 的在线工具!

视频 的 音频通道提取 以及 视频转URL 的在线工具! 工具地址: https://www.lingyuzhao.top/toolsPage/VideoTo.html 它提供了便捷的方法来处理视频文件,具体来说是帮助用户从视频中提取音频轨道,并将视频转换为可以通过网络访问的URL链接。无…

利用红黑树封装map,和set,实现主要功能

如果不知道红黑树是什么的时候可以去看看这个红黑树 思路 首先我们可以把封装分为两个层面理解,上层代码就是set,和map,底层就是红黑树 就相当于根据红黑树上面套了两个map,set的壳子,像下面这张图一样 对于map和set,map里面存…

电子应用设计方案-39:人工智能系统方案设计

人工智能系统方案设计 一、引言 随着人工智能技术的快速发展,越来越多的领域开始应用人工智能系统来解决复杂的问题和实现智能化的任务。本方案旨在设计一个通用的人工智能系统框架,以满足不同业务需求和应用场景。 二、系统概述 1. 系统目标 - 提供高…

Unity 设计模式-策略模式(Strategy Pattern)详解

策略模式(Strategy Pattern)是一种行为型设计模式,定义了一系列算法,并将每种算法封装到独立的类中,使得它们可以互相替换。策略模式让算法可以在不影响客户端的情况下独立变化,客户端通过与这些策略对象进…

你还没有将 Siri 接入GPT对话功能吗?

由于各种原因,国内ios用户目前无缘自带 AI 功能,但是这并不代表国内 ios 无法接入 AI 功能,接下来手把手带你为iPhone siri 接入 gpt 对话功能。 siri 接入 chatGPT 暂时还无法下载 ChatGPT app,或者没有账号的读者可以直接跳到…

linux运维命令

防火墙相关命令 防火墙规则查看 firewall-cmd --list-all 禁ping firewall-cmd --permanent --add-rich-rulerule protocol valueicmp drop firewall-cmd --reload 执行完以上命令后,通过firewall-cmd --list-all查看规则生效情况 firewall-cmd --list-all 其…

矩阵乘法        ‌‍‎‏

矩阵乘法 C语言代码C 语言代码Java语言代码Python语言代码 💐The Begin💐点点关注,收藏不迷路💐 计算两个矩阵的乘法: 设有矩阵(A)为(nm)阶矩阵,矩阵(B)为(mk)阶矩阵,二者相乘得到的矩阵(C)是(…

docker更换容器存储位置

一:原因 今天之前在某个服务器上使用docker搭建的服务突然无法访问了,进入服务器查看发现服务运行正常,但是就是无法使用,然后我这边准备将docker服务重新启动下看看,发现docker服务无法重启,提示内存已满…

11.10VSCode配置 SSH连接远程服务器+免密连接教程

Jk200497 VScode通过remote ssh连接虚拟机 & 报错 过程试图写入的管道不存在(已解决)_连接虚拟机之后,提示管道错误,把上述路径加入到扩展中-CSDN博客 VSCode配置 SSH连接远程服务器免密连接教程

汽车EEA架构:架构的简介

1.架构的定义 汽车领域谈论的架构一词,来源于英文单词Architecture。在《系统架构:复杂系统的产品设计与开发》一书中对架构的定义如下:系统架构是一种概念的具象化,是物理或信息功能到形式元素的分配,是系统之内的元素之间的关系与周边环境…

Nginx下载、安装、启动及常用命令

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

Mac快速安装 chromedriver驱动

全篇大概1200字(含代码),建议阅读时间5分钟。 什么是chromedriver? ChromeDriver 充当了 Selenium WebDriver 和 Chrome 浏览器之间的桥梁,允许开发者通过编程控制浏览器进行自动化测试或操作。 一、下载chromedriver…

大数据项目-Django基于聚类算法实现的房屋售房数据分析及可视化系统

《[含文档PPT源码等]精品Django基于聚类算法实现的房屋售房数据分析及可视化系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程课程答疑等! 数据库管理工具:phpstudy/Navicat或者phpstudy/sqlyog 后台管理系统涉及技术: 后台使…

2024前端框架年度总结报告(二):新生qwik+solid和次新生svelte+Astro对比 -各自盯着前端的哪些个痛点 - 前端的区域发展差异

引言 2024年,前端开发依然是技术领域的热点之一。随着 Web 应用的日益复杂,前端框架的更新换代也加速了。尽管 React、Vue 和 Angular 老牌框架年度总结 等“老牌”框架仍然占据着主流市场,但一些新兴的框架在不断挑战这些“巨头”的地位&am…