Я радий приймати пропозиції або в 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). Розпізнавання мовлення за допомогою насамперед часових підказів. Наука , 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
файлом і випадковим значенням .