参数化降级语音以去除情感内容

信息处理 matlab 声音的 噪音
2021-12-27 08:07:55

我很高兴接受 R 或 Matlab 中的建议,但我在下面提供的代码仅适用于 R。

下面附上的音频文件是两个人之间的一段简短对话。我的目标是扭曲他们的言论,使情感内容变得无法辨认。困难在于我需要一些参数空间来处理这种失真,比如说从 1 到 5,其中 1 是“高度可识别的情绪”,而 5 是“不可识别的情绪”。我认为我可以使用三种方法来使用 R 实现这一目标。

从这里下载“快乐”的音频波

从这里下载“愤怒”的音频波

第一种方法是通过引入噪声来降低整体可懂度。该解决方案如下所示(感谢@carl-witthoft 的建议)。这会降低语音的可理解性和情感内容,但这是非常“肮脏”的方法 - 很难正确获得参数空间,因为您可以控制的唯一方面是噪声的幅度(音量)。

require(seewave)
require(tuneR)
require(signal)
h <- readWave("happy.wav")
h <- cutw(h.norm,f=44100,from=0,to=2)#cut down to 2 sec
n <- noisew(d=2,f=44100)#create 2-second white noise
h.n <- h + n #combine audio wave with noise
oscillo(h.n,f=44100)#visualize wave with noise(black)
par(new=T)
oscillo(h,f=44100,colwave=2)#visualize original wave(red)

在此处输入图像描述

第二种方法是以某种方式调整噪声,仅在特定频带中扭曲语音。我想我可以通过从原始音频波中提取幅度包络,从这个包络产生噪声,然后将噪声重新应用于音频波来做到这一点。下面的代码显示了如何做到这一点。它的作用与噪声本身不同,使声音开裂,但它又回到了同一点——我只能在这里改变噪声的幅度。

n.env <- setenv(n, h,f=44100)#set envelope of noise 'n'
h.n.env <- h + n.env #combine audio wave with 'envelope noise'
par(mfrow=c(1,2))
spectro(h,f=44100,flim=c(0,10),scale=F)#spectrogram of normal wave (left)
spectro(h.n.env,f=44100,flim=c(0,10),scale=F,flab="")#spectrogram of wave with 'envelope noise' (right)

在此处输入图像描述

最后的方法可能是解决这个问题的关键,但它非常棘手。我在Shannon 等人在Science上发表的报告论文中发现了这种方法。(1996 年)他们使用了相当棘手的频谱缩减模式,以实现听起来很机器人的东西。但同时,从描述中,我认为他们可能已经找到了可以解决我的问题的解决方案。重要信息在正文的第二段和参考文献和注释中的注释编号 7- 那里描述了整个方法。到目前为止,我尝试复制它并没有成功,但下面是我设法找到的代码,以及我对如何完成该过程的解释。我认为几乎所有的谜题都在那里,但我还不能以某种方式了解整个画面。

###signal was passed through preemphasis filter to whiten the spectrum 
#low-pass below 1200Hz, -6 dB per octave
h.f <- ffilter(h,to=1200)#low-pass filter up to 1200 Hz (but -6dB?)

###then signal was split into frequency bands (third-order elliptical IIR filters)
#adjacent filters overlapped at the point at which the output from each filter 
#was 15dB down from the level in the pass-band
#I have just a bunch of options I've found in 'signal'
ellip()#generate an Elliptic or Cauer filter
decimate()#downsample a signal by a factor, using an FIR or IIR filter
FilterOfOrder()#IIR filter specifications, including order, frequency cutoff, type...
cutspec()#This function can be used to cut a specific part of a frequency spectrum

###amplitude envelope was extracted from each band by half-wave rectification 
#and low-pass  filtering
###low-pass filters (elliptical IIR filters) with cut-off frequencies of:
#16, 50, 160 and 500 Hz (-6 dB per octave) were used to extract the envelope

###envelope signal was then used to modulate white noise, which was then 
#spectrally limited by the same bandpass filter used for the original signal

那么结果应该如何呢?它应该介于声音嘶哑和嘈杂的破裂声之间,但不是机器人。如果对话在某种程度上可以理解,那就太好了。我知道 - 这有点主观,但不要担心 - 非常欢迎野蛮的建议和松散的解释。

参考:

2个回答

我读了你原来的问题,不太确定你在说什么,但现在清楚多了。您遇到的问题是,即使背景噪音非常高,大脑也非常擅长识别语言和情绪,而您现有的尝试只取得了有限的成功。

我认为获得你想要的东西的关键是理解传达情感内容的机制,因为它们大多与传达可理解性的机制是分开的。我对此有一些经验(实际上我的学位论文是关于类似主题的),所以我会尝试提供一些想法。

将您的两个样本视为非常情绪化的演讲示例,然后考虑什么是“没有情绪”的示例。我现在能想到的最好的是计算机生成的“斯蒂芬霍金”式的声音。所以,如果我理解正确,你想做的是了解它们之间的差异,并弄清楚如何扭曲你的样本,使其逐渐变得像计算机生成的无感情的声音。

我想说,获得你想要的东西的两个主要机制是通过音高和时间失真,因为很多情感内容都包含在语音的语调和节奏中。因此,建议您尝试一些可能值得尝试的事情:

  1. 一种音高失真型效果,可弯曲音高并降低语调。这可以与 Antares Autotune 的工作方式相同,您逐渐将音高逐渐弯曲到一个恒定值,直到它成为一个完整的单调。

  2. 一种时间拉伸效应,它改变了语音某些部分的长度——也许是不断的浊音音素,这会破坏语音的节奏。

现在,如果您决定采用这两种方法中的任何一种,那么老实说 - 它们在 DSP 中实现起来并不是那么简单,而且不会只是几行代码。你需要做一些工作来理解信号处理。如果您知道有人使用 Pro-Tools/Logic/Cubase 和 Antares Autotune 的副本,那么在尝试自己编写类似的代码之前,可能值得尝试看看它是否会产生您想要的效果。

我希望这能给你一些想法并有所帮助。如果您需要我解释我所说的任何事情,请告诉我。

我建议你买一些音乐制作软件并使用它来获得你想要的效果。只有这样你才应该担心以编程方式解决这个问题。(如果您的音乐软件可以从命令行调用,那么您可以从 R 或 MATLAB 调用它)。


另一种尚未讨论的可能性是通过使用语音转文本软件创建一个字符串,然后使用文本转语音软件将该字符串转换为机器人声音来完全去除情感。请参阅 https://stackoverflow.com/questions/491578/how-do-i-convert-speech-to-texthttps://stackoverflow.com/questions/637616/open-source-text-to-speech-library .

为了让它可靠地工作,您可能必须训练第一个软件来识别扬声器。