Python谱减法语音降噪实例

作者:zipaiyou 时间:2023-07-26 05:19:55 

代码中用到了nextpow2,其中n = nextpow2(x) 表示最接近x的2的n次幂。


#!/usr/bin/env python
import numpy as np
import wave
import nextpow2
import math

# 打开WAV文档
f = wave.open("filename.wav")
# 读取格式信息
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
fs = framerate
# 读取波形数据
str_data = f.readframes(nframes)
f.close()
# 将波形数据转换为数组
x = np.fromstring(str_data, dtype=np.short)
# 计算参数
len_ = 20 * fs // 1000
PERC = 50
len1 = len_ * PERC // 100
len2 = len_ - len1
# 设置默认参数
Thres = 3
Expnt = 2.0
beta = 0.002
G = 0.9
# 初始化汉明窗
win = np.hamming(len_)
# normalization gain for overlap+add with 50% overlap
winGain = len2 / sum(win)

# Noise magnitude calculations - assuming that the first 5 frames is noise/silence
nFFT = 2 * 2 ** (nextpow2.nextpow2(len_))
noise_mean = np.zeros(nFFT)

j = 0
for k in range(1, 6):
 noise_mean = noise_mean + abs(np.fft.fft(win * x[j:j + len_], nFFT))
 j = j + len_
noise_mu = noise_mean / 5

# --- allocate memory and initialize various variables
k = 1
img = 1j
x_old = np.zeros(len1)
Nframes = len(x) // len2 - 1
xfinal = np.zeros(Nframes * len2)

# =========================  Start Processing  ===============================
for n in range(0, Nframes):
 # Windowing
 insign = win * x[k-1:k + len_ - 1]
 # compute fourier transform of a frame
 spec = np.fft.fft(insign, nFFT)
 # compute the magnitude
 sig = abs(spec)

# save the noisy phase information
 theta = np.angle(spec)
 SNRseg = 10 * np.log10(np.linalg.norm(sig, 2) ** 2 / np.linalg.norm(noise_mu, 2) ** 2)

def berouti(SNR):
   if -5.0 <= SNR <= 20.0:
     a = 4 - SNR * 3 / 20
   else:
     if SNR < -5.0:
       a = 5
     if SNR > 20:
       a = 1
   return a

def berouti1(SNR):
   if -5.0 <= SNR <= 20.0:
     a = 3 - SNR * 2 / 20
   else:
     if SNR < -5.0:
       a = 4
     if SNR > 20:
       a = 1
   return a

if Expnt == 1.0: # 幅度谱
   alpha = berouti1(SNRseg)
 else: # 功率谱
   alpha = berouti(SNRseg)
 #############
 sub_speech = sig ** Expnt - alpha * noise_mu ** Expnt;
 # 当纯净信号小于噪声信号的功率时
 diffw = sub_speech - beta * noise_mu ** Expnt
 # beta negative components

def find_index(x_list):
   index_list = []
   for i in range(len(x_list)):
     if x_list[i] < 0:
       index_list.append(i)
   return index_list

z = find_index(diffw)
 if len(z) > 0:
   # 用估计出来的噪声信号表示下限值
   sub_speech[z] = beta * noise_mu[z] ** Expnt
   # --- implement a simple VAD detector --------------
   if SNRseg < Thres: # Update noise spectrum
     noise_temp = G * noise_mu ** Expnt + (1 - G) * sig ** Expnt # 平滑处理噪声功率谱
     noise_mu = noise_temp ** (1 / Expnt) # 新的噪声幅度谱
   # flipud函数实现矩阵的上下翻转,是以矩阵的“水平中线”为对称轴
   # 交换上下对称元素
   sub_speech[nFFT // 2 + 1:nFFT] = np.flipud(sub_speech[1:nFFT // 2])
   x_phase = (sub_speech ** (1 / Expnt)) * (np.array([math.cos(x) for x in theta]) + img * (np.array([math.sin(x) for x in theta])))
   # take the IFFT

xi = np.fft.ifft(x_phase).real
   # --- Overlap and add ---------------
   xfinal[k-1:k + len2 - 1] = x_old + xi[0:len1]
   x_old = xi[0 + len1:len_]
   k = k + len2
# 保存文件
wf = wave.open('outfile.wav', 'wb')
# 设置参数
wf.setparams(params)
# 设置波形文件 .tostring()将array转换为data
wave_data = (winGain * xfinal).astype(np.short)
wf.writeframes(wave_data.tostring())
wf.close()

来源:https://blog.csdn.net/weixin_41934101/article/details/81152172

标签:Python,谱减法,语音降噪
0
投稿

猜你喜欢

  • Python中非常实用的Math模块函数教程详解

    2022-12-08 02:12:49
  • .NET中开源文档操作组件DocX的介绍与使用

    2024-06-05 09:28:18
  • Bootstrap3制作自己的导航栏

    2023-08-23 02:13:08
  • citespace数据处理:用python对Ref文档进行去重方式

    2022-07-06 06:01:13
  • 浏览器用户体验:Firefox初体验 VS The world

    2008-08-02 11:58:00
  • python安装dlib库报错问题及解决方法

    2023-01-27 16:24:41
  • Python中生成Epoch的方法

    2021-06-27 15:21:15
  • 利用Python编写个有趣的记仇本

    2022-08-25 19:20:20
  • PHP设计模式 注册表模式(多个类的注册)

    2023-11-20 06:45:13
  • Python实例详解递归算法

    2023-05-17 02:25:06
  • 如何在js中使用FileSystemObject(fso)

    2007-09-23 09:10:00
  • 对python的文件内注释 help注释方法

    2021-12-20 18:12:46
  • python实现本地批量ping多个IP的方法示例

    2023-12-19 02:36:36
  • 分页存储过程(二)在sqlserver中返回更加准确的分页结果

    2024-01-13 03:42:43
  • Django Admin中增加导出CSV功能过程解析

    2021-04-17 06:22:47
  • vue-cli-service build 环境设置方式

    2024-05-25 15:17:08
  • 360搜索引擎自动收录php改写方案

    2024-05-11 09:19:26
  • 有关asp的系统变量ServerVariables (“HTTP_USER_AGENT“)?

    2009-10-29 12:12:00
  • 开心网让人很不开心

    2009-04-05 15:56:00
  • PHP仿微信多图片预览上传实例代码

    2024-05-03 15:27:45
  • asp之家 网络编程 m.aspxhome.com