Je suis heureux d'accepter des suggestions dans R ou Matlab, mais le code que je présente ci-dessous est uniquement R.
Le fichier audio ci-dessous est un court morceau de conversation entre deux personnes. Mon objectif est de déformer leur discours afin que le contenu émotionnel devienne méconnaissable. La difficulté est que j'ai besoin d'un espace paramétrique pour cette distorsion, disons de 1 à 5, où 1 est «émotion hautement reconnaissable» et 5 est «émotion non reconnaissable». Il y a trois façons que je pensais pouvoir utiliser pour y parvenir avec R.
Téléchargez l'onde audio «heureuse» d' ici .
Téléchargez l'onde audio «en colère» d' ici .
La première approche a été de diminuer l'intelligibilité globale en introduisant du bruit. Cette solution est présentée ci-dessous (merci à @ carl-witthoft pour ses suggestions). Cela réduira à la fois l'intelligibilité et le contenu émotionnel du discours, mais c'est une approche très `` sale '' - il est difficile de bien faire pour obtenir l'espace paramétrique, car le seul aspect que vous pouvez contrôler est une amplitude (volume) de bruit.
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)
La deuxième approche consisterait à régler le bruit en quelque sorte, pour déformer la parole uniquement dans les bandes de fréquences spécifiques. J'ai pensé que je pouvais le faire en extrayant l'enveloppe d'amplitude de l'onde audio d'origine, générer du bruit à partir de cette enveloppe, puis ré-appliquer le bruit à l'onde audio. Le code ci-dessous montre comment procéder. Il fait quelque chose de différent du bruit lui-même, fait craquer le son, mais il revient au même point - que je ne peux que modifier l'amplitude du bruit ici.
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'approche finale pourrait être la clé pour résoudre ce problème, mais c'est assez délicat. J'ai trouvé cette méthode dans un rapport publié dans Science par Shannon et al. (1996) . Ils ont utilisé un modèle de réduction spectrale assez délicat pour obtenir quelque chose qui semble probablement assez robotique. Mais en même temps, d'après la description, je suppose qu'ils ont peut-être trouvé la solution qui pourrait répondre à mon problème. Les informations importantes se trouvent dans le deuxième paragraphe du texte et la note numéro 7 dans les références et les notes- toute la méthode y est décrite. Mes tentatives pour le reproduire jusqu'à présent ont été infructueuses, mais voici le code que j'ai réussi à trouver, ainsi que mon interprétation de la façon dont la procédure doit être effectuée. Je pense que presque tous les puzzles sont là, mais je ne peux pas encore obtenir une image complète.
###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
Alors, comment devrait résulter le résultat? Cela devrait être quelque chose entre l'enrouement, un craquement bruyant, mais pas tellement robotique. Il serait bon que le dialogue reste dans une certaine mesure intelligible. Je sais - tout cela est un peu subjectif, mais ne vous inquiétez pas à ce sujet - les suggestions folles et les interprétations lâches sont les bienvenues.
Les références:
- Shannon, RV, Zeng, FG, Kamath, V., Wygonski, J., et Ekelid, M. (1995). Reconnaissance vocale avec des indices principalement temporels. Science , 270 (5234), 303. Télécharger depuis http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
pour une variété de valeurs de k ce que vous voulez? Garder à l'esprit, bien sûr, que «intelligible» est hautement subjectif. Oh, et vous voulez probablement quelques dizaines d' white_noise
échantillons différents pour éviter tout effet de coïncidence dû à une fausse corrélation entre audio
et un seul noise
fichier à valeur aléatoire .