Dégradation paramétrique du discours pour supprimer le contenu émotionnel

12

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)

entrez la description de l'image ici

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)

entrez la description de l'image ici

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:

Geek On Acid
la source
Une approche simple serait de moduler, donc de multiplier, la voix avec le (bruit + 1.0). Mais une autre question: qu'essayez-vous de faire? Quel est votre objectif sous-jacent, lorsque vous rendez les voix inintelligibles?
1
Pourquoi ne pas simplement faire noisy <- audio + k*white_noisepour 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 audioet un seul noisefichier à valeur aléatoire .
En fin de compte, je veux diminuer de manière paramétrique la fiabilité des informations auditives, de sorte que les jugements de précision diffèrent pour différents niveaux de clip audio manipulé. Le jugement de précision portera sur l'émotion - que la conversation soit heureuse ou en colère. Le problème est qu'il est extrêmement difficile de manipuler le contenu émotionnel d'un long discours (comme mon clip ci-dessus). Les gens le font avec une seule voyelles, mais pas les phrases entières. J'ai donc décidé de généraliser la question et de trouver le moyen de dégrader paramétriquement l'ensemble du spectre des informations audio.
@CarlWitthoft Votre solution ajuste uniquement l'amplitude du bruit, et comme je l'ai dit - j'ai besoin de quelque chose qui mélange le bruit avec le signal. Vous attribuer +1 à la suggestion que j'ai besoin de différents échantillons de bruit blanc - cela pourrait en effet faire une différence, comme vous l'avez souligné.
Eh bien ... je plaide l'ignorance ici: quelle est la définition mathématique du "mixage" de deux flux audio? Je supposais naïvement que, en laissant de côté l'existence d'un filtre programmable, tout ce que vous pouvez faire avec deux vecteurs d'amplitudes échantillonnées dans le temps est de les ajouter.

Réponses:

11

J'ai lu votre question initiale et je ne savais pas trop où vous vouliez en venir, mais c'est beaucoup plus clair maintenant. Le problème que vous avez est que le cerveau est extrêmement doué pour détecter la parole et les émotions, même lorsque le bruit de fond est très élevé, ce qui signifie que vos tentatives existantes n'ont connu qu'un succès limité.

Je pense que la clé pour obtenir ce que vous voulez est de comprendre les mécanismes qui véhiculent le contenu émotionnel car ils sont pour la plupart séparés de ceux qui véhiculent l'intelligibilité. J'ai une certaine expérience à ce sujet (en fait, ma thèse était sur un sujet similaire), je vais donc essayer de proposer quelques idées.

Considérez vos deux échantillons comme des exemples de discours très émotifs, puis considérez ce qui serait un exemple "sans émotion". Le mieux que je puisse penser en ce moment est la voix de type "Stephen Hawking" générée par ordinateur. Donc, si je comprends bien, ce que vous voulez faire, c'est comprendre les différences entre eux et comprendre comment déformer vos échantillons pour devenir progressivement comme une voix sans émotion générée par ordinateur.

Je dirais que les deux principaux mécanismes pour obtenir ce que vous voulez sont via la distorsion de hauteur et de temps, car une grande partie du contenu émotionnel est contenue dans l'intonation et le rythme du discours. Donc, une suggestion de quelques choses qui pourraient valoir la peine d'être essayées:

  1. Un effet de type distorsion de hauteur qui plie la hauteur et réduit l'intonation. Cela pourrait être fait de la même manière que Antares Autotune fonctionne où vous pliez progressivement la hauteur vers une valeur constante de plus en plus jusqu'à ce qu'elle soit un monotone complet.

  2. Un effet d'étirement temporel qui modifie la longueur de certaines parties du discours - peut-être les phonèmes à voix constante qui briseraient le rythme du discours.

Maintenant, si vous décidez d'approcher l'une ou l'autre de ces méthodes, je vais être honnête - elles ne sont pas si simples à implémenter dans DSP et ce ne sera pas seulement quelques lignes de code. Vous allez devoir travailler pour comprendre le traitement du signal. Si vous connaissez quelqu'un avec Pro-Tools / Logic / Cubase et une copie d'Antares Autotune, alors il vaudrait probablement la peine d'essayer de voir si cela aura l'effet souhaité avant d'essayer de coder quelque chose de similaire vous-même.

J'espère que cela vous donne quelques idées et vous aide un peu. Si vous avez besoin de moi pour expliquer l'une des choses que j'ai dites, faites le moi savoir.

Redeye
la source
Merci pour vos suggestions @Redeye. L'étirement temporel n'est malheureusement pas une option, car il y aura une condition dans laquelle je leur présenterai les informations vidéo, donc je dois garder le discours modifié de la même longueur que l'original. La distorsion de hauteur est une approche intéressante - connaissez-vous des références publiées pour mieux expliquer cette méthode?
Geek On Acid le
1
Le pitch shifting de la parole pour faire ce que vous voulez impliquera deux étapes - d'une part l'analyse du discours pour établir le profil de fréquence fondamental actuel, et d'autre part le pitch shift. L'analyse est assez simple et plusieurs méthodes sont efficaces. Le pitch shifting est plus complexe - j'essaierais de chercher dans le journal AES les références publiées (JAES Volume 47 Numéro 11 pp. 928-936; novembre 1999 semble utile). Comme je l'ai déjà dit, vous vous lancez dans un traitement assez complexe ici et cela vaut vraiment la peine de l'essayer avec Autotune en premier.
Redeye
2
Redeye a de bonnes suggestions, mais je voudrais simplement noter que pour la parole avec décalage de hauteur, je ne recommanderais pas le vocodeur de phase ou toute approche dans le domaine des fréquences - PSOLA (ajout de chevauchement synchrone) est une bonne façon de faire car il sonnera mieux pour un instrument à verrouillage de phase monophonique comme la voix.
schnarf
4

Je vous suggère de vous procurer un logiciel de production musicale et de jouer avec pour obtenir l'effet que vous souhaitez. Ce n'est qu'alors que vous devriez vous soucier de résoudre ce problème par programme. (Si votre logiciel de musique peut être appelé à partir d'une ligne de commande, vous pouvez l'appeler à partir de R ou MATLAB).


Une autre possibilité qui n'a pas été discutée est de supprimer complètement l'émotion en utilisant un logiciel de synthèse vocale pour créer une chaîne, puis un logiciel de synthèse vocale pour transformer cette chaîne en voix de robot. Voir /programming/491578/how-do-i-convert-speech-to-text et /programming/637616/open-source-text-to-speech-library .

Pour que cela fonctionne de manière fiable, vous devrez probablement former le premier logiciel à reconnaître le haut-parleur.

Richie Cotton
la source
J'ai besoin de filtrer les fichiers originaux pour que la synthèse vocale ne soit malheureusement pas vraiment une option, bien que je puisse penser à un paradigme de morphing entre la parole normale et la parole synthétique.
Geek On Acid le