Sono felice di accettare suggerimenti in R o Matlab, ma il codice che presento di seguito è solo R.
Il file audio allegato di seguito è una breve conversazione tra due persone. Il mio obiettivo è distorcere il loro discorso in modo che il contenuto emotivo diventi irriconoscibile. La difficoltà è che ho bisogno di spazio parametrico per questa distorsione diciamo da 1 a 5, dove 1 è "emozione altamente riconoscibile" e 5 è "emozione non riconoscibile". Ci sono tre modi in cui pensavo di poter usare per raggiungerlo con R.
Scarica un'onda audio "felice" da qui .
Scarica l'onda audio 'arrabbiata' da qui .
Il primo approccio è stato quello di ridurre l'intelligibilità generale introducendo rumore. Questa soluzione è presentata di seguito (grazie a @ carl-witthoft per i suoi suggerimenti). Ciò ridurrà sia l'intelligibilità sia il contenuto emotivo del discorso, ma è un approccio molto "sporco": è difficile renderlo corretto per ottenere lo spazio parametrico, poiché l'unico aspetto che puoi controllare è l'ampiezza (volume) del rumore.
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)
Il secondo approccio sarebbe in qualche modo regolare il rumore, distorcere il discorso solo nelle bande di frequenza specifiche. Ho pensato di poterlo fare estraendo l'inviluppo di ampiezza dall'onda audio originale, generare rumore da questo inviluppo e quindi riapplicare il rumore all'onda audio. Il codice seguente mostra come farlo. Fa qualcosa di diverso dal rumore stesso, fa spezzare il suono, ma torna allo stesso punto - che qui posso solo modificare l'ampiezza del rumore.
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)
L'approccio finale potrebbe essere la chiave per risolverlo, ma è piuttosto complicato. Ho trovato questo metodo nel rapporto pubblicato su Science da Shannon et al. (1996) . Hanno usato un modello piuttosto complesso di riduzione spettrale, per ottenere qualcosa che probabilmente suona abbastanza robotico. Ma allo stesso tempo, dalla descrizione, presumo che avrebbero potuto trovare la soluzione che potesse rispondere al mio problema. Le informazioni importanti si trovano nel secondo paragrafo nel testo e nella nota numero 7 in Riferimenti e note- l'intero metodo è descritto lì. I miei tentativi di replicarlo finora non hanno avuto successo, ma di seguito è riportato il codice che sono riuscito a trovare, insieme alla mia interpretazione di come dovrebbe essere eseguita la procedura. Penso che quasi tutti i puzzle ci siano, ma in qualche modo non riesco ancora a ottenere l'intera immagine.
###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
Come dovrebbe apparire il risultato? Dovrebbe essere qualcosa tra raucedine, un cracking rumoroso, ma non così tanto robotico. Sarebbe bello se il dialogo rimanesse in qualche modo comprensibile. Lo so - è tutto un po 'soggettivo, ma non ti preoccupare - suggerimenti selvaggi e interpretazioni vaghe sono i benvenuti.
Riferimenti:
- Shannon, RV, Zeng, FG, Kamath, V., Wygonski, J., E Ekelid, M. (1995). Riconoscimento vocale con segnali principalmente temporali. Science , 270 (5234), 303. Scarica da http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
per una varietà di valori di k non fa quello che vuoi? Tenendo presente, ovviamente, che "intelligibile" è altamente soggettivo. Oh, e probabilmente vuoi qualche dozzina di white_noise
campioni diversi per evitare effetti audio
casuali a causa della falsa correlazione tra e un singolo noise
file a valore casuale .