Я рад принять предложения в R или Matlab, но приведенный ниже код предназначен только для R.
Аудиофайл, прикрепленный ниже, представляет собой небольшую беседу между двумя людьми. Моя цель - исказить их речь, чтобы эмоциональное содержание стало неузнаваемым. Сложность в том, что мне нужно некоторое параметрическое пространство для этого искажения, скажем, от 1 до 5, где 1 - это «хорошо распознаваемая эмоция», а 5 - «неузнаваемая эмоция». Я думал, что могу достичь этого тремя способами.
Загрузите «счастливую» звуковую волну отсюда .
Загрузите «сердитую» звуковую волну отсюда .
Первый подход состоял в том, чтобы уменьшить общую разборчивость путем введения шума. Это решение представлено ниже (спасибо @ 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)
Окончательный подход может быть ключом к решению этой проблемы, но это довольно сложно. Я нашел этот метод в отчете, опубликованном в Science Shannon et al. (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
Так как должен звучать результат? Это должно быть что-то среднее между хрипотой, шумным треском, но не таким уж роботизированным. Было бы хорошо, если бы диалог оставался в какой-то степени понятным. Я знаю - это все немного субъективно, но не беспокойтесь об этом - дикие предложения и свободные толкования очень приветствуются.
Ссылки:
- Шеннон Р.В., Зенг Ф.Г., Камат В., Вигонски Дж. И Экелид М. (1995). Распознавание речи с преимущественно временными сигналами. Science , 270 (5234), 303. Скачать с http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
для различных значений k то, что вы хотите? Конечно, помнить, что «вразумительный» очень субъективно. О, и вы, вероятно, хотите, чтобы несколько десятков различных white_noise
выборок избежали каких-либо случайных эффектов из-за ложной корреляции между audio
одним noise
файлом случайных значений .