python - 给定信噪比,如何将干净的信号与噪声信号结合起来?
问题描述
当给定指定的 snr 时,我需要结合干净的音频信号和噪声音频信号。我发现这段代码适用于一些文件,但不适用于其他文件。如果此代码不起作用,那么有人可以建议一些其他替代方案或我应该采取的步骤。
import argparse
import array
import math
import numpy as np
import random
import wave
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('--clean_file', type=str, required=True)
parser.add_argument('--noise_file', type=str, required=True)
parser.add_argument('--output_mixed_file', type=str, default='', required=True)
parser.add_argument('--output_clean_file', type=str, default='')
parser.add_argument('--output_noise_file', type=str, default='')
parser.add_argument('--snr', type=float, default='', required=True)
args = parser.parse_args()
return args
def cal_adjusted_rms(clean_rms, snr):
a = float(snr) / 20
noise_rms = clean_rms / (10**a)
return noise_rms
def cal_amp(wf):
buffer = wf.readframes(wf.getnframes())
# The dtype depends on the value of pulse-code modulation. The int16 is set for 16-bit PCM.
amptitude = (np.frombuffer(buffer, dtype="<i2")).astype(np.float64)
return amptitude
def cal_rms(amp):
return np.sqrt(np.mean(np.square(amp), axis=-1))
def save_waveform(output_path, params, amp):
output_file = wave.Wave_write(output_path)
output_file.setparams(params) #nchannels, sampwidth, framerate, nframes, comptype, compname
output_file.writeframes(array.array('h', amp.astype(np.int16)).tobytes() )
output_file.close()
if __name__ == '__main__':
args = get_args()
clean_file = args.clean_file
noise_file = args.noise_file
clean_wav = wave.open(clean_file, "r")
noise_wav = wave.open(noise_file, "r")
clean_amp = cal_amp(clean_wav)
noise_amp = cal_amp(noise_wav)
clean_rms = cal_rms(clean_amp)
print(noise_amp," ",clean_amp)
print(len(noise_amp),len(clean_amp))
print(len(noise_amp)-len(clean_amp))
start = random.randint(0, (len(noise_amp)-len(clean_amp)))
divided_noise_amp = noise_amp[start: start + len(clean_amp)]
noise_rms = cal_rms(divided_noise_amp)
snr = args.snr
adjusted_noise_rms = cal_adjusted_rms(clean_rms, snr)
adjusted_noise_amp = divided_noise_amp * (adjusted_noise_rms / noise_rms)
mixed_amp = (clean_amp + adjusted_noise_amp)
#Avoid clipping noise
max_int16 = np.iinfo(np.int16).max
min_int16 = np.iinfo(np.int16).min
if mixed_amp.max(axis=0) > max_int16 or mixed_amp.min(axis=0) < min_int16:
if mixed_amp.max(axis=0) >= abs(mixed_amp.min(axis=0)):
reduction_rate = max_int16 / mixed_amp.max(axis=0)
else :
reduction_rate = min_int16 / mixed_amp.min(axis=0)
mixed_amp = mixed_amp * (reduction_rate)
clean_amp = clean_amp * (reduction_rate)
save_waveform(args.output_mixed_file, clean_wav.getparams(), mixed_amp)
我得到的错误是
Traceback (most recent call last):
File "mix.py", line 55, in <module>
start = random.randint(0, (len(noise_amp)-len(clean_amp)))
File "C:\AppData\Local\Programs\Python\Python38-32\lib\random.py", line 248, in randint
return self.randrange(a, b+1)
File "C:\AppData\Local\Programs\Python\Python38-32\lib\random.py", line 226, in randrange
raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (0, -47627, -47627)
我必须预处理信号吗?
解决方案
推荐阅读
- git - git如何分支4种不同的环境
- java - Apache gora,在减速器中设置新表名的位置
- java - 使用回收器视图和视图模型获取数据时,映射器函数返回空值
- python-3.x - 如何计算数据框中列中的变量数
- highcharts - 如何在 Timeline Highchart 中将鼠标悬停在鼠标悬停上聚焦或更改标签颜色?
- macos - 使用 javapackager 构建 mac 安装程序时将文件夹添加到 bundle
- html - 如何在formGroup内的formGroupName之间切换内容
- javascript - 为什么函数 getCard 的第二次调用返回甲板的第二次?
- google-apps-script - 从一个单元格值到现有单元格值的递归加法函数
- node.js - 如何删除大括号中的 npm 模块漏洞 babel-cli@6.23.0?