Z przyjemnością przyjmuję sugestie w języku R lub Matlab, ale kod, który przedstawiam poniżej, jest tylko w języku R.
Załączony poniżej plik audio to krótka rozmowa między dwojgiem ludzi. Moim celem jest zniekształcenie ich mowy, aby treść emocjonalna stała się nie do poznania. Trudność polega na tym, że potrzebuję trochę przestrzeni parametrycznej dla tego zniekształcenia, powiedzmy od 1 do 5, gdzie 1 to „bardzo rozpoznawalna emocja”, a 5 to „nie rozpoznawalna emocja”. Są trzy sposoby, dzięki którym mogę to osiągnąć dzięki R.
Pobierz „szczęśliwą” falę dźwiękową stąd .
Pobierz „gniewną” falę dźwiękową stąd .
Pierwsze podejście polegało na zmniejszeniu ogólnej zrozumiałości poprzez wprowadzenie hałasu. To rozwiązanie zostało przedstawione poniżej (dzięki @ carl-witthoft za jego sugestie). Zmniejszy to zarówno zrozumiałość, jak i treść emocjonalną mowy, ale jest to bardzo „brudne” podejście - trudno jest odpowiednio ustawić przestrzeń parametryczną, ponieważ jedynym aspektem, który można kontrolować, jest amplituda (głośność) hałasu.
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)
Drugim podejściem byłoby jakoś dostosowanie szumu, zniekształcenie mowy tylko w określonych pasmach częstotliwości. Pomyślałem, że mogę to zrobić, wydobywając obwiednię amplitudy z oryginalnej fali audio, generując hałas z tej obwiedni, a następnie ponownie stosując szum do fali dźwiękowej. Poniższy kod pokazuje, jak to zrobić. Robi coś innego niż sam hałas, powoduje trzaskanie dźwięku, ale wraca do tego samego punktu - że mogę tutaj zmienić tylko amplitudę hałasu.
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)
Ostateczne podejście może być kluczem do rozwiązania tego, ale jest dość trudne. Znalazłem tę metodę w artykule opublikowanym w Science przez Shannon i in. (1996) . Zastosowali dość skomplikowany wzór redukcji widmowej, aby osiągnąć coś, co prawdopodobnie brzmi dość robotycznie. Ale jednocześnie z opisu zakładam, że mogli znaleźć rozwiązanie, które mogłoby rozwiązać mój problem. Ważna informacja znajduje się w drugim akapicie tekstu i uwadze nr 7 w Odwołaniach i uwagach- cała metoda jest tam opisana. Moje dotychczasowe próby replikacji zakończyły się niepowodzeniem, ale poniżej znajduje się kod, który udało mi się znaleźć, wraz z moją interpretacją tego, jak należy wykonać procedurę. Myślę, że są tam prawie wszystkie zagadki, ale jakoś nie mogę jeszcze uzyskać całego obrazu.
###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
Jak więc powinien brzmieć wynik? Powinno to być coś pomiędzy chrypką, hałaśliwym trzaskaniem, ale nie tyle robotycznym. Byłoby dobrze, gdyby dialog pozostał do pewnego stopnia zrozumiały. Wiem - wszystko jest trochę subiektywne, ale nie martw się tym - dzikie sugestie i luźne interpretacje są bardzo mile widziane.
Bibliografia:
- Shannon, RV, Zeng, FG, Kamath, V., Wygonski, J., i Ekelid, M. (1995). Rozpoznawanie mowy z użyciem przede wszystkim wskazówek czasowych. Science , 270 (5234), 303. Pobierz z http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
różnych wartości k, aby robić to, co chcesz? Oczywiście należy pamiętać, że „zrozumiały” jest wysoce subiektywny. Aha, i zapewne chcesz kilkudziesięciu różnych white_noise
próbek, aby uniknąć przypadkowych efektów z powodu fałszywej korelacji między audio
jednym noise
plikiem o losowej wartości .