Estoy feliz de aceptar sugerencias en R o Matlab, pero el código que presento a continuación es solo para R.
El archivo de audio adjunto a continuación es una breve conversación entre dos personas. Mi objetivo es distorsionar su discurso para que el contenido emocional se vuelva irreconocible. La dificultad es que necesito un espacio paramétrico para esta distorsión, digamos del 1 al 5, donde 1 es 'emoción altamente reconocible' y 5 es 'emoción no reconocible'. Hay tres formas que pensé que podría usar para lograr eso con R.
Descargue la onda de audio 'feliz' desde aquí .
Descargue la onda de audio 'enojado' desde aquí .
El primer enfoque fue disminuir la inteligibilidad general mediante la introducción de ruido. Esta solución se presenta a continuación (gracias a @ carl-witthoft por sus sugerencias). Esto disminuirá tanto la inteligibilidad como el contenido emocional del discurso, pero es un enfoque muy 'sucio': es difícil hacer lo correcto para obtener el espacio paramétrico, porque el único aspecto que puede controlar allí es una amplitud (volumen) de ruido.
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)
El segundo enfoque sería ajustar de alguna manera el ruido, distorsionar el habla solo en las bandas de frecuencia específicas. Pensé que podría hacerlo extrayendo la envolvente de amplitud de la onda de audio original, generar ruido a partir de esta envolvente y luego volver a aplicar el ruido a la onda de audio. El siguiente código muestra cómo hacerlo. Hace algo diferente al ruido en sí, hace que el sonido se agriete, pero vuelve al mismo punto: que solo soy capaz de cambiar la amplitud del ruido aquí.
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)
El enfoque final podría ser la clave para resolver esto, pero es bastante complicado. Encontré este método en un informe publicado en Science por Shannon et al. (1996) . Utilizaron un patrón bastante complejo de reducción espectral para lograr algo que probablemente suene bastante robótico. Pero al mismo tiempo, a partir de la descripción, supongo que podrían haber encontrado la solución que podría resolver mi problema. La información importante se encuentra en el segundo párrafo del texto y la nota número 7 en Referencias y Notas.- Todo el método se describe allí. Mis intentos de replicarlo hasta ahora no han tenido éxito, pero a continuación se muestra el código que pude encontrar, junto con mi interpretación de cómo se debe realizar el procedimiento. Creo que casi todos los acertijos están ahí, pero todavía no puedo entender la imagen completa.
###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
Entonces, ¿cómo debería sonar el resultado? Debería ser algo entre la ronquera, un crujido ruidoso, pero no tanto robótico. Sería bueno si el diálogo se mantuviera hasta cierto punto inteligible. Lo sé, todo es un poco subjetivo, pero no te preocupes por eso, son bienvenidas las sugerencias salvajes y las interpretaciones sueltas.
Referencias
- Shannon, RV, Zeng, FG, Kamath, V., Wygonski, J. y Ekelid, M. (1995). Reconocimiento de voz con señales principalmente temporales. Science , 270 (5234), 303. Descargar desde http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
hacer lo que quieres para una variedad de valores de k? Teniendo en cuenta, por supuesto, que "inteligible" es altamente subjetivo. Ah, y probablemente desee unas pocas docenas de white_noise
muestras diferentes para evitar cualquier efecto coincidente debido a la falsa correlación entre audio
y un único noise
archivo de valor aleatorio .